Bạn có thể làm gì đó không?


30

Thách thức rất đơn giản: viết chương trình hoặc hàm, khi được cung cấp một số nguyên không âm hữu hạn, sẽ tạo ra một mảng lồng nhau.

Những quy định

  • Mã của bạn phải tạo ra một mảng lồng hợp lệ duy nhất cho mỗi số nguyên 0 ‌≤ n ‌ <2 31 .
  • Mỗi mảng lồng nhau có thể có tối đa 16 dấu ngoặc mở phải được xuất ra trong phạm vi này. (Điều này không có nghĩa là mã của bạn không bao giờ có thể xuất ra một mảng lồng nhau với hơn 16 dấu ngoặc mở.)
  • Mã của bạn có thể xuất ra một chuỗi đại diện của mảng lồng nhau thay vì một mảng thực tế (có hoặc không có dấu phẩy).

Một ánh xạ có thể có:

0 -> []
1 -> [[]]
2 -> [[[]]]
3 -> [[], []]
4 -> [[[[]]]]
5 -> [[[], []]]
6 -> [[[]], []]
7 -> [[], [[]]]
8 -> [[], [], []]
9 -> [[[[[]]]]]
etc.

Chấm điểm

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng.


Có bất kỳ hạn chế thời gian / bộ nhớ?
Dennis

@Dennis Có 1 giờ có vẻ hợp lý cho việc giới hạn thời gian không? Tôi không có manh mối gì hợp lý cho bộ nhớ.
Sản xuất ETH

Bộ nhớ không phải là vấn đề lớn nếu có giới hạn thời gian. Một giờ có vẻ rất hào phóng. Tôi sẽ không muốn đợi cả tiếng đồng hồ để xác minh xem mã của tôi có đủ nhanh không.
Dennis

4
Tôi không muốn giới hạn thời gian. Điều đó mang lại nhiều phạm vi hơn cho sự độc đáo
TonMedel

2
@TonH Phúc Bạn có thể xuất mà không có dấu phẩy. Tôi đoán không có giới hạn thời gian sẽ tốt, miễn là bạn có thể chứng minh rằng mục nhập của bạn là hợp lệ.
Sản xuất ETH

Câu trả lời:


12

Python 2.7, 172 149 124 118 byte

x=input();y="";z=0
for b in bin(x)[2+(x<1):]:y+="[]"[b<"1"];z+=b>"0"or-1;z+=99*(z<0)
print"["+(y,"[]"*(x+16))[z>0]+"]"

Giải trình:

Xác định một song ánh bởi [1]0. Bất kỳ sự sắp xếp dấu ngoặc nào sau đó có thể được viết dưới dạng số nhị phân và ngược lại[][]1010(10) và [[][]]110100(52). Tất cả các sắp xếp hợp lệ của tối đa 15 dấu ngoặc mở (tổng cộng 30 dấu ngoặc) được bao phủ bởi các số có tối đa 30 bit (bỏ qua các số 0 đứng đầu), chính xác là các số nhỏ hơn 2 31 .

Vòng lặp for đầu tiên đưa ra nghịch đảo của mệnh đề này, chuyển đổi một số thành một sự sắp xếp của dấu ngoặc, trong khi kiểm tra xem sự sắp xếp đó có hợp lệ không.

