인코딩-셔플-디코딩


23

도전

당신의 임무는 정수를 ASCII 문자 의 문자열로 인코딩 한 다음 해당 문자열이 무작위로 섞인 후에 성공적으로 디코딩하는 것입니다.

EncoderDecoder 라고하는 두 개의 프로그램 / 기능 을 작성 합니다.

엔코더

  • 입력 : 정수 범위 .n[0,2311]
  • 출력 : 문자열 의 아스키 문자 (반드시 인쇄되지 않음).s

디코더

  • 입력 : 임의의 순열 문자열 .ss
  • 출력 : 정수 .n

채점

하자 수 최대 길이 의 모든 가능한 값에서 . 경우] 인코더 비 결정적 행동 (허용되는, 아래 참조), 그 다음 최대 길이 인 것 (아마도 발생 ).AsnAs

하자 수 의 길이 인코더 바이트의 의 길이 디코더 바이트입니다.LEL DLD

그런 다음 점수는 입니다.A(LE+LD)

승리는 가장 낮은 점수를 제출에 수여됩니다 .

시간 제한

단일 테스트 케이스 (즉, 단일 값 )에 대해 인코더디코더 의 실행 시간에 1 분의 임의 시간 제한이 있습니다.n

목표는 모든 속성을 특정 속성으로 열거하여 무차별 인코딩을 찾는 솔루션을 피하는 것입니다. 솔루션이 그보다 더 영리한 작업을 수행하는 경우 시간 제약 조건에 가장 적합하고 유효한 것으로 간주됩니다. 마찬가지로 임의의 선택된 값에 대해 TIO 에서 작동 하면 유효한 것으로 간주됩니다. 그렇지 않으면 내 컴퓨터에서 테스트하지만 솔루션이 순수한 무차별 인 경우 거의 실패합니다.n

규칙

  • 인코더디코더는 작성해야합니다 같은 언어 .
  • 디코더 필수의 출력 올바른 정수 모든 가능한 순열 문자열 에 의해 반환 인코더 .nss
  • 인코더디코더가 되어 있지 허용 정보를 공유 (전역 변수 또는 파일에 의해 예) 어떤 방법이다.
  • 의 출력 인코더는 필요 하지결정 (같은 입력이라고 경우 다른 출력 문자열을 생성 할 수 인코더는 여러 번 실행)하지만, 디코더는 항상 올바른 정수를 생각해야한다 .nnn
  • 인코더디코더 가지고 정수 반환 할 수 에 임의의 편리한 방식으로 (예를 들어 만약 의 입력이되는 것이 괜찮 , 나 ).nn = 14n=1414"14"[1,4]
  • 인코더 수도 문자열 출력 로 인해서 인쇄 그것을 또는 의해 반환 문자열리스트 / 문자 배열 또는 범위의 정수리스트 / 배열 ; 있습니다 디코더는 입력으로의 순열받을 에 의해 반환 인코더 는 문자열을 받아 들여야한다, 그래서 에 같은 형식 으로 .s[ 0 , 127 ] S 'stdout [0,127]sss
  • 표준 허점 은 금지되어 있습니다.
  • 가능하면 코드 작동 방식과 주장 점수가 정확한 이유를 설명 하십시오.

가정하십시오 .n=14

  • 인코더 수신 14입력한다. 출력 될 수 있습니다 "qwerty".
  • 디코더 의 전치 수신 "qwerty"인스턴스로서 입력 "tweyqr". 14편리한 형식으로 출력해야합니다 .

인코더 돌아왔다 수 [113,119,101,114,116,121]있는 경우에,뿐만 아니라 디코더 (예를 들어)받은 것이다 [116,119,101,121,113,114].

인코더 가 반환 한 문자열 에는 인쇄 할 수없는 ASCII 문자도 포함될 수 있습니다 (그러나 항상 범위 내에 있음 [0x00, ..., 0x7F]).


분명히 출력 길이는 무한대가 될 수 없으며 무한 문자열을 섞을 수 없습니다
H.PWiz

H.PWiz 없음 @는 할 수 없습니다 만하면 아이폰에는 억제 할 수 있습니다 인코더는 비 결정적이다
Delfad0r

"인코더와 디코더는 어떤 식 으로든 정보를 공유 할 수 없습니다."여기에는 도우미 기능이 포함됩니까? 즉, 사용자 정의 기능이 계승 N + 3 (임의의 예)를 계산
pizzapants184

인코더가 빈 문자열 / 목록을 반환 할 수 있습니까?
pizzapants184

2
@Kroppeb 예, 현재 규칙에 따르면 바이트를 두 번 계산해야한다고합니다. 그래도 두 개의 동일한 프로그램으로 제출물을 보는 데 관심이 있습니다.
Delfad0r

답변:


12

젤리 , (17 바이트 + 18 바이트) × 길이 6 = 210 포인트

b36µỤỤ + × 3µŒ¿b3U + Ṣ
Ṣ : 3_J
Ṣ % 3Uḅ3œ? Çḅ36

온라인으로 사용해보십시오! (또는 추가 디버그 정보 포함)

