Decifrare Neurotic Frogs


28

Decifrare Neurotic Frogs

Ora che Puzzling.SE ha finalmente violato il mio codice ossessionato dagli anfibi , scriviamo un programma o una funzione per decifrarlo!

(Se vuoi guardare il puzzle prima di averlo viziato, fai clic sul link sopra ora).


Come funziona la cifra

In nevrotica Rane O effettuato l 'acquisto Per Rel una x in M ud Bagni ( "Neurotic Rane" per brevità), ogni lettera è crittografato come uno o due parole:

  • La lunghezza di una parola non in corsivo rappresenta una lettera.
    • neurotic => 8 lettere => H
    • frogs => 5 lettere => E
    • perpendicular => 13 lettere = M
  • Una parola che contiene corsivo modifica la parola seguente, aggiungendo 10 se la parola in corsivo era di lunghezza dispari o 20 se la parola in corsivo era di lunghezza pari. Qualsiasi parola o parte di essa può essere in corsivo. Una parola in corsivo è sempre seguita da una parola non in corsivo.
    • *o*ught to => dispari, 2 => 12 => L
    • lo*u*nging calms => pari, 5 => 25 => Y

Ogni parola di testo in chiaro corrisponde a una frase di testo cifrato e ogni frase di testo in chiaro corrisponde a un paragrafo di testo cifrato.

Formato di input

Il tuo programma o funzione deve inserire un messaggio in Neurotic Frogs, formattato in Markdown. L'input consisterà solo di ASCII e newline stampabili.

  • Le parole sono sequenze di caratteri che corrispondono alla regex [A-Za-z0-9'].
    • Numeri e lettere contano entrambi per la lunghezza di una parola. QB64rappresenta D.
    • NOTA: gli apostrofi non contano per la lunghezza di una parola. Isn'trappresenta D, no E.
  • Le lettere in corsivo sono racchiuse in una coppia di asterischi ( *letters*).
    • Una o più lettere consecutive possono essere in corsivo, fino a un'intera parola ( masseus*es*, *all*); più lettere non consecutive in una parola possono anche essere in corsivo ( g*e*n*e*rates).
    • Il corsivo non comprende mai più parole, non include mai la punteggiatura e non include mai apostrofi.
    • Non si verificheranno mai asterischi spaiati e asterischi multipli adiacenti.
  • La punteggiatura è uno dei seguenti caratteri: .,?!:;-()".
    • Le parole all'interno di una frase sono separate da uno o più caratteri di punteggiatura e / o un singolo spazio. Esempi: *all* welcomed, toad*s*, newts, Ever*y*one--frogs, cap... bliss,they're (I
    • Le frasi terminano con uno o più caratteri di punteggiatura e sono separate da un doppio spazio: Th*e* Montgomery A*m*phibian Salon! Come luxuriate today!
    • I paragrafi sono separati da un'unica riga. (L'ultima frase di un paragrafo ha ancora uno o più caratteri di punteggiatura alla fine.)

Altri caratteri non verranno visualizzati nell'input e non è necessario gestirli.

Il tuo codice può, a tua discrezione, prevedere che l'input abbia una sola nuova riga finale.

Formato di output

Il risultato della decodifica dell'input sarà una o più frasi. Le lettere di testo in chiaro possono essere qualsiasi combinazione di lettere maiuscole e minuscole. Le parole all'interno di una frase devono essere separate da spazi singoli. Le frasi devono terminare con un punto ( .) ed essere separate da un singolo spazio. È possibile generare uno spazio finale dopo l'ultima frase. Il tuo output sarà tutto su una riga, ma potresti generare una nuova riga finale.

Dettagli vari

Il codice può utilizzare uno dei metodi di input e output standard. Deve ricevere input come una stringa multilinea, non un elenco o altra struttura di dati e deve generare una stringa.

Vince il codice più breve in byte!

Casi test

-->
Neurotic Frogs *O*ught To Rel*a*x In *M*ud Baths!
<--
HELLO.

-->
Business standards all*o*w only *adult* amphibians.
<--
HINT.

-->
Rejoice, *a*ll frogs an*d* toads also!  Montgomery Sal*o*n opens up!  Ha*pp*y throng fill*s* street ecstatically!
<--
GOOD JOB PPL.

-->
I like 3.1415926535897.
IM*O*, it's a *b*la*st*, yeah!
<--
ADAM. MAN.

-->
*I*, happily, *th*anks 2 u *e*ditin*g* specific wor*ding*--clarifying a *bit*--betterment :D!
<--
QUARTATA.

-->
Perpendicular l*ou*nging calms.  *A* frog, a m*u*d cap... bliss!  Wallowing g*e*n*e*rates happiness.  Amphibian sp*a* isn't expensive--seventy d*o*llars--cheap!  That'*s* not *a* large e*x*pens*e* from an*y* discerning fr*o*g's money, unlik*e* Super 8.
Ever*y*one--frogs, toad*s*, newts, *a*nd salamanders!  G*e*t a wonderful shiat*s*u, or recei*v*e an other kind.  Masseus*es* are her*e* today!  Invite a fianc*e*e, supervisor, roommate, niece: *all* welcomed!
Y*o*u simply ne*v*er believed these p*o*ssibilitie*s*; they're (I *swear*) absolute truth!  Th*e* Montgomery A*m*phibian Salon!  Come luxuriate today!
<--
MY NAME IS INIGO MONTOYA. YOU KILLED MY FATHER. PREPARE TO DIE.

4
+1 per l'ingresso della sposa principessa. Oh, e anche per la tua abilità.
Magic Octopus Urn,

È garantito che una parola contenente corsivo sia seguita da una non contenente corsivo?
R. Kap,

@ R.Kap Correct. Ho modificato la domanda per chiarirlo.
DLosc,

Risposte:


5

Perl, 72 byte

#!perl -n
$x=/\*/?2-y/'//c%2:!print/ /?$':chr$x.0+y/'//c+64for/[\w*']+|  /g,' . '

