Рекурсивний двійковий опис


14

Рекурсивний двійковий опис

Нещодавно я зробив свій перший внесок у OEIS, розширивши та додавши b-файл до послідовності A049064 . Послідовність починається з 0, а наступні значення виводяться з надання "двійкового опису" останнього елемента.

Наприклад, другий термін був би 10, бо 0в першому елементі був один . Третій термін був би 1110, бо був один 1і один 0. Четвертим було б 11110. тому що є три ( 11у двійкових!) 1 s і один 0. Нижче наведено розбиття п'ятого терміну, щоб зрозуміти цей процес:

> 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)

Ось приклад переходу від 6-го до 7-го терміну:

> 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

Ви можете перевірити довідкову програму φ, яку я зробив для обчислення термінів.

Ваша робота

Потрібно створити програму або функцію яка приймає число nза допомогою стандартних аргументів введення чи функції , і виводить послідовність від 1stтерміна до (n+1)thтерміна, відокремлений новим рядком. Якщо ви хочете подивитися на менші цифри, ви можете звернутися до b-файлу зі сторінки OEIS. Однак ваша програма / функція повинна підтримувати 0 <= n <= 30, тобто до 31-го терміну. Це не маленький подвиг, оскільки A049064(30)довгий δ понад 140 000 цифр . Якщо ви хочете побачити, яким повинен бути 31-й термін, я поставив його на Пастебін .

Приклад вводу / виводу

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

func(0)
0

func(3)
0
10
1110
11110

Є лише одне правило: Ніякі стандартні лазівки!

Це , тому виграє найменший байт.


φ - Gist можна знайти тут , і ideone демо тут .

δ - На всякий випадок, коли вам було цікаво, мої оцінки в тривалість 100-го терміну ставлять це приблизно в 3,28x10 250 символів, що було б досить багато для кого-небудь підрахувати.


Вихід як список дозволений? Like[0]\n[1, 0]\n[1, 1, 1, 0]\n...
Jakube

@Jakube Ні, вам потрібно буде зробити рядок приєднання до нього.
Каде

5
Вітаю вас за внесок у систему OEIS!
Олексій А.

Відповіді:


8

CJam, 18 17 байт

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

Дякуємо @ MartinBüttner за те, що ти граєш на один байт!

Спробуйте його в Інтернеті інтерпретаторі CJam .

Як це працює

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

Піт, 18 17 байт

J]0VQjk~JsjR2srJ8

Спробуйте в Інтернеті: Демонстрація

Завдяки @isaacg за збереження одного байта.

Пояснення:

                     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

Для цього використовується той факт, що 0 і 1 у двійкових також є 0 і 1.


Це на 1 байт коротше, використовуючи Vзамість .u:J]0VQjk~JsjR2srJ8
isaacg

2

Python 2, 125 116 110 байт

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

Збережено 1 байт завдяки @ Sp3000 та 5 байтів, видаливши зайве int виклик.

Старіша версія:

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

Збережено багато, багато байтів завдяки @ Vioz-!

Оригінальна версія:

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

Рубі, 80 72 69 байт

Як функція:

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

Телефонуйте, наприклад, за допомогою: f[6]


Ви можете зберегти кілька байт, якщо взяти введення як аргумент функції:->m{l=?0;0.upto(m){puts l;l.gsub!(/1+|0+/){$&.size.to_s(2)+$&[0]}}}
blutorange

@blutorange Приємно! Повністю забув про uptoі ! - Дякую :)
daniero

1

Python 2, 102 байти

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

Як-небудь комбінація itertoolsбути довше reі groupbyповертати grouperоб'єкти означає, що використання регулярного виразів трохи коротше ...


0

Кобра - 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

Хаскелл, 136 130 байт

import Text.Printf
import Data.List
f n=putStr.unlines.take(n+1).iterate(concatMap(\n->(printf"%b"$length n)++[head n]).group)$"0"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.