いくつかの「deciph4r4ng」をしましょう


58

このチャレンジでは、あなたの仕事は文字列を解読することです。幸いなことに、アルゴリズムは非常に単純です。左から右に読むと、出会った各桁N(0〜9)は、その前のN + 1位置の文字に置き換える必要があります。

入力文字列"Prog2am0in6"は次のようにデコードされます。

例

したがって、予想される出力は"Programming"です。

明確化と規則

  • 入力文字列には、32〜126の範囲のASCII文字のみが含まれます。空になることはないと想定できます。
  • 元の解読された文字列には、数字が含まれないことが保証されています。
  • 文字がデコードされると、次の数字で参照される場合があります。たとえば、"alp2c1"としてデコードする必要があります"alpaca"
  • 参照は文字列をラップすることはありません。前の文字のみを参照できます。
  • 完全なプログラムまたは結果を出力または出力する関数を作成できます。
  • これはコードゴルフであるため、バイト単位の最短回答が優先されます。
  • 標準的な抜け穴は禁止されています。

テストケース

Input : abcd
Output: abcd

Input : a000
Output: aaaa

Input : ban111
Output: banana

Input : Hel0o W2r5d!
Output: Hello World!

Input : this 222a19e52
Output: this is a test

Input : golfin5 3s24o0d4f3r3y3u
Output: golfing is good for you

Input : Prog2am0in6 Puz0les7&1Cod74G4lf
Output: Programming Puzzles & Code Golf

Input : Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d.
Output: Replicants are like any other machine. They're either a benefit or a hazard.

入力を単一の文字列の配列として受け取ることはできますか?数値が9より大きくなることはないと想定できますか?
fəˈnɛtɪk

@ fəˈnɛtɪk入力形式について:これがあなたの言語で唯一受け入れられる形式でない限り、ノーと言います。数値ではなく一桁の数字を扱っています。はい:9以下であることが保証されていますが、連続して複数の数字が表示される場合があります。
アーナルド

1bbab有効な入力になりますか(予想される出力はabbab)?つまり、参照は文字列をラップできますか?
ルーク

@ルーク良い点。いいえ、1bbab無効です。それについての説明を追加しました。
アーナルド

回答:


11

ゼリー9 7バイト

~ịṭṭµ@/

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

使い方

~ịṭṭµ@/  Main link. Argument: s

    µ    Combine the four links to the left into a chain (arity unknown).
     @   Swap the chains arguments. This makes it dyadic.
      /  Reduce s by the chain with swapped arguments. It will be called with
         right argument r (the result of the previous call, initially the first 
         character) and left argument c (the next character of s).
~            Bitwise NOT of c. This maps a digit 'd' to ~d = -(d+1), but all 
             non-digit characters 'D' to 0.
  ṭ          Tack; append c to r.
 ị           Index; select the character of the result to the right at the
             index from the result to the left. Indexing is 1-based and modular,
             so 0 is the last character, -1 the second to last, etc.
   ṭ         Tack; append the resulting character to r.    

13

Java 7、81 80バイト

void a(char[]a){for(int i=0;++i<a.length;)if(a[i]>47&a[i]<58)a[i]=a[i-a[i]+47];}

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

Anders Tornbladのおかげで1バイト節約できました。最初の文字を数字にすることはできないため、チェックする必要はありません。つまり、終了条件をチェックする前に事前にインクリメントすることができます。


2
最初の文字に数字を含めることはできないため、チェックする必要はありません。したがって、for(int i=0;++i<a.length;){代わりにループを使用して、1文字を節約できます。
アンダーストーンブラッド

12

Haskell、55バイト

o#c|c>'/',c<':'=o!!read[c]:o|1<2=c:o
reverse.foldl(#)[]

使用例:reverse.foldl(#)[] $ "Prog2am0in6 Puz0les7&1Cod74G4lf"-> "Programming Puzzles & Code Golf"オンラインでお試しください!

文字列を、数字を対応する文字に置き換えて、それ自体の逆コピーに減らします。「逆」。これは、この方法でこれまで数字にインデックスを作成するときに文字列に簡単にアクセスできたためです。もう一度元に戻します。


1
うわー、私はこの正確な解決策を書いたが、それを投稿するのが遅かった:)まあ、少なくとも今ではそれが良いものだと知っている、+ 1
レオ

11

C、46バイト

f(char*s){for(;*s++;)*s=s[(*s-52)/6?0:47-*s];}

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


C、 52   49  48バイト

バイトを保存してくれた@ l4m2に感謝します!

f(char*s){for(;*s++;)*s>47&*s<58?*s=s[47-*s]:0;}

入力文字列を直接編集します。

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

代替の50バイトバージョン:

f(char*s){for(;*s++;)*s=abs(*s-57)>9?*s:s[47-*s];}

再帰バージョン、48バイト:

f(char*s){*s>47&*s<58?*s=s[47-*s]:0;*s++&&f(s);}

9

05AB1E、11バイト

vydiÂyèëy}J

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

説明

v            # for each character y in input
 ydi         # if y is a digit
    Â        #    push a reversed copy of the string we've built up so far
     yè      #    push the character at index y in the reversed string
       ë     # else
        y    #    push y
         }   # end if
          J  # join stack to a single string
             # output top of the stack at the end of the loop

