Расшифровать невротических лягушек

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

Каждое слово открытого текста соответствует предложению зашифрованного текста, а каждое предложение открытого текста соответствует абзацу зашифрованного текста.

Формат ввода

Ваша программа или функция должна ввести сообщение в Neurotic Frogs, отформатированное в 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.
DLosc
источник
4
+1 за вход принцессы. Да, и для твоего мастерства, это тоже.
Волшебная урна осьминога
Гарантируется ли за словом, содержащим курсив, слово, не содержащее курсива?
Р. Кап
@ R.Kap Верно. Я отредактировал вопрос, чтобы уточнить это.
DLosc

Ответы:

5

Perl, 72 байта

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

Считая Шебанг как единое, ввод берется из стандартного ввода.

Образец использования

$ 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``+"."

Возможно, может быть улучшено. Выходы все строчные.

ETHproductions
источник
Сохраните 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
DLosc
источник
Кажется непобедимым.
Примо
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. Теперь вновь модифицированный ввод разделяется на каждый знак пунктуации, за которым следует newline ( \n), чтобы получить абзацы, затем каждый абзац разделяется на каждую пунктуацию, за которой следуют 2 пробела, чтобы получить предложения, и, наконец, каждое предложение разделяется на слова любая пунктуация, включая пробел. Затем для каждого слова (включая серии последовательных aсимволов s) мы добавляем в строку Wбукву, соответствующую кодовой точке 64Unicode (кодовой точке Unicode символа перед символом A, который является @), плюс len(word). Затем мы добавляем один пробел Wпосле того, как все слова предложения были исчерпаны, а когда все предложения в абзаце исчерпаны, мы добавляем .после него один пробел.

  3. Наконец, после прохождения всего ввода Wвыводится stdoutкак расшифрованное сообщение.

Р. Кап
источник
Незначительная мелочь: спецификация говорит, что выходные предложения разделяются одним пробелом, а не двойным (это изменение также сохраняет байт). Первоначальное предложение игры в гольф: поскольку вы импортируете все из 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 Он был закодирован %0A как функция rawurlencode("\n"). В этом случае я предпочитаю форму с текстовой областью для ввода, и мой html-сайт позволяет автоматически кодировать строку
Jörg Hülsermann
@DLosc Я подозреваю, что error_reporting в 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>. Избегайте перевода строки в тексте, чтобы он работал в оболочке.

Titus
источник
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.для первого теста (с использованием PHP 5.5.21 64-bit, VC14). Использование $argnс -Fможет также быть опцией.
Примо
Я имею в виду, я не понимаю, как php <filename> <string>это возможно, когда <string>могут содержать переводы строк.
DLosc
@DLosc: исправлена ​​ошибка. Для новых строк: убежать от них.
Тит