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.