Ottieni i passaggi della sequenza


17

Sfida

Data una sequenza di numeri, creare una funzione che restituisce i passaggi della sequenza.

  • Supponiamo che sarà una sequenza N >= 3
  • La sequenza lo ripeterà almeno una volta
  • La sequenza conterrà solo numeri naturali
  • La funzione o il programma dovrebbe restituire la sequenza di passaggi più breve possibile

Esempio:

Ingresso: [1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17]

Produzione: [1, 1, 2]

Spiegazione: La sequenza iniziale parte da 1 => 2 (1 step), 2 => 3 (1 step), 3 => 5 (2 steps). Quindi si ripete. L'output quindi è[1 step, 1 step, 2 steps] => [1, 1, 2]

Un altro esempio:

Ingresso: [2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20]

Produzione: [3, 1, 1, 1]

[2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20]
 \  /\ /\ /\ / 
  3   1  1  1  Then it repeats...

Casi test

Input: [1, 4, 8, 9, 10, 13, 17, 18, 19, 22, 26, 27, 28] => Output: [3,4,1,1]

Input: [6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41] => Output: [5,2]

Input: [2, 6, 10, 13, 17, 21, 25, 28, 32, 36, 40, 43, 47] => Output: [4,4,3,4]

Input: [5, 6, 7] => Output: [1]


chiarimenti

  • La lunghezza di input - 1 è divisibile per la lunghezza di output
  • Supponiamo che la sequenza aumenterà sempre

Questo è , quindi vince la risposta più breve in byte.



6
Ho visto alcune sfide che hai pubblicato di recente con molti commenti chiarificatori, e un paio ha chiuso come "poco chiaro", e successivamente riaperto dopo aver apportato le modifiche appropriate. Hai preso in considerazione l'idea di pubblicarli nella sandbox per alcuni giorni / una settimana? Mi sono piaciute le tue sfide dato che sono abbastanza accessibili, ma tutte le sfide, non importa quanto semplici o da chi sono pubblicate, possono usare la raffinatezza.
Giuseppe,

2
@Giuseppe Grazie per i tuoi suggerimenti. Ho pubblicato alcune altre sfide nella sand box (di solito se non riesco a creare una sfida con essa la cancello). Per queste sfide ho pensato che fossero abbastanza chiare ed è per questo che ho pubblicato immediatamente ma inizierò a pubblicarle prima nella sandbox. Grazie
Luis felipe De jesus Munoz il

2
@LuisMendo Heretic! 0 è un numero naturale! Billy Joel aveva persino un intero album dedicato a Peano Man!
ngm,

1
@AdmBorkBork, questo è più correlato in virtù della gestione di elenchi di operazioni di lunghezza arbitraria.
Peter Taylor

Risposte:


10

Gelatina , 9 7 byte

IsJEƇḢḢ

Provalo online!

Come funziona

IsJEƇḢḢ  Main link. Argument: A (array)

I        Increment; compute D, the array of A's forward differences.
  J      Indices; yield [1, ..., len(A)].
 s       Split D into chunks of length k, for each k in [1, ..., len(A)].
   EƇ    Comb equal; keep only partitions of identical chunks.
     Ḣ   Head; extract the first matching parititon.
      Ḣ  Head; extract the first chunk.

9

JavaScript (ES6), 58 byte

Emette una stringa separata da virgola (con una virgola iniziale).

a=>(a.map(p=x=>-(p-(p=x)))+'').match(/N((,\d+)*?)\1*$/)[1]

Provalo online!

O 56 byte se usiamo ,-come separatore e assumiamo che la sequenza sia sempre rigorosamente aumento.

Come?

Per prima cosa convertiamo l'array di input a [] in un elenco di differenze consecutive con:

a.map(p = x => -(p - (p = x)))

Poiché p è inizialmente impostato su un valore non numerico (la funzione di callback di map () ), la prima iterazione produce NaN .

Esempio:

[6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41]
[ NaN, 5, 2, 5, 2, 5, 2, 5, 2, 5, 2 ]

Quindi forziamo il risultato in una stringa:

"NaN,5,2,5,2,5,2,5,2,5,2"

Infine, cerchiamo il modello 1 più breve di numeri interi separati da virgola ( ,\d+) che inizia subito dopo "NaN" e si ripete fino alla fine della stringa:

