Математика, 72 65 61 байт
Print@@@Tuples@{a=##/(b=#5#9#15#21#25#)&@@Alphabet[],b,a,b,a}
Для тестування рекомендую замінити Print@@@
на ""<>#&/@
. Потім Mathematica відобразить усічену форму, де відображаються перші кілька та останніх слів, замість того, щоб назавжди надрукувати 288 000 рядків.
Пояснення
Нарешті я знайшов застосування для поділу рядків. :)
Мене інтригує можливість додавання або множення рядків на деякий час, але фактичні випадки використання досить обмежені. Основний момент полягає в тому, що щось подібне "foo"+"bar"
або "foo"*"bar"
(а отже, коротка форма "foo""bar"
) цілком справедливо в Mathematica. Однак насправді не відомо, що робити з рядками в арифметичних виразах, тому ці речі залишаються неоціненими. Mathematica дійсно застосовується , як правило , застосовуються спрощення , хоча. Зокрема, рядки будуть відсортовані в канонічний порядок (що досить заплутано в Mathematica, як тільки ви почнете сортувати рядки, що містять букви різних справ, цифр та не літер), що часто є порушником, але тут не має значення. . Крім того, "abc""abc"
буде спрощено до"abc"^2
(що є проблемою, коли ви повторюєте рядки, але у нас цього також немає), і щось подібне "abc"/"abc"
насправді скасує (що ми навіть будемо використовувати).
То що ми намагаємося тут займатися гольфом. Нам потрібен список голосних і список приголосних, щоб ми могли їх подавати, Tuples
щоб генерувати всі можливі комбінації. Першим моїм підходом було наївне рішення:
Characters@{a="bcdfghjklmnpqrstvwxz",b="aeiouy",a,b,a}
Цей твердо кодований список приголосних трохи шкодить. У Mathematica є Alphabet
вбудований модуль, який дозволив би мені уникнути цього, якби я міг дешевими способами видалити голосні звуки. Тут це стає складним, хоча. Найпростіший спосіб видалити елементи Complement
, але це закінчується довше, використовуючи один із наступних варіантів:
{a=Complement[Alphabet[],b=Characters@"aeiouy"],b,a,b,a}
{a=Complement[x=Alphabet[],b=x[[{1,5,9,15,21,25}]]],b,a,b,a}
(Зверніть увагу, що нам більше не потрібно застосовуватись Characters
до всієї справи, тому що Alphabet[]
дає список букв, а не рядка.)
Тож спробуємо цей арифметичний бізнес. Якщо ми представляємо весь алфавіт як добуток літер замість списку, то ми можемо видалити літери простим поділом, завдяки правилу скасування. Це економить багато байтів, тому що нам це не потрібно Complement
. Крім того, "a""e""i""o""u""y"
насправді байт коротший, ніж Characters@"aeiouy"
. Тож ми робимо це за допомогою:
a=##/(b="a""e""i""o""u""y")&@@Alphabet[]
Де ми зберігання згодної і гласною продуктів в a
і b
, відповідно. Це працює, записуючи функцію, яка множує всі її аргументи ##
і ділить їх на добуток голосних. Ця функція застосовується до списку алфавіту, який передає кожну букву окремим аргументом.
Поки що добре, але зараз у нас є
{a=##/(b="a""e""i""o""u""y")&@@Alphabet[],b,a,b,a}
як аргумент Tuples
, і ті речі все ще є продуктами, а не списками. Зазвичай, це найкоротший спосіб виправити те, що ставиться List@@@
на фронті, що знову перетворює товари в списки. На жаль, додавання цих 7 байтів робить це довше, ніж наївний підхід.
Однак, виявляється, це Tuples
зовсім не хвилює керівників внутрішніх списків. Якщо ти зробиш
Tuples[{f[1, 2], f[3, 4]}]
(Так, для невизначеного f
.) Ви отримаєте:
{{1, 3}, {1, 4}, {2, 3}, {2, 4}}
Так само, як якщо б ви використовували List
замість цього f
. Тож ми можемо реально передавати ці продукти прямо Tuples
та все-таки отримати правильний результат. Це економить 5 байт над наївним підходом, використовуючи дві твердо кодовані рядки.
Зараз "a""e""i""o""u""y"
це все ще досить дратує. Але зачекайте, і тут ми можемо зберегти кілька байт! Аргументами нашої функції є окремі букви. Тож якщо ми просто підберемо правильні аргументи, ми можемо використати їх замість рядкових літералів, що для трьох з них коротше. Ми хочемо , щоб аргументи #
(скорочено #1
) #5
, #9
, #15
, #21
і #25
. Якщо поставити #
в кінці, то нам також не потрібно додавати жодних *
для їх множення разом, тому що (регулярний вираз) #\d+
- це повна лексема, до якої не може бути додано жодної нецифрової цифри. Отже, ми закінчуємо #5#9#15#21#25#
, зберігаючи ще 4 байти.