공허의 해독


25

void 목록은 목록에없는 개체를 포함하는 수준이없는 목록입니다. 또는 재귀 적 정의를 선호하는 경우

  • 빈 목록이 무효입니다

  • 다른 void 목록 만 포함 된 목록은 void입니다

모든 공극 목록의 깊이는 유한합니다.

다음은 void 구문의 예입니다 (파이썬 구문 사용).

[]
[[]]
[[],[]]
[[[]]]
[[[]],[]]
[[],[[]]]

무효 목록 이 아닌 것들의 예는 다음과 같습니다 .

["a"]
[[...]]
[1]
2
[[],([],[])]

태스크

두 개의 별도 기능 (또는 원하는 경우 프로그램)을 작성하십시오. 하나는 양의 정수 (원하는 경우 0을 포함 할 수 있음)를 인수로 사용하고 void 목록을 리턴하고 다른 하나는 void 목록을 가져와 정수로 리턴해야합니다. 이 두 기능은 항상 서로 반대이어야합니다. 당신의 출력을 전달하는 경우 즉 fg당신의 원래의 입력을 받아야 f의 결과를 g. 이는 매핑이 1 : 1이어야한다는 것을 의미합니다. 즉, 모든 정수에 대해, 해당 정수 를 제공하는 정확히 하나의 void 목록 만 존재할 g 있으며 모든 void 목록에 대해 f해당 공극 목록 을 제공하는 정확히 하나의 정수가 있어야 합니다.

본질적으로 Bijection을 만듭니다

언어 기본 목록 유형 대신 공백 목록 (쉼표와 공백이 있거나없는)의 문자열 표현을 사용하도록 선택할 수 있습니다.

채점

당신의 점수는 두 기능의 길이가 될 것입니다. 이것은 이므로이 합계를 최소화해야합니다.



1
이 질문은 두 가지 기능을 요구하는 반면 중복은 상반기를 요구합니다.
Ian Miller

3
쥐. 나는 내가 작성한 최고의 답변을 거의 올렸으며 다른 도전에는 적합하지 않습니다.
Caleb Kleveter

2
@IanMiller 다른 도전 과제는 인코딩에 대한 다른 지침이 있지만이 도전과는 다릅니다.
Caleb Kleveter

1
아마도이 질문이 단지 디코더 인 것이 더 합리적입니까? 이미 인코더에 대한 질문이 있기 때문입니다.

답변:


7

Pyth, 27 + 29 = 56 바이트

f:

L?bol`NS{sm[d+d]Y]d)ytb]Y@y

테스트 스위트

g:

L?bol`NS{sm[d+d]Y]d)ytb]Yxyl`

테스트 스위트

시스템은 매우 간단합니다. 특정 숫자 이하의 모든 가능한 목록을 생성합니다. [ . 그런 다음 아직 생성하지 않은 목록이 거의 끝나도록 정렬합니다. 이것은 y모두 프로그램에 의해 동일하게 수행됩니다 . 로 작성

L?bol`NS{sm[d+d]Y]d)ytb]Y

그런 다음에 대해이 목록에 색인을 작성하고을 f검색하십시오 g.

내가 생성하는 목록의 수는 무한 정렬 목록에서 원하는 위치에 또는 그 앞에 나타날 수있는 모든 가능한 목록을 생성 할만큼 충분히 크게 선택되었습니다.

프로그램은 옵션으로 0을 허용 / 반환합니다.


5

파이썬 2 , 96 바이트

온라인으로 사용해보십시오! bijection을 테스트합니다.

f=lambda l:len(l)and f(l[0])*2+1<<f(l[1:])

무효 목록을 음이 아닌 정수로 가져옵니다. 42 바이트

g=lambda n:n*[g]and[g(n/(n&-n)/2)]+g(len(bin(n&-n))-3)

음수가 아닌 정수를 사용하여 목록을 무효화합니다. 54 바이트 더 재귀적인 시도는 같은 길이를 주었다.