match(/N((,\d+)*?)\1*$/)

1: usare il non goloso *?


Sto pubblicando una soluzione basata sulla stessa idea regex, ma molto diversa nell'implementazione. Ovviamente non ho esaminato altre soluzioni prima di sviluppare la mia, e sembra abbastanza diverso, e forse è la prima volta in assoluto che riesco a segnare meglio di te qui.
edc65,

1
53 byte: /(,.+?)\1*$/.
Neil,

6

Brachylog , 11 byte

s₂ᶠ-ᵐṅᵐ~j₍t

Provalo online!

Sarebbe 5 byte se fosse incorporato per le differenze consecutive.

Spiegazione

Example input: [6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41] 

s₂ᶠ             Find all substrings of length 2: [[6,11],[11,13],…,[34,39],[39,41]]
   -ᵐ           Map subtraction: [-5,-2,-5,-2,-5,-2,-5,-2,-5,-2]
     ṅᵐ         Map negate: [5,2,5,2,5,2,5,2,5,2]
       ~j₍      Anti-juxtapose the list of differences; the shortest repeated list is found
                  first, with the biggest number of repetitions: [5,[5,2]]
            t   Tail: [5,2]

Puoi negare dopo la coda, per salvare un byte?
Rod

@Rod Avrei ancora bisogno di mapparlo, quindi sarebbe della stessa lunghezza. Negare è un predicato tra due numeri, non vettorializza automaticamente in elenchi come altre lingue (altrimenti non funzionerebbe bene con input / output sconosciuti comuni nei programmi dichiarativi)
Fatalizza il

5

Pyth, 11 byte

<J.+Qf.<IJT

Provalo qui

Spiegazione

<J.+Qf.<IJT
 J.+Q          Call the sequence of differences in the input J.
     f         Find the first positive integer T...
      .<IJT    ... where rotating J by T doesn't change it.
<J             Take that many elements of J.

5

Japt , 14 12 byte

äa
¯@eUéX}aÄ

Provalo


Spiegazione

              :Implicit input of array U
äa            :Consecutive absolute differences
\n            :Reassign to U
 @    }aÄ     :Return the first positive integer X that returns true
   UéX        :  Rotate U right X times
  e           :  Check equality with U
¯             :Slice U to that element

Originale

äa
@eUîX}a@¯XÄ

Provalo


5

R , 49 46 byte

Programma completo:

d=diff(scan());while(any((s=d[1:T])-d))T=T+1;s

Provalo online!

R , 72 58 54 byte

Presentazione della funzione originale con tutti i casi di test in un unico posto:

function(a,d=diff(a)){while(any((s=d[1:T])-d))T=T+1;s}

Provalo online!

Grazie a JayCe per aver suggerito il percorso completo del programma e -4 byte sulla funzione, ea Giuseppe per ulteriori -3.



@JayCe non è nemmeno necessario a<-qui
Giuseppe,

4

J , 22 19 byte

3 byte salvati grazie a FrownyFrog!

0{"1[:~./:|."{}.-}:

Provalo online!

[Provalo online!] [TIO-ji2uiwla]

Come?

                 -      find the successive differences by subtracting 
                  }:    the list with last element dropped
               }.       from the list with the first element dropped 
           |."{         rotate the list of differences
         /:             0..length-1 times (the input graded up)
     [:~.               remove duplicating rows
 0{"1                   take the first element of each row

Se /:invece di #\, è possibile 0{"1[:~.salvare 1 byte.
FrownyFrog,

Ed "0 1è"{
FrownyFrog il

@FrownyFrog Grazie, ancora una volta!
Galen Ivanov,

1
questo è stupendo.
Giona

@Jonah Sì, grazie a FrownyFrog!
Galen Ivanov,

4

05AB1E , 8 byte

Salvato 3 byte grazie a Kevin Cruijssen .

¥.œʒË}нн

Provalo online!


05AB1E , 11 byte

āεI¥ô}ʒË}нн

Provalo online!

āεI ¥ ô} ʒË} нн Programma completo.
Intervallo di lunghezze. Premere [1 ... len (inp)].
 ε} Per ogni ...
  I ¥ ô ... Taglia i delta in pezzi della dimensione corrispondente
      ʒË} Mantieni solo quelli che hanno tutti i loro elementi uguali.
         нн E per prima cosa recupera il primo elemento del primo.