Contando lo shebang come uno, l'input è preso dallo stdin.

Esempio di utilizzo

$ more in.dat
Neurotic Frogs *O*ught To Rel*a*x In *M*ud Baths!
Perpendicular l*ou*nging calms.  *A* frog, a m*u*d cap... bliss!  Wallowing g*e*n*e*rates happiness.  Amphibian sp*a* isn't expensive--seventy d*o*llars--cheap!  That'*s* not *a* large e*x*pens*e* from an*y* discerning fr*o*g's money, unlik*e* Super 8.
Ever*y*one--frogs, toad*s*, newts, *a*nd salamanders!  G*e*t a wonderful shiat*s*u, or recei*v*e an other kind.  Masseus*es* are her*e* today!  Invite a fianc*e*e, supervisor, roommate, niece: *all* welcomed!
Y*o*u simply ne*v*er believed these p*o*ssibilitie*s*; they're (I *swear*) absolute truth!  Th*e* Montgomery A*m*phibian Salon!  Come luxuriate today!

$ perl neurotic-frogs.pl < in.dat
HELLO. MY NAME IS INIGO MONTOYA. YOU KILLED MY FATHER. PREPARE TO DIE.

1
Sto assegnando la generosità a questa risposta, poiché è la più breve alla fine del periodo di ricompensa oltre alla mia (in effetti, l'unica che è arrivata da nessuna parte).
DLosc,

4

JavaScript (ES6), 172 169 157 150 byte

10 byte salvati grazie a @Neil

x=>x.match(/[\w'*]+|\s+/g).map(y=>y[0]==" "?y[1]:y==`
`?". ":/\*/.test(y,l+=y.match(/\w/g).length)?(l=l%2*10+19,""):l.toString(36,l=9),l=9).join``+"."

Probabilmente può essere ulteriormente migliorato. Uscite in minuscolo.


Salvare 2 byte spostando i=0in toString.
Neil,

Per interesse, ho provato a sistemare quei bug e ho x=>x.replace(/([\w*']+)[^\w\n*' ]* ?( ?)/g,(_,y,z)=>/\*/.test(y,l=y.replace(/'/g ,"").length)?(i=l%2||2,""):l+i*10+9).toString(36,i=0)+z,i=0).replace(/\n|$/g,". ")
Neil,

Sembra funzionare nella sua forma attuale.
primo

@ Grazie Grazie. Ciò consente di risparmiare 12 byte, ma non funziona sull'ultimo caso di test. Correzione che aggiunge 9 per un accorciamento netto di 3 byte.
ETHproductions

@Neil Sbarazzarsi di .replacee solo usando .matchsalvato altri 12 byte.
ETHproductions

3

Python 2, 238 221 218 214 207 205 byte

from re import*
def f(x):
 d='';m=0
 for w in split(r"[^\w\d*'~\n]+",sub('  ','~',x))[:-1]:l=len(sub("[*'~\n]",'',w));q='*'in w;d+='. '[w[0]>'}':]*(w[0]in'~\n')+chr(64+l+m)[q:];m=(2-l%2)*10*q
 print d+'.'

Utilizza un sacco di regex per eseguire l'elaborazione. Trasformiamo il doppio spazio in ~e lo usiamo per elaborarlo. ~e \nsono gestiti appositamente.

Il maggior guadagno di carattere deriva dalla preelaborazione dell'input nella forriga; questo può sicuramente essere ulteriormente giocato a golf.

Ideone esso! (tutti i casi di test)

Risparmiato 7 byte grazie a DLosc!


3

Pip , 65 64 byte

Il punteggio è di 62 byte di codice + 2 per le -rsbandiere.

Flg{O{{(zy*t+#a-1)X!Y'*Na&2-#a%2}MJa@`[\w*]+`}MlRM''^sX2O". "}

Provalo online!

Spiegazione

La -rbandiera legge tutte le linee di stdin e ne memorizza un elenco g. Il -sflag imposta il formato di output degli elenchi su spazio separato.

Il modo più semplice per leggere questo codice è dall'esterno in:

Flg{...}                   For each line l in g, do:

O{...}MlRM''^sX2O". "      Translate a paragraph into a sentence of plaintext:
       lRM''               Remove apostrophe characters
            ^sX2           Split on "  " into sentences
 {...}M                    Map the below function to each sentence
O                          Output the result list, space-separated, without newline
                O". "      Output that string, without newline

{...}MJa@`[\w*]+`          Translate a sentence into a word of plaintext:
       a@`[\w*]+`          Find all matches of regex (runs of alphanumeric and *)
{...}MJ                    Map the below function to each word and join into string

(zy*t+#a-1)X!Y'*Na&2-#a%2  Translate a word into a letter of plaintext:
      #a-1                 Length of word minus 1
  y*t+                     Add 10 or 20 if y is set (see below)
(z        )                Use that number to index into lowercase alphabet
              '*Na&        Count * characters in word, logical AND with...
                   2-#a%2  2 if word is even length, 1 if odd
             Y             Yank that value into y, to modify the following word
           X!              String multiply the character by not(y)
                           If y is truthy, the word had italics, and we get ""
                           If y is falsy, the word had no italics, and we get a letter

Sembra imbattibile.
primo

1

Python 2.7, 390 342 341 339 335 byte:

from re import*
def F(i):
 W=X="";S,s=split,sub;D='[^\w\s*]';Q=lambda c,t:len(s(D,X,c.group()).split()[t])
 for m in S('\W\n',s(D+"*\w*\*\w+\*.*?(?=\s) \w+",lambda v:"a"*([20,10][Q(v,0)%2]+Q(v,1)),s("'",X,s("--"," ",i)))):
  for g in S('\W  ',m):
   for q in S('\W',g):
    W+=chr(64+len(q))
   W+=" "
  W=W[:-1]+". "
 print s("@",X,W)

Accetta input nel formato:

F('''Multi or Single-lined String''')

Può essere giocato molto di più, cosa che farò ogni volta che ne avrò la possibilità.

Repl.it con tutti i casi di test!

Spiegazione:

Utilizza l'immenso potere dei built-in di espressioni regolari di Python per decifrare l'input. Questo è il processo fondamentale che la funzione attraversa per ogni input:

  1. Innanzitutto, tutti --vengono sostituiti con un singolo spazio e ogni apostrofo viene rimosso. Quindi, tutte le parole che contengono componenti in corsivo e la parola che la procede sono entrambe abbinate in una stringa e sostituite con il 10 + len(second word)numero di as consecutivi se la lunghezza della prima parola è odd, e s 20 + len(second word)consecutivi in ​​caso acontrario. Questo utilizza la seguente espressione regolare:

    [^\w\s*]*\w*\*\w+\*.*?(?=\s) \w+

    Ad esempio, se abbiamo la frase Perpendicular l*ou*nging calms., l*ou*nging calmsverrà sostituita con aaaaaaaaaaaaaaaaaaaaaaaaa, o 25 as, poiché l*ou*ngingha un numero pari di caratteri e calmsha 5 20+5=25..

  2. Ora, l'input appena modificato viene diviso in corrispondenza di ciascun segno di punteggiatura seguito da una nuova riga ( \n) per ottenere i paragrafi, quindi ogni paragrafo viene suddiviso in corrispondenza di ogni punteggiatura seguito da 2 spazi per ottenere le frasi e, infine, ogni frase viene suddivisa in parole lungo qualsiasi punteggiatura compreso uno spazio. Quindi, per ogni parola (comprese le serie di as consecutivi ), aggiungiamo a una stringa Wla lettera corrispondente al punto di codice unicode 64(il punto di codice unicode del carattere precedente A, che è @) più len(word). Aggiungiamo quindi un singolo spazio Wuna volta esaurite tutte le parole di una frase e quando tutte le frasi in un paragrafo sono esaurite, aggiungiamo un .seguito da un singolo spazio.

  3. Alla fine, dopo che l'intero input è stato passato, Wviene emesso stdoutcome messaggio decifrato.


Minore nitpick: la specifica dice che le frasi di output sono separate da uno spazio singolo, non doppio (questa modifica salva anche un byte). Suggerimento iniziale per il golf: poiché stai importando tutto da re, usa subinvece di str.replace. Suggerimenti golfistici più generali: è probabilmente più efficace trattare tutto ciò che non è una parola o *come punteggiatura. Risparmia su grandi classi di personaggi enormi.
DLosc,

@DLosc Oh, mio ​​male. Ho pensato che la specifica fosse di separare le frasi nell'output di 2 spazi. Lo aggiusterò. Inoltre, grazie per i suggerimenti sul golf! Vedrò cosa posso fare con quelli.
R. Kap,

1

PHP, 196 byte

<?preg_match_all("#[\w*']+|  |$#m",$_GET[s],$m);foreach($m[0]as$s){if(!$s||$s=="  ")echo!$s?". ":" ";else{$l=$p+64+strlen(str_replace("'","",$s));if(!$p=strstr($s,"*")?20-$l%2*10:0)echo chr($l);}}

Se potessi supporre che ci sia un solo apostrofo nel mezzo di una parola 194 byte

<?preg_match_all("#[\w*]+(<?=')[\w*]+|[\w*]+|  |$#m",$_GET[s],$m);foreach($m[0]as$s){if(!$s||$s=="  ")echo!$s?". ":" ";else{$l=$p+64+strlen($s);if(!$p=strstr($s,"*")?20-$l%2*10:0)echo chr($l);}}

@DLosc È stato urlencodificato %0A come funzione rawurlencode("\n"). Preferisco in questo caso un modulo con una textarea per l'input e quindi il mio sito html rende automaticamente codificare la stringa
Jörg Hülsermann

@DLosc Ho il sospetto che error_reporting in php.ini sia attivo. prova 'error_reporting (0);' dopo il <?. Un errore appartiene a $_GET[s]esso funziona, ma è corretto $_GET["s"]ed è meglio dichiarare e inizializzare la variabile $p=0;prima del ciclo. Ora la mia domanda è: posso supporre che in una Parola c'è solo un apostrofo nel mezzo della Parola?
Jörg Hülsermann,

@DLosc per più apostrofi devo usare la mia prima risposta. Il secondo - 2 byte funziona solo con un apostrofo nel mezzo se la parola.
Jörg Hülsermann,

Ho capito quale fosse il mio problema: il mio server non ha tag di apertura brevi abilitati. Passando al lavoro <?php.
DLosc,

@Dlosc non l'ho mai usato <?in realtà. Uso il tag breve solo nel mio post qui. Ora so che può essere ripristinato in una pagina vuota.
Jörg Hülsermann,

1

PHP, 231 226 228 byte

per iniziare

<?preg_match_all("#([\w\*']+)([^\w\*']*)#",$argv[1],$m,2);foreach($m as list(,$a,$b)){$e=strlen(strtr($a,["'"=>""]))+$d;if(!$d=strstr($a,'*')?$e%2*10:0)echo chr($e+64),strpos(".$b","
")?". ":(strpos(".$b","  ")?" ":"");}echo".";

Salva su file, rund php <scriptpath> <text>. Sfuggire alle nuove righe nel testo per farlo funzionare nella shell.


1
Puoi darmi alcune istruzioni su come eseguire questo? Sembra che legga l'input da $argv[1], ma non so come funzionerà quell'approccio quando l'input contiene nuove righe. Ho provato "Neurotic Frogs *O*ught To Re*a*x In *M*ud Baths!"come argomento da riga di comando e ho ottenuto l' IFHCHCFF.output (nonché un Undefined variable: davviso).
DLosc,

@DLosc: quell'avviso (non un avviso) non dovrebbe essere presente con le impostazioni predefinite. Il modo più semplice è anteporre <?, salvarlo in un file e chiamarlo con php <filename> <string>. Potrei dover aggiungere 2 al conteggio dei byte.
Tito,

@Titus Se inizi con <?, puoi anche finire con ?>., per un guadagno netto per 1. FWIW, ottengo IFHCMFF.per il primo caso di test (usando PHP 5.5.21 64-bit, VC14). L'uso $argncon -Fpuò anche essere un'opzione.
primo

Quello che voglio dire è che non vedo come php <filename> <string>sia possibile quando <string>può contenere newline.
DLosc,

@DLosc: corretto il bug. Per le nuove linee: sfuggirle.
Tito,
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.