부인과의


30

문제는 간단합니다. 유한 음이 아닌 정수가 주어지면 중첩 배열을 출력하는 프로그램이나 함수를 작성하십시오.

규칙

  • 코드는 모든 정수 0 ≤ n ≤ 2 31에 대해 고유 한 유효한 중첩 배열을 생성해야합니다 .
  • 최대 16 개의 열린 괄호가있는 가능한 모든 중첩 배열이이 범위 내에서 출력되어야합니다. (코드가 16 개 이상의 열린 대괄호로 중첩 배열을 출력 할 수 없음을 의미하지는 않습니다.)
  • 코드에서 실제 배열 (쉼표가 있거나없는) 대신 중첩 배열의 문자열 표현을 출력 할 수 있습니다.

하나의 가능한 매핑 :

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

채점

이것은 이므로 바이트 단위의 가장 짧은 코드가 이깁니다.


시간 / 메모리 제한이 있습니까?
Dennis

@Dennis 시간 제한으로 1 시간이 합리적으로 보입니까? 나는 메모리에 합당한 것이 무엇인지 전혀 모른다.
ETHproductions

시간 제한이 있다면 메모리는 큰 문제가되지 않습니다. 한 시간은 매우 관대 해 보입니다. 내 코드가 충분히 빠른지 확인하기 위해 한 시간 동안 기다리기를 원하지 않습니다.
Dennis

4
시간 제한이없는 것을 선호합니다. 독창성을위한 더 많은 범위를 제공합니다
Ton Hospel

2
@TonHospel 쉼표없이 출력 할 수 있습니다. 출품작이 유효하다는 것을 증명할 수있는 한 시간 제한은 없을 것 같습니다.
ETHproductions

답변:


12

파이썬 2.7, 172149124118 바이트

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]+"]"

설명:

[1]↔ 으로 bijection을 정의하십시오 0. 모든 괄호 배열은 이진수로 쓰여질 수 있으며 그 반대도 가능합니다 (예 : [][]1010(10) 및[[][]]110100(52)). 최대 15 개의 열린 괄호 (총 30 개의 괄호)의 모든 유효한 배열은 최대 30 비트의 숫자 (앞의 0을 무시)로 덮여 있으며 정확하게 2 31 미만의 숫자 입니다.

첫 번째 for-loop는 배열이 유효한지 확인하면서 숫자를 대괄호 배열로 변환 하여이 bijection의 역수를 제공합니다.

충돌을 피하기 위해 인쇄 배열 내에서 잘못된 배열은 긴 괄호로 대체됩니다. 예를 들어11 (3) ↔ [[은 유효하지 않으므로 대신 3 + 16 개의 괄호를 연결합니다. 이렇게하면 모든 배열이 고유합니다.

그래서 얻어진 배열은, 중첩 배열을 만들기 위해 한 쌍의 대괄호 안에 배치된다 1010(10)하게 [[][]]하고 110100(52)가된다 [[[][]]]. 여분의 열린 브래킷은 이제 모든 어레이를 16 개의 열린 브래킷으로 덮었 음을 의미합니다.


다음 프로그램을 사용하여 최대 16 개의 괄호가있는 주어진 어레이의 번호를 알아낼 수 있습니다.

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

그가 "독특한"을 지정할 때 작전의 의도를
남용한 것

그것은 천재입니다. 잘 했어. (쉼표가없는 형식도 허용됩니다.)
ETHproductions

12

파이썬, 153128 바이트

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)

이진수를 왼쪽에서 오른쪽으로보고 숫자 n 을 중첩 된 목록에 매핑합니다 . 이 알고리즘은 2 32 미만이 아닌 모든 수에 적용 됩니다.

  1. 현재 이진수가 1이면을 출력 [합니다.
  2. 그렇지 않으면, 우리가 지금까지 출력 한 일련의 브래킷이 단일 닫는 브래킷, output에 의해 균형을 잡을 것 ][입니다.
  3. 그렇지 않으면 이진수의 마지막 0이면 output ][.
  4. 그렇지 않으면 출력 ]합니다.

마지막으로 열린 괄호를 닫습니다.


5

숟가락 , 63 바이트 (501 비트)

000001001001001011001101001010011011111001010001000000101010
101101100110100101101001000101100010001000000100011000010000
000000000000001110111110010000001110110110010100100100100100
000110011010001000000110110000010000001010110011011011011001
000000011010010010010001000000111011011011101001001001000110
110110010100100101011001000100000011010001000000111011011001
010010010010010001101101101001000110110010110001101101101101
100100010001010010001010011011001000000011001101001001010010
000001100101001000111

이것은 다음의 brainfuck 프로그램으로 숟가락으로 변환되었습니다.

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

stdin에서 2 진으로 정수를 읽고 stdin에서 중첩 목록을 출력합니다. 0은 빈 문자열 (숫자 없음)로 입력해야하며 8 비트 셀이있는 brainfuck 인터프리터가 필요합니다. 내 파이썬 답변과 같은 알고리즘.

읽을 수있는 버전 :

-[+[+<]>>+]<+++.           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
우리는 최근에 다른 답변에 대해이 토론을했으며 63 바이트 파일을 처리 할 수있는 실제 해석자가없는 것 같습니다. 참조 구현에는 바이트 0x30 및 0x31이 사용되었으므로이 응답에는 501 바이트 파일 이 필요 합니다.
Dennis


5

펄, 80 79 바이트

다시 orlp를 사용 알고리즘을 사용하지만 이번에는 작동하는지 먼저 확인했습니다 ...

에 +1 포함 -p

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

Linus 의 솔루션은 perl에서 64 바이트입니다.

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

Dennis 의 솔루션은 perl에서 59 바이트입니다 (많은 숫자의 경우 점점 느려짐).

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

나는 이것을 65 바이트로 평가해야한다고 생각합니다 (실제로 64 아닙니까)?
Linus

1
@Linus 귀하의 규칙 회피는 훌륭하고 모든 투표를받을 가치가 있지만, 나는 약간의 사기로 간주합니다. 점수를 매기기 위해 -p1 바이트를
더한

5

파이썬 3 120 114 바이트

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)

