让我们做一些“ 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,但您可能连续遇到几个数字。
Arnauld

1bbab是有效输入(预期输出为abbab)吗?换句话说,引用可以环绕字符串吗?
路加福音

@卢克好点。不,1bbab无效。我已经对此做了澄清。
Arnauld

Answers:


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;){改为保存一个字符。
Anders Tornblad '17

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
Leo

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

在开始之前,我真的需要检查一下您是否已经回答得更多了。
Magic Octopus Urn'Apr

@carusocomputing:您仍然可以想出一些比我用过的更好的技巧;)
Emigna

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是的,我以为我以前尝试过,但它出错了。谢谢!
汤姆(Tom),

1
o-m-1可以替换为o+~m
尼尔

2
因为f是递归调用的,所以程序的字符数必须包含该f=部分,因此,这是54个字节,而不是52个字节
。– user5090812

5

视网膜,37字节

字节数假定为ISO 8859-1编码。

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

在线尝试!

说明

\d
$*«»

将每个数字d替换为d « s,然后再替换一个»。我们需要后者a)能够识别d = 0的位置,以及b)作为相邻数字之间的分隔符。

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

+从右到左重复()匹配第一行的正则表达式(r),然后用1第二行的替换项替换最左边的匹配()。

正则表达式本身匹配我们现在的一进制数字之一,并计算«第2组中的s 的数量。向后查找则与d字符进行匹配,(?<-2>.)*然后捕获第1组中的所指字符。随后将«s 的字符串»替换为捕获的字符。


5

MATL21 19 17 16字节

"@t4Y2m?UQ$y]]&h

MATL在线上尝试一下

说明

        % 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'U产量exp(1)不然我可能会摆脱4Y2

这些八度音阶中的另一件事……
Luis 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

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

在线尝试!

实际上挺直截了当的。-F标志将每个字符的输入分为@Fmap{...}@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]可能是\d,一起节约6B
卢克

目前在某个地方有错误,因此请首先解决该问题
fəˈnɛtɪk 17-4-7

x=>[...x].map((p,i,a)=>+p+1?a[i-1-p]:p).join``for 46 bytes
Luke

空格失败+“”给出0,导致它抓住了先前的字符
fəˈnɛtɪk 17-4-7

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

3

05AB1E27 17字节

vyDdiU)DRXèU`X}}J

在线尝试!

vy             }  # For each character
  Dd              #   Push is_number
    i         }   #   If it is
     U            #     Save save it
      )DR         #     Wrap the (reversed) stack into an array
         Xè       #     Get the character at the saved index
           U`X    #     Flatten the whole stack
                J # Join 

2

CJam,13个字节

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

在线演示。

该解决方案使用CJam的内置“ 在堆栈上复制第n个项目”运算符$来实现解码。首先从读取输入(带有q)开始,然后遍历输入字符串中的字符并将它们转储到堆栈中(带有{}/)。但是,在循环体内,它还会复制每个字符(用_),然后再复制每个字符,并通过#在字符串中查找其位置来"0123456789"方便地检查它是否是一个数字,表示为A,s

查找的结果是数字的数字值,或者如果字符不是数字,则为-1。该)运营商则通过增加一个值,并$与下面的堆栈的顶部,许多职位的性质目前的替换它。最后,\;只需_从堆栈中删除我们使用的当前输入字符的副本即可,因为不再需要它。


2

Befunge-9845 43个字节

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

在线尝试!

这个想法:

  1. 对于输入字符串中的每个字符,
    1. 写到第二行
    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 Nope。抱歉,我没有足够仔细地阅读规范。会很快修改
数学迷

似乎有错误。为'Prog2am0in6 Puz0les7&1Cod74G4lf'您的程序打印Programming Puzzles &7Code1Golf!我尝试了共享两个TIO链接!
Keerthana Prabhakaran

@KeerthanaPrabhakaran谢谢!固定为0字节!(我的替代解决方案虽然没有取得成功)
数学迷

那是个好方法!
Keerthana Prabhakaran

您能解释一下'/'<i <':'。我知道它正在测试是否是数字,但是它如何工作?
Matias 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)
  • 如果是这样,它是一个数字:按索引打印前一个字符(并复制到当前索引)
  • 否则打印此字符

感谢@Christoph节省了12%


1
我知道这是一个旧答案,但是:负字符串偏移量!(那$s=$argn……?)for(;_&$c=$argn[$i++];)$t.=($c^"0")<"\n"?$t[~+$c]:$c;echo$t;
Christoph

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字节

-2个字节,感谢@FrownyFrog

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

在线尝试!

用途 ⎕io←1

以下代表评估中的中间值)

⎕d 是字符串 '0123456789'

⎕d⍳⍵在中找到char 的(在这种情况下,从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

Python 2,58字节

lambda s:reduce(lambda t,c:t+(c+t)['/'<c<':'and~int(c)],s)

这实质上是我的Jelly答案的端口,再加上@xnor的Python答案中的数字检查。

在线尝试!



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!如果您不需要函数名称进行递归调用,则未命名的函数有效,因此可以在上保存两个字节f=
Martin Ender

1

> <>(Fish),108字节(= 9 x 12网格)

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

在这里尝试看鱼游动。

  • 将-1附加到输入堆栈,然后反转堆栈。
  • 循环:如果最高值为-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使用的版本都将单个.数字解释为数字0,因此最后一次测试失败。较旧的版本(≤7)似乎可以正常工作。

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.