Мнемоника для запоминания 23940


19

Основная система представляет собой мнемоническое устройство для преобразования чисел в слова , чтобы они могли быть сохранены более легко.

Он основан на том, как слова звучат фонетически, но чтобы не усложнять задачу, мы будем интересоваться только тем, как пишутся слова. Это означает, что будут некоторые неправильные преобразования, но это нормально.

Чтобы преобразовать число в слово, используя нашу упрощенную основную систему:

  • Замените каждый 0на sили z. (Некоторые могут быть, sа некоторые могут быть z. То же самое ниже.)
  • Замените каждый 1на tили dили th.
  • Заменить каждый 2на n.
  • Заменить каждый 3на m.
  • Заменить каждый 4на r.
  • Заменить каждый 5на l.
  • Замените каждый 6на jили shили ch.
  • Замените каждый 7на kили cили gили или q.
  • Замените каждый 8на fили v.
  • Замените каждый 9на pили b.
  • Добавляйте буквы aehiouwxyгде угодно в любых количествах, чтобы сделать реальное английское слово, если это возможно .
    Единственным исключением является то, что hне может быть вставлен после sили c.

Число может фактически быть любой строкой цифр 0-9 (без десятичных знаков, запятых или знаков).
Слово может содержать только строчные буквы az.

Примеры

Число 32должно быть преобразовано как ?m?n?, где ?представляет любую конечную строку, составленную из букв aehiouwxy(строку из свободного моноида, если вы предпочитаете). Есть много способов , которыми это может быть сделано в режиме реального английского слова: mane, moon, yeomanи т.д.

Число 05может быть преобразовано в ?s?l?или ?z?l?. Некоторые возможности easily, hassleи hazel. Слово shawlне допускается, потому что hне может быть помещено после s; это было бы неправильно прочитано как 65.

Вызов

Напишите программу или функцию, которая принимает строку цифр 0-9 и находит все слова, в которые она может быть преобразована, используя упрощенную системную мнемонику.

Ваша программа имеет доступ к текстовому файлу со списком слов, который определяет, каковы все "настоящие" английские слова. В каждой строке этого файла есть одно строчное z-слово, и вы можете при желании предположить, что в нем есть завершающий символ новой строки. Вот список реальных слов, которые вы можете использовать для тестирования. Вы можете предположить, что этот файл списка слов называется f(или что-то более длинное) и находится в любом удобном каталоге.

Для штрафа в 35 байт (прибавьте 35 к вашему счету) вы можете предположить, что список слов уже загружен в переменную в виде списка строк. Это в основном для языков, которые не могут читать файлы, но любая отправка может воспользоваться этим.

Ваша программа должна вывести все слова в списке слов, в которые можно преобразовать введенное число. Они должны быть напечатаны в стандартный вывод (или аналогичный), по одному на строку (с необязательным завершающим символом новой строки), или они могут быть возвращены в виде списка строк, если вы решили написать функцию. Список слов не обязательно находится в алфавитном порядке, и вывод не должен быть либо.

Если нет возможных слов, то вывод (или список) будет пустым. Вывод также пуст, если вводится пустая строка.

Возьмите ввод через stdin, командную строку или как строковый аргумент функции. Список слов или имя его файла не должны быть частью ввода, только цифра.

Вы соответствуете только отдельным словам в списке слов, а не последовательности слов. Слово noon, вероятно, будет одним из результатов для 22, но последовательность слов no oneне будет.

Тестовые случаи

Предположим, это список слов:

stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
zdnmrlshchvb
sthnmrlchgvb
shthnmrlchgvb
bob
pop
bop
bopy
boppy

Вход 0123456789должен дать все длинные слова , кроме zdnmrlshchvbи shthnmrlchgvb:

stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb

Вход 99должен дать:

bob
pop
bop
bopy

(Выходные слова могут быть в любом порядке.)

счет

Самая короткая подача в байтах побеждает. Tiebreaker переходит к представлению, опубликованному первым.

Отличный связанный сайт: numzi.com .


1
Вы случайно не поняли эту проблему из этого видео ? Потому что я на самом деле только что посмотрел это вчера. : P
Ручка двери

1
@ Doorknob Не то видео, а тот парень. Несколько лет назад мне дали одну из его лекций по Великим Курсам . Он немного любезен, но на самом деле делает все аккуратно. :)
Увлечения Келвина

