Cicli nella codifica run-length


27

Considera alcune sequenze binarie, usando 1e 2, ad esempio:

1, 2, 1, 1, 2, 2, 1, 2, 1, 2, 2, 1 ...

Scriviamo le lunghezze di esecuzione di questo:

1, 2, 1, 1, 2, 2, 1, 2, 1, 2, 2, 1 ...
_  _  ____  ____  _  _  _  ____
1, 1, 2,    2,    1, 1, 1, 2,   ...

In questo caso ci capita di ottenere un'altra sequenza binaria. Naturalmente, ciò non è garantito (ad esempio se ripetessimo il processo, la terza esecuzione sarebbe 3), ma supponiamo che lo facciamo.

Ora la domanda è: possiamo trovare una sequenza tale che l'applicazione di questo tipo di codifica di lunghezza di esecuzione più volte ci restituisca la sequenza originale? Per una durata del ciclo pari a 1 (ovvero un punto fisso di questa trasformazione), troviamo la sequenza Oldenburger-Kolakoski (voce OEIS A0000002 ):

1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, ...

(In realtà esiste un'altra soluzione: possiamo anche omettere il comando 1.)

Che dire di un ciclo di lunghezza-2? Anche questo è possibile! Le seguenti due sequenze sono l'elenco delle lunghezze delle esecuzioni:

1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, ...
2, 1, 2, 2, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, ...

(Queste sono le voci OEIS A025142 e A025143 . Questa è l'unica soluzione.)

Possiamo trovare un ciclo di lunghezza 3? Certo, qui ogni sequenza è la codifica della lunghezza della corsa della prossima (e la terza è la codifica della lunghezza della prima):

1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, ...
1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, ...
2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, ...

In questo caso c'è un'altra soluzione. Si scopre che possiamo trovare un tale ciclo per ogni durata del ciclo. In effetti, il numero di cicli distinti di lunghezza n è dato dalla voce OEIS A001037 (questo non conta la scelta arbitraria di quale sequenza in un ciclo è considerata la prima).

Curiosità: per quanto improbabile sembri, questa sfida è stata ispirata dallo studio della complessa mappa f(z) = z - 1/z. Chiunque abbia capito cosa c'entra quella mappa con questa sfida ottiene un cookie.

La sfida

Data una lunghezza del ciclo k > 0e una lunghezza della sequenza n > 0, emette i primi ntermini di ksequenze binarie distinte (infinite) che formano un ciclo sotto la trasformazione di lunghezza di esecuzione sopra. Se esistono più cicli, è possibile emetterne uno qualsiasi. Dipende da quale sequenza nel ciclo iniziare e in quale direzione va il ciclo (quindi è possibile emetterli in modo tale che ogni sequenza descriva la successiva, o tale che ciascuna sequenza descriva ciclicamente la precedente).

È possibile scrivere un programma o una funzione, prendendo l'input tramite STDIN (o l'alternativa più vicina), l'argomento della riga di comando o l'argomento della funzione e producendo il risultato tramite STDOUT (o l'alternativa più vicina), il valore di ritorno della funzione o il parametro della funzione (out).

L'output può essere in qualsiasi formato elenco nidificato conveniente, inequivocabile, in modo tale che la dimensione esterna sia ke la dimensione interna sia n.

Si applicano le regole standard del .

Esempi aggiuntivi

Ecco alcuni esempi. Ma come ho detto, le soluzioni non sono uniche, quindi le tue soluzioni potrebbero essere diverse ed essere ancora corrette. Forse questi ti aiuteranno a trovare una soluzione. Ogni esempio è k nseguito dalle sequenze, in modo tale che ogni riga descriva la successiva (ciclicamente):

4 20
1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2
2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1
2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1
1, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1

5 6
2, 2, 1, 2, 2, 1
1, 1, 2, 2, 1, 2
2, 1, 2, 2, 1, 1
1, 1, 2, 1, 1, 2
2, 1, 2, 2, 1, 2

8 20
2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2
1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1
2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2
2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 2, 1, 2, 2
1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1
2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2
1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1
2, 1, 2, 2, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1

13 50
1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1
1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1
1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2
1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2
1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2
1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2
2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1
1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1
1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1
1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1
1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 2
1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1
1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1

Si noti che non tutte le linee nelle ultime due uscite differiscono, anche se alla fine sarebbero nabbastanza grandi.

domande correlate


1
Possiamo produrre un elenco di generatori?
CalculatorFeline

@CatsAreFluffy No, scusa. (Forse la prossima volta ...)
Martin Ender il

Risposte:


6

CJam (41 byte)

{Ma*{1:Bm<{1+ee{(1&B^)+}%e~A<0:B;}%}@:A*}

Questa è una funzione anonima che accetta input nello stack nell'ordine n ke lascia l'output nello stack. Demo online

L'idea di base è iniziare con una colonna di parole di Lyndon [2 1 1 1 ...]ed estenderla iterativamente proprio sulla base del fatto che conoscendo l'elemento iniziale di ogni riga e l'alternanza possiamo decodificare in lunghezza e ottenere più elementi.


3

Haskell, 72 byte

~(a:b)?c=c:[c|a>1]++b?(3-c)
k!n=take k$take n<$>last(k!n)?2:map(?1)(k!n)

demo:

*Main> 4!20
[[2,1,1,2,2,1,2,2,1,2,1,1,2,1,1,2,2,1,2,1],[1,1,2,1,2,2,1,1,2,1,1,2,2,1,2,2,1,2,1,1],[1,2,1,1,2,1,1,2,2,1,2,1,1,2,1,2,2,1,1,2],[1,2,2,1,2,1,1,2,1,2,2,1,1,2,1,1,2,1,2,2]]

1
Bel lavoro, finalmente! :) Ti dispiacerebbe aggiungere una spiegazione per coloro che non hanno Haskell? :)
Martin Ender il