13 byte

Un'alternativa carina, IMO:

¥©ηʒDg®ôÙ˜Q}н

Provalo online!

¥©ηʒDg®ôÙ˜Q}н   Full program.
¥               Push the deltas.
 ©              Copy them to the register.
  ηʒ       }    And filter the prefixes by...
    D     Q     ... Is the prefix itself equal to...
     g®ô        ... The deltas, split into chunks of its length...
        Ù˜      ... Deduplicated and flattened?
            н   Head.

1
8 byte utilizzando.
Kevin Cruijssen

3

Javascript, 49 56 byte

Modifica 7 byte salvati grazie (indovina chi?) Arnauld

Stessa idea regex di Arnauld, ma curiosamente così diversa nell'implementazione ...

Restituzione di una stringa con passaggi separati da virgola (e una virgola iniziale)

p=>/N(.+?)\1+$/.exec(p.map(p=v=>[v-p,p=v][0]))[1]

Test

var F=
p=>/N(.+?)\1+$/.exec(p.map(p=v=>[v-p,p=v][0]))[1]

;[[1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17]
,[1, 4, 8, 9, 10, 13, 17, 18, 19, 22, 26, 27, 28]
,[6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41] 
,[2, 6, 10, 13, 17, 21, 25, 28, 32, 36, 40, 43, 47]
,[5, 6, 7]]
.forEach(x=>console.log(x + ' -> ' + F(x)))


L'uso è matchstata una mia cattiva decisione. Puoi superarmi ancora un po ' . :-)
Arnauld

3

MATL , 14 13 12 byte

dt5YLFTF#Xu)

Provalo online!

Ho appena scoperto che MATL ha una funzione circolante!

Spiegazione

d - Ottieni le differenze tra termini successivi, come una matrice

t5YL- duplicalo , quindi chiama la funzione YL('gallery') con l' 5opzione ('circulant'). Crea una matrice con il vettore dato come prima riga, quindi le righe successive vengono spostate in modo circolare nello stesso vettore, fino a quando non si avvolge.

FTF#Xu- Controlla le righe univoche e ottieni i loro numeri di riga (non sono sicuro se esiste un modo più breve per farlo). Quando i passaggi della sequenza si ripetono, la riga spostata in modo circolare sarà uguale alla prima riga e le righe successive verranno ripetute. Quindi, questo ottiene gli indici della prima serie di passaggi della sequenza prima che inizino a ripetersi.

) - indicizza usando quello nell'array delle differenze originali, per ottenere la risposta.


Più vecchio:

d`tt@YS-a}@:)

Provalo online!

(-1 byte grazie a Giuseppe)

Spiegazione:

d   % Get the differences between successive terms, as an array
`   % Start do-while loop
  tt  % duplicate the difference array twice
  @   % push the current loop index value
  YS  % circularly shift the difference array by that amount
  -   % subtract the shifted diffs from the original diffs
  a   % see if the subtraction resulted in any non-zeros
    % if it did, shifted differences were not equal to original differences, so continue loop 
}@ % if it didn't, then get loop index
:) % get the differences upto the loop index, before they started repeating
   % implicit loop end

2

Python 2 , 101 byte

def f(l):d=[y-x for x,y in zip(l,l[1:])];g=len(l);print[d[:k]for k in range(1,g+1)if g/k*d[:k]==d][0]

Provalo online!

In primo luogo genera i delta d , quindi trova il primo prefisso p di d che quando ripetuto ⌊len (L) / len (p) ⌋ volte produce L , dove L è l'elenco di input.



2

Java 10, 104 100 byte

a->{var t="";for(int i=a.length;i-->1;t+=a[i]-a[i-1]+" ");return t.replaceAll("( ?.+?)\\1*$","$1");}

Regex ( ?.+?)\1*$per breve ripetizione sottostringa dalla @Neil 's commento su @Arnauld ' JavaScript (ES6) risposta s .

Provalo online.

Spiegazione:

