Посадіть двійковий ліс!


24

Натхненний A014486 .

Виклик

З огляду на цілий вхід в базі 10, побудуйте подання для двійкового лісу, відповідного входу. Представлення включають, але не обмежуються ними, вкладені масиви та рядки.

Як?

Перетворити вхід у двійкове. 1s представляють гілки, а 0s представляють листя.

Щоб зробити це легше зрозуміти, давайте використовувати 834(1101000010 у двійковій) як приклад.


Починаємо з першої цифри. Перша цифра - це 1, тому ми малюємо гілки:

\ /
 1

або як масив, {{1}}


Наступна цифра 1, тому ми малюємо більше гілок (йдемо зліва направо):

\ /
 1
  \ /
    1

або як масив, {{1, {1}}}


Наступна цифра - 0ми розміщуємо аркуш:

0
 \ /
  1
   \ /
     1

або як масив, {{1, {1, 0}}}


Наступна цифра - a 1, тому ми розміщуємо гілку:

     \ /
0 1
 \ /
   1
      \ /
         1

або як масив, {{1, {1, 0, {1}}}}


Повторюючи процес, ми отримуємо наступне дерево після 8-ї цифри:

    0 0
     \ /
0 1
 \ /
   1 0
      \ /
         1

або як масив, {{1, {1, 0, {1, 0, 0}}, 0}}


Для решти цифр намалюємо більше дерев:

Дев'ята цифра - це 0, тому ми розміщуємо аркуш (aww, це молода стрілянина!)

    0 0
     \ /
0 1
 \ /
   1 0
      \ /
         1 0

або як масив, {{1, {1, 0, {1, 0, 0}}, 0}, 0}


Коли ми використовуємо всі цифри, ми закінчуємо це:

    0 0
     \ /
0 1
 \ /
   1 0 0
      \ / \ /
         1 0 1

або як масив, {{1, {1, 0, {1, 0, 0}}, 0}, 0, {1, 0}}


Це виглядає дивно, тому ми покладаємо нуль, щоб завершити дерево:

    0 0
     \ /
0 1
 \ /
   1 0 0 0
      \ / \ /
         1 0 1

або як масив, {{1, {1, 0, {1, 0, 0}}, 0}, 0, {1, 0, 0}}

Зауважте, що вирівнювання масиву дає вихідне число у двійковій формі, але з прокладеним нулем.

Критерії

  • Вихід повинен чітко відображати розділення дерев та гілок (якщо це не вкладений масив, будь ласка, поясніть свій вихідний формат).
  • Вилучення всіх цифр з виводу повинно бути ідентичним двійковому представленню входу (із заниженим нулем (ями) вищевказаного процесу).

Тестові справи

Вихід може відрізнятися до тих пір, поки він відповідає критеріям.

0 -> {0}
1 -> {{1, 0, 0}}
44 -> {{1, 0, {1, {1, 0, 0}, 0}}}
63 -> {{1, {1, {1, {1, {1, {1, 0, 0}, 0}, 0}, 0}, 0}, 0}}
404 -> {{1, {1, 0, 0}, {1, 0, {1, 0, 0}}}}
1337 -> {{1, 0, {1, 0, 0}}, {1, {1, {1, 0, 0}, {1, 0, 0}}, 0}}

Оцінка балів

Це , тому виграє найнижчий байт!


5
Я б не використовував бонуси - це, як правило, не покращує проблему.
Санчіз

1
@Sanchises Я додав бонус, щоб побачити відповіді з візуалізацією ... Як ще я можу заохотити людей спробувати зробити візуалізацію як вихід?
JungHwan Min

4
(Ваш коментар) Потрібен?
msh210

1
@JungHwanMin Подивіться, що я пов’язав більш докладно (особливо коментарі); або, в тому ж мета-питанні, ця відповідь. Ваше поточне запитання вимагає, щоб плакати створили 2 ^ 2 = 4 програми та обчислили бал кожної програми, перш ніж надсилати найкращу програму підрахунку балів. Або вимагайте цього, коли ви думаєте, що це робить кращий виклик, або зніміть його, якщо вважаєте, що це робить для гіршого виклик.
Санчіз

2
@JungHwanMin Ярмарок досить. Вони повинні гольф 3 програми та обчислити кожен окремий рахунок, перш ніж подати відповідь. У вас тут три завдання, зведені в одне. Я б рекомендував розміщувати візуалізацію як окремий виклик.
Санчіз

Відповіді:


2

JavaScript (ES6), 96 89 80 79 74 73 байт

