Facciamo un po 'di "enciph5r47g"


35

Questo è l'inverso di Let's do some "deciph4r4ng"


In questa sfida, il tuo compito è crittografare una stringa. Fortunatamente, l'algoritmo è piuttosto semplice: leggendo da sinistra a destra, ogni tipico carattere di scrittura (intervallo ASCII 32-126) deve essere sostituito da un numero N (0-9) per indicare che è uguale al carattere N + 1 posizioni prima di esso. L'eccezione è quando il carattere non appare nelle precedenti 10 posizioni nella stringa originale. In tal caso, dovresti semplicemente stampare nuovamente il personaggio. In effetti, dovresti essere in grado di invertire l'operazione dalla sfida originale.

Esempio

La stringa di input "Programming"verrebbe codificata in questo modo:

Esempio 1

Quindi, l'output previsto è "Prog2am0in6".

Chiarimenti e regole

  • La stringa di input conterrà esclusivamente caratteri ASCII nell'intervallo 32-126. Puoi presumere che non sarà mai vuoto.
  • La stringa originale è garantita per non contenere alcuna cifra.
  • Una volta che un personaggio è stato codificato, può a sua volta fare riferimento a una cifra successiva. Ad esempio, "alpaca"dovrebbe essere codificato come "alp2c1".
  • 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 : aaaa
Output: a000

Input : banana
Output: ban111

Input : Hello World!
Output: Hel0o W2r5d!

Input : this is a test
Output: this 222a19e52

Input : golfing is good for you
Output: golfin5 3s24o0d4f3r3y3u

Input : Programming Puzzles & Code Golf
Output: Prog2am0in6 Puz0les7&1Cod74G4lf

Input : Replicants are like any other machine. They're either a benefit or a hazard.
Output: Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d.

6
Vedo che i tuoi casi di test utilizzano sempre la cifra più bassa possibile per qualsiasi sostituzione. È un comportamento richiesto o possiamo usare anche cifre più alte, quando esiste più di una possibilità?
Leo,

@Leo Puoi usare qualsiasi cifra che vuoi 0-9 fintanto che è valida.
Ingegnere Toast,

È come un encoder da spostare in avanti , tranne senza lo spostamento :)
pipe

Risposte:


6

05AB1E , 20 19 18 byte

-2 Grazie a Emigna

õ¹vDyåiDykëy}?yìT£

Provalo online!

õ                  # Push an empty string
 ¹v y              # For each character in input
   D               # Duplicate the string on the stack (call this S)
     åi            # If this character is in S
       Dyk         #   Push the index of that that character 
          ë }      # Else
           y       #   Push the character 
             ?     # Print without newline
              yì   # Prepend this character to S
                T£ # Remove all but the first 10 elements from S

Penso che )¹vDyåiDykëy}?y¸ìT£funzioni anche.
Emigna,

In realtà, combinando la tua risposta con la mia si ottiene õIvDyåiDykëy}?yìT£per 18 :)
Emigna,

@Emigna Sentiti libero di aggiornare il tuo :) :)
Riley

Non ci avrei pensato se non fosse per la tua risposta, quindi dovresti averlo. Buon lavoro!
Emigna,

@Emigna Immagino sia giusto. Grazie!
Riley,

12

Retina , 24 23 byte

(.)(?<=\1(.{0,9}).)
$.2

Provalo online!

Una sostituzione regex abbastanza semplice. Abbiniamo ogni personaggio e proviamo a trovarne una copia di 0-9 caratteri prima di esso. Se lo troviamo, sostituiamo il personaggio con il numero di caratteri che dovevamo abbinare per arrivare alla copia.

I risultati non corrispondono esattamente ai casi di test, perché questo utilizza la cifra più grande possibile anziché la più piccola possibile.


4
Look-behind a lunghezza variabile è barare: p
Dada,

8
@Dada Lookbehind di lunghezza variabile è la via dell'illuminazione.
Martin Ender,

Purtroppo è ... Se sei annoiato, sentiti libero di implementarli all'interno di Perl!
Dada,

Secondo il commento del PO sull'attività originale, "Puoi usare qualsiasi singola cifra che vuoi 0-9 fintanto che è valida." ... quindi il più grande possibile dovrebbe essere valido
Doktor J

@DoktorJ sì, l'ho cambiato dopo che l'OP ha aggiunto questo chiarimento.
Martin Ender,

8

JavaScript (ES6), 74 57 54 byte

Salvato 3 byte grazie a ETHproductions con il brillante p=/./ganziché p={}(ispirato a Neil)

s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-11?~i:c)

Casi test


Dato che la stringa è garantita per non contenere una cifra, puoi usare sinvece di p?
Neil,

(Sono stato in grado di superare la tua findversione originale usando lastIndexOf, il che è leggermente sorprendente dato che è lungo 11 lettere ....)
Neil

@Neil non sono davanti a un computer in questo momento ma non penso che funzionerebbe dal momento che le stringhe JS sono immutabili.
Arnauld,