a->{                        // Method with integer-array parameter and String return-type
  var t="";                 //  Temp-String, starting empty
  for(int i=a.length;i-->1; //  Loop backward over the input-array, skipping the first item
    t+=a[i]-a[i-1]          //   Calculate the difference between two adjacent items
       +" ");               //   And append this with a space to the temp-String
  return t.replaceAll("( ?.+?)\\1*$", 
                            //  Find the shortest repeating substring
                     "$1");}//  And only keep one such substring

1

APL + WIN, 39 byte

Richiedi input.

(↑((⍴v)=+/¨(⊂v)=(⍳⍴v)⌽¨⊂v)/⍳⍴v)↑v←-2-/⎕

Provalo online! Per gentile concessione di Dyalog Classic

Spiegazione:

v←-2-/⎕ Prompt for input and take successive differences

(⍳⍴v)⌽¨⊂v create a nested vector ans sequentially rotate by one to length of v

+/¨(⊂v)= compare to original v and sum positions where there is match

(⍴v)= identify where all elements match

(↑(....) identify number of rotations giving a first complete match

(↑(...)↑v take first number of elements from above from v as repeated sequence

1

Python 2 , 86 85 byte

def f(a,n=1):d=[y-x for x,y in zip(a,a[1:])];return d[:-n]==d[n:]and d[:n]or f(a,n+1)

Provalo online!

Costruire le differenze come d; se si dripete con dimensioni unitarie, nallora d[n:]==d[:-n]; altro recluta.


1

Retina 0.8.2 , 42 byte

\d+
$*
(?<=(1+),)\1

1+(.+?)\1*$
$1
1+
$.&

Provalo online! Il link include casi di test. L'output include la virgola iniziale. Spiegazione:

\d+
$*

Converti in unario.

(?<=(1+),)\1

Calcola le differenze in avanti, ad eccezione del primo numero, che viene lasciato indietro.

1+(.+?)\1*$
$1

Abbina le differenze ripetute.

1+
$.&

Converti in decimale.


1

05AB1E , 14 13 byte

¥DηvÐNƒÁ}QD—#

Provalo online o verifica tutti i casi di test .

So che ci sono già due risposte 05AB1E più brevi pubblicate da @ Mr.Xcoder , ma volevo provare questo approccio alternativo usando il controllo di rotazione e uguaglianza.
Potrebbe essere in grado di golf su alcuni byte senza cadereÁ .

-1 byte dopo la punta di @Emigna per rimuovere i registri global_variable ( ©e 2x ®) e utilizzare invece Duplicate ( D) e Triplicate ( Ð).

Spiegazione:

¥             # Calculate the deltas of the input-array
              #  i.e. [1,2,3,5,6,7,9] → [1,1,2,1,1,2]
 D            # Duplicate it
  η           # Push all its prefixes
              #  [1,1,2,1,1,2] → [[1],[1,1],[1,1,2],[1,1,2,1],[1,1,2,1,1],[1,1,2,1,1,2]]
v             # For-each over these prefixes
 Ð            #  Triplicate the (duplicated) deltas-list
  NƒÁ}        #  Rotate the deltas-list N+1 amount of times,
              #  where N is the prefix index (== prefix_length-1)
              #   i.e. [1,1,2] and [1,1,2,1,1,2] (rotate 3 times) → [1,1,2,1,1,2]
      Q       #  If the rotated deltas and initial deltas are equal
              #   [1,1,2,1,1,2] and [1,1,2,1,1,2] → 1
       D—#    #  Print the current prefix-list, and stop the for-each loop

1
Ecco un 9 (risposta separata poiché è un algo molto diverso, sebbene condivida il ¥ η).
Grimmy

@Grimy Stai esaminando tutte le mie risposte 05AB1E e golf ognuna di esse, haha? ; p Bella risposta però (ancora una volta), +1 da parte mia.
Kevin Cruijssen,

1
Non tutti, sto solo esaminando quelli collegati in questo post .
Grimmy,

@Grimy Ah ok, ha senso. :)
Kevin Cruijssen

1

Haskell, 107 byte

let i=map(uncurry(-))$zip(tail x)(init x)in head$filter(\s->take(length i)(concat$repeat s)==i)(tail$inits i)

x è l'array di input.


Benvenuti in particolare al golf PPCG e Haskell! Non si può presumere che l'input sia presente in una determinata variabile, sebbene ciò sia facilmente risolto anteponendo f x=. Anche l'uso di initsrichiede import Data.List, in quanto non fa parte di Prelude: provalo online!
Laikoni,

