문자열을 디코딩


41

이것은 ppcg에 대한 첫 번째 도전입니다!

입력

두 개의 다른 ASCII 문자로 구성된 문자열입니다. 예를 들어

ABAABBAAAAAABBAAABAABBAABA

도전

작업은 다음 규칙에 따라이 문자열을 디코딩하는 것입니다.

  1. 처음 두 문자 건너 뛰기
  2. 나머지 문자열을 8 문자 그룹으로 나눕니다.
  3. 각 그룹에서, 각 문자를 대체 0하는 캐릭터가 원래 문자열의 첫 번째 문자와 같은 경우, 및와 1달리
  4. 이제 각 그룹은 바이트를 나타냅니다. 각 그룹을 바이트 문자 코드에서 문자로 변환
  5. 모든 문자를 연결

위의 문자열을 해독합시다.

 AB  AABBAAAA  AABBAAAB  AABBAABA
 ^^     ^         ^         ^
 |      |         |         |
 |      \---------|---------/
 |                |
Skip      Convert to binary

공지 사항 A원래 문자열의 첫 번째 문자이고, B두 번째입니다. 따라서, 각각의 교체 A0각을 B함께 1. 이제 우리는 다음을 얻습니다.

00110000  00110001  00110010

이는 [0x30, 0x31, 0x32]진수. 이 값은 ["0", "1", "2"]각각 문자를 나타내므로 최종 출력은이어야합니다 012.

채점

이것은 물론 이므로 코드를 최대한 짧게 만듭니다. 점수는 바이트 단위로 측정됩니다.

제약 및 IO 형식

표준 규칙이 적용됩니다. 몇 가지 추가 규칙은 다음과 같습니다.

  • 유효한 입력을 가정 할 수 있습니다
    • 입력 문자열은 정확히 두 개의 다른 문자로 구성됩니다
    • 처음 두 문자가 다릅니다
    • 입력 문자열의 최소 길이는 2 자입니다.
    • 길이는 항상 2 모듈로 8을 제공합니다
  • 문자열이 항상 인쇄 가능한 ASCII 문자로만 구성되어 있다고 가정 할 수 있습니다
    • 입력과 디코딩 된 문자열 모두
  • 출력에서 선행 및 후행 공백이 허용됩니다 (일치하는 모든 것 /\s*/)

5
사람이 첫 번째 도전에 대해 이것은 내가 본 것 중 더 나은 형식의 도전 중 하나라고 말합니다. 참고로, 커뮤니티 샌드 박스 는 게시하기 전에 피드백을 제공하기에 좋은 곳이므로 알지 못하는 규칙에 대해 무작위로 폭탄을 입히지 않습니다.
Magic Octopus Urn

@MagicOctopusUrn. 감사합니다! 샌드 박스에 대해 몰랐습니다. 다음에 게시하겠습니다 :)

2
나는 사람들이 메타를 외우지 않고 듀피에 대해 알기 어려운 규칙을 따르는 매우 간단한 중복 질문에 대해 나를 불러 낼 수 있도록 주로 사용합니다. :). 또한 대화방을 확인하는 것이 좋습니다. 배우고 자하는 거의 모든 언어에 대한 대화가 있으며 질문이 권장됩니다.
Magic Octopus Urn

1
위대한 첫 도전! 더 많은 테스트 사례가 깔끔 할 것입니다.
Lynn

정말 좋은 첫 번째 도전. 이것으로 재미있게 놀았습니다.
ElPedro

답변:



8

Stax , 15 11 바이트

ó║¥U⌂½íèäöñ

staxlang.xyz에서 실행하고 디버그하십시오!

빠른 'n'더티 접근법. 그것을 개선하기 위해 노력하고 있습니다. 그것을 향상시켰다!

압축 해제 (13 바이트) 및 설명

