Facciamo un po 'di "deciph4r4ng"


58

In questa sfida, il tuo compito è decifrare una stringa. Fortunatamente, l'algoritmo è piuttosto semplice: leggendo da sinistra a destra, ogni cifra incontrata N (da 0 a 9) deve essere sostituita con il carattere che è N + 1 posizioni prima di esso.

Esempio

La stringa di input "Prog2am0in6"verrebbe decodificata in questo modo:

esempio

Quindi, l'output previsto è "Programming".

Chiarimenti e regole

  • La stringa di input conterrà esclusivamente caratteri ASCII nell'intervallo 32-126. Puoi presumere che non sarà mai vuoto.
  • Si garantisce che la stringa decifrata originale non contenga alcuna cifra.
  • Una volta che un personaggio è stato decodificato, può a sua volta fare riferimento a una cifra successiva. Ad esempio, "alp2c1"dovrebbe essere decodificato come "alpaca".
  • I riferimenti non avvolgeranno mai la stringa: solo i caratteri precedenti possono essere referenziati.
  • È possibile scrivere un programma completo o una funzione, che stampa o genera il risultato.
  • Questo è il golf del codice, quindi vince la risposta più breve in byte.
  • Sono vietate le scappatoie standard.

Casi test

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.

Possiamo ricevere l'input come una matrice di stringhe a singolo carattere? Possiamo presumere che il numero non sarà mai maggiore di 9?
— fəˈnɛtɪk,

@ fəˈnɛtɪk Per quanto riguarda il formato di input: direi di no, a meno che questo non sia l'unico formato accettabile per la tua lingua. Abbiamo a che fare con cifre singole anziché numeri. Quindi sì: è garantito che sia <= 9 ma potresti incontrare diverse cifre di fila.
— Arnauld,

Sarebbe 1bbabun input valido (con output atteso di abbab)? In altre parole, i riferimenti possono avvolgere la stringa?
— Luca

@Luke buon punto. No, 1bbabnon è valido. Ho aggiunto un chiarimento al riguardo.
— Arnauld,

Risposte:


11

Gelatina , 9 7 byte

~ịṭṭµ@/

Provalo online!

Come funziona

~ịṭṭµ@/  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 byte

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

Provalo online!

Salvato 1 byte grazie ad Anders Tornblad . Il primo carattere non può essere una cifra, quindi non è necessario verificarlo, il che significa che possiamo preincrementare prima di controllare le nostre condizioni di terminazione.


2
Poiché il primo carattere non può mai contenere una cifra, non è necessario verificarlo. Pertanto, il loop può essere for(int i=0;++i<a.length;){invece, salvando un carattere.
— Anders Tornblad,

12

Haskell, 55 byte

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

Esempio di utilizzo: reverse.foldl(#)[] $ "Prog2am0in6 Puz0les7&1Cod74G4lf"-> "Programming Puzzles & Code Golf". Provalo online!

Ridurre la stringa in una copia inversa di se stesso con i numeri sostituiti dai caratteri corrispondenti. "reverse", perché in questo modo abbiamo un facile accesso alla stringa finora quando si indicizzano i numeri. Invertire di nuovo.


1
Wow, ho scritto questa soluzione esatta ma sono stato lento nel pubblicarlo :) Beh, almeno ora so che è stata una buona scelta, +1
— Leo

11

C, 46 byte

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

Provalo online!


C,  52   49  48 byte

Grazie a @ l4m2 per aver salvato un byte!

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

Modifica direttamente la stringa di input.

Provalo online!

Versione alternativa a 50 byte:

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

Versione ricorsiva, 48 byte:

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

9

05AB1E , 11 byte

vydiÂyèëy}J

Provalo online!

Spiegazione

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

Ho davvero bisogno di verificare se hai già risposto più spesso prima di iniziare.
— Magic Octopus Urn

@carusocomputing: potresti ancora escogitare qualche trucco migliore di quello che ho usato;)
— Emigna,

7

JavaScript (ES6), 59 53 byte

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

Salvataggio di 7 byte grazie 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 (...) può essere sostituito con [...] per un risparmio di 7 byte
— fəˈnɛtɪk

x.charAt (...) equivale a x [...]
— fəˈnɛtɪk

@ fəˈnɛtɪk Sì, pensavo di averlo provato prima ma ha generato un errore. Grazie!
— Tom,

1
o-m-1può essere sostituito con o+~m.
— Neil,

2
Poiché f viene chiamato in modo ricorsivo, il conteggio dei caratteri del programma deve includere la f=parte, quindi si tratta di 54 byte, non di 52.
— user5090812

5

Retina , 37 byte

Il conteggio dei byte presuppone la codifica ISO 8859-1.

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

Provalo online!

Spiegazione

\d
$*«»