g=lambda n,i=0:n*[g]and[g(n/2,i+1),[g(n/2)]+g(i)][n%2]

1

자바 7, 725 바이트

f(int)( 325 바이트 ) :

String f(int i){String s="";for(int j=0,e=0;e<i;e+=v(s))s=Integer.toBinaryString(j++);return"["+s.replace("1","[").replace("0","]")+"]";}int v(String s){for(;!s.isEmpty();s=s.replaceFirst("1","").replaceFirst("0",""))if(s.replace("1","").length()!=s.replace("0","").length()|s.charAt(0)<49|s.endsWith("1"))return 0;return 1;}

g(String)( 75 + 325 바이트 ) :

int g(String s){int r=0;for(String i="10";!i.equals(s);i=f(++r));return r;}

메소드 g는 메소드 f를 사용 하여 입력 된 것과 동일한 것을 발견 할 때까지 가능한 void-list를 반복하여 결과를 계산하므로 바이트 수는 f두 번 계산됩니다 (두 가지 방법 모두이 문제에 대해 다른 방법없이 실행될 수 있기 때문에).

설명:

일반적으로, 메소드 f는 정수의 모든 이진 문자열 표현을 단순히 반복하고 유효한 것을 찾을 때마다 카운터를 증가시킵니다. 이 챌린지에 유효한 이진 문자열은 다음 규칙을 따릅니다. 규칙은으로 시작 1하고 0;으로 끝납니다 . 그것들은 1과 0의 같은 수를 가지고; 모든 시간은 첫 번째를 제거 1하고 0하고,이 두 가지 규칙이 여전히 적용 것을 다시 남아 확인합니다. 카운터는 입력과 동일하면, 모든 대체함으로써, 문자열 공극 목록이 이진수 문자열로 변환 1하여 [, 모든0] .

method g: 우리는 "[]"(void-list를 나타내는 0)로 시작한 다음 finput-String과 일치 할 때까지 정수를 늘리면서 method를 계속 사용 합니다.

String f(int i){         // Method `f` with integer parameter and String return-type
  String s="";           //  Start with an empty String
  for(int j=0,e=0;e<i;   //  Loop as long as `e` does not equal the input
      e+=v(s))           //    And append increase integer `e` if String `s` is valid
    s=Integer.toBinaryString(j++);
                         //   Change `s` to the next byte-String of integer `j`
                         //  End of loop (implicit / single-line body)
  return"["+             //  Return the result String encapsulated in "[" and "]"
    s.replace("1","[").replace("0","]")+"]";
                         //  after we've replaced all 1s with "[" and all 0s with "]"
}                        // End of method `f`

int v(String s){         // Separate method with String parameter and integer return-type
  for(;!s.isEmpty();     //  Loop as long as String `s` isn't empty
      s=s.replaceFirst("1","").replaceFirst("0",""))
                         //    After each iteration: Remove the first "1" and "0"
    if(s.replace("1","").length()!=s.replace("0","").length()
                         //   If there isn't an equal amount of 1s and 0s
       |s.charAt(0)<49   //   or the String doesn't start with a 1
       |s.endsWith("1")) //   or the String doesn't end with a 0
      return 0;          //    Return 0 (String is not valid)
                         //  End of loop (implicit / single-line body)
  return 1;              //  Return 1 (String is valid)
}                        // End of separate method

int g(String s){         // Method `g` with String parameter and integer return-type
  int r=0;               // Result integer
  for(String i="[]";!i.equals(s);
                         //  Loop as long as `i` does not equal the input String
      i=f(++r));         //   After each iteration: Set `i` to the next String in line
  return r;              //  Return the result integer
}                        // End of method `g`

입력 및 출력 사례 예 :

여기에서 시도하십시오. (참고 : 지난 몇 가지 테스트 사례의 경우 속도가 매우 느립니다. 모든 경우 10-15 초 정도 걸립니다.)