언급 된 승리 조건을 목표로이 과제를 해결해 보았 기 때문에 가상의 대체 승리 조건 ( 출력에 가능한 최소 길이가 주어진 을 선택하는 것이 흥미로울 것이라고 생각했습니다 .

설명

부호화

인코딩의 첫 번째 단계는 입력을 기본 36 ( b36)으로 표시하는 것입니다. 36 6 = 2176782336> 2147483647이므로 결과에는 최대 6 개의 숫자가 있으며 각 숫자는 0-35 범위에 있습니다.

다음으로, 우리는 6이 개 포함 된 표현으로이 변환 다른 숫자를. 여기에는 여러 가지 가능한 알고리즘이 있지만 여기에 사용되는 알고리즘은 1을 가장 작은 자릿수에, 2를 두 번째로 가장 작은 숫자에, 3을 세 번째로 가장 작은 식으로 추가하는 것입니다. 즉, 두 자리수가 같으면 그 중 하나가 임의로 작게 간주되어 달라집니다. 분명히이 알고리즘은 두 개의 다른 숫자를 동일하게 만들 수 없습니다. Jelly에서 이것을 나타 내기 위해, 우리는 ( "값으로 인덱스 정렬")을 사용하여 정렬 된 순서로 인덱스리스트를 얻는다; 다시 원본의 각 요소를 정렬 된 순서로 해당 위치에 효과적으로 매핑합니다. 과µ…+원본을 새 목록에 추가합니다. 결과는 입력 번호를 1–41 범위 (최소 0 + 1, 최대 35 + 6)의 6 가지 숫자 로 표현한 것입니다 .

A : 우리는 다른 형태로이 분할 소트 . 숫자가 있었던 720 가능한 순열의 어떤 대표 720 1에서 숫자와 함께 상기 1-41 범위의 숫자 목록합니다 ( Œ¿순열 번호를 추출하고 정렬 각각 목록을 작성하십시오.)

마지막으로, 우리는 1에서 720까지의 숫자를 기수 3 ( b3) 으로 변환하고 , 거꾸로 한 후 ( U) 6 개의 기수 3 자리 숫자와 6 개의 1 ~ 41 자리 숫자를 역 divmod ( 문자 mod 3은 기본 3 자리이며, 3으로 나눈 값은 1-41 자리입니다. 가능한 결과 범위는 ASCII 범위 내에서 최소 (1 × 3) + 0 = 3, 최대 (41 × 3) + 2 = 125입니다. 패킹을 통해 이루어집니다 ×3+추가와 함께, µ반드시 모든 명령은 데이터의 오른쪽 비트에서 작동하는지 확인합니다. (여기서 우리는 순열을 추출 하기 전에 3을 곱하기 때문에 약간의 골프 트릭이 있습니다 . 그러면 그룹화 문자에 바이트를 소비 할 필요가 없습니다.)

또한 기본 3 숫자를 뒤집는 이유는 1–41 숫자보다 적은 자릿수가있을 수 있기 때문입니다. (더 이상 가질 수는 없습니다. n !> 3 n 이 6보다 약간 작은 숫자입니다 .) 젤리는 서로 다른 길이의 두 숫자를 더할 때 후행 0을 효과적으로 삽입하여 일치시킵니다. 후행 0은 숫자의 해석에 영향을 주지만 선행 0은 그렇지 않습니다. 따라서 반대의 0은 우리의 답을 어지럽히 지 않는 어딘가에있게됩니다.

디코딩

디코딩의 첫 단계는 두 숫자 (기본 3 숫자와 1–41 숫자)를 추출하는 것입니다. 우리는 각각 division ( :3)과 modulo ( %3) 로 쉽게 자릿수를 얻을 수 있지만 어떤 순서인지 알 수 있습니까? 1 ~ 41 개의 숫자는 순서대로 정렬되었으며 두 숫자의 해당 위치에있는 숫자는 동일한 문자로 저장되었습니다. 따라서 1-41 숫자의 숫자가 상대적인 값을보고 섞인 순서를 알아낼 수 있으며 기본 3 숫자의 숫자는 같은 방식으로 섞여 있어야합니다. 실제로 ASCII 인코딩의 문자는 1-41 숫자와 같은 방식으로 정렬되기 때문에 (모두 고유하고 기본 3 숫자보다 중요합니다.). 따라서 두 추출 모두로 시작하고 그 뒤에 %3또는 :3적절하게 시작합니다.

1–41 개의 숫자는 여전히 정렬 된 순서이지만, 우리는 36 진법의 0-35 자리로 돌아가는 매우 편리한 방법을 가지고 있습니다. 첫 번째에서 1을 빼고 두 번째에서 2를 빼고 세 번째에서 3을 빼십시오. 젤리에서는 _J( "subtract index")로 그렇게 할 수 있습니다 .

한편, 디코드의 다른 분기에서는 기본 3 숫자의 자릿수를 순서 ( U) 로 되돌리고를 사용하여 기본 3의 숫자를 순열 인덱스로 다시 변환합니다 ḅ3.

그런 다음 두 가지를 결합 할 수 있습니다 œ?Ç. œ?"이 순열 인덱스가 주어진 상태에서 permute"를 Ç의미하고 "위의 라인을 적용한 결과"를 의미합니다. 즉, Jelly가 두 입력을 동일한 입력에서 개별적으로 실행하도록 지시합니다.

우리가 지금 가지고있는 것은 원래 36의 숫자 (으로 인해 _J)와 원래의 순서 (으로 인해 왔습니다)의 숫자입니다. œ?따라서 간단히 ḅ36기본 36에서 단일 정수로 다시 변환 할 수 있습니다 .

해설

티오! 위의 링크는 인코딩 할 숫자로 312699167을 사용합니다. 기본 36의이 숫자는입니다 [5, 6, 6, 8, 7, 35]. 따라서 인코딩의 모든 측면을 보여줍니다. 35는 0-127 범위의 한계를 테스트합니다. 중복 6은 원래베이스 (36)에서 동일한 자릿수의 해상도를 테스트하고; 숫자가 거의 (정확히 정렬되지는 않음) 정렬되어 있다는 사실은 순열 수가 매우 작아서 기본 36 수보다 많은 수의 자릿수를 제공하므로 원래 숫자를 추가하기 전에 뒤집을 필요가 있음을 나타냅니다.

여기에 모든 상수가 어떻게 맞는지 정말 편리합니다. 36 (6)가 아니라 단지 2 맞도록 충분히 높은 31 3 6 아니라 단지 6 맞게 충분히 높은!를 (36 + 6) × 3이 아니라 단지 우리가 128 가능성 내에 맞도록 충분히 높은. (여기서 마지막 제약 조건은 1- 인덱싱 대신 0- 인덱싱을 사용하여 0-2 범위의 문자를 사용할 수 있기 때문에 가장 타이트합니다. 그럼에도 불구하고 37을 기본으로 사용하기에 충분한 공간 만 제공합니다. 36 세 이상)


9

젤리 , ( 4 3 바이트 + 6 5 바이트) × 길이 8 = 80 64 포인트

b⁴Ä
ṢŻIḅ⁴

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

젤리 , ( 2 1 바이트 + 4 3 바이트) × 길이 10 = 60 40 포인트

에이
ṢŻI

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

설명

해결책 1

이것은 대부분의 다른 답변과 다른 알고리즘을 사용하고 있습니다. b⁴다른 답변과 마찬가지로 16 진수 ( )로 값을 인코딩 한 다음 누적 합계 ( Ä) 를 가져옵니다 . 각 입력은 분명히 다른 출력을 제공하며 (두 작업 모두 가역적 임) 16 진수 인코딩에는 최대 8 자릿수 (최대 값은 7 (마지막 8 자리) 및 15 (마지막 ~ 7 번째) 마지막 숫자), 출력 목록의 최대 숫자는 7+ (7 × 15) = 112이며 질문에 필요한 127보다 작습니다. 또한 출력은 반드시 순서대로 정렬되어 셔플을 뒤집을 수 있습니다.

디코더의 경우 먼저 셔플을 정렬 ( )로 뒤집습니다 . 그런 다음 0을 앞에두고 Ż연속 쌍의 차이를 취하여 누적 합을 역전시킵니다 ( I). 그런 다음 16 진수 ( ḅ⁴) 에서 다시 변환하십시오 .

해결책 2

이 질문은 실제로 입력을 (아마도 십진수) 숫자의 목록으로 가져갈 수있게 해주므로 간단히 기본 변환을 제거하여 "속임수"를 쓸 수 있습니다. 출력에 사용 된 최대 수는 2 + (9 × 9) = 83입니다 (2999999999가 범위를 벗어 났기 때문에 실제로 82이므로 최악의 입력은 1999999999입니다). 결과 인코딩은이 문제에 대한 인코딩이 진행됨에 따라 매우 끔찍하지만 생성하는 것이 매우 간결하여 인코딩의 상세보다 더 큰 이점이 있습니다.

이 답변은 속임수처럼 느껴져이 문제에 대한 나의 주요 해결책은 아니지만 기술적으로 규칙을 준수하고 더 나은 점수를 얻으므로 추가 가치가있는 것처럼 보입니다.

해설

길이 8 이하로 떨어지는 알고리즘을 염두에두고 있지만 길이 7 알고리즘을 ≤9 바이트 (비 치팅) 또는 ≤5 바이트 (치팅)로 구현할 수 없을 것 같습니다. 따라서 문제의 점수를 매기면 가장 좋은 방법 일 것입니다. (그러나 어쨌든 재미를 위해서 대안으로 "인코딩의 길이를 최소화하는"도전에 대한 해결책을 찾았을 것입니다.)

일부 솔루션과 달리 16을 기본으로 사용하는 것은 중요하지 않습니다. 길이 8 해 (예 : 18)에 사용할 수있는 다른 숫자가 많이 있습니다. Jelly는 1 바이트 방식을 나타 내기 때문에 첫 번째 솔루션으로 16을 선택했으며 다른 실행 가능한베이스는 프로그램에서 여러 바이트를 사용해야합니다. 물론, 두 번째 솔루션은 허점을 이용하기 위해 10을 기본으로 사용해야합니다.

이 알고리즘을 작성하기가 더욱 어려워진 일부 새로운 Jelly 명령을 지적한 @Dennis에게 감사드립니다.


3
Ä의 약자 +\, Ż줄임말입니다 0;.
Dennis

7

셰익스피어 프로그래밍 언어 , 10 * (264 + 494) = 8650 7910 7580

인코더 : 264 바이트

,.Ajax,.Ford,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Be you nicer zero?You be the sum ofyou the product ofthe sum ofI a big big pig the sum ofa big big big big cat a big big pig.If soSpeak thy.Ford:You are the sum ofyou a cat.If soLet usAct I.

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

디코더 : 494

,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Is you nicer a pig?If soRemember you.If soLet usAct I.Scene V:.Ford:Remember I.Ajax:Recall.Is you worse the sum ofPage twice the sum ofa big big cat a cat?If soYou be the difference betweenyou Page.If soOpen heart.If notlet usScene V.Scene X:.Ford:Recall.Ajax:Be I nicer zero?If soRemember I.If soLet usScene X.[Exit Ajax][Enter Page]Ford:You be the sum ofyou twice twice the sum ofa big big cat a pig.Let usAct I.

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

이것은 일이었다.

인코더는 각 자릿수에 자릿수와 12의 자릿수를 더한 값으로 인코딩합니다. 디코더는 모든 입력을 Ford의 메모리에 저장 한 다음 카운터를 반복하여 카운터 * 12 + 10보다 낮은 각 숫자를 출력 한 다음 삭제합니다.

설명:

엔코더

,.Ajax,.Ford,.Act I:.Scene I:.      Boilerplate introducing the two characters
[Exeunt][Enter Ajax and Ford]       Enter the two characters Ajax and Ford
                                    Ford will be handling the input
                                    Ajax will be the counter
Ajax:Open mind.                     Set Ford to the next character of input
Be you nicer zero?                  Check if it is EOF
You be the sum of                   Set Ford to the sum of 
    you                             His original value (48 to 58)
    the product of                 
          the sum of               
              I                     Ajax's value
              a big big pig         Minus 4 (this handles the offset of 48)
          the sum of                Multiplied by
              a big big big big cat 2^4
              a big big pig.        + -2^2 = 12
                                    This essentially sets Ford to (F+12*(A-4))
If soSpeak thy.                      If not EOF, print Ford's value
Ford:You are the sum ofyou a cat.   Increment Ajax's value
If soLet usAct I.                   If not EOF, Repeat again.

디코더

,.Ajax,.Ford,.Page,.Act I:.Scene I:.  Boilerplate introducing three characters
                                      Ajax is the spare stack
                                      Ford is the storage stack
                                      Puck is the counter, increasing by 12
[Exeunt][Enter Ajax and Ford]            Enter Ajax and Ford onto the stage
Ajax:Open mind.                          Get the next character of input
Is you nicer a pig?                      If not EOF
If soRemember you.                         Store the value in Ford's memory
If soLet usAct I.                          And repeat the loop
Scene V:.                                Otherwise move to the next scene
Ford:Remember I.                         Store Ford's value (initially -1 from EOF) in Ajax's memory
Ajax:Recall.                             Get the next value from Ford's memory
Is you worse the sum of                  Is the value smaller than
        Puck                                  Puck's value
        twice the sum ofa big big cat a cat?  + 10 ?
                                              i.e. is it the next digit?
If soYou be the difference betweenyou Puck.   If so, subtract Puck's value from Ford
If soOpen heart.                              And print Ford's value
If notlet usScene V.                     If that was not the digit, repeat
Scene X:.
Ford:Recall.                             Get the next value from Ajax's memory
Ajax:Be I nicer zero?                    Until the -1
If soRemember I.                         Returning the values to Ford's memory
If soLet us Scene X.                     Repeat until Ajax's memory is exhausted
[Exit Ajax][Enter Page]                  Swap Ajax and Page
Ford:You be the sum of                   Set Puck's value to
              you                        Puck +   
              twice twice the sum of     2*2*(
                           a big big cat      4
                           a pig.             -1) = 12
Let usAct I.                             And start from the beginning again, having removed one number

5

파이썬 2.7, 31 * (52 + 37) = 2759

인코더 ( 69 52 바이트) :

lambda n:[chr(i)if n&(1<<i)else""for i in range(32)]

디코더 ( 41 37 바이트) :

lambda s:sum([1<<(ord(c))for c in s])

입력 번호의 0이 아닌 모든 비트를 ASCII 값으로 저장합니다. ASCII 문자의 값은 설정된 비트의 위치를 ​​저장합니다. 예를 들어 값 'a'는 97 번째 비트가 설정되었음을 의미합니다.

@ Delfad0r 덕분에 몇 가지 개선 사항

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


PPGC에 오신 것을 환영합니다! 당신은 놓을 수 e = 와를 d = 시작 부분에 - 익명 함수는 완벽하게 정상입니다. 또한 문제 설명에 따르면 인코더 가 문자 대신 정수 목록을 반환 할 수 있으므로 정수-> 문자-> 정수 변환을 피할 수 있습니다. 또한 2 바이트 n&(1<<i)대신 사용 n&(1<<i)>0하여 저장할 수 있습니다 . 마지막으로 i(127) 의 상한 은 너무 커서 32는 충분하고 1 바이트를 절약합니다.
Delfad0r

1
문제 설명 의 점수 섹션에 따라 점수를 기재하십시오.
Delfad0r

@ Delfad0r 점수가 정확합니까? 그리고 팁 주셔서 감사합니다.
Hein Wessels

나는 (52+37)*31=275931 비트가 모두 설정되었을 때부터 가장 긴 점수라고 생각합니다 .
Jonathan Allan

인코더는 lambda n:[chr(i)*(n&1<<i>0)for i in range(32)]6 바이트를 절약 할 수 있습니다 .
mypetlion

5

Stax , 점수 8 × (10 + 9) = 152

인코더, 10 바이트

Ç·MÉJ'♀τ│½

실행 및 디버깅

16|E{i16*+m Full program, implicit input
16|E        Get hexadecimal digits
    {     m Map:
     i16*+    Add 16 * loop index
            Implicit output as string

인코더는 문자열을 오름차순으로 출력합니다.

디코더, 9 바이트

üL∟n╫k∞‼9

실행 및 디버깅

o{16%m16|E Full program, implicit input
o          Sort string
 {16%m     Module each element by 16
      16|E Interpret as array of hex digits


5

파이썬 3 , 8 * (45 + 38) = 664

인코더 (45 바이트) :

lambda n:[16*i+(n>>4*i)%16 for i in range(8)]

디코더 (38 바이트) :

lambda l:sum(x%16<<x//16*4 for x in l)

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


1
당신은, "를"전에 공백을 제거 할 수 있습니다 lambda l:sum(x%16<<x//16*4for x in l):) 잘 작동
인 FatalError

4
작동하지 않습니다. 출력은 일반 ASCII가 아닙니다 (0..127 범위)
GB

2
@GB 내 실수. 나는 마지막 편집으로 그것을 깨뜨렸다. 지금 되돌리기
Curtis Bechtel

인코더에서 3 바이트를 절약 lambda n:[n>>4*i&15|i<<4for i in range(8)]하고 디코더에서 1을 절약 하십시오 : lambda l:sum(x%16<<x//16*4for x in l)총 632 점
Aaron

4

자바 스크립트 (ES6), 8 * (40 + 32) = 576

08

인코더 (40 바이트)

E=(n,k=0)=>n?[k|n&15,...E(n>>4,k+16)]:[]

디코더 (32 바이트)

s=>s.map(c=>s|=c%16<<(c/4&~3))|s

데모

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

방법?

입력은 4 비트의 8 블록으로 나뉘며 각 블록은 16 개의 가능한 문자 중 1로 인코딩됩니다. 마지막 블록의 최상위 비트는 설정되지 않습니다.

       3222222222211111111110000000000
bit:   0987654321098765432109876543210
       \_/\__/\__/\__/\__/\__/\__/\__/
block:  7  6   5   4   3   2   1   0

block #0 is encoded with char. 00 to 0F (NUL to SI)
block #1 is encoded with char. 10 to 1F (DLE to ES)
block #2 is encoded with char. 20 to 2F (' ' to '/')
block #3 is encoded with char. 30 to 3F ('0' to '?')
block #4 is encoded with char. 40 to 4F ('@' to 'O')
block #5 is encoded with char. 50 to 5F ('P' to '_')
block #6 is encoded with char. 60 to 6F ('`' to 'o')
block #7 is encoded with char. 70 to 77 ('p' to 'w')

4

젤리 , (8 + 9) 바이트 * 8 최대 길이 = 136

b⁴+J’Ɗ⁴¡

인코더 (명확성을 위해 파이썬이 원하는대로 바닥 글 형식을 지정)

Ṣ_J‘Ɗ⁴¡ḅ⁴

디코더

이론적으로 최대 길이는 6입니다. 22 바이트 이하로 수행 할 수 있습니까?

이므로 최대 길이가 5이면 불가능합니다.i=0i=5(127+i127)=321402081<2311

방법?

23117fffffff[7,15,15,15,15,15,15,15][7,15,15,15,15,15,15,15] + [0,16,32,48,64,80,96,112] = [7,31,47,63,79,95,111,127]

엔코더 :

b⁴+J’Ɗ⁴¡ - Link: integer, n    e.g. 1234
 ⁴       - literal 16               16          
b        - convert to base          [4,13,2]
       ¡ - repeat...
      ⁴  - ...16 times:
     Ɗ   -   last 3 links as a monad:
   J     -     range of length        [1,2,3]     iter 2    iter 3    ...  iter 16
  +      -     add                    [5,15,5]   [5,16,7]   [5,17,9]  ...  [5,30,35]
    ’    -     decrement              [4,14,4]   [4,15,6]   [4,16,8]  ...  [4,29,34]
         -                                                                 [4,29,34]

디코더 :

Ṣ_J‘Ɗ⁴¡ḅ⁴ - Link: list of integers   e.g. [29,34,4]
Ṣ         - sort                          [4,29,34]
      ¡   - repeat...
     ⁴    - ...16 times:
    Ɗ     -   last 3 links as a monad:
  J       -     range of length           [1,2,3]
 _        -     subtract                  [3,27,31]   [3,26,29]   [3,25,27]  ...  [3,12,1]
   ‘      -     increment                 [4,28,32]   [4,27,30]   [4,26,28]  ...  [4,13,2] 
        ⁴ - literal 16                    16
       ḅ  - from base                     1234

"16 진수"입니다. ( "일반 16 진수를 사용하는 숫자"는 더 길며, "숫자"만으로는 10 진수를 의미합니다.)
Outgolfer Erik

문맥에서 분명해야했지만 16 진수를 즉시 참조 했음에도 불구하고 변경했습니다.
Jonathan Allan

계산은 하나만으로 끝납니다 : 최대 길이가 5 인 대체품으로 321402081 조합과 최대 길이가 6 인
7177979809

@AndersKaseorg oops, 그래서 그것은 최대 길이 6이 가능합니다 ... 22 바이트를 가지고 놀 수 있습니다!
Jonathan Allan

4

셰익스피어 언어 프로그래밍 31 * (472 + 383 379 344) = 26,505 26,381 25,296

이전 점수 : 16909322 * (246 + 217) = 7829016086

이것은 여전히 ​​높지만 지금 생각할 수있는 가장 낮습니다.

인코더 :

,.Ajax,.Ford,.Act I:.Scene I:.[Enter Ajax and Ford]Ajax:Remember a pig.Ford:Listen tothy.Scene V:.Ajax:Remember the remainder of the quotient betweenI a big cat.Ford:You be the quotient betweenyou a big cat.Be you nicer zero?If solet usScene V.Remember a pig.Scene X:.Ajax:Recall.Ford:Am I worse zero?If notremember I.If notlet usScene X.Ajax:You zero.Scene L:.Ford:Recall.Ajax:You be the sum ofyou a cat.Am I nicer zero?If sospeak thy.Am I worse zero?If notlet usScene L.

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

디코더 :

,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:You cat.Ford:Open mind.Remember the sum ofyou I.Scene V:.Ajax:Am I nicer a cat?If soyou be twice you.Ford:If soyou be the sum ofyou a pig.If solet usScene V.[Exit Ford][Enter Page]Page:Recall.Ajax:Am I worse a cat?If notyou be the sum ofyou Ford.If notlet usAct I.Open heart

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

기본적으로 문자열에 ASCII 코드 (n + 1)의 문자가 포함되어 있으면 n 번째 이진수가 설정됩니다.


디코더를위한 344 바이트
Jo King

3

Python 3, (208 바이트 + 200 바이트) * 6 길이 = 2448

온라인으로 사용해보십시오! (둘 다 포함되며 여분의 바이트는 그들 사이의 줄 바꿈입니다).

빈 목록을 사용하여 -4 바이트 (-24 점) (0에서 더 많은 항목을 시작할 수 있음)

인코더 (208 바이트)

def E(n,h=128):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    d=l=0
    s=[]
    while n>=T(h,d):
        n-=T(h,d)
        d+=1
    for i in range(d):
        while n>=T(h-l,d+~i):
            n-=T(h-l,d+~i)
            l+=1
        s+=[l]
    return s

디코더 (200 바이트)

def D(s):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    s.sort()
    l=0
    d=len(s)
    n=sum(T(128,D)for D in range(d))
    for i in s:
        for j in range(l,i):
            n+=T(128-j,d-1)
        l=i
        d-=1
    return n

관찰 :

  • 엄격하게 증가하지 않는 (즉, 정렬 된) 목록의 경우 셔플 링을 손실없이 되돌릴 수 있습니다.

  • 같은 길이의 엄청나게 증가하지 않는 숫자 목록은 (파이썬에서와 같이) 완전히 주문할 수 있습니다 .

  • 모든 정렬 된 목록의 전체 순서를 형성하기 위해 목록을 길이별로 순서대로 정의 할 수 있습니다.

  • 리스트에서 유일하게 유효한 값 0127포함 하는 정수로 정의하면 (즉, 길이가 한정된 유효한 수의 한정된 수의리스트가 존재 함) 정의하면 이러한리스트의 색인 가능한 순서를 구성 할 수 있습니다 L.

계략:

  • 인코더 : 숫자가 주어지면 유효하고 증가하지 않는 유효한 목록을 N찾으십시오 N.

  • 디코더 : (셔플 된) 유효한 목록이 있으면이를 정렬하고 유효한 목록 순서로 색인을 반환합니다.

일반적인 코드 설명 :

  • T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1

  • nth- simplex 수를 계산d

    • 의 경우 d=0항상1

    • 를 들어 d=1, n(길이 도트 라인의 도트 수 n)

    • d=2i=1nin

    • d=3j=1ni=1jin

인코더 설명 :

  • def E(n,h=128): d=l=0, s=[]

  • n입력 된 번호가, 인 h은 "고 부가가치"(+ 1 허용 가장 많은, 즉)되어 d출력 될 길이이며 s, 출력은 l은 "낮은 값"(0에서 시작하여 더 후술)

  • while n>=T(h,d):, n-=T(h,d),d+=1

  • 있다 T(h,d)유효한 길이 - d목록, 그리고 경우에 우리의 계산은 쉽게 n목록에 인덱스 기준으로합니다 [0]*d(인덱스가 0) 너무 감소, 대신 실제 인덱스를 n따라. 이것은 또한 d주어진 길이에 맞게 (길이)를 조정합니다 n.

  • for i in range(d):

  • 효과적으로 : " i+1목록에있는 숫자"

    • 여기서는 l"낮은 가치"를 설명 할 것입니다

    • 목록에 숫자를 입력 한 후에는 목록에 넣을 수있는 수보다 적은 숫자를 사용하여 정렬 된 상태로 유지하므로 l목록에 추가 된 마지막 숫자도 마찬가지 입니다.

    • while n>=T(h-l,d+~i):, n-=T(h-l,d+~i),i+=1

    • 이 "자리"에서 n인코딩하기에 너무 큰 경우 l, n이에 따라 조정 하고 증가l

    • s+=[l]

    • 인코딩 nl이 "자리"에서.

    • 처음에는 h다음에 "자리"를 입력 할 수있는 옵션이 있지만, "자리"(에 지정된 l) h-l를 입력하면 다음 "자리"에 대한 옵션 으로 제한됩니다 .

    • 처음에는 T(h,d)유효한 목록이 있었지만 "digit"를 추가하여 l남은 "digits" d-1수와 유효한 다음 "digits" h-l수를 줄였습니다.이 이후의 유효한 목록 수는T(h-l,d-1)

디코더 설명 :

  • def D(s):, s.sort(), l=0,d=len(s)

  • s(셔플 된) 입력리스트입니다 s.sort(); l"낮은 값"( h"높은 값"은 128바이트를 절약하기 위해 코드에서 리터럴 임)이며 n출력 번호이며 d길이입니다.

  • n=sum(T(128,D)for D in range(d))

  • n순서대로 포인트로 조정[0]*length

  • for i in s:

  • 각 자리수에 대해 :

    • for j in range(l,i):, n+=T(128-j,d-1)

    • n순서대로 포인트로 조정[...prevdigits, thisdigit, 0...]

      • l=i: "낮은 값"을 가장 최근 숫자로 설정

      • d-=1: 숫자를 사용했기 때문에 길이를 줄입니다.

  • return n: n모든 숫자에 대해 조정 된 후 올바른 숫자입니다. 반환.

이것이 명확하지 않은 경우 죄송하지만 여기에 원래의 골프화 되지 않은 디버그 버전이 있습니다. 온라인으로 사용해보십시오! 빈 목록을 사용하지 않으므로이 버전에 사용 된 모든 숫자에서 1을



3

, 10 * (10 + 15) = 250

십진수를 사용합니다. 이전 기본 16 기반 솔루션은 328 296 264를 기록했습니다.

인쇄 할 수없는 문자를 출력 할 수 있습니다. 특히, 캐릭터 10은 숯에 입력하기 까다 롭습니다.

인코더, 10 바이트 :

⭆⮌S℅⁺Iι×χκ

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다.

디코더, 15 바이트 :

IΣES×﹪℅ιχXχ÷℅ιχ

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다.

정수 목록을 사용하는 버전은 360 296 점 (기본 16, 10 진수는 310)입니다.

인코더, 19 바이트 :

NθIE⁸⁺﹪÷θX¹⁶ι¹⁶×¹⁶ι

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다.

디코더, 18 바이트 :

IΣEE⁸N×﹪ι¹⁶X¹⁶÷ι¹⁶

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다.

버전 점수 360를 인쇄 가능한 문자를 사용하여 (이었다 416 384 368 기수 16)

인코더, 19 바이트 :

⭆⮌S℅⁺Iι×χ⁺κ×⁵⊕׳÷κ⁵

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다.

디코더, 17 바이트 :

Fθ⊞υ⌈Φθ¬№υκ⭆υ﹪℅ιχ

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다.


2

Brachylog , 17 + 18 바이트 * 8 길이 = 280

인코더 :

ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐ

디코더 :

ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐp

엔코더 끝에 p를 추가 할 수 있습니다. 디코더는 (셔플 된) 결과를 출력으로 넣고 입력에서 원래 숫자를 가져 와서 실행됩니다.

(적절하게 구현 된) 누적 합계 조건자가 있으면 점수가 20으로 떨어질 수 있습니다.

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


@ Delfad0r p를 인코더에 추가하면 인코딩 및 디코딩을위한 동일한 코드가됩니다.
Kroppeb

2

05AB1E , 점수 : (2 + 2 바이트 ) * 11 최대 길이 = 44

인코더 (2 바이트 ) :

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

디코더 (2 바이트 ) :

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

인코더의 입력 및 디코더의 출력은 자릿수 목록입니다.

@ ais523 포트 의 두 번째 젤리 답변 .

설명:

    # Undelta (automatically prepends a 0)
      #  i.e. [3,0,4,7,8,2,0,1,9] → [0,3,3,7,14,22,24,24,25,34]

{     # Sort
      #  i.e. [14,7,22,25,24,3,0,24,34,3] → [0,3,3,7,14,22,24,24,25,34]
 ¥    # Deltas
      #  i.e. [0,3,3,7,14,22,24,24,25,34] → [3,0,4,7,8,2,0,1,9]

2311


2

골> <> , 8 * (14 + 13) = 216

인코더 온라인으로 사용해보십시오! , 14 바이트 :

I8FfPSD8*L+o|;

디코더 온라인으로 사용해보십시오! , 13 바이트 :

iEh8SD4*2$X*+

이것은 인쇄 할 수없는 ASCII 문자를 출력 할 수 있으므로 디코더를 망칠 수 있으므로 출력 / 입력에 숫자를 사용하는 버전이 있습니다.

인코더 온라인으로 사용해보십시오! , 14 바이트 :

I8FfPSD8*L+N|;

디코더 온라인으로 사용해보십시오! , 13 바이트 :

IEh8SD4*2$X*+

부호화:

주어진 숫자를 8 x 4 비트 청크로 나누면 인코딩이 작동합니다. 이 청크는 3 비트 씩 오른쪽으로 이동하고 청크의 원래 위치는 끝에 0과 7 사이의 숫자로 추가됩니다. 따라서 인코딩은 다음과 같습니다.

0AAAABBB
 |__|    -> the original part of the number
     |_| -> the position of the chunk inside the original number 0 = LSB and 7 = MSB

2

펄 (6) , (10) * (10 + 12) = 340 220

인코더 :

{^@_ Z~@_}

디코더 :

{.sort X%10}

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

엔코더 기능은 각 숫자를 0의 인덱스로 압축합니다. 그런 다음 인코더는 숫자 목록을 정렬하고 모듈로를 10, 즉 숫자의 두 번째 숫자로 가져옵니다.

총 길이는 10이며, 최대 길이는 2 31 -1입니다.


1

하스켈 , 10 * (23 + 51) = 740

다음은 값을 인코딩, 셔플, 디코딩 및 유효성 검사하는 프로그램입니다. 온라인으로 사용해보십시오!

인코더, 23 바이트

zipWith((+).(10*))[0..]

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

디코더, 51 바이트

map snd.sortOn fst.map(`divMod`10)
import Data.List

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

설명

우리는 십진수로 사용하기 입력으로 허용하고 있기 때문에, 우리가 그것을 사용합니다 .. 인코더에 발생하는 각 숫자에 매핑 10*index + digit, 모든 참고 digit들에있을 것입니다 [0..9]우리가 사용 이상 되돌릴 수 있도록를 divMod. 인덱스와 숫자를 복원 한 후에는 인덱스를 정렬하고 제거하기 만하면됩니다.

이 솔루션은 최대 2 311 = 2147483647의 값으로 작동합니다.2311=214748364799=81<128



1

LE+LD=36;A=8288

d←{16n-16×⍳≢n←⍵[⍋⍵]}
e←(⊢+16×⍳∘≢)16⊥⍣¯1

온라인으로 사용해보십시오! (할당 및 줄 바꾸기에 5 개의 추가 바이트가 포함되어 있습니다).

용도 ⎕IO←0

방법:

(⊢+16×⍳∘≢)16⊥⍣¯1  Encoder; input 1234
          16⊥⍣¯1  Convert input to base 16  4 13 2
      ⍳∘≢           [0..length of the list-1]  0 1 2
   16×              times 16  0 16 32
 ⊢+                 plus the original list  4 29 34

{16n-16×⍳≢n←⍵[⍋⍵]}  Decoder; input   34 4 29
              [⍋⍵]   Grade  up  2 0 1
                    Index  with that list  4 29 34
           n        assign that to n
      16×⍳≢          16×[0..length(n)-1]  0 16 32
    n-               subtract that from n  4 13 2
 16                 Decode from base 16  1234

1

PHP, 8 * (44 + 53) = 776

인코더, 44 바이트 :

for(;$n=&$argn;$n>>=4)echo$n&15|16*$i++," ";

공백으로 구분 된 정수 목록을 인쇄합니다. 로 파이프로 실행하십시오 -nR.

4 데이터 비트 (더 낮은 니블) 및 3 웨이트 비트 (상한 니블)의 최대 8 바이트

간단히 말해서 :
각 16 진수를 자신의 문자에 넣고 바이트의 상반부를 사용하여 숫자의 위치를 ​​저장하십시오.

예:

1457893891( 0x56e5b203)로 바뀝니다
0x03, 0x10, 0x22, 0x3b, 0x45, 0x5e, 0x66, 0x75
3 16 34 59 69 94 102 117

디코더, 53 바이트 :

while($i++<8)$n+=(15&$x=$argv[$i])<<($x>>4)*4;echo$n;

또는

while($i++<8)$n+=(15&$x=$argv[$i])<<($x/4&~3);echo$n;

또는

for(;$i<9;$x=$argv[++$i])$n+=$x%16<<($x/4&~3);echo$n;

명령 행 인수에서 정수를 가져옵니다. 로 실행하십시오 -nr.


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


0

파이썬 2 , 10 * (68 + 54) = 1220

e=lambda n:"".join(chr(int(`i`+j))for i,j in enumerate(`n`)if j<'L')
d=lambda s:int("".join(`ord(c)%10`for c in sorted(s)))

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

편집 : 포인터에 대한 조 킹 덕분에-왜 내가 32로 상쇄했는지 잘 모르겠습니다.

NUL 바이트 0x0 [space] (위치 0, 값 0)로 시작하여 각 장소의 위치와 값을 단일 문자로 인코딩합니다 .

다음과 같이 디코딩합니다 :

  • 문자열 정렬 (Python은 서수 값으로 문자를 정렬합니다)
  • 각 문자를 서수 값으로 변환
  • 각 서수의 마지막 숫자를 취합니다.
  • 정수를 문자열로 결합
  • 결합 된 문자열을 다시 int로 변환

32오프셋 이 필요 합니까? 또한, 대신 올바른 장소에 [-1]있을 수 있습니다%10
Jo King

0

C (gcc) , 10 * 112 = 1120

c,i;e(i,s)char*s;{for(c=1;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=--c%10*pow(10,c/10));s=i;}

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

전역 변수가 있지만 실제로 두 함수 사이에 정보를 전달하지는 않습니다. 변수 선언 c은 두 코드에서 2 바이트를 절약하는 두 함수에서 모두 사용됩니다.

3 5 바이트 페널티에 대해서만 인쇄 가능한 ASCII를 사용하는 버전 은 다음과 같습니다.

c,i;e(i,s)char*s;{for(c=32;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=(c-=32)%10*pow(10,c/10));s=i;}

70 포인트 개선을 위해 @ceilingcat에게 감사드립니다.

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