開始する前に、あなたがすでに頻繁に答えているかどうかを確認する必要があります。
魔法のタコUr

@carusocomputing:まだ私が使ったよりも良いトリックを考え出すことができた;)
エミグナ

7

JavaScript(ES6)、59 53バイト

f=x=>/\d/.test(x)?f(x.replace(/\d/,(m,o)=>x[o+~m])):x

fəˈnɛtɪkのおかげで7バイト節約されました。

f=x=>/\d/.test(x)?f(x.replace(/\d/,(m,o)=>x[o+~m])):x

console.log(f("Prog2am0in6"));
console.log(f("abcd"));
console.log(f("a000"));
console.log(f("ban111"));
console.log(f("Hel0o W2r5d!"));
console.log(f("this 222a19e52"));
console.log(f("golfin5 3s24o0d4f3r3y3u"));
console.log(f("Prog2am0in6 Puz0les7&1Cod74G4lf"));
console.log(f("Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d."));


.charAt(...)は、7バイトの節約のために[...]に置き換えることができます
fəˈnɛtɪk

x.charAt(...)はx [...]と同等です
-fəˈnɛtɪk

@ fəˈnɛtɪkうん、私は前にそれを試したと思ったが、エラーを投げた。ありがとう!
トム

1
o-m-1に置き換えることができますo+~m
ニール

2
fは再帰的に呼び出されるため、プログラムの文字カウントにはf=パーツが含まれている必要があります。したがって、これは52バイトではなく54バイト
です。– user5090812

5

網膜、37バイト

バイトカウントはISO 8859-1エンコードを前提としています。

\d
$*«»
r1+`(?<=(.)(?<-2>.)*)(«)*»
$1

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

説明

\d
$*«»

各数字dd « sに置き換え、その後にoneを続け»ます。後者は、a)d = 0の位置とb)隣接する数字の間の区切り文字としての位置を認識できる必要があります。

r1+`(?<=(.)(?<-2>.)*)(«)*»
$1

繰り返し(+)最初の行の正規表現を右から左(r)に一致させ、左端の一致(1)を2行目の置換に置き換えます。

正規表現自体は、私たちの今単項桁のいずれかに一致し、数カウント«グループ後読みは、次に一致する2でSをDで文字を(?<-2>.)*の言及-に文字グループ1内の文字列取り込む前に«Sをし、»その後、撮影した文字に置き換えられます。


5

MATL21 19 17 16バイト

"@t4Y2m?UQ$y]]&h

MATL Online試しください

説明

        % Implicitly grab input as a string
"       % For each character in the input
  @     % Push that character to the stack
  t     % Make a copy of it
  4Y2   % Push the pre-defined array '0123456789' to the stack
  m     % Check if the current character is part of this array (a digit)
  ?     % If it is
    UQ  % Convert it to a number and add 1 (N)
    $y  % Make a copy of the element N-deep in the stack. MATL uses one-based indexing
        % So 1$y is the element at the top of the stack, 2$y is the next one down, etc.
  ]     % End of if statement
        % Non-digit characters remain on the stack as-is
]       % End of for loop
&h      % Horizontally concatenate the entire stack to form a string
        % Implicitly display the result

$y新しいバージョンでの素晴らしい使用!
ルイスメンドー

@LuisMendoありがとう!いやスタックベースの言語は、この課題に適している
Suever

@LuisMendo残念なことにU、数字だけで機能していれば、これはさらに短縮された可能性があります。残念ながら'e'Uexp(1)それ以外の場合、私は4Y2ものを取り除くことができたかもしれません
-Suever

