Numero minimo di sottosequenze monotoniche contigue


23

Descrizione della sfida

Una sottosequenza monotonica è una sequenza di numeri [a1, a2, ..., an]tale che

a1 <= a2 <= ... <= ano a1 >= a2 >= ... >= an. [1, 3, 3, 7, 9, 13, 13, 100]è una sottosequenza monotonica (non decrescente), così come [9, 4, 4, 3, 0, -10, -12](questa non è in aumento), ma [1, 3, 6, 9, 8]non lo è. Dato un elenco di numeri interi (in qualsiasi formato ragionevole), genera il numero più piccolo in modo Ntale che la sequenza di questi numeri interi possa essere suddivisa in Nsequenze monotoniche.

Esempi

[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

Per chiarire, le sottosequenze devono essere contigue, giusto?
Zgarb,

@Zgarb Sì, lo fanno.
shooqie

3
Consiglio di aggiungere un caso di prova in cui le sequenze non vanno sempre nella direzione opposta: [4,4,8,8,1,4,5] -> 2
Nathan Merrill

@NathanMerrill: buon punto, aggiunto uno.
shooqie

Quando lo scrivi per una stringa vuota, il risultato è 0 / undefined, sembra che dovrebbe essere 0 o la rappresentazione undefinednella nostra lingua, ma dal tuo commento sulla risposta Jelly di Jonathan Allan, sembra che undefinedsignifichi anything... Quale è ? Nel secondo caso, suggerirei di scrivere anythinginvece diundefined
Dada,

Risposte:


6

Brachylog , 12 byte

~c:{<=|>=}al

Provalo online!

Questo ritorna false.per l'elenco vuoto [].

Spiegazione

(?)~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

Ciò restituirà il più piccolo perché ~cgenererà i punti di scelta dal numero più piccolo di elenchi al più grande.


Qual è l'argomento "Z" nel collegamento TIO? (Sembra far parte del programma come farebbe un argomento da riga di comando).
Jonathan Allan,

@JonathanAllan Questo argomento è l'output. Idealmente, se potessimo personalizzare l'interfaccia di TIO, ci sarebbero l'input e l'output e nessun argomento. L'argomento è Zperché Zè un nome variabile; quindi stiamo dicendo "chiama questo programma con l'output come variabile". È possibile passare Za qualsiasi altra lettera maiuscola ; è solo un nome variabile. Il motivo per cui esiste questo argomento è consentire la possibilità di impostare effettivamente l'output su qualcosa, anziché su una variabile.
Fatalizza il

(Ad esempio se imposti l'output su 4in quell'esempio, ti dirà se è corretto o meno )
Fatalizza il

1
@JonathanAllan Qualsiasi linguaggio simile a Prolog è così: i predicati possono solo avere successo o fallire e non restituiscono alcun valore. Quindi per ottenere un output bisogna avere un argomento variabile al predicato che verrà unificato al risultato.
Fatalizza il

1
@JonathanAllan Alla fine fallirà 3perché non troverà alcun elenco di elenchi in cui tutti sono monotonici e di lunghezza 3. Ci vuole solo molto tempo perché proverà tutti i possibili elenchi di elenchi secondari, anche quelli che in realtà sono più lunghi di 3 elementi perché la lunghezza viene verificata dopo aver trovato l'elenco. Perché 5dice trueperché esiste davvero almeno un elenco di lunghezza 5con elenchi monotonici che funzionano. Quindi questo programma restituisce la lunghezza più piccola quando l'output è una variabile e se esiste un elenco di quella lunghezza che funziona se l'output è un numero intero.
Fatalizza il

4

Perl, 65 byte

62 byte di codice + 3 byte per -nflag.

monot_seq.pl:

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

Dai l'input senza la nuova riga finale, con i numeri separati da spazi:

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

-5 byte grazie a @Gabriel Benamy.


Salva 5 byte trasformando ($&<=>$1)*($1<=>$2)||$1==$2in($&<=>$1)*($1<=>$2)>=0
Gabriel Benamy il

@GabrielBenamy In effetti, grazie.
Dada,

2

Mathematica, 111 byte

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]

Funzione denominata che fprende un elenco non vuoto di numeri (numeri interi o anche reali). Funziona da davanti a dietro, scartando ripetutamente il primo elemento e tenendo traccia di quante sottosequenze sono necessarie. Più dettagliato:

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-#&@@#&;inoltre, definire uno fo gcome operatore unario ±probabilmente salverà alcuni byte.
Martin Ender,

2

Gelatina , 19 byte

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

TryItOnline! o esegui tutti i test (elenco vuoto risultati in1)

Come?

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

(Non sono convinto che questo sia il metodo più adatto per ridurre al minimo il conteggio dei byte)


@shooqie - Possiamo restituire qualche valore per l'elenco vuoto dato il commento "non definito"? Questo ritorna 1(che in realtà penso abbia più senso di 0).
Jonathan Allan,

1
Voglio dire, questo è ciò che undefinedsignifica: il risultato è irrilevante.
Shooqie,

2

Perl, 98 97 96 79 byte

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

L'input viene fornito come un elenco di numeri, separati da spazi, forniti in fase di esecuzione, ad es

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

(il 4 è l'output)

Leggibile:

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

L '"operatore dell'astronave" <=>restituisce -1 se LHS <RHS, 0 se LHS = RHS e +1 se LHS> RHS. Quando si confrontano tre elementi sequenziali $a,$b,$cper determinare se sono monotonici, è necessario solo determinare che non è il caso che esattamente uno di $a<=>$b, $b<=>$csia 1 e l'altro sia -1, il che accade solo quando il loro prodotto è -1. Se uno $a==$bo $b==$c, allora la sequenza è monotona e il prodotto è 0. Se $a < $b < $c, allora entrambi danno come risultato -1 e -1 * -1 = 1. Se $a > $b > $c, allora entrambi danno come risultato 1 e 1 * 1 = 1. In entrambi i casi, la sequenza è monotona e desideriamo continuare.

Se il prodotto è inferiore a 0, sappiamo che la sequenza non è monotonica e scartiamo i valori di $a,$bcui siamo attualmente in possesso e incrementiamo il nostro contatore di sottosequenza. Altrimenti, avanziamo di un numero.

Non restituisce nulla se l'ingresso è vuoto, altrimenti restituisce il numero più piccolo di sottosequenze monotoniche contigue


Non hai bisogno di uno spazio tra 1e if(o forse lo fai sui vecchi perl, ma su quelli recenti non lo fai). Inoltre puoi (probabilmente) sostituire shiftcon pop. Tuttavia, ci sono alcuni casi di test in cui il codice non funziona: 6 3 6 3(si stampa 3 anziché 2), 4 3 2 1(si stampa 2 anziché 1). Usando popinvece di shiftrisolverli ma crearne di nuovi ( 1 2 3 4stampa 3 anziché 1) ...
Dada,

1

C # 6, 297 209 byte

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;

Ungolfed con spiegazioni

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 byte

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

Accetta input come parametri multipli. Funziona confrontando in modo ricorsivo i primi tre elementi per vedere se sono monotonici, in tal caso, rimuove l'elemento centrale in quanto è inutile, in caso contrario rimuove i primi due elementi e avvia una nuova sequenza.


0

Clojure, 97 byte

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

reducetiene traccia dell'attuale sottosequenza e calcola quante volte <=e >=condizioni falliscono. L'ultimo 1prende il 2 ° elemento dal risultato (essendo il contatore i).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.