2
Posso confermare che l'impostazione delle proprietà sui valori letterali delle stringhe non funziona. Ma ... sembra che funzioni con regex, quindi penso che potresti farlo s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-10?~i:c)per salvare 3 byte.
ETHproductions

1
@YOU Non so davvero cosa sia successo qui, ma risulta che ho introdotto un bug per tutti i browser nella mia ultima modifica. Questo è stato risolto. Grazie per averlo notato!
Arnauld,

7

Haskell , 72 66 byte

Grazie a Laikoni per il golf 6 byte!

(a:r)%s=last(a:[n|(n,b)<-zip['0'..'9']s,b==a]):r%(a:s)
e%s=e
(%"")

Provalo online!

La funzione %mantiene inversa la stringa parzialmente elaborata nel secondo argomento, quindi è in grado di cercare i primi 10 elementi di questa stringa per individuare le occorrenze del personaggio che sta esaminando. L'invio è costituito dalla funzione senza nome (%"")che chiama la funzione precedente con la stringa vuota come secondo argomento.


f(a:s)=f s++(last$[a]:[show n|(n,b)<-zip[0..9]s,b==a])salva due byte.
Laikoni,

Aspetta, f(a:s)=f s++[last$a:[n|(n,b)<-zip['0'..'9']s,b==a]]risparmia ancora di più.
Laikoni,

L'inversione in movimento invece di utilizzare reverseconsente di salvare un ulteriore byte: provalo online!
Laikoni,

@Laikoni Grazie, è meraviglioso!
Leo


3

Perl 5 , 36 byte

35 byte di codice + -pflag.

s/(\D)(.{0,9})\K\1/length$2/e&&redo

Provalo online!

Alcune spiegazioni:
l'obiettivo è quello di sostituire un carattere senza cifre ( \Dma corrisponde al riferimento indietro \1nel mio regex) che è preceduto da meno di 10 caratteri ( .{0,9}) e lo stesso carattere ( (\D)... \1) dalla lunghezza del .{0,9}gruppo ( length$2). E redomentre i personaggi vengono sostituiti.


apparentemente .*non è richiesto, nessun carattere valido nell'intervallo prima che la cifra sostituita sia ok.
Colsw,

@ConnorLSW Sì, ho appena visto quell'aggiornamento della sfida e ho modificato la mia risposta, grazie per averlo sottolineato.
Dada,

3

Python 2, 89 84 byte

m=input()[::-1];j=1;t=''
for i in m:s=m[j:].find(i);t=[i,`s`][0<s<10]+t;j+=1
print t

Provalo online!

Scorre la stringa al contrario e crea una nuova stringa con i numeri corretti inseriti.


3

Japt , 18 byte

£¯Y w bX s r"..+"X

Provalo online!

Spiegazione

£   ¯  Y w bX s r"..+"X
mXY{s0,Y w bX s r"..+"X}
                          // Implicit: U = input string
mXY{                   }  // Replace each char X and index Y in U by this function:
    s0,Y                  //   Take U.slice(0,Y), the part of U before this char.
         w bX             //   Reverse, and find the first index of X in the result.
                          //   This gives how far back this char last appeared, -1 if never.
              s           //   Convert the result to a string.
                r"..+"X   //   Replace all matches of /..+/ in the result with X.
                          //   If the index is -1 or greater than 9, this will revert to X.
                          // Implicit: output result of last expression


2

05AB1E , 20 byte

õIv¹N£RT£©yåi®ykëy}J

Provalo online!

Spiegazione

õ                     # push an empty string
 Iv                   # for each [index,char] [N,y] in input
   ¹N£                # push the first N characters of input
      R               # reverse
       T£             # take the first 10 characters of this string
         ©            # save a copy in register
          yåi         # if y is in this string
             ®yk      #   push the index of y in the string in register
                ë     # else 
                 y    #   push y
                  }   # end if
                   J  # join stack as one string

2

Python 3, 125 118 byte

def p(x):print(x,end='')
l={}
for i,c in enumerate(input()):
 if l.get(c,i+9)<i+9:
  p(i-l[c]-1)
 else:
  p(c)
 l[c]=i

Provalo online!


2

C (tcc) , 113 byte

Poiché la funzione crea una copia di una stringa di input, la dimensione massima dell'input è di 98 caratteri (più che sufficiente per adattarsi all'input di test più lungo). Naturalmente, questo può essere modificato in qualsiasi altro valore.

i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j;j=-1;}

Provalo online!

modificare

-15 byte. Grazie Johan du Toit .


Agh! Limita l'input a 98 caratteri e risparmia un byte!
pipe

Bella soluzione ma puoi risparmiare altri 15 byte: i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j,j=-1;}
Johan du Toit,

@JohanduToit Grazie! Ho una domanda. Come funziona esattamente s [i] come condizione del ciclo for? L'ho visto molte volte nelle risposte degli altri su questo sito.
Maxim Mikhaylov,