1
Примечание для тех, кто заинтересован в использовании основной мнемонической системы в реальной жизни: важен только звук , а не орфография. Таким образом, «c», хотя и указано здесь как значение 7, может фактически означать 0, если в слове оно произносится со звуком «s» (как в «ace» = 0). Тем не менее, я уверен, что OP упростил задачу, так как найти словарь с полной фонетикой гораздо сложнее, чем простой список слов. О, и один рендеринг 23940 - это «числа».
ErikE

@ErikE Я утверждаю, что мы используем версию, основанную на правописании, во втором предложении поста ...
Увлечения Кэлвина

Я вижу это сейчас, хотя поначалу мне это и не хватало, но мне все еще кажется, что ваше объяснение может быть приведено чуть подробнее и приведен пример или два.
ErikE

Ответы:


6

Perl, 87 84

open A,f;"@ARGV"eq s/[cs]h/j/gr=~y/stnmrljkfpzdcgqvb\0-z/0-90177789/dr&&print for<A>

Принимает ввод в качестве параметра командной строки:

$perl m.pl 23940

Можно сделать несколько короче, если список слов будет разрешен для стандартного ввода:

$perl -lnE'INIT{$;=pop}$;eq s/[cs]h/j/gr=~y/stnmrljkfpzdcgqvba-z/0-90177789/dr&&say' 99 <f

Что Aзначит в open A,f?
feersum

@feersum Дескриптор файла, используемый позже для чтения файла ( <A>).
nutki

4

Python 2, 215 208 байт

Это решение Python создает регулярное выражение из частей, проиндексированных аргументом командной строки, а затем проверяет каждое слово с помощью этого (довольно большого) регулярного выражения.

import re,sys
a='[sz] (d|th?) n m r l (j|sh|ch) [kcgq] [fv] [pb]'.split()
b=z='((?<![sc])h|[aeiouwxy])*'
for i in sys.argv[1]:b+=a[int(i)]+z
for d in open('f'):
 d=d.strip()
 if re.match('^'+b+'$',d):print d

Первоисточник перед минификатором:

import re,sys
regexbits = '[sz] (d|th?) n m r l (j|sh|ch) [kcgq] [fv] [pb]'.split()

regex = other = '((?<![sc])h|[aeiouwxy])*'
for i in sys.argv[1] :
    regex += regexbits[int(i)] + other
print regex     # DEBUG

for word in open('f'):
    word = word.strip()
    if re.match('^'+regex+'$', word) :
        print word

Например, регулярное выражение для теста 99:

^((?<![sc])h|[aeiouwxy])*[pb]((?<![sc])h|[aeiouwxy])*[pb]((?<![sc])h|[aeiouwxy])*$

Этот (?<![sc])hбит является компонентом «поиска за отрицательным утверждением», который следит за тем, чтобы a hне следовало за sили cв общих частях наполнителя.

Спасибо, Кальвин. Этот вызов побудил меня освежить свои ржавые навыки регулярных выражений.


b=c='((?<![sc])h|[aeiouwxy])*'сэкономит два байта.
matsjoyce

t|th -> th?сохраняет байт
Sp3000

Вы можете избежать карты, взяв int (i) напрямую.
xnor

Спасибо matsjoyce, Sp3000 и xnor за полезные советы по игре в гольф. Теперь редактируется с предложениями реализованы.
Рыцарь логики

2

Питон 3, 170

import sys,re
t=str.maketrans('sztdnmrljkcgqfvpb','00112345677778899','aehiouwxy\n')
for s in open('f'):re.sub('sh|ch','j',s).translate(t)!=sys.argv[1] or print(s,end='')

Читаемая версия:

import sys, re

table = str.maketrans('sztdnmrljkcgqfvpb', '00112345677778899', 'aehiouwxy\n')

for line in open('f'):
    line = re.sub('sh|ch', 'j', line)
    if line.translate(table) == sys.argv[1]:
        print(line, end='')

В коде используется тот факт, что он thявляется избыточным (поскольку он отображается на тот же номер t, что и hдополнительный символ).

Статическая maketransфункция создает таблицу, в которой символы первого аргумента сопоставляются символам второго аргумента, а символы третьего аргумента - None(что приведет к удалению этих символов).

Окончательный код можно сделать на несколько байтов короче, создав таблицу в качестве прямого аргумента translate.


