Odszyfruj neurotyczne żaby


28

Odszyfruj neurotyczne żaby

Teraz, gdy Puzzling.SE w końcu złamał mój obsesyjny na punkcie płazów szyfr , napiszmy program lub funkcję, aby go odszyfrować!

(Jeśli chcesz spojrzeć na układankę, zanim zostanie zepsuta, kliknij teraz powyższy link.)


Jak działa szyfr

W Neurotic Frogs O ught Aby Rel x w M ud Wanny ( „Neurotic Żaby” w skrócie), każda litera jest szyfrowana w postaci jednego lub dwóch słów:

  • Długość słowa bez kursywy oznacza literę.
    • neurotic => 8 liter => H
    • frogs => 5 liter => E
    • perpendicular => 13 liter = M
  • Słowo zawierające kursywę modyfikuje następujące słowo, dodając 10, jeśli kursywą było nieparzyste lub 20, jeśli kursywą było parzyste. Dowolne lub wszystkie słowa mogą być pisane kursywą. Po kursie zawsze występuje słowo bez kursywy.
    • *o*ught to => nieparzyste, 2 => 12 => L
    • lo*u*nging calms => parzysty, 5 => 25 => Y

Każde słowo tekstu jawnego odpowiada zdaniu tekstu zaszyfrowanego, a każde zdanie tekstu jawnego odpowiada akapitowi tekstu zaszyfrowanego.

Format wejściowy

Twój program lub funkcja powinna wprowadzić komunikat w Neurotic Frogs, sformatowany w Markdown. Dane wejściowe będą składały się wyłącznie z drukowalnego ASCII i nowego wiersza.

  • Słowa to ciągi znaków pasujące do wyrażenia regularnego [A-Za-z0-9'].
    • Liczby i litery liczą się do długości słowa. QB64reprezentuje D.
    • UWAGA: Apostrofy nie liczą się do długości słowa. Isn'treprezentuje Dnie E.
  • Litery kursywą są zawinięte w parę gwiazdek ( *letters*).
    • Jedna lub więcej kolejnych liter może być pisanych kursywą, aż do całego słowa ( masseus*es*, *all*); wiele nie następujących po sobie liter w słowie może być również kursywą ( g*e*n*e*rates).
    • Kursywa nigdy nie obejmuje wielu słów, nigdy nie zawiera interpunkcji i nigdy nie zawiera apostrofów.
    • Niesparowane gwiazdki i wiele sąsiadujących gwiazdek nigdy nie wystąpią.
  • Interpunkcyjny jest którykolwiek z następujących znaków: .,?!:;-()".
    • Słowa w zdaniu są oddzielone jednym lub kilkoma znakami interpunkcyjnymi i / lub pojedynczym odstępem. Przykłady: *all* welcomed, toad*s*, newts, Ever*y*one--frogs, cap... bliss,they're (I
    • Zdania kończą się jedną lub kilkoma znakami interpunkcyjnymi i są oddzielone podwójną spacją: Th*e* Montgomery A*m*phibian Salon! Come luxuriate today!
    • Akapity są oddzielone pojedynczym znakiem nowej linii. (Ostatnie zdanie akapitu wciąż ma jeden lub więcej znaków interpunkcyjnych na końcu).

Inne znaki nie pojawią się na wejściu i nie muszą być obsługiwane.

Twój kod może, według własnego uznania, oczekiwać, że dane wejściowe będą miały pojedynczy znak nowej linii.

Format wyjściowy

Rezultatem odszyfrowania danych wejściowych będzie jedno lub więcej zdań. Litery tekstu jawnego mogą być dowolną kombinacją wielkich i małych liter. Słowa w zdaniu muszą być oddzielone pojedynczymi spacjami. Zdania muszą kończyć się kropką ( .) i być oddzielone pojedynczym odstępem. Możesz podać końcowe spacje po ostatnim zdaniu. Twój wynik będzie w jednym wierszu, ale możesz wygenerować końcowy znak nowej linii.

Różne szczegóły

Twój kod może wykorzystywać dowolną standardową metodę wejścia i wyjścia. Musi otrzymywać dane wejściowe w postaci ciągu wielowierszowego, a nie listy lub innej struktury danych, i musi generować ciąg.

Najkrótszy kod w bajtach wygrywa!

Przypadki testowe

-->
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 za wkład księżniczki. Aha, i na twoje umiejętności.
Magic Octopus Urn

Czy po słowie zawierającym kursywę można wstawić słowo, które nie zawiera kursywy?
R. Kap.

@ R.Kap Prawidłowo. Zredagowałem pytanie, aby to wyjaśnić.
DLosc

Odpowiedzi:


5

Perl, 72 bajty

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

Licząc shebang jako jeden, dane wejściowe są pobierane ze standardowego wejścia.

Przykładowe użycie

$ 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
Przyznam nagrodę za tę odpowiedź, ponieważ jest ona najkrótsza pod koniec okresu nagrody oprócz mojej własnej (w rzeczywistości jedyna, która zbliżyła się wszędzie).
DLosc

4

JavaScript (ES6), 172 169 157 150 bajtów

Zaoszczędź 10 bajtów dzięki @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``+"."

Prawdopodobnie można go jeszcze ulepszyć. Wyjścia są pisane małymi literami.


Zaoszczędź 2 bajty, przenosząc i=0do toString.
Neil

Z zainteresowania zainteresowałem się naprawieniem tych błędów i wymyśliłem: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

Wydaje się działać w obecnej formie.
primo

@Neil Thanks. To oszczędza 12 bajtów, ale nie działa na ostatnim przypadku testowym. Naprawianie, które dodaje 9 do skrótu netto o 3 bajty.
ETHproductions

@ Neil Pozbywanie się .replacei używanie tylko .matchzapisanych kolejnych 12 bajtów.
ETHprodukcje

3

Python 2, 238 221 218 214 207 205 bajtów

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

Używa wielu wyrażeń regularnych do przetwarzania. Przekształcamy podwójną spację w ~i używamy jej do przetwarzania. ~i \nsą traktowane specjalnie.

Największy przyrost postaci wynika z przetwarzania wstępnego danych wejściowych w forlinii; na pewno można dalej grać w golfa.

Ideone to! (wszystkie przypadki testowe)

Zaoszczędzono 7 bajtów dzięki DLosc!


3

Pip , 65 64 bajtów

Wynik to 62 bajty kodu + 2 dla -rsflag.

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

Wypróbuj online!

Wyjaśnienie

-rFlag czyta wszystkie linie stdin i przechowuje ich listę w g. -sFlaga ustawia format wyjściowy do listy rozdzielonych spacjami.

Najprostszym sposobem na odczytanie tego kodu jest z zewnątrz w:

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

Wydaje się nie do pobicia.
primo

1

Python 2.7, 390 342 341 339 335 bajtów:

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)

