Vamos fazer um "deciph4r4ng"

58

Nesse desafio, sua tarefa é decifrar uma string. Felizmente, o algoritmo é bastante simples: lendo da esquerda para a direita, cada dígito encontrado N (0 a 9) deve ser substituído pelo caractere que está nas posições N + 1 antes dele.

Exemplo

A string de entrada "Prog2am0in6"seria decodificada da seguinte maneira:

exemplo

Portanto, a saída esperada é "Programming".

Esclarecimentos e regras

  • A sequência de entrada conterá caracteres ASCII exclusivamente no intervalo 32 - 126. Você pode assumir que nunca estará vazio.
  • A sequência decifrada original é garantida para não conter nenhum dígito.
  • Uma vez decodificado, um caractere pode ser referenciado por um dígito subsequente. Por exemplo, "alp2c1"deve ser decodificado como "alpaca".
  • As referências nunca serão agrupadas em torno da string: somente caracteres anteriores podem ser referenciados.
  • Você pode gravar um programa completo ou uma função que imprima ou produz o resultado.
  • Isso é código de golfe, então a resposta mais curta em bytes vence.
  • As brechas padrão são proibidas.

Casos de teste

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.
Arnauld
fonte
Podemos receber a entrada como uma matriz de cadeias de caracteres únicos? Podemos supor que o número nunca será maior que 9?
fənɛtɪk
@ fəˈnɛtɪk Em relação ao formato de entrada: eu diria que não, a menos que este seja o único formato aceitável para o seu idioma. Estamos lidando com dígitos únicos em vez de números. Então, sim: é garantido que seja <= 9, mas você pode encontrar vários dígitos seguidos.
Arnauld
Seria 1bbabuma entrada válida (com saída esperada de abbab)? Em outras palavras, as referências podem envolver a string?
Lucas
@Luke Bom argumento. Não, 1bbabnão é válido. Eu adicionei um esclarecimento sobre isso.
Arnauld

Respostas:

11

Geléia , 9 7 bytes

~ịṭṭµ@/

Experimente online!

Como funciona

~ịṭṭµ@/  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.    
Dennis
fonte
13

Java 7, 81 80 bytes

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];}

Experimente online!

Guardou 1 byte graças a Anders Tornblad . O primeiro caractere não pode ser um dígito, portanto, não precisa ser verificado, o que significa que podemos pré-incrementar antes de verificar nossa condição de término.

Cutucar
fonte
2
Como o primeiro caractere nunca pode conter um dígito, você não precisa verificá-lo. Portanto, seu loop pode estar for(int i=0;++i<a.length;){salvando um caractere.
precisa saber é o seguinte
12

Haskell, 55 bytes

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

Exemplo de uso: reverse.foldl(#)[] $ "Prog2am0in6 Puz0les7&1Cod74G4lf"-> "Programming Puzzles & Code Golf". Experimente online!

Reduza a sequência para uma cópia reversa de si mesma com os números substituídos pelos caracteres correspondentes. "reverse", porque dessa maneira temos fácil acesso à string até o momento ao indexar os números. Inverta novamente.

nimi
fonte
11
Uau, eu escrevi esta solução exata, mas eu era lento em publicá-la :) Bem, pelo menos agora eu sei que foi um bom, +1
Leo
11

C, 46 bytes

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

Experimente online!


C,  52   49  48 bytes

Obrigado a @ l4m2 por salvar um byte!

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

Edita a sequência de entrada diretamente.

Experimente online!

Versão alternativa de 50 bytes:

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

Versão recursiva, 48 bytes:

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

05AB1E , 11 bytes

vydiÂyèëy}J

Experimente online!

Explicação

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
Emigna
fonte
Eu realmente preciso verificar se você já respondeu com mais frequência antes de começar.
Urna de polvo mágico
@carusocomputing: Você ainda pode pensar em algum truque melhor do que eu usei;)
Emigna
7

JavaScript (ES6), 59 53 bytes

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

Economizou 7 bytes graças a fəˈnɛtɪk.

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."));

Tom
fonte
.charAt (...) pode ser substituído por [...] economia de 7 bytes
fəˈnɛtɪk
x.charAt (...) é equivalente a x [...]
fəˈnɛtɪk
@ fəˈnɛtɪk Sim, eu pensei que tinha tentado isso antes, mas deu um erro. Obrigado!
Tom
11
o-m-1pode ser substituído por o+~m.
711 Neil
2
Porque f é chamada de forma recursiva, a contagem de caracteres do programa deve incluir a f=parte, por isso esta é 54 bytes, e não 52.
user5090812
5

Retina , 37 bytes

A contagem de bytes assume a codificação ISO 8859-1.

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

Experimente online!

Explicação

\d
$*«»

Substitua cada dígito d por d « s, seguido por um ». Precisamos que o último a) seja capaz de reconhecer posições onde d = 0 eb) como um separador entre dígitos adjacentes.

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

Faça corresponder repetidamente ( +) a regex na primeira linha da direita para a esquerda ( r) e substitua a correspondência mais à esquerda ( 1) pela substituição na segunda linha.

