Найменша кількість суміжних монотонних підрядів


23

Опис виклику

Монотонна підпослідовність є послідовність чисел , [a1, a2, ..., an]таких , що

a1 <= a2 <= ... <= anабо a1 >= a2 >= ... >= an. [1, 3, 3, 7, 9, 13, 13, 100]є монотонним (не спадаючим) підпорядком, як і [9, 4, 4, 3, 0, -10, -12](цей не збільшується), але [1, 3, 6, 9, 8]це не так. Враховуючи список цілих чисел (у будь-якому розумному форматі), виведіть найменше число Nтаким чином, щоб послідовність цих цілих чисел можна розділити на Nмонотонні послідовності.

Приклади

[1, 3, 7, 5, 4, 2] -> [[1, 3, 7], [5, 4, 2]] -> 2
[1, 2, 3, 4, 5, 6] -> [1, 2, 3, 4, 5, 6]     -> 1
[3, 1, 5, 5, 6]    -> [[3, 1], [5, 5, 6]]    -> 2
[4, 6, 8, 9, 1, 6] -> [[4, 6, 8, 9], [1, 6]] -> 2
[3, 3, 3, 3]       -> [[3, 3, 3, 3]]         -> 1
[7]                -> [[7]]                  -> 1
[]                 -> []                     -> anything (you don't actually have to handle an empty list case)
[1, 3, 2, -1, 6, 9, 10, 2, 1, -12] -> [[1, 3], [2, -1], [6, 9, 10], [2, 1, -12]] -> 4

Щоб уточнити, подальший підхід повинен бути суміжним, правда?
Згарб

@ Zgarb Так, вони.
shooqie

3
Я рекомендую додати тестовий випадок, коли послідовності не завжди йдуть у зворотному напрямку: [4,4,8,8,1,4,5] -> 2
Натан Меррілл

@NathanMerrill: Хороший момент, додали один.
shooqie

Коли ви пишете, що для порожнього рядка, результат є 0 / undefined, це здається, що це повинно бути або 0, або представленням undefinedнашої мови, але з вашого коментаря до відповіді Джонатана Аллана Jelly, це виглядає як undefinedозначає anything... Який це? ? У другому випадку я б запропонував написати anythingзамістьundefined
Dada

Відповіді:


6

Брахілог , 12 байт

~c:{<=|>=}al

Спробуйте в Інтернеті!

Це повертається false.до порожнього списку [].

Пояснення

(?)~c                 Take a list of sublists which when concatenated result in the Input
     :{<=|>=}a        Each sublist must be either increasing or decreasing
              l(.)    Output is the length of that list

Це поверне найменший, оскільки ~cстворить очки вибору від найменшої кількості списків до найбільшої.


Що таке аргумент "Z" у посиланні TIO? (Схоже, це частина програми, як аргумент командного рядка).
Джонатан Аллан

@JonathanAllan Цей аргумент є результатом. В ідеалі, якби ми могли налаштувати інтерфейс TIO, не було б аргументів Input and Output, а аргументів немає. Аргумент Zтому Z, що це ім'я змінної; тому ми говоримо "викликайте цю програму з Виведенням як змінну". Ви можете змінити Zв будь-який інший великої літери ; це лише назва змінної. Причина цього аргументу полягає в тому, щоб дозволити можливість фактично встановити вихід на щось, а не на змінну.
фаталізувати

(Наприклад, якщо ви встановите результат 4у цьому прикладі, він підкаже, чи правильно це чи ні )
Fatalize

1
@JonathanAllan Будь-яка мова, подібна до Prolog, виглядає так: предикати можуть лише успішно або не вдаватися і не повертати жодного значення. Отже, щоб отримати вихід, необхідно мати аргумент змінної предиката, який отримає уніфікований результат.
Фаталізувати

1
@JonathanAllan Це врешті-решт не вдасться, 3оскільки він не знайде жодного списку підсписок, де всі монотонні та за довжиною 3. Це займе тривалий час, тому що він спробує всі можливі списки списків, навіть ті, які насправді довші трьох елементів, оскільки довжина перевіряється після знаходження списку. Адже 5це говорить trueтому, що дійсно є хоча б один список довжини 5з монотонними підсписками, який працює. Отже, ця програма повертає найменшу довжину, коли вихід є змінною і чи є якийсь список тієї довжини, який працює, якщо вихід є цілим числом.
Фаталізувати

4

Perl, 65 байт

62 байти коду + 3 байти для -nпрапора.

monot_seq.pl:

#!perl -n
s/\S+ /($_<=>$&)*($&<=>$')-$g>=0?$g=1:$.++;$g--;$_=$&/ge,$_=$.

Введіть введення без остаточного нового рядка з цифрами, розділеними пробілами:

$ echo -n "1 3 2 -1 6 9 10 2 1 -12" | perl -M5.010 monot_seq.pl
4

-5 байт завдяки @Gabriel Benamy.


Збережіть 5 байт, перетворившись ($&<=>$1)*($1<=>$2)||$1==$2на($&<=>$1)*($1<=>$2)>=0
Габріель Бенамі

@GabrielBenamy Дійсно, дякую.
Дада

2

Математика, 111 байт

d=#[[2]]-#[[1]]&;r=Rest;f@{n_}:=1;f@k__:=If[d@k==0,f@r@k,g[k Sign@d@k]];g@{n_}:=1;g@k__:=If[d@k>0,g@r@k,1+f@r@k]

Названа функція, що fприймає не порожній список чисел (цілих чисел і навіть дійсних цифр). Працює спереду та назад, відкидаючи перший елемент неодноразово та відстежуючи, скільки підпорядків потрібно. Більш докладно:

d = #[[2]] - #[[1]] &;         function: difference of the first two elements
r = Rest;                      function: a list with its first element dropped
f@{n_} := 1;                   f of a length-1 list equals 1
f@k__ := If[d@k == 0, f@r@k,   if the first two elements are equal, drop one
                                 element and call f again ...
            g[k Sign@d@k]];  ... otherwise call the helper function g on the
                                 list, multiplying by -1 if necessary to ensure
                                 that the list starts with an increase
g@{n_} := 1;                   g of a length-1 list equals 1
g@k__ := If[d@k > 0, g@r@k,    if the list starts with an increase, drop one
                                 element and call g again ...
            1 + f@r@k];        ... otherwise drop one element, call f on the
                                 resulting list, and add 1

d=#2-#&@@#&;також, визначивши fабо gяк оператор унарного ±, ймовірно, буде збережено кілька байт.
Мартін Ендер

2

Желе , 19 байт

IṠḟ0E
ŒṖÇ€€0e$Ðḟḅ1Ṃ

СпробуйтеItOnline! або запустити всі тести (порожній список результатів1)

Як?

IṠḟ0E - Link 1, test for monotonicity: a sublist
I     - incremental differences
 Ṡ    - sign {fall:-1; same:0; rise:1}
  ḟ0  - filter out the zeros
    E - all equal?

ŒṖÇ€€0e$Ðḟḅ1Ṃ - Main link
ŒṖ            - all partitions of the input list
  Ç€€         - call last link (1) as a monad for €ach for €ach
        Ðḟ    - filter out results:
       $      -    last two links as a monad
     0e       -        contains zero?
          ḅ1  - convert from unary (vectorises)
            Ṃ - minimum

(Я не переконаний, що це найбільш підходящий метод для мінімізації кількості байтів)


@shooqie - Чи можемо ми повернути будь-яке значення для порожнього списку з огляду на "невизначений" коментар? Це повертається 1(що, я думаю, має сенс більше 0).
Джонатан Аллан

1
Я маю на увазі, ось що undefinedозначає - результат не має значення.
shooqie

2

Perl, 98 97 96 79 байт

($a,$b)=($a<=>$b)*($b<=>$c)<0?($c,shift,$d++):($b,$c)while$c=shift;say$d+1 if$a

Введення надається у вигляді списку чисел, розділених пробілами, наданих під час виконання, наприклад

perl -M5.010 monotonic.pl 1 3 2 -1 6 9 10 2 1 -12
4

(4 - вихід)

Читає:

($a,$b)=($a<=>$b)*($b<=>$c)<0
    ?($c,shift,$d++)
    :($b,$c)
  while$c=shift;
say$d+1
  if$a

Оператор космічного корабля <=>повертає -1, якщо LHS <RHS, 0, якщо LHS = RHS, і +1, якщо LHS> RHS. При порівнянні трьох послідовних елементів , $a,$b,$cщоб визначити , якщо вони монотонні, необхідно тільки визначити , що це не той випадок , що саме один з $a<=>$b, $b<=>$cє 1 , а іншим -1 - що відбувається тільки тоді , коли їх продукт -1. Якщо або $a==$bабо $b==$c, то послідовність є монотонною, а добуток дорівнює 0. Якщо $a < $b < $c, то обидва призводять до -1, а -1 * -1 = 1. Якщо $a > $b > $c, то вони обидва приводять до 1, а 1 * 1 = 1. У будь-якому випадку послідовність є монотонною, і ми хочемо продовжувати.

Якщо продукту менше 0, ми знаємо, що послідовність не є монотонною, і ми відкидаємо значення, які $a,$bми зараз тримаємо, і збільшуємо свій лічильник підпорядкування . В іншому випадку ми рухаємось вперед на одне число.

Нічого не повертає, якщо вхід порожній, інакше повертається найменша кількість суміжних монотонних підрядів


Вам не потрібен пробіл між 1і if(або, можливо, ви робите на старих перлов, але на останніх - ні). Також ви можете (ймовірно) замінити shiftна pop. Однак є деякі тестові випадки, коли ваш код не працює: 6 3 6 3(ви друкуєте 3 замість 2), 4 3 2 1(ви друкуєте 2 замість 1). Використовуючи popзамість того, щоб shiftрозв’язувати їх, але створювати нові ( 1 2 3 4відбитки 3 замість 1) ...
Dada

1

C # 6, 297 209 байт

using System.Linq;int G(int[] a)=>a.Any()?a.SkipWhile((x,i)=>i<1||x>=a[i-1]).Count()<a.SkipWhile((x,i)=>i<1||x<=a[i-1]).Count()?G(a.Select(x=>-x).ToArray()):G(a.SkipWhile((x,i)=>i<1||x<=a[i-1]).ToArray())+1:0;

Необурений з поясненнями

int G(int[] a)=>
    a.Any()
        ?a.SkipWhile((x,i)=>i<1||x>=a[i-1]).Count()<a.SkipWhile((x,i)=>i<1||x<=a[i-1]).Count()   // If a begins by decreasing (including whole a decreasing)...
            ?G(a.Select(x=>-x).ToArray())   // ... Then flip sign to make a begins by increasing
            :G(a.SkipWhile((x,i)=>i<1||x<=a[i-1]).ToArray())+1   // ... Else skip the increasing part, recursively find the remaining part number, then add 1
        :0;   // Return 0 if a is empty

1

JavaScript (ES6), 69 байт

f=(d,c,b,...a)=>1/b?(d>c)*(b>c)+(d<c)*(b<c)?1+f(b,...a):f(d,b,...a):1

Вводить вхід у вигляді декількох параметрів. Працює, рекурсивно порівнюючи перші три елементи, щоб побачити, чи вони монотонні, якщо так, то видаляє середній елемент, оскільки він марний, якщо ні, видаляє перші два елементи та запускає нову послідовність.


0

Clojure, 97 байт

#((reduce(fn[[C i]s](let[S(conj C s)](if(or(apply <= S)(apply >= S))[S i][[s](inc i)])))[[]1]%)1)

reduceвідслідковує поточну послідовність і обчислює, скільки разів <=і >=умови виходять з ладу. Останній 1бере результат 2-го елемента з результату (будучи лічильником i).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.