Déchiffrer les grenouilles névrotiques

28

Déchiffrer les grenouilles névrotiques

Maintenant que Puzzling.SE a finalement déchiffré mon chiffre obsédé par les amphibiens , écrivons un programme ou une fonction pour le déchiffrer!

(Si vous voulez regarder le puzzle avant de l'avoir gâté pour vous, cliquez sur le lien ci-dessus maintenant.)


Comment fonctionne le chiffrement

Dans Neurotic grenouilles O ught Pour Rel un x dans M ud Bains ( « Neurotic grenouilles » pour faire court), chaque lettre est cryptée comme un ou deux mots:

  • La longueur d'un mot non en italique représente une lettre.
    • neurotic => 8 lettres => H
    • frogs => 5 lettres => E
    • perpendicular => 13 lettres = M
  • Un mot qui contient de l'italique modifie le mot suivant, en ajoutant 10 si le mot en italique était de longueur impaire ou 20 si le mot en italique était de même longueur. Tout ou partie du mot peut être en italique. Un mot en italique est toujours suivi d'un mot non en italique.
    • *o*ught to => impair, 2 => 12 => L
    • lo*u*nging calms => pair, 5 => 25 => Y

Chaque mot de texte en clair correspond à une phrase de texte chiffré et chaque phrase de texte en clair correspond à un paragraphe de texte chiffré.

Format d'entrée

Votre programme ou fonction doit entrer un message dans Neurotic Frogs, formaté dans Markdown. L'entrée consistera uniquement en ASCII imprimable et en sauts de ligne.

  • Les mots sont des séquences de caractères qui correspondent à l'expression régulière [A-Za-z0-9'].
    • Les chiffres et les lettres comptent pour la longueur d'un mot. QB64représente D.
    • REMARQUE: les apostrophes ne comptent pas pour la longueur d'un mot. Isn'treprésente D, non E.
  • Les lettres en italique sont entourées d'une paire d'astérisques ( *letters*).
    • Une ou plusieurs lettres consécutives peuvent être en italique, jusqu'à un mot entier ( masseus*es*, *all*); plusieurs lettres non consécutives dans un mot peuvent également être en italique ( g*e*n*e*rates).
    • L'italique ne couvre jamais plusieurs mots, n'inclut jamais la ponctuation et n'inclut jamais les apostrophes.
    • Les astérisques non appariés et plusieurs astérisques adjacents ne se produiront jamais.
  • Ponctuation est l' un des caractères suivants: .,?!:;-()".
    • Les mots d'une phrase sont séparés par un ou plusieurs caractères de ponctuation et / ou un seul espace. Exemples: *all* welcomed, toad*s*, newts, Ever*y*one--frogs, cap... bliss,they're (I
    • Les phrases se terminent par un ou plusieurs caractères de ponctuation et sont séparées par un double espace: Th*e* Montgomery A*m*phibian Salon! Come luxuriate today!
    • Les paragraphes sont séparés par une seule nouvelle ligne. (La dernière phrase d'un paragraphe contient toujours un ou plusieurs caractères de ponctuation.)

Les autres caractères n'apparaîtront pas en entrée et n'ont pas besoin d'être traités.

Votre code peut, à votre discrétion, s'attendre à ce que l'entrée ait une seule nouvelle ligne de fin.

Format de sortie

Le résultat du décryptage de l'entrée sera une ou plusieurs phrases. Les lettres de texte en clair peuvent être n'importe quelle combinaison de majuscules et de minuscules. Les mots d'une phrase doivent être séparés par des espaces simples. Les phrases doivent se terminer par un point ( .) et être séparées par un seul espace. Vous pouvez afficher un espace de fin après la dernière phrase. Votre sortie sera sur une seule ligne, mais vous pouvez sortir une nouvelle ligne de fin.

Détails divers

Votre code peut utiliser n'importe laquelle des méthodes d'entrée et de sortie standard. Il doit recevoir une entrée sous forme de chaîne multiligne, pas une liste ou une autre structure de données, et il doit sortir une chaîne.

Le code le plus court en octets gagne!

Cas de 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.
DLosc
la source
4
+1 pour l'entrée de la mariée princesse. Oh, et pour votre compétence aussi.
Magic Octopus Urn
Est-il garanti qu'un mot contenant des italiques sera suivi d'un mot ne contenant pas d'italiques?
R. Kap
@ R.Kap Correct. J'ai édité la question pour clarifier cela.
DLosc

Réponses:

5

Perl, 72 octets

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

En comptant le shebang comme un, l'entrée provient de stdin.

Exemple d'utilisation

$ 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.
primo
la source
1
J'attribue la prime à cette réponse, car c'est la plus courte à la fin de la période de prime en plus de la mienne (en effet, la seule qui soit arrivée de près).
DLosc
4

JavaScript (ES6), 172 169 157 150 octets

10 octets enregistrés grâce à @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``+"."

Peut probablement être encore amélioré. Sorties en minuscules.

ETHproductions
la source
Économisez 2 octets en déplaçant le i=0dans le toString.
Neil
Par intérêt, j'ai essayé de corriger ces bogues et j'ai trouvé ceci: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
Semble fonctionner dans sa forme actuelle.
primo
@Neil Merci. Cela économise 12 octets, mais cela ne fonctionne pas sur le dernier cas de test. Correction qui ajoute 9 pour un raccourcissement net de 3 octets.
ETHproductions
@Neil Se débarrasser .replaceet simplement utiliser a .matchsauvé encore 12 octets.
ETHproductions
3

Python 2, 238 221 218 214 207 207 205 octets

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

Utilise beaucoup d'expressions régulières pour effectuer le traitement. Nous transformons le double espace en ~et l'utilisons pour le traiter. ~et \nsont manipulés spécialement.

Le gain de caractère le plus important provient du prétraitement de l'entrée dans la forligne; cela peut certainement être joué plus loin.

Ideone it! (tous les cas de test)

7 octets enregistrés grâce à DLosc!

Cuivre
la source
3

Pip , 65 64 octets

Le score est de 62 octets de code + 2 pour les -rsdrapeaux.

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

Essayez-le en ligne!

Explication

Le -rdrapeau lit toutes les lignes de stdin et en stocke une liste g. L' -sindicateur définit le format de sortie des listes à espace séparé.

La façon la plus simple de lire ce code est de l'extérieur dans:

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
DLosc
la source
Semble imbattable.
primo
1

Python 2.7, 390 342 341 339 335 octets:

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)

Prend entrée au format:

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

Peut être joué au golf beaucoup plus, ce que je ferai chaque fois que j'en aurai l'occasion.

Repl.it avec tous les cas de test!

Explication:

Utilise l'immense puissance des expressions régulières de Python intégrées pour déchiffrer l'entrée. Il s'agit du processus fondamental suivi par la fonction pour chaque entrée:

  1. Tout d'abord, tous --sont remplacés par un seul espace et chaque apostrophe est supprimée. Ensuite, tous les mots contenant des composants en italique et le mot qui le précède sont tous deux mis en correspondance dans une chaîne et remplacés par un 10 + len(second word)nombre de as consécutifs si la longueur du premier mot est odd, et 20 + len(second word)des as consécutifs sinon. Cela utilise l'expression régulière suivante:

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

    Par exemple, si nous avons la phrase Perpendicular l*ou*nging calms., l*ou*nging calmssera remplacé par aaaaaaaaaaaaaaaaaaaaaaaaa, ou 25 as, car l*ou*nginga un nombre pair de caractères et en calmsa 5 20+5=25..

  2. Maintenant, l'entrée nouvellement modifiée est divisée à chaque signe de ponctuation suivie d'une nouvelle ligne ( \n) pour obtenir les paragraphes, puis chaque paragraphe est divisé à chaque ponctuation suivi de 2 espaces pour obtenir les phrases, et enfin, chaque phrase est divisée en mots le long toute ponctuation y compris un espace. Ensuite, pour chaque mot (y compris les séquences de as consécutifs ), nous ajoutons à une chaîne Wla lettre correspondant au point de code unicode 64(le point de code unicode du caractère précédent A, qui est @) plus len(word). Nous ajoutons ensuite un espace unique à Wune fois que tous les mots d'une phrase ont été épuisés, et lorsque toutes les phrases d'un paragraphe sont épuisées, nous ajoutons un .suivi d'un espace unique.

  3. Enfin, après que l'intégralité de l'entrée a été effectuée, la Wsortie est transmise en stdouttant que message déchiffré.

R. Kap
la source
Nitpick mineur: la spécification indique que les phrases de sortie sont séparées par un seul espace, et non par deux (ce changement enregistre également un octet). Suggestion initiale de golf: puisque vous importez tout de re, utilisez subplutôt que str.replace. Suggestion plus générale sur le golf: il est probablement plus efficace de traiter tout ce qui n'est pas un mot ou une *ponctuation. Économise sur les grandes classes de personnages énormes.
DLosc
@DLosc Oh, mon mauvais. Je pensais que la spécification était de séparer les phrases dans la sortie par 2 espaces. Je vais arranger ça. Merci aussi pour les suggestions de golf! Je vais voir ce que je peux faire avec ça.
R. Kap
1

PHP, 196 octets

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

Si je pouvais supposer qu'il n'y a qu'une seule apostrophe au milieu d'un mot 194 octets

<?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);}}
Jörg Hülsermann
la source
@DLosc Il a été urlencodé en %0A tant que fonction rawurlencode("\n"). Je préfère dans ce cas un formulaire avec une zone de texte pour l'entrée et donc mon site html le fait automatiquement pour encoder la chaîne
Jörg Hülsermann
@DLosc Je soupçonne que error_reporting dans le php.ini est activé. essayez 'error_reporting (0);' après le <?. Une erreur appartient à $_GET[s]cela fonctionne mais c'est correct $_GET["s"]et il vaut mieux déclarer et initialiser la variable $p=0;avant la boucle. Maintenant, ma question est la suivante: puis-je supposer que dans un mot il n'y a qu'une seule apostrophe au milieu du mot?
Jörg Hülsermann
@DLosc pour plusieurs apostrophes Je dois utiliser ma première réponse. Le second - 2 octets ne fonctionne qu'avec un apostroph au milieu si le mot.
Jörg Hülsermann
J'ai compris quel était mon problème - mon serveur n'a pas de balises d'ouverture courtes activées. Changer pour <?phptravaillé.
DLosc
@Dlosc je n'ai jamais utilisé <?en réalité. J'utilise la balise courte uniquement dans mon message ici. Maintenant, je sais qu'il peut résulter sur une page vierge.
Jörg Hülsermann
1

