Цель
Напишите программу или функцию, которая переводит числовой номер телефона в текст, который позволяет легко сказать. Когда цифры повторяются, они должны читаться как «двойной n» или «тройной n».
Требования
вход
Строка цифр.
- Предположим, что все символы представляют собой цифры от 0 до 9.
- Предположим, строка содержит хотя бы один символ.
Выход
Слова, разделенные пробелами, о том, как эти цифры можно прочитать вслух.
Перевести цифры в слова:
0 "ой"
1 "один"
2 "два"
3 "три"
4 "четыре"
5 "пять"
6 "шесть"
7 "семь"
8 "восемь"
9 "девять"Когда одна и та же цифра повторяется дважды подряд, напишите «двойное число ».
- Когда одна и та же цифра повторяется трижды подряд, напишите «тройное число ».
- Когда одна и та же цифра повторяется четыре или более раз, напишите «двойное число » для первых двух цифр и оцените оставшуюся часть строки.
- Между каждым словом ровно один пробел. Допускается один пробел в начале или в конце.
- Выходные данные не чувствительны к регистру.
счет
Исходный код с наименьшим количеством байтов.
Тестовые случаи
input output
-------------------
0123 oh one two three
4554554 four double five four double five four
000 triple oh
00000 double oh triple oh
66667888 double six double six seven triple eight
19999999179 one double nine double nine triple nine one seven nine
code-golf
kolmogorov-complexity
Hand-E-Food
источник
источник
Ответы:
05AB1E ,
5352515049 байтовПопробуйте онлайн!
Объяснение:
источник
M
также заглядывает в списки при определении максимального целого числа в стеке? Не знал этого. Похоже, что-то вспомнить. :)8088 Assembly, IBM PC DOS,
164159156155 байтBinary:
Создайте и протестируйте исполняемый файл, используя
xxd -r
выше, или загрузите PHONE.COM .Несобранный список:
TL; DR:
Строка ввода читается справа налево, чтобы упростить поиск тройки. Выходные данные помещаются в стек x86, чтобы упростить изменение порядка отображения, а также упростить перестановку «двойных» и «тройных» слов, чтобы предшествовать имени цифры.
Если следующая цифра отличается от последней, имя ищется в списке слов и помещается в стек. Поскольку в машинном коде отсутствует формальная концепция «индексированного массива строк переменной длины», список слов сканируется
i
(индекс слова) несколько раз, чтобы разделитель строк ($
) находил соответствующее слово. Полезно, что в x86 есть пара коротких инструкций (REPNZ SCASB
что аналогичноmemchr()
C), что упрощает это (спасибо CISC !).Если цифра такая же, как и предыдущая, счетчик длины «прогона» увеличивается и продолжает цикл на входе влево. По окончании цикла имя цифры берется из стека, поскольку его нужно будет ставить после «двойного» или «тройного» для каждой группировки. Если длина цикла нечетна (а длина цикла
> 1
), то имя цифры, за которым следует строка «тройка», помещается в стек, а длина цикла уменьшается на 3. Поскольку длина цикла теперь будет четной, шаг повторяется для «double», пока длина пробега не станет равной 0.Когда входная строка достигла конца, стек выгружается, и каждая сохраненная строка записывается на экран в обратном порядке.
I / O:
Автономный исполняемый файл для ПК с DOS, ввод из командной строки в консоль.
Загрузите и протестируйте PHONE.COM .
источник
repne scasb
естьmemchr
(илиstrchr
если вы знаете, что будет хит), нетstrstr
.mov cl, byte[si]
это эквивалентноmovzx cx, byte [si]
. Интересно, если бы использование другого reg, напримерAH
, для счетчикаdec ah / jnz
вместо вместоloop
, спасло бы что-нибудь от того, что нет необходимости нажимать / вставлять CX. Вероятно, нет, и у вас не осталось 16-битных регистров, которые бы допускали 1 байтdec
.CH=0
я пошел по fysnet.net/yourhelp.htm , который для любого разумного выпуска DOS всегда нулевой, как и вBX
. Хорошая мысль о нулевом расширенииmov
, хотя технически я не думаю, чтоmovzx
доступно на 808x (сохраняя целевую платформу IBM PC 5150 и все). Я возился со всеми регистрами, как мог, чтобы спасти байты, но если вы видите что-то, что я, вероятно, пропустил, пожалуйста, дайте мне знать!memchr
ИМО. Именование «строковой инструкции» вводит людей в заблуждение, заставляя их думать, что они работают со строками C неявной длины, но в действительности они работают со строками явной длины, такими какstd::string
или буферы. Напримерmemcpy
,memset
(movs / stos),memchr
/memrchr
(repne scas с DF = 0 или 1) иmemcmp
(repeat cmps). Единственный эквивалент C дляrepe scas
-strspn
потому что я не думаю, что для этого естьmem
функция. Можно даже описатьstosw
илиstosd
какwmemset
например.movzx
стоит дополнительный байт кода операции, и да, он был введен только с 386. Было проще набрать текст, чтобы описать тот факт, что вы выполняете слияние с младшим байтом и предполагаете, что он правильно расширен на ноль. Если вы знаете CX или хотя бы CH = 0, тогда да, для игры в гольф всегда переходитеmov
к CL. Но вне игры в гольф, идти в байтах нагрузку х86 являютсяmovzx
иmovsx
: они избегают каких - либо ложных зависимостей или другой парциального регистра проделки. На современных процессорах с назначением dword они работают так же быстро, как и dwordmov
.05AB1E ,
6156535251 байт-9 байт благодаря @Grimy .
Попробуйте онлайн или проверьте все контрольные примеры .
Объяснение:
Посмотрите эту подсказку 05AB1E (раздел Как пользоваться словарем? ), Чтобы понять, почему
… ‹¶½¿
есть" double triple"
и“Šç€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“
есть"oh two three four five six seven eight nine"
.источник
if(length>=4)
прежде чем добавить остальные, но, конечно, это не обязательно для целых чисел1,2,3
, потому что;Å2¨3ª£
они оставят строки нетронутыми (просто в любом случае просто обернуты в список, который мы сглаживаем после карты). Спасибо, что заметили! И с нетерпением жду вашего ответа сÅγ
. У меня действительно было чувство, что первая часть может быть сделана как-то короче.Dg;LàäR
по-прежнему на один байт корочеāɨšJõK
, и гораздо более похож на то, что у вас было изначально.á
аõK
не в конце. :)á
! Вот 51 и еще один . 50 кажется возможным.QuadR , 137 байтов SBCS
Заголовок дела с пробелом.
Попробуйте онлайн!
∊
ε NLIST (Flatten)¯2↑¨
взять последние два символа (набивка на левую сторону с пробелом) каждые символы@
в позициях , где(∊∘⎕A)
символы являются членами верхнего регистра A lphabet⍵
в результате операции ниже PCRE Replace ...(.)
любой символ,\1
за которым следует*
ноль или более раз, заменяется результатом следующего…{…}⍵M
"DFN";⍵
это М ATCH вышеуказанного узора('OhOneTwoThreeFourFiveSixSevenEightNine'(
…)⎕A)
Применить следующую анонимную молчаливую функцию с длинной строкой и заглавной буквой A в качестве аргументов слева:∊
членство (из букв в длинной строке в верхнем алфавите)⊂
разделы (с новым разделом, начинающимся всякий раз, когда является членом⊣
левый аргумент (то есть длинная строка)(
…)⎕R
PCRE R заменить следующие шаблоны этими словами:⎕D
цифры от 0 до 9,¨
относиться к каждому как к отдельному образцу⍺←
назначить эту функцию для замены в⍺
(для в lphabetise)⋄
тогда,⊃⍵
первый персонаж матча,
как строка⍺
применить⍺
к этомуw←
назначить этоw
(для слова )' '∊
…:
Если пробел является его членом (т.е. если совпадение было пустым):⍬
ничего не возвращать (становится пустой строкой)⋄
иначе,1=≢⍵:
если один равен количеству символов в совпадении (то есть его длине):⍺⍵
алфавит этой цифры⋄
иначе,3=≢⍵:
если три равно количеству символов в совпадении (то есть его длине):'Triple',w
перед именем «Triple» в ш Орд⋄
иначе,2↓⍵
перейти к цифрам из матча∇
отреагировать на этоw,
добавить слово'Double',
prepend "Double"источник
JavaScript (ES6),
161 160 152144 байтаВывод включает в себя один ведущий пробел.
Попробуйте онлайн!
или см. отформатированный исходный код
Как?
Преобразование выполняется в три этапа:
"X X"
на"double X"
"double X X"
на"triple X"
Чтобы сохранить байты, мы используем одно и то же регулярное выражение для всех шагов:
который работает следующим образом:
На шаге 1 мы используем функцию обратного вызова, которая выбирает правильное слово из таблицы поиска:
"799999"
→" seven nine nine nine nine nine"
На шаге 2 мы заменим на
"$1 double$2"
:" (seven)( nine)( nine)"
→" seven double nine"
"( nine)( nine) nine"
→" double nine nine"
На шаге 3 мы заменим на
"triple$2"
:" (double)( nine)( nine)"
→" triple nine"
источник
Wolfram Language (Mathematica) , 115 байт
Попробуйте онлайн!
Принимает список цифр в качестве ввода. Вывод включает ведущий пробел.
источник
Stax , 56 байт
Запустите и отладьте его
источник
Python 2 ,
171169168 байтПопробуйте онлайн!
-1 байт, спасибо Jitse
источник
1312
;)['','double ','triple '][n]
до' eellpbiurotd'[-n:0:-2]
168 байт: Попробуйте его в Интернете!Perl 5
-p
, 111 байтПопробуйте онлайн!
Объяснение:
источник
Scala , 213 байтов
Понял. Каким-то образом рекурсивная версия, которую я пытался создать, была гораздо более многословной, чем эта (хотя все еще рекурсивной, но только в одном случае). Функция
f
принимает в качестве входной строки номер телефона и выводит его фонетику с пробелом в конце.Попробуйте онлайн!
Изменить : -8b благодаря DrY Wit!
Scala , 215 байт
И вот идет ведущая версия пробелов, по некоторым причинам длиннее на два байта (даже при масштабном рефакторинге).
Попробуйте онлайн!
источник
(o(0)+"").toInt
наo(0)-48
.PHP ,
174169166159 байтПопробуйте онлайн!
Для каждой цифры в индексе,
$i
начиная с 0:$i
равен 3, печатает'triple '
и добавляет 2 к$i
так, чтобы на следующей итерации было перепрыгнуто 2 цифры.$i
равен или больше 2, но не равен 3, печатает'double '
и добавляет 1,$i
так что на следующей итерации будет перепрыгивать 1 цифра.$i++
,источник
Сетчатка 0.8.2 , 105 байт
Попробуйте онлайн! Выводит пробел. Объяснение: Первоначально я попробовал регулярное выражение, которое автоматически соответствует 2 или 3 цифрам, но подход @ Арнаулда оказался более удачным. Объяснение:
Подберите пары одинаковых цифр и замените первую на
=
. Затем повторите, чтобы для нечетного числа вторая последняя цифра также была заменена на=
.Поместите цифры (и
=
).Обрабатывать регистр из трех одинаковых цифр.
Замените все оставшиеся символы словами.
источник
Желе , 59 байт
Попробуйте онлайн!
Монадическая ссылка, которая принимает в качестве аргумента строку цифр и возвращает строку Jelly из слов, разделенных пробелами. Когда вызывается как полная программа, выводит неявно.
источник
T-SQL 2017, 238 байт
Добавлены некоторые разрывы строк, чтобы сделать его читабельным
Попробуйте онлайн
источник
C ++, 382 байта
Это не суперсловер, но кто-то должен был написать версию C ++. Рекурсивная функция R проходит по входной строке и считает повторные значения. Если есть более 3 повторов, он делает вид, что было 2 повторения, затем перематывает и пытается снова.
Еще несколько исходных символов могли бы быть вытеснены с помощью
#define
Major, но я уверен, что лучший алгоритм мог бы выжать больше.и проверка контрольных примеров:
источник
#include <sstream>
? Или вы могли бы сдвинуть это после гольфовой части для тестовой функции? Я думаю, что печататьstd::ostream&s
заняло бы меньше места, чемusing namespace std;
, если нет других мест, где вам нужноstd::
.Perl 6 ,
9693 байтаПопробуйте онлайн!
Это блок анонимного кода, который принимает число и возвращает строку с цифрами в верхнем регистре, например,
0123 => oh ONE TWO THREE
с одним завершающим пробелом.Это было удалено на некоторое время, пока я не узнал, как использовать перехваты в запросе, но это должно быть исправлено сейчас.
источник
Красный , 242 байта
Попробуйте онлайн!
источник
Scala , 253 байта
Попробуйте онлайн!
источник
Oracle SQL, 578 байт (в отформатированном виде)
Решение не является кратким, поэтому публикуйте его в формате.
Тест в SQL * Plus
Основная хитрость заключается в том, что цифры преобразуются в слова с использованием моделей формата Oracle вместо жестко закодированных литералов «один» ... «девять».
источник
union all
сselect regexp_replace(s,case when length(regexp_substr(s, '(.)(\1)+')) = 3 then '^...' else '^(.)\1|^.' end) from r
.JavaScript, 142 байта
Попробуйте онлайн!
источник
(Roblox) Lua 5.1 , 166 байт
Убедитесь,
s
что это предопределенное строковое значение, заполненное только цифрами; это будет переменная, которая будет изменена. Результат будет включать ведущий символ пробела[\u20]
.источник
s
чтобы ввод уже был. Кроме того, у вас есть хороший первый пост! Я бы порекомендовал вам включить ссылку на сайт онлайн-тестирования, например, tio.run/#lua, чтобы другие могли проверить ваше решение