文字列をデコードする


41

これは、ppcgに対する私の最初の挑戦です!

入力

2つの異なるASCII文字で構成される文字列。例えば

ABAABBAAAAAABBAAABAABBAABA

チャレンジ

タスクは、これらの規則に従ってこの文字列をデコードすることです。

  1. 最初の2文字をスキップします
  2. 残りの文字列を8文字のグループに分割します
  3. 各グループで、各文字を0元の文字列の最初の文字と同じ場合は各文字に置き換え、そうでない場合は各文字を置き換え1ます
  4. 各グループは1バイトを表します。各グループをバイト文字コードから文字に変換します
  5. すべての文字を連結する

上記の文字列をデコードしましょう。

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

これAが元の文字列の最初の文字でBあり、2番目の文字であることに注意してください。そのため、それぞれ置き換えるA0、それぞれをBして1。今、私たちは取得します:

00110000  00110001  00110010

これは[0x30, 0x31, 0x32]バイナリです。これらの値は["0", "1", "2"]それぞれ文字を表すため、最終的な出力はである必要があります012

得点

これはもちろんであり、コードをできるだけ短くすることを意味します。スコアはバイト単位で測定されます。

制約とIOフォーマット

標準ルールが適用されます。追加のルールは次のとおりです。

  • 有効な入力を想定できます
    • 入力文字列は正確に2つの異なる文字で構成されます
    • 最初の2文字は異なります
    • 入力文字列の最小長は2文字です
    • 長さは常に2モジュロ8になります
  • 文字列は常に印刷可能なASCII文字のみで構成されると仮定できます。
    • 入力とデコードされた文字列の両方で
  • 出力では、先頭と末尾の空白が許可されます(一致するものすべて/\s*/

5
おっと、男、最初の挑戦のために、これは私が今まで見たより良いフォーマットされた挑戦の一つです。FYIとして、地域社会のサンドボックスは、投稿する前に、フィードバックのための絶好の場所であるあなたがランダムに取得しないように、担当者は、あなたが知らなかったルールの爆撃しました。
魔法のタコ

しょーた ありがとうございました!サンドボックスについて知らなかった、私は次回そこに投稿します:)

2
私は主にそれを使用して、人々が重複する質問で私を呼び出すことができます。ルールに従うのは非常に簡単で、メタを記憶せずにデュープについて知るのはかなり難しいです:)。また、チャットルームをチェックすることをお勧めします。学習したいほぼすべての言語のチャットがあり、質問をお勧めします。
魔法のタコ

1
素晴らしい最初の挑戦!さらにいくつかのテストケースが適切です。
リン

本当にいい最初の挑戦。これで遊んで楽しかった。
エルペドロ

回答:


13

brainfuck76 71 65バイト

ニトロドンのおかげで-6バイト!

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

オンラインでお試しください!

Pythonを打つ奇妙な感じ...


1
BFの8つのキーワードがPythonの対応するキーワードと同じ長さだった場合ではありません。
user202729

BFが自動的にユニコードを変換するのに役立ちます。
LastStar007


8

スタックス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.

ああ...これは私たちを打ち負かすことを知っていた。
魔法のタコ

6

JavaScript(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コンストラクターの2つの異なる構文を使用します。

  • Buffer([n])唯一のバイトnを含むバッファを生成し、対応するASCII文字に強制します。nの 8つの最下位ビットのみが考慮されます。
  • Buffer(n)nバイトのバッファーを生成します。したがって、Buffer(0)空の文字列に強制される空のバッファを生成します。

注:これらは両方とも、最近のNodeバージョンでは非推奨です。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のおかげです。

この課題は、一連のcoreutilsで非常にうまく機能しdcます(そして最後に変換と出力を行います)。まず、使用します

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

入力の2文字をゼロと1に音訳します。-tフラグは、第二の長さの最初の引数を切り捨て、これはに入力して最初の2つの文字を翻字に縮小0して1、私たちが望むものです。次に、

cut -c3-

最初の2文字を削除し、

fold -8

1行に8文字を出力します。最後に、sedコマンドは各行をdcスニペットに変換し、数値をバイナリとして読み取り、そのバイトを出力します。


bashの答えを見て、必ず素敵な:)あなたが使用することができますから、各文字を印刷したDCコードに各行を変換して直流でそれをeval'ingことにより、直流の計算を簡素化するためにsedをtio.run/##S0oszvj/...(とスペースをcut -c削除できます)
Kritixi Lithos

6

アムストラッド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そうでない場合は文字通り、文字が入力文字列の2番目の文字と一致することを確認しません。最初と同じ文字と最初とは異なる文字をチェックするだけです。

私は、レジスタ(Z80のみ、残りの必要性長い指示を7簡単に使用可能な8ビットのレジスタを持っている)私は入れてを使い果たし&01におけるH使用に伴い、LASCII文字を構築するために(私はちょうどそれが初期化する必要があります実現しL、1つのバイトを保存します)。ときはHキャリーフラグにオーバーフロー、の文字がL出力する準備ができています。幸いなことに、左シフト命令の仕事をする16ビットADCAd dとC arry)があります。