PHP, 231 226 228 octets

pour un début

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

Enregistrer dans un fichier, rund php <scriptpath> <text>. Échappez aux sauts de ligne dans le texte pour le faire fonctionner en shell.

Titus
la source
1
Pouvez-vous donner des instructions sur la façon de procéder? On dirait qu'il lit les entrées $argv[1], mais je ne sais pas comment cette approche fonctionnera lorsque les entrées contiennent des sauts de ligne. J'ai essayé "Neurotic Frogs *O*ught To Re*a*x In *M*ud Baths!"comme argument de ligne de commande et j'ai obtenu IFHCHCFF.une sortie (ainsi qu'un Undefined variable: davertissement).
DLosc
@DLosc: Cet avis (pas un avertissement) ne devrait pas être là avec les paramètres par défaut. Le moyen le plus simple consiste à ajouter le préfixe <?, à l'enregistrer dans un fichier et à l'appeler avec php <filename> <string>. Je devrai peut-être ajouter 2 au nombre d'octets.
Titus
@Titus Si vous commencez par <?, vous pouvez également terminer avec ?>., pour un gain net pour 1. FWIW, je reçois IFHCMFF.pour le premier cas de test (en utilisant PHP 5.5.21 64 bits, VC14). Utiliser $argnavec -Fpeut également être une option.
primo
Ce que je veux dire, c'est que je ne vois pas comment php <filename> <string>est possible quand <string>peut contenir des nouvelles lignes.
DLosc
@DLosc: correction du bug. Pour les nouvelles lignes: échappez-leur.
Titus