2:/8/{{[Im:bm
2:/              Split at index 2. Push head, then tail.
   8/            Split into length-8 segments.
     {      m    Map block over each segment:
      {  m         Map block over each character:
       [             Copy first two elements (below) in-place.
        I            Index of character in first two characters.
          :b       Convert from binary.
                 Implicit print as string.

아아 ..이게 우리를 이길 줄 알았어
Magic Octopus Urn

6

자바 스크립트 (Node.js) , 67 바이트

s=>s.replace(/./g,x=(c,i)=>(x=x*2|c==s[1],Buffer(i<3|i&7^1?0:[x])))

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

어떻게?

Buffer생성자의 구문은 두 가지가 있습니다 .

  • Buffer([n])단일 바이트 n을 포함하는 버퍼를 생성 하고 해당 ASCII 문자로 강제 변환됩니다. n 의 8 개의 최하위 비트 만 고려됩니다.
  • Buffer(n)n 바이트 의 버퍼를 생성 합니다. 따라서 Buffer(0)빈 버퍼를 생성하여 빈 문자열로 강제 변환합니다.

참고 : 둘 다 최신 노드 버전에서 더 이상 사용되지 않습니다. Buffer.from([n])그리고 Buffer.alloc(n)대신 사용해야합니다.

댓글

s =>                   // given the input string s
  s.replace(/./g, x =  // initialize x to a non-numeric value (will be coerced to 0)
    (c, i) => (        // for each character c at position i in s:
      x = x * 2 |      //   shift x to the left
          c == s[1],   //   and append the new bit, based on the comparison of c with s[1]
      Buffer(          //   invoke the constructor of Buffer (see above):
        i < 3 |        //     if i is less than 3
        i & 7 ^ 1 ?    //     or i is not congruent to 1 modulo 8:
          0            //       replace c with an empty string
        :              //     else:
          [x]          //       replace c with the ASCII char. whose code is the LSB of x
      )                //   end of Buffer constructor
  ))                   // end of replace(); return the new string

6

bash, 59 58 52 바이트

tr -t "$1" 01 <<<$1|cut -c3-|fold -8|sed 'i2i
aP'|dc

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

6 바이트를 절약 한 Cows quack 에게 감사드립니다 .

이 과제는 일련의 coreutils (그리고 dc마지막에 변환 및 출력) 와 함께 잘 작동합니다 . 먼저 우리는

tr -t "$1" 01 <<<$1

입력의 두 문자를 0과 1로 음역합니다. -t이의 입력에 처음 두 문자를 음역을 줄일 수 있도록 플래그, 두 번째의 길이 첫 번째 인수를 절단 0하고 1우리가 원하는이다. 그때,

cut -c3-

처음 두 문자를 제거하고

fold -8

한 줄에 8 개의 문자를 출력합니다. 마지막으로,이 sed명령은 각 줄을 dc숫자로 이진수로 읽고 그 바이트를 출력 하는 스 니펫 으로 바꿉니다 .


항상 bash는 대답을 볼 좋은 :) 당신은 직류 코드에 각 라인을 변환하여 직류 계산을 단순화하기 위해 sed를 사용하여 다음 인쇄 밖으로 각 문자 및 DC에서 그것을 eval'ing 그 tio.run/##S0oszvj/... (그리고 후 공간을 cut -c제거 할 수 있습니다)
Kritixi Lithos

6

Amstrad CPC의 Z80 기계 코드, 32 31 30 바이트

000001  0000  (9000)        ORG &9000
000002  9000  EB            EX DE, HL
000003  9001  46            LD B, (HL)
000004  9002  23            INC HL
000005  9003  5E            LD E, (HL)
000006  9004  23            INC HL
000007  9005  56            LD D, (HL)
000009  9006  1A            LD A, (DE)
000010  9007  05            DEC B
000011  9008  13            INC DE
000012  9009  4F            LD C, A
000014  900A                Light
000015  900A  26 01         LD H, &01
000016  900C                Last
000017  900C  13            INC DE
000018  900D  05            DEC B
000019  900E  C8            RET Z
000021  900F                Loop
000022  900F  1A            LD A, (DE)
000023  9010  B9            CP C
000024  9011  28 01         JR Z, Lable
000025  9013  37            SCF
000026  9014                Lable
000027  9014  ED 6A         ADC HL, HL
000028  9016  30 F4         JR NC, Last
000029  9018  7D            LD A, L
000030  9019  CD 5A BB      CALL &BB5A
000032  901C  18 EC         JR Light

코드 명령어가 얻어 각 문자를 대체 0하는 캐릭터가 원래 문자열의 첫 번째 문자와 같은 경우, 및와 1달리 문자와 적 캐릭터가 입력 문자열의 두 번째 문자가 일치하는지 확인 귀찮게하지 않는다. 첫 문자와 동일하고 첫 문자와 다른지 확인합니다.

나는 레지스터합니다 (Z80 만, 나머지 필요 이상 지침을 칠 쉽게 사용할 수있는 8 비트 레지스터를 가지고) 내가 넣어 있도록 부족 &01H사용과 함께, LASCII 문자를 구축 (나는 그냥 초기화 할 필요의 실현 L, 한 바이트를 저장 ). HCarry 플래그로 오버플로 되면 문자 in L을 출력 할 수 있습니다. 다행히 왼쪽 시프트 명령을 수행 하는 16 비트 ADC( C arry가있는 Ad d )가 있습니다.

(DE)단으로 판독 될 수 A있지만, (HL)어떤 8 비트 레지스터에 판독 할 수 있으므로 하나의 사용 타협이었다. 나는 비교할 수 (DE)C내가으로 한로드했다, 그래서 바로 A첫 번째. 레이블은 L(어셈블러의 요구 사항)으로 시작하는 임의의 단어입니다 .

  • A 누산기-비교를 수행 할 수있는 유일한 레지스터
  • B카운터 레지스터 명령에 대한 DJNZ: D의 ecrement ( B)와 J의 UMP 경우 NZ의 ERO . 코드를 재정렬하여 DJNZ바이트 수를 줄인 작업을 수행 할 수있었습니다.
  • C 입력 문자열의 첫 문자
  • D, E같은 DE현재의 입력 문자의 어드레스
  • H 캐리 트리거 (8 번째 루프마다)
  • L 출력되는 캐릭터

여기에 이미지 설명을 입력하십시오


6

05AB1E , 10 바이트

¦¦Sk8ôJCçJ

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

emigna 덕분에 -3입니다.


Ù             # Unique letters, in order they appear.
 v            # For each...
  yN:         # Push letter and index, replace in input.
     }        # End loop.
      ¦¦      # Remove first x2.
        8ô    # Split into eighths.
          C   # Convert to integer.
           ç  # Convert to char.
            J # Join together entire result.

1
01‡루프 대신 사용할 수 있습니다 . 편집 : 또는 더 나은 :¦¦Sk8ôJCçJ
Emigna


5

J, 17 13 바이트

u:_8#.\2}.1{=

FrownyFrog 덕분에 -4

구 버전:

u:_8#.\2&({.i.}.)

설명:

u:_8#.\2}.1{=
            =  | Self classify, for each unique element x of y, compute x = y, element-wise
          1{   | Second row
       2}.     | Drop 2
  _8#.\        | Convert non-intersecting subarrays of length 8 from binary
u:             | Convert to characters

예 :

   = 'ABAABBAAAAAABBAAABAABBAABA'
1 0 1 1 0 0 1 1 1 1 1 1 0 0 1 1 1 0 1 1 0 0 1 1 0 1
0 1 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0

   2}.1{= 'ABAABBAAAAAABBAAABAABBAABA'
0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0

   _8#.\2}.1{= 'ABAABBAAAAAABBAAABAABBAABA'
48 49 50

   u:_8#.\2}.1{= 'ABAABBAAAAAABBAAABAABBAABA'
012

1
2}.1{=4 바이트를 절약 할 수 있습니다.
FrownyFrog

오, 묶여 ... 다른 바이트를 찾을 수 없습니다.
Magic Octopus Urn

1
@MagicOctopusUrn 실제로 스 니펫입니다 [:. 시작시 :)
FrownyFrog


5

R , 71 바이트

function(s)intToUtf8(2^(7:0)%*%matrix((y=utf8ToInt(s))[-1:-2]==y[2],8))

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

놀랍게도 골프!

먼저을 사용하여 문자열을 ASCII 코드 포인트로 변환하여로 utf8ToInt저장합니다 y. 음수 인덱싱으로 처음 두 문자를 제거하면을 사용하는 것보다 짧습니다 tail.

배열 y[-1:-2]==y[2]%*%(행렬 곱셈)이 적용될 때 비트와 동일 하지만 먼저 배열을 matrixwith 로 재구성 nrow=8하고 선형 배열에서 바이트 그룹으로 변환합니다. 우연히, 우리는 2의 적절한 거듭 제곱을 가진 행렬 곱셈을 사용하여 ASCII 코드 포인트 2^(7:0)로 변환 한 다음 코드 포인트를로 문자열로 다시 변환 할 수 있습니다 intToUtf8.



4

PHP, 73 71 바이트

while($s=substr($argn,-6+$i+=8,8))echo~chr(bindec(strtr($s,$argn,10)));

파이프로 실행 -nR하거나 온라인으로 사용해보십시오 .

골프 :

  • -6의해 색인 시작 및 사전 증가8
  • strtr더 긴 매개 변수에서 과도한 문자 를 무시하는 악용 ( substr필요 없음 )
  • 번역 10하고 뒤집을 때 따옴표가 필요하지 않습니다-> -1 바이트
  • ASCII 코드 대신 문자 반전-> ~단어 경계-> -1 바이트로 사용됩니다.

3
최소한 brainfuck와 일치해야합니다.for(;$s=substr($argn,2+8*$i++,8);)echo~chr(bindec(strtr($s,$argn,10)));
Christoph

2
@Christoph 나는 Brainfuck이 갑작스런 대답 길이의 표준 인 방법을 좋아합니다.
Nit

4

Pyth, 20 9 바이트

CittxLQQ2

FryAmTheEggman 덕분에 11 바이트를 절약했습니다.

여기 사용해보십시오

설명

CittxLQQ2
    xLQQ    Find the index of each character in the string.
  tt        Exclude the first 2.
 i      2   Convert from binary.
C           Get the characters.

@FryAmTheEggman 감사합니다. 분명히 나는 ​​여전히 Pyth에 대해 배울 것이 많다.
니모닉

하하, 나도! 매우 복잡한 골프 언어입니다. 나는 당신이 그것에 계속 골프를 바랍니다 :)
FryAmTheEggman

3

루비 , 82 79 바이트

->s{s[2..-1].tr(s[0,2],'01').chars.each_slice(8).map{|s|s.join.to_i(2).chr}*''}

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


1
PPCG에 오신 것을 환영합니다! 난 내가 내 게시하기 전에 이미 루비의 대답이 있었다는 것을 보지 못했지만, 몇 가지 일반적인 골프 트릭은 당신의 접근 방식도 적용 - 예를 들어, 마지막은 .join교체 할 수 있습니다 *'', 그리고 s[0..1]에 의해 s[0,2].
Kirill L.

3

apt, 11 바이트

¤£bXÃò8 ®Íd

시도 해봐


설명

¤               :Slice from the 3rd character
 £  Ã           :Map over each X
  bX            :  Get the first 0-based index of X in the input
     ò8         :Split to an array of strings of length 8
        ®       :Map
         Í      :  Convert from base-2 string to base-10 integer
          d     :  Get the character at that codepoint

s2지름길을 매우 영리하게 사용합니다 .
Nit

3

PHP + GNU 다중 정밀도, 63 61

<?=gmp_export(gmp_init(substr(strtr($argn,$argn,"01"),2),2));

슬프게도 GMP 확장은 기본적으로 활성화되어 있지 않습니다 (그러나 배송 됨).

다음과 같이 실행하십시오.

echo "ABABABAAAAABABAAAAAABAABBAABAAAABBABAAABBB" | php -F a.php

<?=2 바이트 및 가능하면 하루를 저장합니다. ;-)
Titus

@Titus 예, 그러나 슬프게도 작동하지 않습니다 -R(내가 시도했습니다).
Christoph

1
-F대신 보십시오
Titus


3

자바 (8) 143 142 141 바이트

s->{char i=47;for(;++i<50;)s=s.replace(s.charAt(i%2),i);for(i=2;i<s.length();)System.out.print((char)Long.parseLong(s.substring(i,i+=8),2));}

@ OlivierGrégoire 덕분에 -1 바이트 .

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

설명:

s->{                            // Method with String parameter and no return-type
  char i=47;                    //  Index character, starting at 47
  for(;++i<50;)                 //  Loop 2 times
    s.replace(s.charAt(i%2),i)  //   Replace first characters to 0, second characters to 1
  for(i=2;i<s.length();)        //  Loop `i` from 2 upwards over the String-length
    System.out.print(           //   Print:
     (char)                     //    As character:
      Long.parseLong(           //     Convert Binary-String to number
       s.substring(i,i+=8)      //      The substring in range [i,i+8),
      ,2));}



2

APL + WIN, 30 바이트

인덱스 원점 0. 문자열 입력 프롬프트

⎕av[2⊥¨(+\0=8|⍳⍴b)⊂b←2↓s≠↑s←⎕]

설명:

s≠↑s←⎕ prompts for string and creates binary vector not equal to first character

b←2↓s drops first two elements of binary

(+\0=8|⍳⍴b)⊂ splits binary into groups of 8

2⊥¨ converts each group to decimal

⎕av[...] displays decoded characters

Quad-AV가 APL + WIN의 ASCII와 일치한다고 가정합니까?
Zacharý

@ Zacharý 예 첫 128 자입니다. 특수 APL 문자는 확장 ASCII 문자 세트의 일부 문자를 대체합니다.
Graham

2

빨강 , 110 바이트

func[s][t: 0 i: 128 foreach c next next s[if c = s/2[t: t + i]i: i / 2 if i = 0[prin to-char t t: 0 i: 128]]] 

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

설명:

내장 된 간단한 간단한 솔루션입니다.

f: func [s] [                      ; s is the argument (string)
    t: 0                           ; total - initially 0
    i: 128                         ; powers of 2, initially 0
    b: s/2                         ; b is the second charachter
    foreach c next next s [        ; for each char in the input string after the 2nd one
        if c = b [t: t + i]        ; if it's equal to b than add the power of 2 to t
        i: i / 2                   ; previous power of 2
        if i = 0 [                 ; if it's 0 
            prin to-char t         ; convert t to character and print it
            t: 0                   ; set t to 0
            i: 128                 ; i to 128
        ]
    ]
] 

2

Google 스프레드 시트, 123 바이트

=ArrayFormula(Join("",IfError(Char(Bin2Dec(Substitute(Substitute(Mid(A1,3+8*(Row(A:A)-1),8),Left(A1),0),Mid(A1,2,1),1))),""

입력이 셀에 A1있습니다. Google은 )))수식 끝에 자동으로 추가 됩니다.

설명:

  • Mid(A1,3+8*(Row(A:A)-1),8) 세 번째부터 시작하여 한 번에 8 개의 문자 청크를 잡습니다.
  • Substitute(Mid(~),Left(A1),0) 첫 번째 문자의 각 인스턴스를 0으로 바꿉니다.
  • Substitute(Substitute(~),Mid(A1,2,1),1) 두 번째 문자를 1로 바꿉니다.
  • Char(Bin2Dec(Substitute(~))) 청크를 10 진수로 변환 한 다음 ASCII로 변환합니다.
  • IfError(Char(~,""))우리보다 훨씬 더 많은 값 을 Row(A:A)반환 한다는 사실에서 발생하는 모든 오류를 수정 하므로 많은 0 값과 0에서 오류가 발생합니다.Bin2DecChar
  • ArrayFormula(Join("",IfError(~)))모두 함께 조인 Char결과와 ArrayFormula만드는 것입니다 Row(A:A)반환 대신 첫 번째 값의 값의 배열을.




2

파이썬 2 , 88 바이트

i=input()
f=''.join('10'[x==i[0]]for x in i[2:])
while f:print chr(int(f[:8],2));f=f[8:]

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

가장 짧은 방법이 아닌 다른 방법입니다.

다음 버전에서는 후행 공백이 허용된다는 규칙이 있지만 다음 버전에서는 출력을 한 줄에 98 바이트 동안 인쇄합니다.

i=input();f=''.join('10'[x==i[0]]for x in i[2:]);o=""
while f:o+=chr(int(f[:8],2));f=f[8:]
print o

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


최종 출력은 세 줄이 아닌 한 줄에 있어야합니다.
idrougge

OP에서 : "리딩 및 후행 공백은 출력에 허용됩니다 (/ \ s * /와 일치하는 모든 것). 줄 바꿈이 일치 /\s*/합니다.
ElPedro

1
죄송합니다. 정규 표기법에 정통하지 않습니다. : /
idrougge

나도 아니지만 나는 그것을 확신하기 위해 그것을
구글로 만들었다




1

하스켈 , 124 (105) 93 바이트

f(x:_:y)=fromEnum.(/=x)<$>y
g[]=[]
g s=(toEnum.sum.zipWith((*).(2^))[7,6..0])s:g(drop 8s)
g.f

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

f각 문자를 첫 번째 문자와 비교하여 Bools를 0과 1로 바꾸어 문자열을 비트 목록으로 변환합니다 fromEnum. g그룹 8 진수로 변환리스트로 분할하고, AS를 생성 수의 값을 얻어 Enum, Char인스턴스이다.

변경 사항 :

  • @Laikoni 덕분에 -19 바이트 (가져 오기 제거, map기능에 포함)
  • @Lynn의 답변에서 영감을 얻은 -12 바이트 ( take더 짧은 목록으로 압축하여 제거 )

2
가져 오기 toEnum대신 사용할 수 있습니다 chr. 또한에 map포함될 수 있습니다 g. 사이의 공간을 8 s제거 할 수 있습니다.
Laikoni

1

넷째 (gforth) , 83 바이트

: f over c@ 0 rot 2 do 2* over i 4 pick + c@ <> - i 8 mod 1 = if emit 0 then loop ;

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

입력은 표준 Forth 문자열 (주소 및 길이) 출력이 표준 출력으로 인쇄됩니다

설명

over c@          \ get the value of the first character in the string
0 rot            \ add a starting "byte" value of 0 and put the length on top of the stack
2 do             \ start a loop from 2 to length-1
   2*            \ multiply the current byte value by 2 (shift "bits" left one)
   over          \ copy the reference char to the top of the stack
   i 4 pick +    \ add the index and the starting address to get address of the current char
   c@ <>         \ get the char at the address and check if not equal to the reference char
   -             \ subtract the value from our bit count, -1 is default "true" value in forth
   i 8 mod 1 =   \ check if we are at the last bit in a byte
   if            \ if we are
      emit 0     \ print the character and start our new byte at 0
   then          \ and end the if statement
loop             \ end the loop
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.