0

APL (Dyalog Unicode) , 35 byte

{(⍺↑¨⊣{⍵/(≢⍵)⍴⍺,3-⍺}¨¯1⌽⊢)⍣≡⍨1+⍵↑1}

Provalo online!

Un dfn anonimo il cui argomento sinistro è ne giusto è k.

Traduzione quasi diretta della risposta Haskell di Anders Kaseorg (adattata alla natura finita e rigorosa degli array APL), con un po 'di indizio dall'idea di Peter Taylor :

L'idea di base è iniziare con una colonna di parole di Lyndon [2 1 1 1 ...]ed estenderla iterativamente proprio sulla base del fatto che conoscendo l'elemento iniziale di ogni riga e l'alternanza possiamo decodificare in lunghezza e ottenere più elementi.

Come funziona

{(⍺↑¨⊣{⍵/(≢⍵)⍴⍺,3-⍺}¨¯1⌽⊢)⍣≡⍨1+⍵↑1}   left argument(⍺)←n, right(⍵)←k
                             1+⍵↑1    u←[2, 1, ..., 1] of length k
                                     Run the following with both sides being u:
 (                       )⍣≡           Repeat until fixpoint:
                                       (left: u, right: intermediate result v)
                     ¯1⌽⊢               Rotate v down once
     ⊣{                               Zip with left side u: (left elem u_i, right elem v_i)
              ⍺,3-⍺                      Make a 2-elem array [u_i, 3-u_i] which is [1 2] or [2 1]
         (≢⍵)⍴                           Cycle the above to the length of v_i
       ⍵/                                Duplicate each element of above v_i times e.g. 1 1 2/2 1 2  2 1 2 2
       ⍵/(≢⍵)⍴⍺,3-⍺                      Run-length decode v_i with alternating 1 and 2's, starting with u_i
  ⍺↑¨                                ⍝   Extend or truncate each row to length n

Confronto con la versione Haskell di Anders

Il codice Haskell di Anders (tra parentesi per chiarezza) funziona in questo modo:

~(a:b)?c=(c:[c|a>1])++(b?(3-c))
  (c:[c|a>1])  -- Two copies of c if head of x > 1, one copy otherwise
  ++(b?(3-c))  -- Run-length decode the rest with alternating 1 and 2

k!n=take k$take n<$>((last(k!n))?2):(map(?1)(k!n))
  take k$         -- take first k rows
  take n<$>       -- take first n elements from each row
  ((last(k!n))?2) -- run-length decode the last row with starting value 2
  :(map(?1)(k!n)) -- run-length decode the other rows with starting value 1

In una iterazione, questo equivale a "anteporre la k-esima riga, decodificare la lunghezza di ogni riga e quindi scartare l'ultima riga". Possiamo semplificarlo per "ruotare una volta e decodificare la lunghezza", che ho implementato come ¯1⌽.

Per la funzione di decodifica di durata, ho semplicemente usato la primitiva APL /, mentre la versione di Haskell utilizza infiniti elenchi per implementarla.

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.