...それらのオクターブのものの別
ルイス・Mendo

4

JavaScript(ES6)、51バイト

f=
s=>s.replace(/\d/g,(c,i)=>a[i]=a[i+=~c]||s[i],a=[])
<input oninput=o.textContent=f(this.value)><pre id=o>

a は、他の数字を参照する数字を処理するために、置き換えられた数字を保存するために使用されます。


`` `s => s.replace(a = / \ d / g、(c、i)=> a [i] = a [i + =〜c] || s [i])` ``
l4m2

3

Perl 5、34バイト

33バイトのコード+ -pフラグ。

s/\d/substr$_,-$&-1+pos,1/e&&redo

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

s/\d/.../e...Perlコードとして評価して最初の数字を置き換えます。(と...されsubstr$_,-$&-1+pos,1ている場合には。substr$_,-$&-1+pos,1のストリングを返します$_長さの1指標で-$&-1+pos$&ちょうどマッチした数であるが、そしてpos試合の開始の指標である。私達はちょうどに必要なredoすべての桁を交換するために成功した場合には交換してください。 (および結果は、-pフラグのおかげで暗黙的に印刷されます)。


古いアプローチ、47バイト:

44バイトのコード+ -Fフラグ。

map{$F[$i]=$F[$i-$_-1]if/\d/;++$i}@F;print@F

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

実際には非常に簡単です。-Fflagは、各文字の入力をに分割し@Fます。(つまり、入力のすべての文字)をmap{...}@F反復処理し@Fます。文字が数字(/\d/)の場合、indexの文字で置き換えます$i-$_-1$i(私たちが見て、各文字にインクリメントすることによって維持すること)現在のインデックス変数です。


3

JavaScriptのES6、61の 59バイト

@ Luke、8バイトのゴルフをありがとう

x=>[...x].map((p,i,a)=>a[i]=/\d/.test(p)?a[i-1-p]:p).join``

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


x.split``また、可能性があり[...x][0-9]可能性があり\d6B節約一緒に、
ルーク

現在どこかにエラーがあるため、最初にそれを修正します
-fəˈnɛtɪk

x=>[...x].map((p,i,a)=>+p+1?a[i-1-p]:p).join``46バイト
ルーク

スペースの失敗+ ""は0を
返し

x=>[...x].map((p,i,a)=>a[i]=1+p>9?a[i-1-p]:p).join``
l4m2


2

CJam、13バイト

q{_A,s#)$\;}/

オンラインデモ。

このソリューションでは、CJamの組み込み「スタック上のn番目のアイテムをコピー」演算子$を使用して、デコードを実装します。入力を(withを使用してq)読み取り、入力文字列から文字をループして、スタックに(withを使用して{}/)ダンプすることから開始します。ただし、ループ本体内では、スタックに置かれた(with _)後に各文字を複製#し、文字列"0123456789"で位置を検索することで数字であるかどうかをチェックしA,sます。

このルックアップの結果は、数字の数値、または文字が数字でない場合は-1です。次に、)オペレーターはその値を1 $増やし、スタックの最上部より下のその位置にある現在の文字に置き換えます。最後に、スタックから\;作成した現在の入力文字のコピーを、_不要になったので削除します。


2

Befunge-9845の 43バイト

::::#@~\1p:1g::'9`!\'/`*j;'/--1g\1p\1g#;,1+

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

アイデア:

  1. 入力文字列の各文字に対して、
    1. 2行目に書いてください
    2. 数値でない場合は、出力するだけです
    3. それ以外の場合は、正しい値を検索して書き換え、出力します
::::            ; There's a counter on the stack, duplicate it 4 times  ;
    #@~         ; Get the next char of input, exiting if there is none  ;
       \1p      ; At the location (counter, 1), write the input char    ;
          :1g   ; Re-obtain the char. Stack is now [counter * 4, input] ;

::                ; Stack: [counter * 4, input * 3]      ;
  '9`!\'/`*       ; If !(input > '9') and (input > '/')  ;
                  ; IE If ('0' <= input && input <= '9') ;
           j;...; ; Then execute the ...                 ;

; Stack: [counter * 4, input] ;
; The ... branch:             ;

'/-             ; input -> int. (input -= '/')             ;
   -            ; counter - int(input) - 1                 ;
                ; Stack: [counter * 3, lookupPosition ]    ;
    1g          ; Get the char that we want to find        ;
      \1p\1g#   ; Overwrite the current char (not the old) ;

; Both branches: ;
,1+             ; Print the number and increment the counter ;

このバージョンを短くすることはできませんでしたが、これは44バイトです。

s #@~\3p:3g::'9`!\'/`*j;'/--3g#;:10g3p,1+:::

私はそれをきちんとしたトリックのために共有すると思いましたs-しかし、スタックにカウンターを保存すると、その1文字の改善につながります



2

Python 2、75 71バイト

s='';j=-1
for i in input():s+=s[j-int(i)]if'/'<i<':'else i;j+=1
print s

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

編集: 32から47の間のASCII値の修正ダブルデコードの修正(例: "alp2c1"から "alpaca")


1
@Arnauldいいえ。申し訳ありませんが、仕様を十分に読みませんでした。間もなく変更されます
数学中毒

バグがあるようです。以下のための'Prog2am0in6 Puz0les7&1Cod74G4lf'プログラムプリントProgramming Puzzles &7Code1Golf!両方のTIOリンクを共有してみました!
Keerthana Prabhakaran

@KeerthanaPrabhakaranありがとう!0バイトのコストで修正されました!(しかし、私の代替ソリューションはカットしませんでした)
数学中毒

それは素晴らしいアプローチです!
Keerthana Prabhakaran

'/' <i <':'を説明できますか。私はそれが数字かどうかをテストしていることを知っていますが、どのように機能しますか?
マティアスK

2

PHP 7.1 67 59バイト

while(_&$c=$argn[$i++])$t.=($c^"0")<"
"?$t[~+$c]:$c;echo$t;

STDINから入力を受け取ります。でパイプとして実行する-nR、オンラインで試してください

  • _&$c=$s[$i++]文字列をループします(そう_&$cでないものになり"0"ます;ループを破ることができる唯一の文字は空の文字列=入力の終わりです)
  • $c^"0" ASCIIコードのビット5と6を切り替えます
  • <"\n" 結果が<chr(10)かどうかを確認します
  • もしそうなら、それは数字です:インデックスによって前の文字を印刷します(そして現在のインデックスにコピーします)
  • それ以外の場合、この文字を印刷します

12%節約してくれた@Christophに感謝


1
私はこれが古い答えであることを知っていますが、負の文字列オフセット!(そして$s=$argn... ...)for(;_&$c=$argn[$i++];)$t.=($c^"0")<"\n"?$t[~+$c]:$c;echo$t;
クリストフ

2

Vimマクロ/キーストローク、49バイト

^M 戻り文字(0x0A、1バイト)を表します。

qqqqq/[0-9]^Myl:exe 'norm '.(@"+1).'h'^Mylnphx@qq@q

説明

qqq                                                     clear register q
   qq                                                   record into q
     /[0-9]^M                                           move the cursor to the next digit
             yl                                         yank the digit
               :exe 'norm '.(@"+1).'h'^M                move the cursor left that number of characters plus one
                                        yl              yank the char
                                          n             go back to the digit
                                           p            paste the char 
                                            hx          delete the digit
                                              @q        recursive call
                                                q       stop recording
                                                 @q     run the macro

2

APL(Dyalog Classic)25 23バイト

@FrownyFrogのおかげで-2バイト

((⊂⌷⊢)⍣≡⍳∘≢-11|⎕d∘⍳)⊃¨⊂

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

使用する ⎕io←1

以下は評価の中間値を表します)

⎕d 文字列です '0123456789'

⎕d⍳⍵ののcharsのインデックス(この場合は1ベース)を検索し⎕dます; 数字以外の場合、インデックスは11です

11|⍵ モジュロ-11は0になります

≢⍵ の長さです

⍳≢⍵ある1 2 ...まで≢⍵

したがって、結果の文字を取得するために調べる必要があるインデックスの(⍳≢⍵)-11|⎕d⍳⍵ベクトルiを提供します。ただし、これらのインデックスの一部は、さらに他の(より小さい)インデックスにリダイレクトされる場合があります。推移閉包(つまり、有効なインデックス)を計算するには、ベクトルをそれ自体(⊂⌷⊢(⊂i)⌷iまたはに相当するトレイン)にインデックスし、i[i]安定するまで固定します固定小数点演算子⍣≡として知られています)。

最後に、元の文字列にインデックスを付けます。 (...)⊃¨⊂


電車のように見えますか?
FrownyFrog

@FrownyFrog確かに、短い
ngn


1

Japt、24バイト

£Xn >J?U=UhYUgJ+Y-X):PÃU

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

