Алиса , 23 байта
/o!
\i@/e)q&w[?'`-+k3-n
Попробуйте онлайн!
Ввод должен быть в нижнем регистре. Печать 1
на долларовые слова и 0
прочее.
объяснение
Время показать ленту Алисы и продвинутый поток управления. Несмотря на то, что Алиса довольно хорошо умеет работать с целыми числами и строками по отдельности, у нее нет встроенных функций для: а) определения длины строки, б) преобразования между символами и их кодовыми точками. Причина этого заключается в том, что все команды Алисы отображают целые числа в целые числа или строки в строки. Но оба из них потребуют сопоставления строк с целыми числами или наоборот, поэтому они не вписываются ни в один из режимов Алисы.
Однако, помимо стека, у Алисы также есть лента, а режимы Cardinal и Ordinal по-разному интерпретируют данные на ленте.
- В режиме Cardinal это обычная лента, знакомая по другим языкам, таким как Brainfuck. Вы можете хранить одно целое число в каждой ячейке и перемещать головку ленты. Лента бесконечно длинна и изначально содержит -1 в каждой ячейке. Ячейки также индексируются, а головка ленты начинается с индекса 0 .
- Порядковый режим имеет собственную головку ленты (также начинающуюся с индекса 0 ) и интерпретирует ленту как список строк. Строки завершаются не символьными ячейками (т. Е. Любыми значениями, которые не являются допустимой кодовой точкой Юникода), в частности -1 . Поэтому для обычного режима лента изначально заполнена пустыми строками.
Эта лента может использоваться для обеих вышеуказанных операций: чтобы получить длину строки, мы записываем ее на ленту в обычном режиме, ищем завершающий -1 в кардинальном режиме и получаем положение головки ленты. Чтобы преобразовать символы в их кодовые точки, мы просто читаем их с ленты в режиме Cardinal.
Две другие важные функции, используемые в этом решении - это стек возвратов и итератор. У Алисы есть стек возвратов, который обычно заполняется при использовании команды прыжка j
, и с которого вы можете получить адрес для перехода назад k
. Тем не менее, также возможно поместить текущий адрес в стек возврата, не переходя никуда с помощью w
. Если мы соединим w
с повтора команды &
, мы можем нажать на текущий адрес в стеке возвратов п раз. Теперь каждый раз, когда мы достигаем k
, одна копия извлекается из стека возврата, и мы выполняем другую итерацию w
(начиная с ячейки после нее, потому что IP перемещается до выполнения другой команды). Когда возвращаемый стек становится пустым,k
вообще ничего не делает и IP просто проходит. Следовательно, &w...k
появляется целое число n, а затем выполняется ...
n + 1 раз, что дает нам очень краткий способ выразить простой for
цикл.
На сам код ...
/ Reflect to SE. Switch to Ordinal.
i Read the input word as a string.
Bounce off bottom boundary, move NE.
! Store the input word on the tape.
Bounce off top boundary, move SE.
/ Reflect to E. Switch to Cardinal.
e Push -1.
) Seek right on the tape for a -1, which finds the -1 terminating
the input word.
q Push the tape head's position, which gives us the string length N.
&w Repeat this loop n+1 times (see above for an explanation)...
[ Move the tape head left by one cell.
? Retrieve the code point of the character in that cell.
'` Push 96.
- Subtract it from the code point to convert the letters to 1...26.
+ Add the result to a running total. This total is initialised to
zero, because in Cardinal mode, the stack is implicitly filled with
an infinite amount of zeros at the bottom.
k End of loop.
Note that the above loop ran once more than we have characters in the
string. This is actually really convenient, because it means that we've
added a "-1 character" to the running total. After subtracting 96 to
convert it to its "letter value" this gives 97. So dollar words will
actually result in 100 - 97 = 3, which we can check against for one
byte less than for equality with 100.
3- Subtract 3 to give 0 for dollar words.
n Logical NOT. Turns 0 (dollar words) into 1 and everything else into 0.
The IP wraps around to the beginning of the first line.
\ Reflect to NE. Switch to Ordinal.
o Implicitly convert the result to a string and print it.
Bounce off top boundary, move SE.
@ Terminate the program.