Alice , 23 bytes
/o!
\i@/e)q&w[?'`-+k3-n
Experimente online!
A entrada deve estar em minúscula. Imprime 1
para palavras em dólar e 0
outros.
Explicação
Hora de mostrar a fita de Alice e algum fluxo de controle avançado. Apesar de ser bastante bom em trabalhar com números inteiros e seqüências de caracteres individualmente, Alice não possui built-ins para: a) determinar o comprimento de uma string; b) converter entre caracteres e seus pontos de código. A razão para isso é que todos os comandos de Alice mapeiam números inteiros para números inteiros ou cadeias para cadeias. Mas os dois exigiriam mapear seqüências de caracteres para números inteiros ou vice-versa, para que não se encaixem nos modos de Alice.
No entanto, além de sua pilha, Alice também possui uma fita e os modos Cardinal e Ordinal interpretam os dados na fita de diferentes maneiras.
- No modo Cardinal, é uma fita comum familiar de outras línguas, como Brainfuck. Você pode armazenar um número inteiro em cada célula e mover uma cabeça de fita. A fita é infinitamente longa e inicialmente contém um -1 em cada célula. As células também são indexadas e a cabeça da fita começa no índice 0 .
- O modo ordinal tem sua própria cabeça de fita (também iniciando no índice 0 ) e interpreta a fita como uma lista de seqüências de caracteres. As strings são finalizadas por células sem caracteres (ou seja, quaisquer valores que não sejam um ponto de código Unicode válido), em particular -1 . Portanto, no modo Ordinal, a fita é inicialmente preenchida com cadeias vazias.
Essa fita pode ser usada para as duas operações acima: para obter um comprimento de string, escrevemos na fita no modo Ordinal, procuramos o -1 no modo Cardinal e recuperamos a posição da cabeça da fita. Para converter caracteres em seus pontos de código, simplesmente os lemos da fita no modo Cardinal.
Os outros dois recursos importantes usados nesta solução são a pilha de retorno e um iterador. Alice tem uma pilha de retorno que geralmente é preenchida ao usar o comando jump j
e da qual você pode inserir um endereço para retornar k
. No entanto, também é possível enviar o endereço atual para a pilha de retorno sem precisar ir a lugar nenhum w
. Se combinarmos w
com o comando repeat&
, podemos enviar o endereço atual para a pilha de retorno n vezes. Agora, cada vez que chegamos k
, uma cópia é retirada da pilha de retorno e executamos outra iteração w
(iniciando na célula depois dela, porque o IP se move antes de executar outro comando). Quando a pilha de retorno fica vazia,k
não faz nada e o IP simplesmente passa. Portanto, &w...k
aparece um número inteiro n e, em seguida, executa ...
n + 1 vezes, o que nos dá uma maneira muito concisa de expressar um for
loop simples .
Para o próprio código ...
/ 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.