(DE)読み取ることA(HL)できるのは8ビットのレジスタだけですが、どちらを使用するかは妥協でした。直接比較することができなかったため(DE)、最初Cにロードする必要がありましたA。ラベルはL(アセンブラの要件)で始まるランダムな単語です。

  • A アキュムレータ-比較を実行できる唯一のレジスタ
  • Bカウンタレジスタ命令のためDJNZDの ecrement( B)及びJの UMPもしNZの ERO。コードを再配置することでDJNZ、1バイト少ないジョブを実行できました
  • C 入力文字列の最初の文字
  • D、現在の入力文字のアドレスEとしてDE
  • H キャリートリガー(8番目のループごと)
  • L 構築される出力文字

ここに画像の説明を入力してください


6

05AB1E、10バイト

¦¦Sk8ôJCçJ

オンラインでお試しください!

-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
エミグナ


5

J、17 13バイト

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

-4 FrownyFrogに感謝

旧版:

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

なんてこった...もうバイトが見つからない。
魔法のタコ

1
@MagicOctopusUrnそれは実際にはスニペットです、[:開始時にあるはずです:)
FrownyFrog


5

R、71バイト

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

オンラインでお試しください!

驚くほどゴルフです!

まず、文字列をでASCIIコードポイントに変換し、utf8ToIntとして保存しますy。負のインデックス付けで最初の2文字を削除するのは、を使用するよりも短くなり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、オンラインで試してください

ゴルフ

  • インデックスを開始し-68
  • strtr長いパラメーターの余分な文字を無視するエクスプロイト(substr不要)
  • 変換し10てから反転するには、引用符は不要-> -1バイト
  • ASCIIコードの代わりに文字を反転します-> ~ワード境界として機能します-> -1バイト。

3
少なくともBrainfuckと一致する必要があります。– for(;$s=substr($argn,2+8*$i++,8);)echo~chr(bindec(strtr($s,$argn,10)));
クリストフ

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へようこそ!私は私が鉱山を投稿する前に答えがRubyですでにあったことを見ていなかったが、いくつかの典型的なゴルフのトリックはあまりにもあなたのアプローチに適用されます-例えば、最後に.join置き換えることができ*''、かつs[0..1]によってs[0,2]
キリルL.

3

Japt、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バイト、場合によっては1日を節約します。;-)
タイタス

@タイタスええが、残念ながらそれは動作しません-R(私は試しました)。
クリストフ

1
-F代わりに試す
タイタス


3

Java 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ýはい、最初の128文字に対して。特殊なAPL文字は、拡張ASCII文字セットの一部の文字を置き換えます。
グラハム

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))),""

入力はcell A1です。Googleは自動的に)))式の最後に追加します。

説明:

  • Mid(A1,3+8*(Row(A:A)-1),8) 3番目から始めて、一度に8文字のチャンクを取得します。
  • Substitute(Mid(~),Left(A1),0) 最初の文字の各インスタンスを0に置き換えます。
  • Substitute(Substitute(~),Mid(A1,2,1),1) 2番目の文字を1に置き換えます。
  • Char(Bin2Dec(Substitute(~))) チャンクを10進数に変換してから、ASCIIに変換します。
  • IfError(Char(~,""))私たちよりもはるかに多くの値をRow(A:A)返すという事実に起因するすべてのエラーを修正します。そのため、多くのゼロ値とゼロでのエラーが発生します。Bin2DecChar
  • ArrayFormula(Join("",IfError(~)))すべて一緒に参加しCharた結果をしてArrayFormula作るものですRow(A:A)、戻り値の配列だけではなく最初の値。




2

Python 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バイトの出力が1行で出力されますが、ルールでは末尾の空白が許可されています。

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

オンラインでお試しください!


最終出力は、3行ではなく1行にする必要があります。
idrougge

OPから:「先頭および末尾の空白は出力で許可されます(/ \ s * /に一致するものすべて)」。改行が一致し/\s*/ます。
エルペドロ

1
申し訳ありませんが、正規表現の表記法に精通していません。:/
idrougge

私も私も
ElPedro




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に変換することにより、文字列をビットのリストに変換しますfromEnumgこのリストを8つのグループに分割し、それらを10進数に変換し、結果の数値をのインスタンスでEnumあるとして取得Charします。

変更点:

  • @Laikoniのおかげで-19バイト(インポートの削除、map関数への埋め込み)
  • @Lynnの回答に触発された-12バイト(takeより短いリストで圧縮することで解消)

2
インポートのtoEnum代わりに使用chrしてドロップできます。もmapに含めることができますg。間のスペースは8 s削除できます。
ライコニ

1

Forth(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文字列(アドレスと長さ)で、出力はstdoutに出力されます

説明

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.