Trồng rừng nhị phân!


24

Lấy cảm hứng từ A014486 .

Thử thách

Cho một đầu vào số nguyên trong cơ sở 10, xây dựng một đại diện cho rừng nhị phân tương ứng với đầu vào. Các đại diện bao gồm, nhưng không giới hạn, các mảng và chuỗi lồng nhau.

Làm sao?

Chuyển đổi đầu vào thành nhị phân. 1s đại diện cho các nhánh và 0s đại diện cho lá.

Để làm cho điều này dễ hiểu hơn, hãy sử dụng 834(1101000010 ở dạng nhị phân) làm ví dụ.


Chúng tôi bắt đầu với chữ số đầu tiên. Chữ số đầu tiên là a 1, vì vậy chúng tôi vẽ các nhánh:

\ /
 1

hoặc như một mảng, {{1}}


Chữ số tiếp theo là 1, vì vậy chúng tôi vẽ thêm các nhánh (chúng tôi đi từ trái sang phải):

\ /
 1
  \ /
    1

hoặc như một mảng, {{1, {1}}}


Chữ số tiếp theo là 0, vì vậy chúng tôi đặt một chiếc lá:

0
 \ /
  1
   \ /
     1

hoặc như một mảng, {{1, {1, 0}}}


Chữ số tiếp theo là a 1, vì vậy chúng tôi đặt một nhánh:

     \ /
0 1
 \ /
   1
      \ /
         1

hoặc như một mảng, {{1, {1, 0, {1}}}}


Lặp lại quá trình, chúng ta thu được cây sau chữ số thứ 8:

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

hoặc như một mảng, {{1, {1, 0, {1, 0, 0}}, 0}}


Đối với các chữ số còn lại, chúng tôi vẽ thêm cây:

Chữ số thứ 9 là a 0, vì vậy chúng tôi đặt một chiếc lá (aww, đó là một chồi non!)

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

hoặc như một mảng, {{1, {1, 0, {1, 0, 0}}, 0}, 0}


Khi chúng tôi sử dụng tất cả các chữ số, chúng tôi kết thúc bằng:

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

hoặc như một mảng, {{1, {1, 0, {1, 0, 0}}, 0}, 0, {1, 0}}


Điều đó có vẻ kỳ lạ, vì vậy chúng tôi đệm số 0 để hoàn thành cây:

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

hoặc như một mảng, {{1, {1, 0, {1, 0, 0}}, 0}, 0, {1, 0, 0}}

Lưu ý rằng việc làm phẳng mảng mang lại số gốc ở dạng nhị phân, nhưng với số 0 được đệm.

Tiêu chí

  • Đầu ra phải hiển thị rõ ràng sự phân tách của cây và nhánh (nếu nó không phải là một mảng lồng nhau, vui lòng giải thích định dạng đầu ra của bạn).
  • Trích xuất tất cả các chữ số từ đầu ra phải giống hệt với biểu diễn nhị phân của đầu vào (với số 0 được đệm từ quá trình trên).

Các trường hợp thử nghiệm

Đầu ra có thể khác nhau miễn là đáp ứng các tiêu chí.

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

Chấm điểm

Đây là , vì vậy byte thấp nhất sẽ thắng!


5
Tôi sẽ tránh sử dụng tiền thưởng - nó thường không cải thiện thử thách.
Chiếm

1
@Sanchises Tôi đã thêm phần thưởng để xem câu trả lời bằng trực quan ... Làm thế nào khác tôi có thể khuyến khích mọi người thử thực hiện trực quan hóa như đầu ra?
JungHwan Min

4
(lại bình luận của bạn) Yêu cầu nó?
msh210

1
@JungHwanMin Hãy nhìn vào những gì tôi liên kết chi tiết hơn (đặc biệt là các bình luận); hoặc, trong cùng một câu hỏi Meta, câu trả lời này . Câu hỏi hiện tại của bạn yêu cầu người đăng tạo ra 2 ^ 2 = 4 chương trình và tính điểm của từng chương trình, trước khi gửi chương trình tính điểm tốt nhất. Hoặc yêu cầu nó khi bạn nghĩ rằng nó làm cho một thách thức tốt hơn, hoặc loại bỏ nó nếu bạn cảm thấy nó làm cho một thách thức tồi tệ hơn.
Chiếm

2
@JungHwanMin Đủ công bằng. Họ phải chơi 3 chương trình và tính toán từng điểm số trước khi gửi câu trả lời. Những gì bạn có ở đây, là ba thách thức được gói thành một. Tôi sẽ khuyên bạn nên đăng hình ảnh như một thách thức riêng biệt.
Chiếm

