Розшифруйте невротичних жаб


28

Розшифруйте невротичних жаб

Тепер, коли нарешті Puzzling.SE зламав мій одержимий шифром амфібій , давайте напишемо програму або функцію, щоб розшифрувати її!

(Якщо ви хочете переглянути головоломку, перш ніж вона була зіпсована для вас, натисніть на вищезазначене посилання зараз.)


Як працює шифр

У Neurotic Жабах Про ught До Rel х В М уд ванни ( «Невротичні Жаби» для стислості), кожна буква шифрується в вигляді одного або двох слів:

  • Довжина слова, що не вказується курсивом, являє собою букву.
    • neurotic => 8 літер => H
    • frogs => 5 літер => E
    • perpendicular => 13 літер = M
  • Слово, що містить курсив, модифікує наступне слово, додаючи 10, якщо слово, яке накреслене курсивом, було непарним у довжину, або 20, якщо курсивне слово було навіть по довжині. Будь-яке або все слово може бути курсивом. Курсивне слово завжди супроводжується не курсивним словом.
    • *o*ught to => непарне, 2 => 12 => L
    • lo*u*nging calms => рівне, 5 => 25 => Y

Кожному слову простого тексту відповідає речення шифротексту, а кожне речення простого тексту відповідає абзацу шифротексту.

Формат введення

Ваша програма чи функція повинні вводити повідомлення у Невротичних жабах, відформатованих у Markdown. Вхід буде складатися лише з друкованих ASCII та нових рядків.

  • Слова - це прогони символів, які відповідають регексу [A-Za-z0-9'].
    • Обидві цифри та літери зараховуються до довжини слова. QB64представляє D.
    • ПРИМІТКА: Апострофи не враховуються до довжини слова. Isn'tпредставляє D, не E.
  • Італізовані літери загортаються в пару зірочок ( *letters*).
    • Одна чи більше послідовних літер можуть бути курсивом, до цілого слова ( masseus*es*, *all*); кілька непослідовних літер у слові також можуть бути курсивом ( g*e*n*e*rates).
    • Курсиви ніколи не охоплюють декілька слів, ніколи не включають розділові знаки і не включають апострофи.
    • Непарні зірочки та кілька суміжних зірочок ніколи не виникатимуть.
  • Пунктуація є будь-який з наступних символів: .,?!:;-()".
    • Слова всередині речення розділені одним або кількома знаками пунктуації та / або одним пробілом. Приклади: *all* welcomed, toad*s*, newts, Ever*y*one--frogs, cap... bliss,they're (I
    • Речення закінчуються одним або кількома знаками пунктуації і розділені подвійним пробілом: Th*e* Montgomery A*m*phibian Salon! Come luxuriate today!
    • Абзаци розділені одним новим рядком. (В останньому реченні абзацу все ще є один або кілька знаків пунктуації в кінці.)

Інші символи не відображатимуться на вводі та їх не потрібно обробляти.

Ваш код може, на ваш розсуд, очікувати, що вхід матиме один зворотний новий рядок.

Формат виводу

Результатом розшифровки введення буде одне або кілька пропозицій. Літери простого тексту можуть бути будь-якими комбінаціями з верхнього та нижнього регістру. Слова в реченні повинні бути розділені пробілами. Речення повинні закінчуватися періодом ( .) і бути розділеними єдиним пробілом. Ви можете виділити пробіл після останнього речення. Усі результати будуть знаходитися в одному рядку, але ви можете вивести зворотний новий рядок.

Різні деталі

Ваш код може використовувати будь-який із стандартних методів введення та виводу. Він повинен отримувати введення як рядковий рядок, а не список або інша структура даних, і він повинен виводити рядок.

Виграє найкоротший код у байтах!

Тестові справи

-->
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 для введення принцеси нареченої. О, і для вашої майстерності, що теж.
Чарівна восьминога урна

Чи гарантовано, що слово, що містить курсив, буде дотримуватися слова, яке не містить курсивом?
Р. Кап

@ R.Kap Правильно. Я відредагував питання, щоб уточнити це.
DLosc

Відповіді:


5

Perl, 72 байти

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

Підрахувавши шебанг як один, вхід береться з stdin.

Використання зразка

$ 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
Я присуджую цю нагороду за цю відповідь, оскільки це найкоротший на кінець періоду щедрості, окрім мого власного (справді, єдиного, хто прийшов десь близько).
DLosc

4

JavaScript (ES6), 172 169 157 150 байт

Збережено 10 байт завдяки @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``+"."

Можливо, може бути ще вдосконалено. Виходи у всіх малих регістрах.


Збережіть 2 байти, перемістивши i=0в toString.
Ніл

Не цікавившись, я намагався виправити ці помилки і придумав це: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 Дякую Це економить 12 байт, але це не працює на останньому тестовому випадку. Виправлення, що додає 9 для скорочення чистоти в 3 байти.
ETHproductions

@Neil Позбавлення .replaceта просто використання .matchзбережених ще 12 байт.
ETHproductions

3

Python 2, 238 221 218 214 207 205 байт

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

Для обробки використовується велика кількість регулярних виразів. Ми перетворюємо подвійний простір в ~і використовуємо його для його обробки. ~і \nобробляються спеціально.

Найбільший приріст символів відбувається від попередньої обробки вводу в forрядку; це, безумовно, може бути додатково гольф.

Ідей це! (усі тестові випадки)

Збережено 7 байт завдяки DLosc!


3

Піп , 65 64 байт

Оцінка - 62 байти коду + 2 для -rsпрапорів.

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

Спробуйте в Інтернеті!

Пояснення

-rПрапор читає все рядки стандартного введення і зберігає їх список в g. -sПрапор встановлює формат виведення списків в просторі-відокремленою.

Найпростіший спосіб прочитати цей код ззовні:

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

Здається, неперевершеним.
примо

1

Python 2.7, 390 342 341 339 335 байт:

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)