f=($,_=~Math.log2($))=>0>_?[(g=f=>$&1<<~_++&&[1,g(),g()])(),...f($,_)]:[]
<input type="number" value="1337" oninput="document.querySelector('#x').innerHTML=JSON.stringify(f(+this.value))"/><br/><pre id="x"></pre>

Визначає функцію, fяка повертає вкладений масив. HTML-код призначений лише для тестування.


На секунду я замислювався, "що, чорт, $&робить .replace?" : P
ETHproductions

@ETHproductions Я якось набрид і заплутав імена змінних. Шкода, що JS не дозволяє використовувати інші символи: D
PurkkaKoodari

9

Befunge, 138 117 104 байт

p&1v
%2:_v#:/2p9p00+1:g00
3\9g<>$\:!v!:<
9g!v ^,"}"_1-\1-:
"0"_2\"1{",,:|:,
`#@_\:#v_"}",>$\:8
,"0":-1<^

Спробуйте в Інтернеті!

Пояснення

Рядок 1 читає число зі stdin, а рядок 2 перетворює це число у двійкову послідовність, яку він зберігає в ігровому полі в рядку 10. Рядки 3 до 5 потім повторюють ці двійкові цифри, виводячи відповідне подання дерева під час обробки кожної цифри. Стек Befunge використовується для того, щоб відстежувати глибину дерева і скільки місця залишається на кожному рівні листя, щоб ми знали, коли створити нову гілку. Рядки 6 і 7 обробляють остаточну 0підкладку, щоб заповнити порожні листя.

Для того, щоб якомога більше пограти в гольф, я зняв коми з виходу, а також сторонні зовнішні дужки. Це все ще не перемогло рішення Mathematica, але це було весело, намагаючись.

Якщо ви хочете побачити , як це виглядало з оригінальним багатослівним форматом висновок, я заощадив більш ранню версію коду тут (131 байт).


1
(для цього недостатньо грошей: D)
Аддісон Кримп

4

Математика, 167 161 байт

b=Append;a=If[#&@@#>0,a[Rest@#~b~0,a[#,#3[#,{1,#4,#2},##5]&,#3,#2,##4]&,#2,##3],
#2[Rest@#~b~0,0,##3]]&;a[#~IntegerDigits~2,If[c=#3~b~#2;Tr@#>0,a[#,#0,c],c]&,
{}]&

Анонімна функція. Бере число в якості вхідного даних і повертає довільно вкладений список чисел як вихід. Для чіткості додано розриви рядків. Використовується якийсь механізм, що передбачає продовження, але я занадто втомився, щоб більше про це думати.


#[[1]]до #&@@#слід зберегти байт. !#~FreeQ~1замість #~MemberQ~1збереження байта також.
JungHwan Min

4

Математика, 115 109 108 104 98 байт

(i=#~IntegerDigits~2;f:=Switch[If[i=={},0,i={##2};#]&@@i,0,0,1,f~1~f];NestWhileList[f&,f,i!={}&])&

Генерує повідомлення про помилки, які можна сміливо ігнорувати. Виводить двійковий ліс. Він трохи відрізняється від вибірки вибірок, оскільки 1це Headне перший елемент списку. (наприклад, 1[0, 0]замість {1, 0, 0})

Версія без помилок (104 байти)

(i=#~IntegerDigits~2;f:=Switch[If[i=={},i={0}];(i={##2};#)&@@i,0,0,1,f~1~f];NestWhileList[f&,f,i!={}&])&

Пояснення

i=#~IntegerDigits~2;

Перетворення вхідних даних у список базових 2. Зберігайте його в i.

f:=

SetDelay fнаступне (оцінюється щоразу, коли fвикликається):

Switch[If[i=={},0,i={##2};#]&@@i,0,0,1,f~1~f]

Switch заява.

По-перше, якщо iпорожній, виведіть 0. Якщо ні, виведіть перший елемент iта виведіть його зі списку. Використовуйте вихід як контрольну змінну.

Якщо змінна керування є 0, виведіть 0. Якщо він є 1, вихід 1[f, f](рекурсивний).

NestWhileList[f&,f,i!={}&]

Хоча iце не порожньо, продовжуйте дзвонити f. Виведіть результат, обгорнутий List.

Приклад

(i=#~IntegerDigits~2;f:=Switch[If[i=={},0,i={##2};#]&@@i,0,0,1,f~1~f];NestWhileList[f&,f,i!={}&])&[1337]

{1[0, 1[0, 0]], 1[1[1[0, 0], 1[0, 0]], 0]}

Альтернативне рішення (120 байт)

Ідентично моєму байтовому рішенню на 104 бати, але перетворює висновок у формат, заданий у запитанні.

(i=#~IntegerDigits~2;f:=Switch[If[i=={},i={0}];(i={##2};#)&@@i,0,0,1,f~1~f];NestWhileList[f&,f,i!={}&]//.1[a__]:>{1,a})&

2

Python 2, 133 118 117 байт

Частково рекурсивний, частково ітераційний. Я спробував використовувати ціле число, але дерево починається з найбільш значущих бітів, тому я не думаю, що цього варто.

def t():global b;a=b[:1];b=b[1:];return a and'0'<a and[1,t(),t()]or 0
b=bin(input())[2:]
L=[]
while b:L+=t(),
print L

Спробуйте в Інтернеті


1

Java 8, 367 байт

Гольф:

class f{static String r="";static int p=0;static void g(char[]s,int k){if(p>=s.length||s[p]=='0'){r+="0";p++;return;}else{r+="{1";p++;g(s,k+1);g(s,k+1);r+="}";}if(k==0&&p<s.length)g(s,0);}public static void main(String[]a){java.util.Scanner q=new java.util.Scanner(System.in);r+="{";g(Integer.toBinaryString(q.nextInt()).toCharArray(),0);r+="}";System.out.print(r);}}

Безголівки:

class f{
    static String r="";
    static int p=0;
    static void g(char[]s,int k){
        // if there's empty space in last tree or current character is a 0
        if(p>=s.length || s[p]=='0'){
            r+="0";
            p++;
            return;
        }
        // if current character is a 1
        else{
            r+="{1";
            p++;
            // left branch
            g(s,k+1);
            // right branch
            g(s,k+1);
            r+="}";
        }
        // if they're still trees that can be added
        if(k==0 && p<s.length)g(s,0);
    }
    public static void main(String[]a){
        java.util.Scanner q=new java.util.Scanner(System.in);
        r+="{";
        g(Integer.toBinaryString(q.nextInt()).toCharArray(),0);
        r+="}";
        System.out.print(r);
    }
}

1

DUP , 84 байти (82 символи)

0[`48-$1_>][\10*+]#%1b:[$1>][2/b;1+b:]#[['{,1.b;1-b:FF'},][0.b;1-b:]?]⇒F[b;0>][F]#