Câu trả lời:


2

JavaScript (ES6), 96 89 80 79 74 73 byte

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>

Xác định hàm ftrả về một mảng lồng nhau. Mã HTML chỉ để thử nghiệm.


Trong một giây, tôi đã nghĩ "cái quái $&gì đang làm mà không có .replace?" : P
Sản phẩm ETH

@ETHproductions Tôi hơi chán và làm xáo trộn tên biến. Quá tệ, JS không cho phép các biểu tượng đơn khác: D
PurkkaKoodari

9

Befunge, 138 117 104 byte

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

Hãy thử trực tuyến!

Giải trình

Dòng 1 đọc một số từ stdin và dòng 2 chuyển đổi số đó thành một chuỗi nhị phân mà nó lưu trong sân chơi trên dòng 10. Dòng 3 đến 5 sau đó lặp qua các chữ số nhị phân đó, xuất ra biểu diễn cây thích hợp khi mỗi chữ số được xử lý. Ngăn xếp Befunge được sử dụng để theo dõi độ sâu vào cây và lượng không gian lá còn lại ở mỗi cấp độ để chúng ta biết khi nào cần tạo một nhánh mới. Dòng 6 và 7 xử lý phần 0đệm cuối cùng để lấp đầy bất kỳ lá trống nào.

Để chơi golf này càng nhiều càng tốt, tôi đã loại bỏ dấu phẩy ra khỏi đầu ra cũng như các dấu ngoặc ngoài. Điều này vẫn chưa đánh bại giải pháp Mathicala, nhưng thật vui khi thử.

Nếu bạn muốn xem nó trông như thế nào với định dạng đầu ra dài dòng gốc, tôi đã lưu một phiên bản mã trước đó ở đây (131 byte).


1
(điều này không có đủ upvote: D)
Addison Crump

4

Toán học, 167 161 byte

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]&,
{}]&

Chức năng ẩn danh. Lấy một số làm đầu vào và trả về một danh sách các số được lồng tùy ý làm đầu ra. Ngắt dòng thêm cho rõ ràng. Sử dụng một số cơ chế liên quan đến việc tiếp tục, nhưng tôi đã quá mệt mỏi để nghĩ về nó nữa.


#[[1]]để #&@@#tiết kiệm một byte. !#~FreeQ~1thay vì #~MemberQ~1tiết kiệm một byte là tốt.
JungHwan Min

4

Toán học, 115 109 108 104 98 byte

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

Tạo thông báo lỗi có thể được bỏ qua một cách an toàn. Đầu ra một rừng nhị phân. Nó hơi khác so với đầu ra mẫu vì 1là một Head, không phải là yếu tố đầu tiên của danh sách. (ví dụ 1[0, 0]thay vì {1, 0, 0})

Phiên bản không có lỗi (104 byte)

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

Giải trình

i=#~IntegerDigits~2;

Chuyển đổi đầu vào thành danh sách cơ sở 2. Lưu trữ nó trong i.

f:=

SetDelay fsau đây (đánh giá bất cứ khi nào fđược gọi):

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

Switch tuyên bố.

Đầu tiên, nếu itrống, đầu ra 0. Nếu không, xuất phần tử đầu tiên ivà thả nó khỏi danh sách. Sử dụng đầu ra là biến điều khiển.

Nếu biến điều khiển là 0, đầu ra 0. Nếu có 1, đầu ra 1[f, f](đệ quy).

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

Trong khi ikhông trống, tiếp tục gọi f. Kết quả đầu ra, bọc bằng List.

Thí dụ

(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]}

Giải pháp thay thế (120 byte)

Đồng nhất với giải pháp 104 byte của tôi nhưng chuyển đổi đầu ra thành định dạng được đưa ra trong câu hỏi.

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

Một phần đệ quy, lặp một phần. Tôi đã thử sử dụng một số nguyên, nhưng cây bắt đầu bằng các bit quan trọng nhất, vì vậy tôi không nghĩ nó đáng giá.

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

Dùng thử trực tuyến


1

Java 8, 367 byte

Chơi gôn

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

Ung dung:

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 byte (82 ký tự)

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

Vì lý do chơi gôn, tôi đã loại bỏ các dấu ngoặc nhọn bên ngoài và dấu phẩy vì chúng không cần thiết cho việc tái tạo lại cây.

Kết quả ví dụ:

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}

Giải trình:

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

Dùng thử với trình thông dịch DUP Javascript trực tuyến trên quirkster.com hoặc sao chép kho lưu trữ GitHub của trình thông dịch DUP của tôi được viết bằng Julia.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.