Мнемоніка для запам'ятовування 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 і знайде всі слова, які можна було б перетворити за допомогою спрощеної основної мнемонізованої системи.

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

Для штрафу в 35 байт (додайте 35 до своєї оцінки) ви можете припустити, що список слів уже завантажений у змінну як список рядків. Це в основному для мов, які не можуть читати файли, але будь-яке подання може скористатися ним.

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

Якщо немає можливих слів, то вихід (або список) буде порожнім. Вихід також порожній, якщо вводиться порожній рядок.

Візьміть вхід через 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 переходить до подання, розміщеного першим.

Сайт, пов’язаний з Nifty: numzi.com .


1
Чи траплялось вам отримати ідею для цього виклику з цього відео ? Тому що я насправді лише вчора спостерігав це. : P
Дверна ручка

1
@Doorknob Не те відео, але той хлопець. Роки тому мені дали одну з його лекцій Великих курсів . Він свого роду зані, але дійсно акуратний матеріал. :)
Захоплення Кальвіна

1
Зверніть увагу на тих, хто зацікавлений у використанні мнемонічної основної системи в реальному житті: важливий лише звук , а не правопис. Тож "c", перерахований тут як значення 7, насправді може означати 0, якщо в слові він вимовляється зі звуком "s" (як у "тузі" = 0). Однак я впевнений, що ОП спростила виклик, оскільки словник із повною фонетикою набагато складніше, ніж простий список слів. О, і одна передача 23940 - це "числа".
ErikE

@ErikE Я стверджую, що ми використовуємо правописну версію у другому реченні допису ...
Захоплення Calvin's

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

Відповіді:


6

Перл, 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Біт є «вид ззаду негативного затвердження» компонент , який робить впевнений , що 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 байт).
екхуморо

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

2

sed, паста, греп, вирізати - 109

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

Бере файл "w", перетворює кожне слово на його номер, вставляє назад до оригіналу, прив'язує до числа і повертає слово, яке відповідає. Зауважте, що пробіл після лапки після 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замінює цифри можливими їх замінами
  • The eval printf використанні оболонка фігурних дужок розкладання розширити всі можливі заміни
  • Другий sedрядок 1-го рядка видаляє aeiouwxyта h(якщо цього не передує [sc]) зі списку слів
  • Греп виводить усі відповідники з номерами рядків
  • Оскільки ми викреслили 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.