@Max Lawnboy. Originariamente avevi il seguente: 's [i] ^' \ 0 '' che abbreviazione di 's [i]! =' \ 0 ''. Il carattere '\ 0' letterale è uguale a zero, quindi puoi scriverlo in questo modo: 's [i]! = 0'. L'istruzione if in C verifica solo se il valore viene valutato su zero o diverso da zero, pertanto "! = 0" non è necessario.
Johan du Toit,


2

Java 7, 102 101 byte

void a(char[]a){for(int b=a.length,c;--b>0;)for(c=b;c-->0&c+11>b;)if(a[c]==a[b])a[b]=(char)(b-c+47);}

Provalo online!

-1 byte grazie a Kevin Cruijssen . Mi piace sempre una scusa per usare l'operatore professionale.


Perché il --c>=0? Puoi sostituirlo con c-->0per salvare un byte.
Kevin Cruijssen l'

@KevinCruijssen In qualche modo avevo in testa che avevo bisogno di predecrement altrimenti il ​​calcolo effettivo sarebbe sbagliato ... Bella cattura!
Colpisce l'

1

MATL, 31 30 byte

&=R"X@@f-t10<)l_)t?qV}xGX@)]&h

Provalo su MATL Online!

Spiegazione

        % Implicitly grab input as a string
&=      % Perform element-wise comparison with automatic broadcasting.
R       % Take the upper-triangular part of the matrix and set everything else to zero
"       % For each column in this matrix
X@      % Push the index of the row to the stack
@f      % Find the indices of the 1's in the row. The indices are always sorted in
        % increasing order
-       % Subtract the index of the row. This result in an array that is [..., 0] where
        % there is always a 0 because each letter is equal to itself and then the ...
        % indicates the index distances to the same letters
t10<)   % Discard the index differences that are > 9
l_)     % Grab the next to last index which is going to be the smallest value. If the index
        % array only contains [0], then modular indexing will grab that zero
t?      % See if this is non-zero...
  qV    % Subtract 1 and convert to a string
}       % If there were no previous matching values
  x     % Delete the item from the stack
  GX@)  % Push the current character
]       % End of if statement
&h      % Horizontally concatenate the entire stack
        % Implicit end of for loop and implicit display

Si potrebbe essere un po 'fuori, ma super- non si può dire dove. L'input this is a testproduce this 222a1te52invece di this 222a19e52. Il secondo tnon viene convertito in 9.
ingegnere Toast l'

@EngineerToast Haha grazie. Darò un'occhiata.
Suever,

1

PHP, 104 byte

soluzione diretta

for($i=0;$i<strlen($a=&$argn);$f[$l]=$i++)$a[$i]=is_int($f[$l=$a[$i]])&($c=$i-$f[$l]-1)<10?$c:$l;echo$a;

Soluzioni all'indietro

Versioni online

PHP, 111 byte

for(;++$i<$l=strlen($a=&$argn);)!is_int($t=strrpos($argn,$a[-$i],-$i-1))?:($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

PHP, 112 byte

for(;++$i<$l=strlen($a=&$argn);)if(false!==$t=strrpos($argn,$a[-$i],-$i-1))($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

Versione online


1

REXX, 124 125 byte

a=arg(1)
b=a
do n=1 to length(a)
  m=n-1
  c=substr(a,n,1)
  s=lastpos(c,left(a,m))
  if s>0&m-s<=9 then b=overlay(m-s,b,n)
  end
say b

Potresti essere un po 'fuori. Non conosco REXX ma presumo che l'errore sia nella riga 7 dove ha s<9invece di s<10o s<=9. L'input this is a testproduce this 222a1te52invece di this 222a19e52. Il secondo tnon viene convertito in 9. Provalo online
Ingegnere Toast,

Grazie, è stato uno stupido tentativo di radere via un byte. Il codice è stato corretto
idrougge,

1

C (gcc) , 117 103 byte

i,j;f(char*s){for(i=strlen(s)-1;s[i];i--)for(j=i-1;s[j]&&i-j<11;j--)if(s[i]==s[j]){s[i]=47+i-j;break;}}

Provalo online!

103 byte senza importazione string.h, funziona con avviso. Se questo è contro le regole, lo tirerò

Codice grazioso:

i,j;
f(char *s) {
    // Chomp backwards down the string
    for(i=strlen(s)-1; s[i]; i--)
        // for every char, try to match the previous 10
        for(j=i-1; s[j] && i-j < 11; j--)
            // If there's a match, encode it ('0' + (i-j))
            if (s[i] == s[j]) {
                s[i] = 47+i-j;
                break;
            }
}

modifiche:

  • Modificato da LLVM in gcc per consentire la dichiarazione implicita i, j, l'importazione lib è stata rimossa.
  • Aggiunto wrapper di funzione per conformità

Suggerisci (i=strlen(s);s[--i];)invece di(i=strlen(s)-1;s[i];i--)
ceilingcat il
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.