A regex em si corresponde a um de nossos dígitos agora unários e conta o número de «s no grupo 2. O lookbehind combina os caracteres d com (?<-2>.)*antes de capturar o caractere referido no grupo 1. A sequência de «s e »é substituída pelo caractere capturado .

Martin Ender
fonte
5

MATL , 21 19 17 16 bytes

"@t4Y2m?UQ$y]]&h

Experimente no MATL Online!

Explicação

        % 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
Suever
fonte
Bom uso de $yna nova versão!
Luis Mendo
@LuisMendo Thanks! Sim linguagens baseadas em pilha são uma boa opção para este desafio
Suever
@LuisMendo Infelizmente, isso poderia ter sido reduzido ainda mais se Ufuncionasse apenas com dígitos. Infelizmente 'e'Uproduz exp(1)senão eu poderia ter se livrado do 4Y2material
Suever
Outra daquelas coisas Octave ...
Luis Mendo
4

JavaScript (ES6), 51 bytes

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 é usado para armazenar os dígitos substituídos para lidar com dígitos referentes a outros dígitos.

Neil
fonte
`` s ​​=> s.replace (a = / \ d / g, (c, i) => a [i] = a [i + = ~ c] || s [i]) ``
l4m2
3

Perl 5 , 34 bytes

33 bytes de código + -psinalizador.

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

Experimente online!