説明:

£Xn >J?U=UhYUgJ+Y-X):PÃU
£                     Ã    Iterate through the input (implicit U) 
                             X becomes the iterative item, Y becomes the index
 Xn                          Try parseInt(X)
    >J                       > -1
                               In this case, this checks if X is a digit
      ?                      If true:
       U=                      Set U to 
         UhY                     U with the char at index Y set to:     
            UgJ+Y-X               The index at -1+Y-X
                   ):        Else:
                     P         variable P (just a no-op in this case)
                       U   Finally, return U




1

JavaScript ES6、54バイト

f=r=>[...r].reduce((a,s,i)=>a+(/\d/.test(s)?a[i+~s]:s))

f=r=>[...r].reduce((a,s,i)=>a+(/\d/.test(s)?a[i+~s]:s))

console.log(f("Prog2am0in6"));
console.log(f("abcd"));
console.log(f("a000"));
console.log(f("ban111"));
console.log(f("Hel0o W2r5d!"));
console.log(f("this 222a19e52"));
console.log(f("golfin5 3s24o0d4f3r3y3u"));
console.log(f("Prog2am0in6 Puz0les7&1Cod74G4lf"));
console.log(f("Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d."));


1
PPCGへようこそ!再帰呼び出しに関数名が必要ない場合は、名前のない関数が有効なので、に2バイトを保存できますf=
マーティンエンダー

