Descrizione binaria ricorsiva


14

Descrizione binaria ricorsiva

Di recente, ho dato il mio primo contributo a OEIS estendendo e aggiungendo un file b alla sequenza A049064 . La sequenza inizia con 0, quindi i valori successivi derivano dal dare una "descrizione binaria" dell'ultimo elemento.

Ad esempio, il secondo termine sarebbe 10, perché ce n'era uno 0nel primo elemento. Il terzo termine sarebbe 1110, perché ce n'era uno 1e uno 0. Il quarto sarebbe 11110. perché ci sono tre ( 11in binario!) se 1 uno 0. Di seguito è riportato un dettaglio del quinto termine per chiarire questo processo:

> 11110
> 1111 0    (split into groups of each number)
> 4*1 1*0   (get count of each number in each group)
> 100*1 1*0 (convert counts to binary)
> 100110    (join each group back together)

Ed ecco un esempio per passare dal 6 ° al 7 ° termine:

> 1110010110
> 111 00 1 0 11 0
> 3*1 2*0 1*1 1*0 2*1 1*0
> 11*1 10*0 1*1 1*0 10*1 1*0
> 111100111010110

Puoi consultare un programma di riferimento φ che ho fatto per calcolare i termini.

Il tuo lavoro

È necessario creare un programma o una funzione che accetta un numero ntramite input standard o argomenti di funzione e stampa la sequenza dal 1sttermine al (n+1)thtermine, separati da una nuova riga. Se desideri dare un'occhiata ai numeri più bassi, puoi fare riferimento al file b dalla pagina OEIS. Tuttavia, il tuo programma / funzione dovrebbe supportare 0 <= n <= 30, vale a dire fino al 31 ° termine. Questa non è un'impresa da poco, poiché A049064(30)è lunga oltre 140.000 cifre δ . Se vuoi vedere quale dovrebbe essere il 31 ° termine, l'ho messo su Pastebin .

Esempio di I / O

func(10)
0
10
1110
11110
100110
1110010110
111100111010110
100110011110111010110
1110010110010011011110111010110
1111001110101100111001011010011011110111010110
1001100111101110101100111100111010110111001011010011011110111010110

func(0)
0

func(3)
0
10
1110
11110

C'è solo una regola: nessuna scappatoia standard!

Questo è , quindi vince il numero di byte più basso.


φ - Gist può essere trovato qui , e una demo di ideone è qui .

δ - Nel caso te lo stessi chiedendo, le mie stime sulla lunghezza del centesimo termine lo collocano a circa 3,28x10 di lunghezza di 250 caratteri, il che sarebbe parecchio da calcolare per chiunque.


Uscita come elenco consentito? Mi piace[0]\n[1, 0]\n[1, 1, 1, 0]\n...
Jakube,

@Jakube No, dovrai fare un join di stringa su di esso.
Kade,

5
Congratulazioni per aver contribuito a OEIS!
Alex A.

Risposte:


8

CJam, 18 17 byte

0{sN1$e`2af.b}ri*

Grazie a @ MartinBüttner per giocare a golf con un byte!

Provalo online nell'interprete CJam .

Come funziona

0                 e# Push 0.
 {           }ri* e# Repeat int(input)) times:
  s               e#   Stringify the element on top of the stack.
                       EXAMPLE: [[[1 1] '1] [[1] '0]] -> "11110"
   N              e#   Push a linefeed.
    1$            e#   Copy the last stack.
      e`          e#   Perform run-length encoding.
                  e#   EXAMPLE: "100110" -> [[1 '1] [2 '0] [2 '1] [1 '0]]
        2a        e#   Push [2].
          f.b     e#   For each pair [x 'y], execute: [x 'y][2].b
                  e#   This pushes [x2b 'y], where b is base conversion.

4

Pyth, 18 17 byte

J]0VQjk~JsjR2srJ8

Provalo online: dimostrazione

Grazie a @isaacg per aver salvato un byte.

Spiegazione:

                     implicit: Q = input number
 ]0                  create an initial list [0]
J                    and store in J
   VQ                for loop, repeat Q times:
              rJ8       run-length-encoding of J
             s          sum, unfolds lists
          jR2           convert each value to base 2
         s              sum, unfolds lists
       ~J               store the result in J

                        but return the old list,
     jk                 join it and print it

Questo utilizza il fatto che 0 e 1 in binario sono anche 0 e 1.


Questo è più corto di 1 byte usando Vinvece di .u:J]0VQjk~JsjR2srJ8
isaacg

2

Python 2, 125 116 110 110 byte

from itertools import*
v='0'
exec"print v;v=''.join(bin(len(list(g)))[2:]+k for k,g in groupby(v));"*-~input()

Salvato 1 byte grazie a @ Sp3000 e 5 byte rimuovendo una intchiamata ridondante .

Versione precedente:

import itertools as t
v='0'
exec"print v;v=''.join(bin(int(len(list(g))))[2:]+k for k,g in t.groupby(v));"*-~input()

Salvati molti, molti byte grazie a @ Vioz-!

Versione originale:

import itertools as t
v='0'
for n in range(input()+1):print v;v=''.join(bin(int(len(list(g))))[2:]+k for k,g in t.groupby(v))

1

Rubino, 80 72 69 byte

Come una funzione:

f=->m{l=?0;0.upto(m){puts l;l.gsub!(/1+|0+/){$&.size.to_s(2)+$&[0]}}}

Chiamalo ad esempio con: f[6]


Potresti risparmiare qualche byte se prendi input come argomento di funzione:->m{l=?0;0.upto(m){puts l;l.gsub!(/1+|0+/){$&.size.to_s(2)+$&[0]}}}
blutorange

@blutorange Nice! Totalmente dimenticato uptoe ! - Grazie :)
Daniele

1

Python 2, 102 byte

import re
o='0'
exec"print o;o=''.join(bin(len(x))[2:]+x[0]for x in re.findall('0+|1+',o));"*-~input()

In qualche modo la combinazione di itertoolsessere più lunghi ree groupbyrestituire grouperoggetti significa che usare regex è un po 'più breve ...


0

Cobra - 128

do(i)=if(i-=1,(r=RegularExpressions).Regex.replace(f(i),'1+|0+',do(m=r.Match())=Convert.toString('[m]'.length,2)+'[m]'[:1]),'0')

0

Haskell, 136 130 byte

import Text.Printf
import Data.List
f n=putStr.unlines.take(n+1).iterate(concatMap(\n->(printf"%b"$length n)++[head n]).group)$"0"
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.