s/\d/.../esubstitua o primeiro dígito por ...avaliado como código Perl. ( ...sendo substr$_,-$&-1+pos,1nesse caso. substr$_,-$&-1+pos,1retorna a substring of $_of length 1no índice -$&-1+pos, onde $&é o número que acabou de corresponder e posé o índice do início da partida. Só precisamos saber redose a substituição foi bem-sucedida para substituir todos os dígitos. (e o resultado é impresso implicitamente graças à -pbandeira).


Abordagem antiga, 47 bytes:

44 bytes de código + -Fsinalizador.

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

Experimente online!

Muito simples, na verdade. -Fflag divide as entradas em cada caractere @F. map{...}@Fitera através @F(ou seja, todos os caracteres da entrada). Se o caractere for um dígito ( /\d/), então o substituiremos pelo caractere no índice $i-$_-1. A $ié a variável de índice atual (que mantemos incrementando a cada caractere visto).

dada
fonte
3

JavaScript ES6, 61 59 bytes

Obrigado @Luke por jogar fora 8 bytes

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

Experimente online!

fəˈnɛtɪk
fonte
x.split``Também poderia ser [...x], [0-9]poderia ser \d, em conjunto poupança 6B
Lucas
Atualmente tem um erro em algum lugar para ir para corrigir esse primeiro
fənɛtɪk
x=>[...x].map((p,i,a)=>+p+1?a[i-1-p]:p).join``para 46 bytes
Luke
Falhar por espaços +"" fornece 0 que faz com que ele pegue o caractere anterior
fənɛtɪk
x=>[...x].map((p,i,a)=>a[i]=1+p>9?a[i-1-p]:p).join``
L4m2 23/04
3

05AB1E , 27 17 bytes

vyDdiU)DRXèU`X}}J

Experimente online!

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 
Riley
fonte
2

CJam, 13 bytes

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

Demonstração online.

Esta solução usa o operador "copiar n- ésimo item na pilha" do CJam $para implementar a decodificação. Começa lendo a entrada (com q) e, em seguida, fazendo um loop sobre os caracteres da sequência de entrada e os colocando na pilha (com {}/). No entanto, dentro do corpo do loop, ele também duplica cada caractere depois de ter sido colocado na pilha (com _) e verifica se é um dígito procurando sua posição #na string "0123456789", convenientemente representada como A,s.

O resultado dessa pesquisa é o valor numérico do dígito ou, se o caractere não for um dígito, -1. O )operador então incrementa esse valor em um e o $substitui pelo caractere atual em várias posições abaixo da parte superior da pilha. Finalmente, \;apenas remove a cópia do caractere de entrada atual que criamos _da pilha, pois não é mais necessário.

Ilmari Karonen
fonte
2

Befunge-98 , 45 43 bytes

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

Experimente online!

A ideia:

  1. Para cada caractere na sequência de entrada,
    1. Escreva na linha 2
    2. Se não for um número, basta enviá-lo
    3. Caso contrário, procure o valor correto, reescreva-o e depois produza-o
::::            ; 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 ;

Não consegui obter esta versão mais curta, mas esta tem 44 bytes:

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

Pensei que eu iria compartilhar por causa do truque, smas armazenar o contador na pilha leva a uma melhoria de 1 caracter

Justin
fonte
2

Python 2, 75 71 bytes

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

Experimente Online!

Editar: corrigido para valores ascii entre 32 e 47 ; Corrigido para decodificação dupla (por exemplo, "alp2c1" para "alpaca")

viciado em matemática
fonte
11
@Arnauld Nope. Desculpe, eu não li as especificações o suficiente. Modificará logo
matemática viciado em
Parece que há um erro. para o 'Prog2am0in6 Puz0les7&1Cod74G4lf'seu programa imprime Programming Puzzles &7Code1Golf! Eu tentei com os dois links TIO compartilhados!
Keerthana Prabhakaran
@KeerthanaPrabhakaran Thanks! Corrigido ao custo de 0 bytes! (Minha solução alternativa não fez o corte embora)
viciado em matemática
Essa é uma ótima abordagem!
Keerthana Prabhakaran
Você pode explicar '/' <i <':'. Sei que está testando se é um número, mas como funciona?
Matias K
2

PHP 7.1 67 59 bytes

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

Recebe entrada do STDIN; execute como pipe -nRou experimente online .

  • _&$c=$s[$i++]loop pela string ( _&$cresultará em algo que não é "0"; portanto, o único caractere que pode interromper o loop é a string vazia = final da entrada)
  • $c^"0" alternar os bits 5 e 6 no código ascii
  • <"\n" verifique se o resultado é <chr (10)
  • nesse caso, é um dígito: imprima o caractere anterior pelo índice (e copie para o índice atual)
  • mais imprima esse caractere

Obrigado @Christoph por economizar 12%

Titus
fonte
11
Eu sei que esta é uma resposta antiga, mas: Compensações de string negativas! (e que $s=$argn...?)for(;_&$c=$argn[$i++];)$t.=($c^"0")<"\n"?$t[~+$c]:$c;echo$t;
Christoph
2

Macro / pressionamentos de tecla do Vim, 49 bytes

^M representa o caractere de retorno (0x0A, 1 byte).

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

Explicação

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
TheFamilyFroot
fonte
2

APL (Dyalog Classic) , 25 23 bytes

-2 bytes graças a @FrownyFrog

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

Experimente online!

usa ⎕io←1

( abaixo significa um valor intermediário na avaliação)

⎕d é a string '0123456789'

⎕d⍳⍵localiza os índices (baseados neste caso) em 1 dos caracteres de ⎕d; para um não dígito, o índice é 11

11|⍵ é módulo - os 11s se tornam 0s

≢⍵ é o comprimento de

⍳≢⍵é 1 2 ...até≢⍵

assim, (⍳≢⍵)-11|⎕d⍳⍵nos fornece um vetor i dos índices onde devemos procurar para obter os caracteres resultantes; no entanto, alguns desses índices podem ser redirecionados para outros ainda (menores). Para calcular o fechamento transitivo (ou seja, os índices efetivos), indexamos o vetor em si mesmo ( ⊂⌷⊢um trem equivalente a (⊂i)⌷iou i[i]) e repetimos isso até que ele se estabilize ( ⍣≡conhecido como operador de ponto fixo ).

finalmente indexamos na string original: (...)⊃¨⊂

ngn
fonte
Como seria um trem?
FrownyFrog
@FrownyFrog, de fato, mais curto
ngn
1

Python 2 , 83 80 bytes

r=input()
for i in r:
 if'/'<i<':':r=r.replace(i,r[r.find(i)+~int(i)],1)
print r

Experimente online!

  • salvou 3 bytes, mas verificando ascii em vez de é dígito! Obrigado a math_junkie!
Keerthana Prabhakaran
fonte
1

Japt , 24 bytes

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

Experimente online!

Explicação:

£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
Oliver
fonte
1

Ruby, 56 46 bytes

->s{i=0;s[i]=s[i+~s[i].to_i]while i=s=~/\d/;s}

Experimente online!

Value Ink
fonte
1

Python 2 , 58 bytes

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

Esta é essencialmente uma porta da minha resposta Jelly, mais a verificação de dígitos da resposta Python do @ xnor.

Experimente online!

Dennis
fonte
1

JavaScript ES6, 54 bytes

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."));

ogur
fonte
11
Bem-vindo ao PPCG! Se você não precisar do nome da sua função para chamadas recursivas, as funções sem nome são válidas, para que você possa salvar dois bytes no f=.
Martin Ender
1

> <> (Peixe), 108 bytes (= grade 9 x 12)

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

Experimente aqui para ver os peixes nadando ao redor.

  • Acrescente -1 à pilha de entrada e depois inverta a pilha.
  • Loop: se o valor máximo for -1, então termina (passamos por todos os caracteres). De outra forma:
  • Coloque o personagem principal no registro; verifique se está no intervalo "0" a "9". Se então:
    • gire a pilha o número apropriado de lugares
    • obter o personagem que está sendo apontado
    • gire para trás e substitua o número pelo caractere do registro
  • Resultado; retomar o loop.
Théophile
fonte
1

Código de máquina 8086, 35 bytes

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
user5434231
fonte
1

Japt v2.0a0, 16 bytes

r\d@=hYUgY-°X¹gY

Tente


Explicação

                     :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
Shaggy
fonte
1

J , 20 bytes

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

Experimente online

                  ,.  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

Crédito para ngn pela inspiração.

22 bytes

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

Esta é uma porta da resposta Jelly.

                    |. 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.

Nas duas soluções, a versão usada pelo TIO interpreta um único .como o número 0, portanto, o último teste falha. As versões mais antigas (≤7) parecem funcionar corretamente.

Experimente online!

FrownyFrog
fonte