Sostituisci ogni cifra d con d « s, seguita da una ». Abbiamo bisogno che quest'ultimo a) sia in grado di riconoscere posizioni in cui d = 0 eb) come separatore tra cifre adiacenti.

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

Ripetutamente ( +) abbina la regex sulla prima riga da destra a sinistra ( r), quindi sostituisci la corrispondenza più a sinistra ( 1) con la sostituzione sulla seconda riga.

L'espressione regolare per sé corrisponde a uno dei nostri cifre ora unari e conta il numero di «s nel gruppo 2. Il lookbehind quindi corrisponde d caratteri con (?<-2>.)*prima di catturare la cui da personaggio in gruppo 1. La stringa di «s e »viene poi sostituito con il carattere catturato .


5

MATL , 21 19 17 16 byte

"@t4Y2m?UQ$y]]&h

Provalo su MATL Online!

Spiegazione

        % 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

Buon uso di $ynella nuova versione!
— Luis Mendo,

@LuisMendo Grazie! Sì, le lingue basate
— sullo

@LuisMendo Purtroppo questo avrebbe potuto essere abbreviato ancora di più se avesse Ufunzionato solo con le cifre. Sfortunatamente 'e'Ucedere exp(1)altrimenti avrei potuto sbarazzarmi delle 4Y2cose
— Suever

Un'altra di quelle cose di Ottava ...
— Luis Mendo,

4

JavaScript (ES6), 51 byte

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 viene utilizzato per memorizzare le cifre sostituite per gestire le cifre che si riferiscono ad altre cifre.


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

3

Perl 5 , 34 byte

33 byte di codice + -pflag.

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

Provalo online!