Ideone에서 테스트하십시오 .

작동 원리

정의 된 함수 f 는 입력 n을 취하고 k0으로 초기화 합니다. 합니다. 우리는 증가하겠습니다 케이 때까지 N + 1 의 값 k 개의 유효한 출력 결과. 마다 우리는 같은 값을 찾을 K를 , N 이 도달하면 감소한다 -1 , ~n수득 0 및리스트 (R) 의 최후의 값에 해당하는 K가 인쇄된다.

양의 정수에서 중첩 된 목록 (즉, k ↦ r )으로 의 부분 매핑은 형용 해야하지만 다른 제약은 없습니다. 이 답변에 사용 된 것은 다음과 같이 작동합니다.

  1. k0b 로 시작하는 이진 문자열 표현으로 변환 합니다.

    예를 들어 44 ↦ "0b101100" 입니다.

  2. 문자열 표현 의 모든 0 (코드 포인트 48 )을 문자열 "]"로 바꾸고 모든 1 (코드 포인트 49 )을 [ .

    예를 들어 "0b101100"↦ "], b [], [[],]," 입니다.

  3. 처음 3자를 제거하십시오 ( "0b"에 해당). )와 후행 문자 (쉼표)를 제거하십시오.

    예를 들어, "], b [], [[],],"↦ "[], [[],]" 입니다.

  4. 생성 된 코드를 평가하십시오. 이로 인해 오류가 발생하면 k 는 목록에 매핑되지 않습니다.

    예를 들어 "[], [[],]"↦ ([], [[]]) 입니다.

  5. 결과 (있는 경우)를 빈 목록으로 연결하십시오. 이로 인해 오류가 발생하면 k 는 목록에 매핑되지 않습니다.

    예를 들면, ([] []) + [] 보낸 오류 + 는 목록과 튜플을 연결할 수 없으므로 입니다.


4

하스켈, 71 바이트

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

마지막 행의 주요 함수는 크기 (열린 대괄호 수)별로 정렬 된 모든 중첩 배열 목록으로 색인합니다. 따라서 최대 16 개의 모든 크기 배열이 먼저 나열됩니다.

더 좋고 더 짧은 코드를 먼저 살펴 보자. 그러나 Haskell의 타입 체커는 수락하지 않습니다.

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

p입력 기능 은 n중첩 된 모든 크기의 배열 n(열린 대괄호) 목록을 제공합니다 . 이것은 재귀 적으로 수행됩니다. 이러한 각 배열은 크기가 아닌 일부 헤드 h(첫 번째 멤버)와 크기가 k일부인 꼬리 t(다른 멤버)로 구성되며 크기 n-k는 모두 0이 아닙니다. 또는 크기의 빈 배열입니다.n==1 .

p=<<[1..]그런 다음 표현식 p(1), p(2), ...은 크기별로 정렬 된 모든 배열의 단일 무한 목록으로 평면화 됩니다.

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

주요 기능이 색인으로 생성됩니다.

... 또는 Haskell이 "무한한 유형을 구성하는 것에 대해 소리를 내지 않으면 : t ~ [t]"입니다. Haskell은 위의 요소가 임의로 중첩 된 배열 인 무한 목록을 나타낼 수 없습니다. 모든 요소는 동일한 유형을 가져야하지만 유형 t는 t 목록과 같을 수 없습니다. 실제로, 기능p Haskell이 부족한 의존적 타이핑이 없으면 자체에 일관된 유형을 할당 할 수 없습니다.

대신 대괄호 문자열을 작업하여 []문자를 사용 하여 단점 작업을 시뮬레이션합니다 . 추가 9 바이트가 필요합니다. 안전한 유형의 언어로 골프를하는 데 따르는 위험.


3

하스켈, 87 82 바이트

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

배열 요소를 출력합니다. 사용 예 : (([0..]>>= \y->y#y)!!) 3-> "[][]".

함수 는 얼마나 많은 각 #배열 이 남았는지 추적하여 중첩 된 모든 배열을 n열기 및 m닫기 괄호 문자열로 만듭니다 . 항상로 시작합니다 n == m. main 함수는 y # yevery를 호출 y <- [0,1,...]하고 입력에 의해 주어진 색인에서 요소를 선택합니다.


2

MATL , 31 바이트

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

온라인으로 사용해보십시오! 또는 처음 몇 가지 테스트 사례를 확인하십시오. (몇 초 소요).

생성 된 매핑은 다음과 같습니다.

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

설명

코드는 숫자 0-1; 즉 사용된다 1-1숫자로. 자리가 1나타냅니다 '['-1나타냅니다 ']'.

프로그램은 n +1 유효 숫자를 얻을 때까지 계산 합니다 . 다음 두 조건이 충족되는 경우 숫자가 유효합니다.

  1. 자릿수의 합은 0입니다 (즉, 1와 수가 동일 함 -1).
  2. 누적 자릿수는 항상 양수입니다 (즉, 누적 된 수 1-1 끝 (조건 1에 의해 0 인 경우)을 제외하고 자릿수가 항상을 초과합니다 ).

일단 N +1 유효한 수치가 얻어졌다 마지막 하나는 변경되고 음역 1으로[ 하고-1 내로] 하고이를 표시한다.

암호:

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.