Sắp xếp không hợp lệ được thay thế trong câu lệnh in bằng chuỗi dài của dấu ngoặc để tránh va chạm. Ví dụ 11(3) [[không hợp lệ, vì vậy chúng tôi ghép nối 3 + 16 dấu ngoặc thay thế. Điều này đảm bảo tất cả các sắp xếp là duy nhất.

Sắp xếp kết quả được đặt trong một cặp dấu ngoặc để tạo một mảng lồng nhau, sao cho 1010(10) trở thành [[][]]110100(52) trở thành [[[][]]]. Dấu ngoặc mở thêm có nghĩa là chúng ta hiện đã bao phủ tất cả các mảng với 16 dấu ngoặc mở.


Chương trình sau đây có thể được sử dụng để tìm ra số cho một mảng nhất định với tối đa 16 dấu ngoặc.

s=raw_input();o="";
for c in s[1:-1]:
 if c=="[":o+="1"
 if c=="]":o+="0"
print int(o,2)

Một sự lạm dụng tốt đẹp ý định của op khi anh ta chỉ định "duy nhất"
TonMedel

Đó chỉ là thiên tài. Làm tốt. (Và cho phép định dạng không có dấu phẩy.)
ETHproductions

12

Python, 153 128 byte

s=l=0;r="";n=input()
for d in bin(n)[2:]*(n>0):c=d<"1";l=[l,s>1][c];r+="]"*c+(1-l*c)*"[";s+=1-c-l*c
print"["+r+"["*l+"]"*(s+l+1)

Chúng tôi ánh xạ một số n vào một danh sách lồng nhau bằng cách nhìn vào các chữ số nhị phân của nó từ trái sang phải. Thuật toán này hoạt động cho bất kỳ số nào, không chỉ dưới 2 32 .

  1. Nếu chữ số nhị phân hiện tại là 1, đầu ra [.
  2. Mặt khác, nếu chuỗi dấu ngoặc chúng ta xuất ra cho đến nay sẽ được cân bằng bởi một dấu ngoặc đơn, đầu ra ][.
  3. Mặt khác, nếu đây là 0 cuối cùng trong số nhị phân, đầu ra ][.
  4. Nếu không thì đầu ra ].

Cuối cùng, chúng tôi đóng bất kỳ dấu ngoặc mở.


5

Muỗng , 63 byte (501 bit)

000001001001001011001101001010011011111001010001000000101010
101101100110100101101001000101100010001000000100011000010000
000000000000001110111110010000001110110110010100100100100100
000110011010001000000110110000010000001010110011011011011001
000000011010010010010001000000111011011011101001001001000110
110110010100100101011001000100000011010001000000111011011001
010010010010010001101101101001000110110010110001101101101101
100100010001010010001010011011001000000011001101001001010010
000001100101001000111

Đây là chương trình brainfuck sau đây được chuyển đổi thành muỗng:

-[+[+<]>>+]<+++.[->+>+<<]>>++>>,[>-[<->-----]+<+++[-<+<<.>>>>-<]>[-<<-[->+<]<<<[-]>>>>[-<+<<<+>>>>]<<.>>+<[>-]>[-<+<<.>>>>]<<>>]<,]<<<<[>.>.<<[-]]>>>+[-<.>]+

Đọc một số nguyên trong nhị phân trên stdin và xuất ra danh sách lồng nhau trên stdin. Yêu cầu 0 là đầu vào dưới dạng chuỗi trống (không có chữ số) và yêu cầu trình thông dịch Brainfuck với các ô 8 bit. Thuật toán tương tự như câu trả lời Python của tôi.

Phiên bản dễ đọc:

-[+[+<]>>+]<+++.           push open bracket and print it
[->+>+<<]                  dup
>>++                       increment to close bracket

>>,[                       read input loop
    >-[<->-----]+<+++          subtract 48 and set up if/else
    [-                         if c == 1
        <+                         increment s
        <<.>>>                     output open bracket
    >-<]>[-<                   else
        <-[->+<]                   decrement and move s
        <<<[-]                     zero l
        >>>>[-<+<<<+>>>>]          l = s and restore s
        <<.>                       output close bracket
        >+<[>-]>[-                 if s == 0
            <+                         undo s decrement
            <<.                        output open bracket
        >>>>]<<
    >>]<
,]

<<<<[                      if l
    >.>.                   output pair
<<[-]]
>>>+[-<.>]                 output close bracket s+1 times

3
Gần đây chúng tôi đã có cuộc thảo luận này về một câu trả lời khác và dường như không có thông tin thực tế nào có thể xử lý tệp 63 byte. Việc thực hiện tham chiếu đã sử dụng các byte 0x30 và 0x31, vì vậy câu trả lời này sẽ yêu cầu tệp 501 byte .
Dennis

5

Thạch , 28 byte

ḃ2-*µSN;+\>-Ạ
1Ç#Ṫḃ2ṭ2;1ị⁾][

Điều này lặp lại trên tất cả các chuỗi của các ký tự []bắt đầu bằng a [và kết thúc bằng a ], xác minh nếu dấu ngoặc khớp và in kết quả khớp thứ n .

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


5

Perl, 80 79 byte

Một lần nữa sử dụng thuật toán của orlp , nhưng lần này tôi lần đầu tiên kiểm tra xem nó có hoạt động không ...

Bao gồm +1 cho -p

Cung cấp số đầu vào trên STDIN

nest.pl <<< 8

nest.pl:

#!/usr/bin/perl -p
($_=sprintf"%b",$_).=2x(s^.^$&or++$n-pos&&/.0/g?++$n%1:$`&&21^eg-$n);y;102;();

Giải pháp của Linus là 64 byte trong perl:

#!/usr/bin/perl -p
$_=sprintf"%b",/.+/g;$_=10x($&&&$&+16)if!/^(1(?1)*0)+$/;y;10;()

Giải pháp của Dennis là 59 byte tính theo perl (ngày càng chậm hơn đối với số lượng lớn):

#!/usr/bin/perl -p
1while$_-=(sprintf"%b",$n++)=~/^(1(?1)*0)+$/;$_=$&;y;10;()

Tôi cảm thấy như bạn chỉ nên chấm điểm này là 65 byte, (thực tế không phải là 64)?
Linus

1
@Linus Trong khi quy tắc né tránh của bạn là tuyệt vời và xứng đáng với tất cả các ưu điểm của nó, tôi thực sự coi đó là một chút gian lận. Để ghi điểm, số -pđược tính là 1 byte thêm
TonMedel

5

Python 3, 120 114 byte

def f(n,k=0):
 while~n:
  k+=1
  try:r=eval(bin(k).translate({48:'],',49:'['})[3:-1])+[];n-=1
  except:0
 print(r)

Kiểm tra nó trên Ideone .

Làm thế nào nó hoạt động

Hàm f được xác định lấy đầu vào n và khởi tạo k thành 0 . Chúng tôi sẽ tiếp tục tăng k cho đến khi giá trị n + 1 của k dẫn đến đầu ra hợp lệ. Mỗi khi chúng ta tìm thấy giá trị k như vậy , n sẽ giảm đi một khi nó đạt -1 , ~nmang lại 0 và danh sách r tương ứng với giá trị cuối cùng của k được in.

Ánh xạ một phần từ các số nguyên dương sang các danh sách lồng nhau (nghĩa là k ↦ r ) phải là tính từ, nhưng không có ràng buộc nào khác. Một trong những câu trả lời được sử dụng như sau.

  1. Chuyển đổi k thành biểu diễn chuỗi nhị phân, nhìn chằm chằm bằng 0b .

    Ví dụ: 44 "0b101100" .

  2. Thay thế tất cả 0 '(điểm mã 48 ) trong biểu diễn chuỗi bằng chuỗi "]," và tất cả 1 ' (điểm mã 49 ) bằng [ .

    Ví dụ, "0b101100" "], b [], [[],]," .

  3. Xóa ba ký tự đầu tiên (chúng tương ứng với "0b" ) và ký tự dấu (hy vọng là dấu phẩy).

    Ví dụ, "], b [], [[],]," ↦ "[], [[],]" .

  4. Hãy thử đánh giá mã được tạo. Nếu điều này dẫn đến một lỗi, k không được ánh xạ tới bất kỳ danh sách nào.

    Ví dụ: "[], [[],]" ([], [[]]) .

  5. Nối kết quả (nếu có) với danh sách trống. Nếu điều này dẫn đến một lỗi, k không được ánh xạ tới bất kỳ danh sách nào.

    Ví dụ: lỗi [[], [[]]) + []+ không thể nối các danh sách và bộ dữ liệu.


4

Haskell, 71 byte

p 1=["[]"]
p n=['[':h++t|k<-[1..n-1],h<-p k,_:t<-p$n-k]
((p=<<[1..])!!)

Hàm chính trên dòng cuối cùng lập chỉ mục thành một danh sách tất cả các mảng lồng nhau, được sắp xếp theo kích thước (số dấu ngoặc mở). Vì vậy, tất cả các mảng có kích thước tối đa 16 được liệt kê đầu tiên.

Trước tiên chúng ta hãy xem mã đẹp hơn và ngắn hơn, nhưng máy đánh chữ của Haskell từ chối chấp nhận.

p 1=[[]]
p n=[h:t|k<-[1..n-1],h<-p k,t<-p$n-k]
((p=<<[1..])!!)

Hàm ptrên đầu vào ncung cấp một danh sách tất cả các mảng có kích thước lồng nhau n(dấu ngoặc mở). Điều này được thực hiện đệ quy. Mỗi mảng như vậy bao gồm một số đầu h(thành viên đầu tiên) có kích thước kvà một số đuôi t(các thành viên khác) có kích thước n-k, cả hai kích thước khác không. Hoặc, đó là mảng trống cho kích thướcn==1 .

Biểu thức p=<<[1..]sau đó làm phẳng p(1), p(2), ...thành một danh sách vô hạn duy nhất của tất cả các mảng được sắp xếp theo kích thước

[ [], [[]], [[],[]], [[[]]], [[],[],[]], [[],[[]]], [[[]],[]], [[[],[]]], ...

và các chức năng chính lập chỉ mục vào nó.

... Hoặc, nó sẽ, nếu Haskell không than vãn về "xây dựng [ing] loại vô hạn: t ~ [t]". Haskell không thể biểu diễn danh sách vô hạn ở trên có các phần tử là các mảng được lồng tùy ý. Tất cả các yếu tố của nó phải có cùng loại, nhưng loại t không thể giống như danh sách của t. Trong thực tế, chức năngp tự nó không thể được chỉ định một loại nhất quán mà không cần gõ phụ thuộc, mà Haskell thiếu.

Vì vậy, thay vì chúng tôi làm việc trên các chuỗi dấu ngoặc, mô phỏng thao tác khuyết điểm bằng cách hành động []ký tự. Điều này cần thêm 9 byte. Những nguy hiểm của việc chơi golf trong một ngôn ngữ an toàn loại.


3

Haskell, 87 82 byte

0#0=[""]
n#m=['[':x|n>0,x<-(n-1)#m]++[']':x|n<m,x<-n#(m-1)]
(([0..]>>= \y->y#y)!!)

Đầu ra các phần tử mảng. Ví dụ sử dụng: (([0..]>>= \y->y#y)!!) 3-> "[][]".

Hàm #xây dựng tất cả các mảng lồng nhau dưới dạng chuỗi cho dấu ngoặc nmở và mđóng, bằng cách theo dõi xem có bao nhiêu mảng còn lại. Luôn luôn bắt đầu với n == m. Hàm chính gọi y # ycho mọi y <- [0,1,...]và chọn phần tử tại chỉ mục được đưa ra bởi đầu vào.


2

MATL , 31 byte

O`@BEqXJYs0&)0>w~hA+tG>~]x92J-c

Hãy thử trực tuyến! Hoặc xác minh một vài trường hợp thử nghiệm đầu tiên (mất vài giây).

Ánh xạ được tạo ra là:

0 -> []
1 -> [[]]
2 -> [[][]]
3 -> [[[]]]
4 -> [[][][]]
5 -> [[][[]]]
6 -> [[[]][]]
7 -> [[[][]]]
...

Giải trình

Mã tiếp tục kiểm tra tăng số nhị phân, với chữ số được 0thay thế bằng -1; đó là, sử dụng 1-1dưới dạng chữ số. Chữ số 1sẽ đại diện '['-1sẽ đại diện ']'.

Chương trình được tính cho đến khi đạt được n số hợp lệ +1 . Một số hợp lệ nếu hai điều kiện sau giữ:

  1. Tổng các chữ số bằng 0 (có nghĩa là có một số bằng 1-1)
  2. Tổng các chữ số tích lũy luôn dương (nghĩa là số 1chữ số tích lũy luôn vượt quá số -1) ngoại trừ ở cuối (trong đó nó bằng 0 theo điều kiện 1).

Khi đã nhận được n số hợp lệ +1, số cuối cùng được phiên âm bằng cách thay đổi 1thành [-1thành] , sau đó nó được hiển thị.

Mã số:

O          % Push 0: initial count of valid numbers
`          % Do...while
  @        %   Push iteretation index k, starting at 1
  B        %   Convert to binary. For example, k=6 gives [1 1 0 0]
  Eq       %   Multiply by 2, subtract 1: transforms [1 1 0 0] into [1 1 -1 -1]
  XJ       %   Copy that to clipboard J, without popping it
  Ys       %   Cumulative sum: gives [1 2 1 0]
  0&)      %   Split array into its final element and the rest. Gives 0, [1 2 1]
  0>       %   Yields 1 for positive entries (condition 2). So in this case it
           %   gives [1 1 1]
  w        %   Swap: moves second-top element in the stack (0 in this case) to top
  ~        %   Negate: yields 1 if input is 0 (condition 1). Gives 1 in this case
  h        %   Concatenate horizontally. Gives [1 1 1 1]
  A        %   All: gives 1 if all elements are 1. Gives 1 in this case, meaning
           %   that this k is valid
  +        %   Add the result (0 or 1) to the count of valid numbers
  t        %   Duplicate
  G        %   Push input n
  >~       %   Loop condition: false (exit loop) if count exceeds input n
]          % End loop. At this point the result is in clipboard J, in 1/-1 format
x          % Delete count
92         % Push 92. Will be used to convert 1, -1 to '[', ']' (ASCII 91, 93)
J          % Push result in 1/-1 format
-          % Subtract: converts 1 to 91, -1 to 93
c          % Convert to char. Implicitly display
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.