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.

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.    

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.


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.


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

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

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


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


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

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.


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


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!


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 

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.


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



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


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%


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

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: (...)⊃¨⊂


Como seria um trem?
— FrownyFrog

@FrownyFrog, de fato, mais curto
— ngn


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


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!



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


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.

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


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

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!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.