З міркувань гольфу я позбувся зовнішніх фігурних брекетів і коми, тому що вони не потрібні для реконструкції дерев.

Приклади виходів:

0      → 0
1      → {100}
44     → {10{1{100}0}}
63     → {1{1{1{1{1{100}0}0}0}0}0}
404    → {1{100}{10{100}}}
1023   → {1{1{1{1{1{1{1{1{1{100}0}0}0}0}0}0}0}0}0}
1024   → {100}00000000
1025   → {100}0000000{100}
1026   → {100}000000{100}
1027   → {100}000000{1{100}0}
1028   → {100}00000{100}
1337   → {10{100}}{1{1{100}{100}}0}
4274937288 → {1{1{1{1{1{1{10{1{100}{1{1{100}{10{1{1{10{1{1{100}{100}}0}}0}0}}}0}}}0}0}0}0}0}0}
4294967297 → {100}00000000000000000000000000000{100}

Пояснення:

0[`48-$1_>][\10*+]#           While loop to read in the characters and convert them into a
                              base-10 integer.
0                             Push 0 (temporary value)
 [`48-$0>]       #            While input character-48 (digit)>-1
          [     ]
           \                      Swap top values
            10                    Push 10
              *                   Multiply (temporary value by 10)
               +                  Add to input value
%                                 Pop stack (EOL)
1b:                           Variable b=1 (bit count)
[$1>][2/b;1+b:]#              While loop to convert the number to base-2 digits on the
                              data stack, MSB on top. Each iteration increments bit count b.
[$1>]          #              While (DUP>1)
     [        ]#
      2                           Push 2
       /                          MOD/DIV (pushes both mod and div on the stack)
        b;1+b:                    Fetch b, increment, store b


[['{,1.b;1-b:FF'},][0.b;1-b:]?]⇒F     
[                             ]⇒F     Define operator F:
                                      pop top stack value
 [                ]          ?        if value != 0:
  '{,1.                                   print '{1'
       b;1-b:                             fetch b, decrement b, store b
             F                            execute operator F
              F                           execute operator F again
               '},                        print '}'
                   [        ]?        if value == 0:
                    0.                    print '0'
                      b;1-b:              fetch b, decrement b, store b
[b;0>][F]#
[b;0>]   #                            While (fetch b, b>0==true)
      [F]#                                execute operator F

Спробуйте це за допомогою інтерпретатора Javascript DUP на сайті quirkster.com або клонуйте моє сховище GitHub мого перекладача DUP, написане в Джулії.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.