Pobiera dane wejściowe w formacie:

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

Można grać w golfa o wiele więcej, co zrobię, gdy tylko będę miał okazję.

Zamień na wszystkie przypadki testowe!

Wyjaśnienie:

Wykorzystuje ogromną moc wbudowanych wyrażeń regularnych Pythona do odszyfrowania danych wejściowych. Jest to podstawowy proces, przez który przechodzi funkcja dla każdego wejścia:

  1. Po pierwsze, wszystkie --są zastępowane pojedynczą spacją, a każdy apostrof jest usuwany. Następnie wszystkie słowa zawierające składniki pochylone i słowo po nim są dopasowywane w jednym ciągu i zastępowane 10 + len(second word)liczbą kolejnych as, jeśli długość pierwszego słowa wynosi odd, a 20 + len(second word)kolejne as w przeciwnym razie. Wykorzystuje to następujące wyrażenie regularne:

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

    Na przykład, jeśli mamy zdanie Perpendicular l*ou*nging calms., l*ou*nging calmszostanie zastąpione aaaaaaaaaaaaaaaaaaaaaaaaalub 25 as, ponieważ l*ou*ngingma parzystą liczbę znaków i calmsma 5 20+5=25..

  2. Teraz nowo zmodyfikowane dane wejściowe są dzielone przy każdym znaku interpunkcyjnym, po którym następuje znak nowej linii ( \n), aby uzyskać akapity, następnie każdy akapit jest dzielony przy każdej interpunkcji, a następnie 2 spacje, aby uzyskać zdania, a na koniec każde zdanie jest dzielone na słowa wzdłuż wszelkie znaki interpunkcyjne, w tym spacja. Następnie dla każdego słowa (w tym serii kolejnych as) dodajemy do łańcucha Wliterę odpowiadającą punktowi kodu Unicode 64(punkt kodu Unicode znaku przedtem A, czyli @) len(word). Następnie dodajemy pojedynczą spację do Wwyczerpania wszystkich słów zdania, a po wyczerpaniu wszystkich zdań w akapicie dodajemy znak .spacji.

  3. Na koniec, po przejściu całego wejścia, Wjest wyprowadzany stdoutjako odszyfrowany komunikat.