Вы можете сохранить пару байтов, используя input () вместо sys.argv [1] и '[sc] h' для вашего регулярного выражения.
swstephe

@swstephe. Спасибо за отзыв, но я не думаю input(), что его можно использовать, потому что он вызывается внутри цикла. Кроме того, предложенное вами регулярное выражение имеет ту же длину, что и то, которое я уже использую (5 байт).
ekhumoro

Я думал что-то вроде "z, t = input (), str.maketrans ...", а затем просто используйте z вместо sys.argv. Хорошо, я думал, что мое регулярное выражение было 4 байта.
swstephe

2

sed, paste, grep, cut - 109

sed -e 's/[sc]h/6/g;s/[aehiouwxy]//g;y/sztdnmrljkcqgfvpb/00112345677778899/' w|paste w -|grep " $1$"|cut -f1

Принимает файл "w", преобразует каждое слово в его число, вставляет обратно в оригинал, grep для числа и возвращает найденное слово. Обратите внимание, что пробел после кавычки после grep является вкладкой, вставьте разделитель по умолчанию.

Я знаю, что Perl далеко впереди, просто хотел иметь лучшую версию оболочки в качестве примера.

О да, часть $ 1 означает, что она должна быть запущена из сценария оболочки (большинство оболочек должно работать), поэтому она принимает аргумент командной строки.


Я думал о том, чтобы преобразовать мой ответ в чистый, sedчтобы избежать открытых и @ARGVнакладных расходов Perl , но отсутствие диапазонов и удаление функций y///нарушает его. Удивительно, хотя, хотя нет переменных, вы можете выразить саму логику непосредственно в sed. Вот мое решение 92:sed -e'h;s/[sc]h/6/g;y/sztdnmrljkcqgfvpb/00112345677778899/;s/[^0-9]*//g;T;s/^$1$//;x;t;d' f
Nutki

Кажется, работает, почему бы не сделать это ответ?
swstephe

1

Bash + coreutils, 216

sed -n "$(sed 's/[aeiouwxy]//g
:l
s/\([^sc]\)h/\1/g
tl'<w|grep -nf <(eval printf '%s\\n' `sed 's/0/{s,z}/g
s/1/{t,th,d}/g
y/2345/nmrl/
s/6/{j,sh,ch}/g
s/7/{k,c,g,q}/g
s/8/{f,v}/g
s/9/{p,b}/g'<<<$1`)|sed s/:.\*/p/)" w
  • Список слов в файле с именем w
  • Самое внутреннее sedзаменяет цифры с их возможными заменами
  • В eval printfиспользовании оболочка фигурных скобок разложения расширить все возможные замены
  • Второй sedв 1-й строке удаляет aeiouwxyи h(если не предшествует [sc]) из списка слов
  • Grep распечатывает все совпадения с номерами строк
  • Так как мы вычеркнули aeiouwxyи hиз списка слов, последнее sedпревращает результаты grep (номера строк каждого соответствия) в другое sedвыражение, которое обрабатывается самым внешним, sedчтобы выявить все возможные слова из списка слов.

Выход:

Файл списка слов указывается в виде аргумента командной строки, за которым следует мнемонизация:

ubuntu@ubuntu:~$ ./numzi.sh 99
bob
pop
bop
bopy
boppy
$ ./numzi.sh 0123456789
stnmrljkfp
zthnmrlshqfb
asatanamaralajakafapa
aizxydwwwnhimouooraleshhhcavabe
zdnmrlshcvb
sthnmrlchgvb
$ 

@ Calvin'sHobbies Готово.
Цифровая травма

Похоже, вы забыли обновить свой пример.
Увлечения Кэлвина

-1

tr, sed, grep, xargs, sh, 77

tr 0123456789 ztnmrljkfp|sed 's/ */[aehiouwxy]*/g'|xargs sh -c 'grep -x $0 f'

Ожидается, что число в stdin и список слов должны храниться в файле f.

Не использует все замены (1 всегда будет z, 7 всегда будет k), поэтому его можно назвать ленивым решением, но он находит по крайней мере одну мнемонику для 95 чисел в [1-100].


3
Вопрос требует, чтобы вы нашли все подходящие слова в списке слов. Вы не можете заставить 1всегда быть zили 7всегда k. Это недействительно.
Увлечения Кэлвина

Справедливо, я удалю свой ответ.
pgy
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.