Вводиться у форматі:

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

Можна пограти в гольф набагато більше, що я буду робити, коли матиму можливість.

Repl.it з усіма тестовими справами!

Пояснення:

Для розшифровки вводу використовується величезна сила вбудованих регулярних виразів Python. Це основний процес, через який функціонує кожен вхід:

  1. По-перше, всі --замінюються одним простором, і кожен апостроф видаляється. Потім усі слова, що містять курсивні компоненти, і слово, що переходить до нього, обидва поєднуються в один рядок і замінюються 10 + len(second word)кількістю послідовних as, якщо довжина першого слова odd, і 20 + len(second word)послідовні as - інакше. Для цього використовується наступний регулярний вираз:

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

    Наприклад, якщо у нас є речення Perpendicular l*ou*nging calms., l*ou*nging calmsйого буде замінено aaaaaaaaaaaaaaaaaaaaaaaaaабо 25 aс, оскільки l*ou*ngingмає парну кількість символів і calmsмає 5 20+5=25.

  2. Тепер щойно модифікований ввід розділяється на кожен розділовий знак, а потім новий рядок ( \n), щоб отримати абзаци, потім кожен абзац розділяється на кожний розділовий знак, а потім 2 пробіли, щоб отримати речення, і, нарешті, кожне речення ділиться на слова уздовж будь-який розділовий знак, включаючи пробіл. Потім для кожного слова (включаючи проміжки послідовних as) ми додаємо до рядка Wбукву, відповідну кодовій точці 64unicode (точці коду unicode символу раніше A, що є @) плюс len(word). Потім ми додаємо один пробіл, Wколи всі слова речення вичерпані, і коли всі речення в абзаці вичерпані, ми додаємо .наступний пробіл.

  3. Нарешті, після того, як весь вхід був пройдений, Wвін виводиться stdoutяк розшифроване повідомлення.


Незначна нитка: spec каже, що вихідні пропозиції розділені між собою проміжком, а не подвійними (ця зміна також економить байт). Початкова пропозиція щодо гольфу: оскільки ви імпортуєте все з re, використовуйте subзамість цього str.replace. Більш загальна пропозиція про гольф: напевно, ефективніше трактувати все, що не є словом або *як пунктуацією. Економить на великих величезних класах персонажів.
DLosc

@DLosc О, мій поганий. Я думав, що специфікація полягає у розділенні речень у висновку на 2 пробіли. Я це виправлю. Також дякую за пропозиції з гольфу! Я побачу, що я можу з ними зробити.
Р. Кап

1

PHP, 196 байт

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

Якби я міг припустити, що в середині слова є лише один Апостроф 194 Байт

<?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 Це було urlencoded %0A як функція rawurlencode("\n"). Я віддаю перевагу в цьому випадку форму з текстовою областю для введення, і тому мій html-сайт дозволяє автоматично кодувати рядок
Jörg Hülsermann,

@DLosc Я підозрюю, що у php.ini ввімкнено повідомлення про помилки. спробуйте "error_reporting (0);" після того , як <?. Одна помилка належить $_GET[s]йому працює, але правильна, $_GET["s"]і краще оголосити ініціалізувати змінну $p=0;перед циклом. Тепер моє запитання до вас таке: чи можу я вважати, що в одному Слові є лише один Апостроф посеред Слова?
Йорг Гюльсерманн

@DLosc для декількох апострофів. Я повинен використовувати свою першу відповідь. Другий - 2 байти працює лише з одним апострофом посередині, якщо слово.
Йорг Гюльсерманн

Я зрозумів, у чому моя проблема - на моєму сервері не ввімкнено короткі теги відкриття. Перехід до <?phpвідпрацьованого.
DLosc

@Dlosc Я ніколи не використовую <?насправді. Я використовую тут короткий тег лише у своєму дописі. Тепер я знаю, що це може бути використане на порожній сторінці.
Йорг Гюльсерманн

1

PHP, 231 226 228 байт

для початку

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

Збережіть у файл, rund php <scriptpath> <text>. Уникніть нових рядків у тексті, щоб він працював у оболонці.


1
Чи можете ви дати деякі вказівки щодо цього? Схоже, він читає вхід з $argv[1], але я не знаю, як буде працювати цей підхід, коли вхід містить нові рядки. Я спробував "Neurotic Frogs *O*ught To Re*a*x In *M*ud Baths!"як аргумент командного рядка і отримав IFHCHCFF.для виведення (а також Undefined variable: dпопередження).
DLosc

@DLosc: Це повідомлення (не попередження) не повинно бути там із налаштуваннями за замовчуванням. Найпростіший спосіб - зробити попередній запис <?, зберегти його у файл та зателефонувати за допомогою php <filename> <string>. Можливо, мені доведеться додати 2 до кількості байтів.
Тит

@Titus Якщо ви почнете <?, ви можете також закінчити з ?>.чистим виграшем для 1. FWIW, я отримую IFHCMFF.перший тестовий випадок (використовуючи 64-розрядний PHP 5.5.21, VC14). Використання $argnз -Fтакож може бути варіантом.
примо

Я маю на увазі те, що я не бачу, як php <filename> <string>це можливо, коли <string>можуть міститися нові рядки.
DLosc

@DLosc: виправлено помилку. Для нових рядків: уникайте їх.
Тит
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.