Drobny nitpick: spec mówi, że zdania wyjściowe są oddzielone pojedynczą spacją, a nie podwójną (ta zmiana również zapisuje bajt). Wstępna propozycja gry w golfa: ponieważ wszystko importujesz re, użyj subzamiast str.replace. Bardziej ogólna sugestia golfowa: prawdopodobnie bardziej efektywne jest traktowanie wszystkiego, co nie jest słowem lub *interpunkcją. Oszczędza na dużych, ogromnych klasach postaci.
DLosc

@DLosc Oh, my bad. Myślałem, że specyfikacja polega na oddzieleniu zdań na wyjściu 2 spacjami. Naprawię to. Dziękujemy również za sugestie dotyczące gry w golfa! Zobaczę, co mogę z nimi zrobić.
R. Kap

1

PHP, 196 bajtów

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

Gdybym mógł założyć, że w środku słowa 194 bajtów jest tylko jedna apostrofa

<?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 Został on zakodowany %0A jako funkcja rawurlencode("\n"). Wolę w tym przypadku formularz z
polem

@DLosc Podejrzewam, że raportowanie błędów w php.ini jest włączone. spróbuj „error_reporting (0);” po <?. Jeden błąd należy do $_GET[s]niego działa, ale jest poprawny $_GET["s"]i lepiej jest zadeklarować i zainicjować zmienną $p=0;przed pętlą. Teraz moje pytanie do ciebie brzmi: czy mogę założyć, że w jednym Słowie jest tylko jeden Apostrof w środku Słowa?
Jörg Hülsermann

@DLosc dla wielu apostrofów muszę użyć mojej pierwszej odpowiedzi. Drugi - 2 bajty działa tylko z jednym apostrofem pośrodku, jeśli słowo.
Jörg Hülsermann

Zrozumiałem, na czym polegał mój problem - mój serwer nie ma włączonych krótkich tagów otwierających. Przejście do <?phppracy.
DLosc

@Dlosc Nigdy nie używałem <?w rzeczywistości. Używam krótkiego tagu tylko w moim poście tutaj. Teraz wiem, że można go zamknąć na pustej stronie.
Jörg Hülsermann

1

PHP, 231 226 228 bajtów

na początek

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

Zapisz do pliku, rund php <scriptpath> <text>. Unikaj znaków nowej linii w tekście, aby działał w skorupkach.


1
Czy możesz podać kilka instrukcji na temat uruchamiania tego? Wygląda na to, że odczytuje dane wejściowe $argv[1], ale nie wiem, jak to podejście zadziała, gdy dane wejściowe zawierają znaki nowej linii. Próbowałem "Neurotic Frogs *O*ught To Re*a*x In *M*ud Baths!"jako argument wiersza polecenia i dostałem IFHCHCFF.na wyjście (jak również Undefined variable: dostrzeżenie).
DLosc

@DLosc: To powiadomienie (nie ostrzeżenie) nie powinno być dostępne przy ustawieniach domyślnych. Najprostszym sposobem jest dodanie <?, zapisanie go w pliku i wywołanie go za pomocą php <filename> <string>. Być może będę musiał dodać 2 do liczby bajtów.
Tytus

@Titus Jeśli zaczniesz <?, możesz także zakończyć ?>., dla zysku netto dla 1. FWIW, dostaję IFHCMFF.dla pierwszego przypadku testowego (używając PHP 5.5.21 64-bit, VC14). Używanie $argnz -Fmoże być również opcją.
primo

Mam na myśli to, że nie rozumiem, jak php <filename> <string>to możliwe, kiedy <string>może zawierać znaki nowej linii.
DLosc

@DLosc: naprawiono błąd. Dla nowych linii: unikaj ich.
Tytus
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.