1

> <>(魚)、108バイト(= 9 x 12グリッド)

01-r>:0(\
"/"&::;?/
)?\v    \
":/v!?(":
")\ :>:"0
 !?\
${/  \ -1
&>\ ~{:&$
\ \ :"0"=
/\- 1}$/?
:v&//}~/~
 \o}\&$/ 

ここで試して、泳いでいる魚を見てください。

  • 入力スタックに-1を追加し、スタックを逆にします。
  • ループ:topの値が-1の場合、終了します(すべての文字を循環しました)。そうでなければ:
  • レジスタに先頭の文字を入れます。「0」から「9」の範囲にあるかどうかを確認します。その場合:
    • スタックを適切な数だけ回転させます
    • 指し示されているキャラクターを取得する
    • 回転して戻り、数値をレジスタの文字に置き換えます
  • 出力; ループを再開します。

1

8086マシンコード、35バイト

00000000  be 82 00 ac 98 50 2c 30  3c 09 77 0c 4e 89 f7 4e  |.....P,0<.w.N..N|
00000010  29 c6 58 ac aa 89 fe 50  5a b4 02 cd 21 80 fa 0d  |).X....PZ...!...|
00000020  75 e1 c3                                          |u..|
00000023


1

Japt v2.0a0、16バイト

r\d@=hYUgY-°X¹gY

それを試してみてください


説明

                     :Implicit input of string U
r                    :Replace
 \d                  :  RegEx /\d/g
   @                 :  Pass each match X at index Y through a function
     hY              :    Set the character at index Y in U
       UgY-°X        :    To the character at index Y-++X
    =        ¹       :    Reassign to U
              gY     :    Get the character at index Y

1

J、20バイト

{~[:{~^:_#\-2+_1".,.

オンラインで試す

                  ,.  Each character on a separate row
              _1".    Convert to numbers, replacing non-numbers with -1
                         (it becomes one row again)
            2+        Add 2.
         #\           Prefix lengths (range 1..length)
           -          Subtract
  [:{~^:_             Index into itself as long as it changes the result
{~                    Index into the original string

インスピレーションのngnへの信用。

22バイト

(],,{~1{._1-_1".[)/@|.

これはゼリーの答えの移植版です。

                    |. The string backwards, because reduce is right-to-left.
            _1".[      The next character as a number (d), -1 if it's not a number,
                          and a space character produces an empty array.
         _1-           -1-d
      1{.              Take 1. If we have a nothing
                          at this point, that makes it a 0.
   ,                   Prepend the next character to the result of the previous call.
    {~                 Select the character. 0 is the first, _2 is second to last.
 ],                    Append the result.

どちらのソリューションでも、TIOが使用するバージョンは1つ.を数値0として解釈するため、最後のテストは失敗します。古いバージョン(≤7)は正しく動作するようです。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.