0   <-> []
1   <-> [[]]
2   <-> [[][]]
3   <-> [[[]]]
4   <-> [[][][]]
5   <-> [[][[]]]
6   <-> [[[]][]]
7   <-> [[[][]]]
8   <-> [[[[]]]]
9   <-> [[][][][]]
10  <-> [[][][[]]]
11  <-> [[][[]][]]
12  <-> [[][[][]]]
13  <-> [[][[[]]]]
14  <-> [[[]][][]]
50  <-> [[[][[[]]]]]
383 <-> [[[][]][[[][]]]]

1
나는 그것이 [][]목록 이라고 생각하지 않습니다 . 아마도 Java가 무엇이든하는 방식을 오해하고있을 것입니다. [...]그들 주위에 모두 추가 하고 0 맵을 사용 []하면 트릭을 수행해야합니다.
밀 마법사

@WheatWizard 아, 잘 했어. 이 문제를 해결하려고합니다. 어쨌든 아직 충분한 바이트가 없었습니다. ; P
Kevin Cruijssen

@WheatWizard 자, 이제 수정해야합니다. 터프하지만 재미있는 도전 btw. 나는 당신이 무엇을 의미하는지 이해하기까지 시간이 걸렸 으며이 답변을 쓰는 ​​데 더 오래 걸렸습니다. :)
Kevin Cruijssen



0

Python 3- 부호 / ab, 73 바이트

f=lambda n:[[[]]*(n<0),[[]]*abs(n)]
g=lambda l:[-1,1][not l[0]]*len(l[1])

온라인으로 사용해보십시오!

간단한 구현으로 음수를 지원합니다.

정수 i[sign(i), abs(i)]여기서 sign(i)=[] if i > 0 else [[]], 그리고 abs(i)=[[]] * i즉, 길이가 abs (i) 인 빈 목록의 목록으로 인코딩 됩니다.

파이썬 3- 바이너리, 126 바이트

이것은 더 정교한 버전이며 훨씬 더 길다. 여기서 절대 값은 이진리스트 표현으로 인코딩된다.

f=lambda n:[[[]]*(n<0),[[[]]*int(i)for i in f"{n:+b}"[1:]]]
g=lambda l:[-1,1][not l[0]]*int(''.join(map(str,map(len,l[1]))),2)

온라인으로 사용해보십시오!


1
더 복잡한 무효 목록에는 작동하지 않습니다. 온라인에서 사용해보십시오!
Jitse

아, 어쨌든 놓친 모든 무효 목록에 대한 매핑이 있어야 합니다 ... 당신이 맞습니다.
movatica

0

Stax , 총 33 바이트

이 프로그램들은 서로 반대입니다. 그것들은 0을 포함하는 모든 void 목록과 음이 아닌 정수로 변환합니다. 이것은 내가 알지 못하는 대수학의 유명한 함수 인 것 같습니다. 머리를 감싸기 위해 먼저 파이썬에서 함수로 프로그램을 구현했습니다.

def convert_to_void(n):
    lst = []
    while n > 0:
        n -= 1
        choices = len(lst) + 1
        choice = n % choices
        cutpoint = len(lst) - choice
        n //= choices
        newgroup = lst[cutpoint:]
        del lst[cutpoint:]
        lst.append(newgroup)
    return lst

def convert_from_void(lst):
    n = 0
    while lst != []:
        newgroup = lst.pop()
        n *= len(lst) + len(newgroup) + 1
        n += len(newgroup) + 1
        lst.extend(newgroup)
    return n

stax 프로그램의 동작은 동일합니다.

음이 아닌 정수 → 무효 목록, 15 바이트

ƒâ₧~└3BI─¿-rÅ;ì

실행 및 디버깅

무효 목록 → 음이 아닌 정수, 18 바이트

Çäê[!σ`c↑Ö§░NR╥ç=Æ

실행 및 디버깅

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