Tuttavia è possibile salvare parecchi byte: (init x)può essere solo xperché si ziptronca automaticamente se uno degli elenchi è più lungo dell'altro. E per map(uncurry(-))$zipesiste una build-in: zipWith(-). Invece di f x=let i=...inche si può usare una guardia modello: f x|i<-...=.
Laikoni,

Inoltre è possibile utilizzare una comprensione dell'elenco anziché filter, !!0anziché heade cycleinvece di concat$repeat: Provalo online!
Laikoni,

@Laikoni Grazie mille per i tuoi miglioramenti! Hai ragione, il mio codice richiede una dichiarazione di funzione e un'importazione per Data.List.inits. Ma mi chiedevo, dovrebbe essere aggiunto alla lunghezza del codice? Sto chiedendo perché alcuni degli altri esempi di codice si basano anche su un codice aggiuntivo.
misja111

Sì, è opinione generale che tali byte siano inclusi nel punteggio. Abbiamo una guida alle regole del golf a Haskell che copre la maggior parte di questi casi.
Laikoni,


1

Perl 6 , 57 byte

{~(.rotor(2=>-1).map:{.[1]-.[0]})~~/^(.+?){}" $0"+$/;~$0}

Provalo

L'output è separato da spazio ( "1 1 2")

Allargato:

{      # bare block lambda with implicit parameter $_

  ~(   # stringify (space separated)

    .rotor( 2 => -1 )     # from the input take 2 backup 1, repeat
    .map: { .[1] - .[0] } # subtract each pair to find the differences
  )

  ~~   # smartmatch

  /    # regex

    ^  # beginning of string

    ( .+? ) # match at least one character, but as few as possible
    {}      # make sure $0 is set (probably a compiler bug)
    " $0"+  # match $0 one or more times (with a leading space)

    $  # end of string
  /;

  ~$0  # return the stringified $0
}

L'intera prima parte può essere~(.skip Z-$_)
Jo King,

1

05AB1E , 9 byte

¥©η.ΔÞ®Å?

Spiegazione:

          # take input implicitly
¥         # deltas, eg [4, 5, 7, 8, 10] -> [1, 2, 1, 2]
 ©        # save this to the global register
  η       # prefixes, eg [1, 2, 1, 2] -> [[1], [1, 2], ...]
   .Δ     # find the first one such that
     Þ    # cycled infinitely, eg [1, 2] -> [1, 2, 1, 2, ...]
       Å? # starts with
      ®   # the global register
          # and implicitly print the found element

Alternativo a 9 byte:

¥η.ΔÞ.¥-Ë

Stesso algoritmo, ma invece di confrontarsi con l'elenco dei delta (che deve essere salvato / ripristinato), questo usa (undelta) quindi confronta con l'input (implicito).

Provalo online!


0

K4 , 30 byte

Soluzione:

(*&d~/:c#'(!c:#d)#\:d)#d:1_-':

Esempi:

q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20
3 1 1 1
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17
1 1 2
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':1, 4, 8, 9, 10, 13, 17, 18, 19, 22, 26, 27, 28
3 4 1 1
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41
5 2
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':2, 6, 10, 13, 17, 21, 25, 28, 32, 36, 40, 43, 47
4 4 3 4
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':5 6 7
,1

Spiegazione:

Sembra pesante per quello che stiamo cercando di risolvere. Ottieni i delta dell'input, quindi costruisci sequenze e determina quella più breve che corrisponde.

(*&d~/:c#'(!c:#d)#\:d)#d:1_-': / the solution
                           -': / deltas 
                         1_    / drop first
                       d:      / save as d
                      #        / take (#) from
(                    )         / do this together
                 #\:d          / take (#) each-left (\:) from d
          (     )              / do this together
              #d               / count length of d
            c:                 / save as c
           !                   / range 0..c-1
       c#'                     / take c copies of each
   d~/:                        / d equal (~) to each right (/:)
  &                            / where true
 *                             / first one


0

Perl 5 -p , 55 byte

s/\d+ (?=(\d+))/($1-$&).$"/ge;s/\d+$//;s/^(.+?)\1*$/$1/

Provalo online!

I numeri vengono inseriti come un elenco separato da spazi. L'output è dello stesso formato.

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.