s/\d/.../esostituire la prima cifra ...valutata come codice Perl. (con l' ...essere substr$_,-$&-1+pos,1in quel caso. substr$_,-$&-1+pos,1restituisce la sottostringa della $_lunghezza 1all'indice -$&-1+pos, dove $&è il numero appena abbinato, ed posè l'indice dell'inizio della partita. Dobbiamo solo fare in modo redoche la sostituzione abbia avuto successo per sostituire ogni cifra. (e il risultato è implicitamente stampato grazie alla -pbandiera).


Vecchio approccio, 47 byte:

44 byte di codice + -Fflag.

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

Provalo online!

Abbastanza diretto in realtà. -Fflag divide gli input di ciascun personaggio in @F. map{...}@Fscorre attraverso @F(cioè ogni carattere dell'input). Se il carattere è una cifra ( /\d/), lo sostituiamo con il carattere all'indice $i-$_-1. La $iè la variabile indice corrente (che effettuiamo incrementando ogni carattere visto).


3

JavaScript ES6, 61 59 byte

Grazie @Luke per il golf di 8 byte

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

Provalo online!


x.split``potrebbe anche essere [...x], [0-9]potrebbe essere \d, insieme risparmiando 6B
— Luca

Attualmente ha un errore da qualche parte quindi risolverlo per primo
— fəˈnɛtɪk

x=>[...x].map((p,i,a)=>+p+1?a[i-1-p]:p).join``per 46 byte
— Luca

Non riesce per gli spazi + "" dà 0 che gli fa afferrare il personaggio precedente
— fəˈnɛtɪk

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

3

05AB1E , 27 17 byte

vyDdiU)DRXèU`X}}J

Provalo 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 byte

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

Demo online.

Questa soluzione utilizza l'operatore incorporato "copia n -esimo elemento nello stack" di CJam $per implementare la decodifica. Inizia leggendo l'input (con q), quindi eseguendo il ciclo sopra i caratteri dalla stringa di input e scaricandoli nello stack (con {}/). Tuttavia, all'interno del corpo del loop, duplica anche ogni personaggio dopo che è stato messo in pila (con _) e controlla se è una cifra osservando la sua posizione con #nella stringa "0123456789", convenientemente rappresentata come A,s.

Il risultato di questa ricerca è il valore numerico della cifra o, se il carattere non è una cifra, -1. L' )operatore quindi incrementa quel valore di uno e lo $sostituisce con il carattere corrente in quelle posizioni sotto la parte superiore della pila. Infine, \;rimuove solo la copia del carattere di input corrente che abbiamo creato _dallo stack, poiché non è più necessario.


2

Befunge-98 , 45 43 byte

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

Provalo online!

L'idea:

  1. Per ogni carattere nella stringa di input,
    1. Scrivilo alla riga 2
    2. Se non è un numero, basta emetterlo
    3. In caso contrario, cercare il valore corretto, riscriverlo, quindi emetterlo
::::            ; 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 ;

Non sono riuscito a ridurre questa versione, ma questa è di 44 byte:

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

Ho pensato di condividerla a causa del trucco accurato con s- ma la memorizzazione del contatore in pila porta a quel miglioramento di 1 carattere



2

Python 2, 75 71 byte

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

Provalo online!

Modifica: risolto per valori ASCII compresi tra 32 e 47 ; Risolto per doppia decodifica (es. "Alp2c1" in "alpaca")


1
@Arnauld Nope. Mi dispiace, non ho letto abbastanza attentamente le specifiche. A breve cambierò
— drogato di matematica il

Sembra che ci sia un bug. per 'Prog2am0in6 Puz0les7&1Cod74G4lf'le stampe del tuo programma Programming Puzzles &7Code1Golf! Ho provato con entrambi i link TIO condivisi!
— Keerthana Prabhakaran,

@KeerthanaPrabhakaran Grazie! Risolto al costo di 0 byte! (La mia soluzione alternativa non ha fatto il taglio però)
— drogato di matematica il

Questo è un ottimo approccio!
— Keerthana Prabhakaran,

Puoi spiegare '/' <i <':'. So che sta testando se è un numero, ma come funziona?
— Matias K

2

PHP 7.1 67 59 byte

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

Riceve input da STDIN; esegui come pipe -nRo provalo online .

  • _&$c=$s[$i++]loop through string ( _&$csi tradurrà in qualcosa che non lo è "0"; quindi l'unico carattere che può interrompere il loop è la stringa vuota = fine dell'input)
  • $c^"0" attiva / disattiva i bit 5 e 6 nel codice ascii
  • <"\n" controlla se il risultato è <chr (10)
  • in tal caso, è una cifra: stampa il carattere precedente per indice (e copia nell'indice corrente)
  • altrimenti stampa questo personaggio

Grazie @Christoph per aver risparmiato il 12%


1
So che questa è una vecchia risposta ma: offset di stringa negativi! (e quello $s=$argn...?)for(;_&$c=$argn[$i++];)$t.=($c^"0")<"\n"?$t[~+$c]:$c;echo$t;
— Christoph,

2

Vim macro / sequenze di tasti, 49 byte

^M rappresenta il carattere di ritorno (0x0A, 1 byte).

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

Spiegazione

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 byte

-2 byte grazie a @FrownyFrog

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

Provalo online!

usi ⎕io←1

(di ⍵seguito indica un valore intermedio nella valutazione)

⎕d è la stringa '0123456789'

⎕d⍳⍵trova gli indici (basati su 1 in questo caso) dei ⍵caratteri in ⎕d; per una non cifra l'indice è 11

11|⍵ è modulo - gli 11 diventano 0

≢⍵ è la lunghezza di ⍵

⍳≢⍵è 1 2 ...fino a≢⍵

quindi, (⍳≢⍵)-11|⎕d⍳⍵ci fornisce un vettore i degli indici in cui dovremmo cercare di ottenere i caratteri risultanti; tuttavia alcuni di questi indici possono reindirizzare verso altri (più piccoli) indici. Per calcolare la chiusura transitiva (cioè gli indici effettivi), indicizziamo il vettore in se stesso ( ⊂⌷⊢, un treno equivalente a (⊂i)⌷io i[i]) e lo ripetiamo fino a quando non si stabilizza ( ⍣≡è noto come operatore a punto fisso ).

infine indicizziamo nella stringa originale: (...)⊃¨⊂


Come sarebbe un treno?
— FrownyFrog,

@FrownyFrog infatti, più breve
— ngn


1

Japt , 24 byte

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

Provalo online!

Spiegazione:

£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 byte

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

Questa è essenzialmente una porta della mia risposta Jelly, oltre al controllo delle cifre dalla risposta Python di @ xnor.

Provalo online!



1

JavaScript ES6, 54 byte

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
Benvenuti in PPCG! Se non è necessario il nome della funzione per le chiamate ricorsive, le funzioni senza nome sono valide, quindi è possibile salvare due byte sul f=.
— Martin Ender,

1

> <> (Pesce), 108 byte (= griglia 9 x 12)

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

Provalo qui per vedere il pesce che nuota intorno.

  • Aggiungi -1 allo stack di input, quindi inverti lo stack.
  • Ciclo: se il valore massimo è -1, quindi fine (abbiamo passato in rassegna tutti i caratteri). Altrimenti:
  • Inserisci il carattere principale nel registro; controlla se è compreso nell'intervallo da "0" a "9". Se è così:
    • ruotare la pila del numero appropriato di posizioni
    • ottenere il personaggio indicato
    • ruotare indietro e sostituire il numero con il carattere dal registro
  • Produzione; riprendere il ciclo.

1

8086 codice macchina, 35 byte

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 byte

r\d@=hYUgY-°X¹gY

Provalo


Spiegazione

                     :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 byte

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

Provalo 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

Ringraziamo ngn per l'ispirazione.

22 byte

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

Questa è una porta della risposta 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.

In entrambe le soluzioni la versione che TIO utilizza interpreta un singolo .come il numero 0, quindi l'ultimo test ha esito negativo. Le versioni precedenti (≤7) sembrano funzionare correttamente.

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.