TTT: Turing Text Tape
Introdução
Ah, INTERCAL ...
Por mais que eu queira encorajar todos a Experimentar Online , a produção de texto é simplesmente dolorosa.
De acordo com a documentação, ele usa o "Modelo de Texto de Turing". Embora seja um conceito ... interessante , usá-lo é tão divertido quanto atirar no próprio pé. E o que fazemos com uma tarefa como essa? Automatize.
O modelo de texto de Turing
Os caracteres que INTERCAL conhece são impressos em uma fita circular que só pode ser movida na direção positiva. A impressão é feita passando os comandos de movimento da cabeça da fita em uma matriz para a READ OUTinstrução. Cada caractere ASCII é escrito no interior da fita (o exterior contém os caracteres para a entrada, dãã). Isso resulta em bytes dos caracteres na fita ao contrário. Além disso, a cabeça da fita se move para trás ao longo da lista de caracteres, porque seu posicionamento é baseado na parte externa da fita.
O cabeçote começa na posição 0.
Agora a mágica começa. Eu vou estar usando a explicação de Truttle1 sobre como conseguir a saída .
- Configure uma matriz com o comprimento de saída.
- Preencha as entradas na matriz com os valores de movimento da cabeça da fita.
- Encontre o valor ASCII do caractere atual em binário
- Inverta-o e converta de volta um número
n. - Subtraia
nda posição atual da cabeça e do módulo em 256, se necessário, resultando em um valorr ré o valor que você precisa armazenar na matriz- A cabeça está agora na posição
n.
DO READ OUTa matriz.
OBSERVE
- Array é pré-inicializado com
0, o primeiro índice é1 - INTERCAL usa caracteres ASCII de 8 bits estendidos, portanto, o comprimento da fita de 256.
- Entre 1/3 e 1/5 de todas as linhas devem começar
PLEASE. Observe que, nesse caso, você ignora oDOforGIVE UPeREAD OUT, mas não para qualquer outra coisa, como visto nos exemplos.
Desafio
Dada uma string de entrada, produza um programa INTERCAL válido que imprime essa string e termina.
Exemplos
Imprime "BUZZ"
DO ,1 <- #4
DO ,1 SUB #1 <- #190
DO ,1 SUB #2 <- #152
PLEASE DO ,1 SUB #3 <- #336
DO READ OUT ,1
PLEASE GIVE UP
O espaço em branco é opcional. O seguinte imprime "FIZZ"
DO,1<-#4DO,1SUB#1<-#158DO,1SUB#2<-#208DO,1SUB#3<-#312PLEASEREADOUT,1PLEASEGIVEUP
(Exemplos descaradamente roubados do programa FizzBuzz de Truttle1 do vídeo.)
Você pode encontrar uma implementação de referência não dada em python 3 aqui
Regras
- Sem lacunas padrão
- Este é o código de golfe , o menor código vence.
- Você pode esperar entrada> = 1, caracteres ASCII apenas.
- O programa não pode lançar quaisquer erros além de
ICL774I RANDOM COMPILER BUGeICL666I COMPILER HAS INDIGESTION. O primeiro acontece ao acaso, o segundo é o C-Intercal ficando sem memória e contornando isso não faz parte do desafio
Respostas
Python 3 , 157 bytes
t=i=0
p=o='PLEASE'
for c in input():i+=1;k=int(f'{ord(c):08b}'[::-1],2);o+=i%4//3*p+f'DO,1SUB#{i}<-#{t-k&255}';t=k
print(f'DO,1<-#{i}{o}DOREADOUT,1DOGIVEUP')
Experimente online!
Isso imprime \$n+3\$instruções, das quais \$\left\lfloor \frac{n+5}{4} \right\rfloor\$são educados. Essa proporção mal se encaixa no \$[1/5, 1/3]\$intervalo de educação para todos \$n \geq 1\$.
-1 byte graças a Neil.
JavaScript (Node.js) , 156 148 bytes
s=>`DO,1<-#${Buffer(s).map(c=>o+=`${i++&&~i&3?'':'PLEASE'}DO,1SUB#${i}<-#`+(p-(g=k=>p=k--&&c>>k&1|g(k)*2)(8)&255),i=p=o=""),i+o}DOREADOUT,1DOGIVEUP`
Experimente online!
Experimente a saída em INTERCAL!
Quão?
Inversão de bits
Usamos uma função recursiva para reverter os bits do caractere c .
( g = k => // k = bit position counter
k-- && // decrement k; if it was not 0:
c >> k & 1 // bring the k-th bit of c at position 0 and isolate it
| g(k) // bitwise OR with a recursive call,
* 2 // whose result is doubled
)(8) // initial call with k = 8
Polidez
Começando com i = 0, inserimos uma declaração educada sempre que a seguinte expressão for falsa:
i++ && ~i & 3
Isso significa que inserimos um PLEASEpara o primeiro caractere processado e, em seguida, a cada 4 caracteres começando com o terceiro.
Nem a instrução inicial nem as duas instruções posteriores são educadas. Eles são marcados como Le TTrespectivamente na tabela a seguir.
length | output structure | politeness ratio
--------+--------------------+------------------
1 | LPTT | 1/ 4 = 0.250
2 | LP-TT | 1/ 5 = 0.200 <-- lower bound
3 | LP-PTT | 2/ 6 ≈ 0.333 <-- upper bound
4 | LP-P-TT | 2/ 7 ≈ 0.286
5 | LP-P--TT | 2/ 8 = 0.250
6 | LP-P---TT | 2/ 9 ≈ 0.222
7 | LP-P---PTT | 3/10 = 0.300
8 | LP-P---P-TT | 3/11 ≈ 0.273
9 | LP-P---P--TT | 3/12 = 0.250
10 | LP-P---P---TT | 3/13 ≈ 0.231
11 | LP-P---P---PTT | 4/14 ≈ 0.286
12 | LP-P---P---P-TT | 4/15 ≈ 0.267
13 | LP-P---P---P--TT | 4/16 = 0.250
14 | LP-P---P---P---TT | 4/17 ≈ 0.235
15 | LP-P---P---P---PTT | 5/18 ≈ 0.278
.. | ... | 1/5 < r < 1/3
05AB1E , 77 74 54 bytes
Ç₁+₁šb퀨C¥(₁%€‘‚µ,1<-#1€·,1—¨#1<-#ÿ€·‚Ø€Ä,1‘J‘ÿ€·†¿€¾
-20 bytes portando a resposta Jelly de @UnrelatedString , então certifique-se de votar nele !!
Saídas com espaços no #1 DO,1 SUB#, DO READ OUTe DO GIVE UP.
Experimente online ou verifique mais alguns casos de teste .
Experimente a saída em INTERCAL.
Explicação:
Ç # Convert the (implicit) input-string to a list of codepoint integers
₁+ # Add 256 to each value
₁š # Prepend 256 at the front of the list
b # Convert each value to a binary string
í # Reverse each
۬ # Remove the last digit of each
C # Convert each from binary back to a base-10 integer
¥ # Take the forward differences (deltas) of this list
( # Negate each difference
₁% # Take modulo-256 on each
€ # Map over each integer:
‘‚µ,1<-#1€·,1—¨#1<-#ÿ€·‚Ø€Ä,1‘
# Push dictionary string "PLEASE,1<-#1 DO,1 SUB#1<-#ÿ DO READ OUT",
# where the `ÿ` is automatically filled with the integer
J # Join this list of strings together
‘ÿ€·†¿€¾ # Push string "ÿ DO GIVE UP", where the `y` is filled with the string
# (after which the result is output implicitly)
Veja esta minha dica 05AB1E (seção Como usar o dicionário? ) Para entender por que ‘‚µ,1<-#1€·,1—¨#1<-#ÿ€·‚Ø€Ä,1‘é "PLEASE,1<-#1 DO,1 SUB#1<-#ÿ DO READ OUT"e ‘ÿ€·†¿€¾é "ÿ DO GIVE UP".
Carvão , 90 89 85 bytes
DO,1<-#ILθ⊞υ⁰⭆θ⪫⟦×PLEASE⊖﹪κ³DO,1SUB#⊕κ<-#﹪⁻⊟υΣ⊞Oυ⍘⮌◧⍘℅ι !⁸ !²⁵⁶⟧ω”Z1∨?AE₂-πK↷Y:γüD0←✂
Experimente online! O link é para a versão detalhada do código. Explicação:
DO,1<-#ILθ
Imprima a instrução para definir o comprimento da saída.
⊞υ⁰
Comece com o cabeçote na posição 0. O valor é realmente armazenado na lista vazia predefinida, pois podemos modificar o valor da lista posteriormente usando as funções Pop e PushOperator em vez de ter que recorrer a um comando.
⭆θ⪫⟦...⟧ω
Faça um loop sobre os caracteres e imprima a concatenação de 5 expressões para cada caractere. (Isso é um pouco mais golfo, pois a concatenação sequencia automaticamente os dois valores numéricos na lista).
×PLEASE⊖﹪κ³
Seja educado a cada três caracteres. Há também um PLEASEno final, de modo que a proporção de polidez é ¹⁄₄, ¹⁄₅, ²⁄₆, ²⁄₇, ²⁄₈, ³⁄₉, ³⁄₁₀, ³⁄₁₁ ... depois do qual a taxa de polidez tende a ¹⁄₃.
DO,1SUB#⊕κ<-#
Imprima o índice indexado 1 no início da instrução para produzir o caractere.
﹪⁻⊟υΣ⊞Oυ⍘⮌◧⍘℅ι !⁸ !²⁵⁶
Calcule o binário reverso do caractere atual, produza a diferença da cabeça e atualize a cabeça com o novo binário reverso, tudo em uma expressão. O binário é codificado usando espaço para, de 0modo que pode ser facilmente preenchido para 8 bits, além do uso de strings evita separadores que seriam necessários de outra forma.
”Z1∨?AE₂-πK↷Y:γüD0←✂
Imprima as instruções finais compactadas para produzir a string e sair. A compactação da string significa que não preciso me preocupar em otimizar o número de vezes que produzo PLEASEmais.
Python 3 , 128 bytes
t=0
for c in input():n=int(f'{ord(c):08b}'[::-1],2);print(f'PLEASE,1<-#1DO,1SUB#1<-#{t-n&255}DOREADOUT,1');t=n
print('DOGIVEUP')
Experimente online!
Produz uma saída semelhante à minha solução Jelly, mas é uma modificação da solução Python de Lynn.
Usava originalmente o operador "walrus" do Python 3.8 , mas acabou sendo mais curto, sem 2 bytes.
Jelly , 62 59 bytes
OŻ+⁹BUṖ€Ḅ_Ɲ%⁹“!![ẓ,ȮFẈẋ⁹⁾V!ĖÐĊnß6ṛ»;;“Œ°þ[ṪȦṄ»Ʋ€;“©⁴Œ½OлŒu
Experimente online!
Usa um comprimento de array de 1 e imprime repetidamente para economizar na indexação e define o comprimento para um repetidamente para economizar na lógica de polidez: length-element-print forma uma unidade muito conveniente de 3.
Sem compressão de string:
OŻ+⁹BUṖ€Ḅ_Ɲ%⁹“please,1<-#1do,1sub#1<-#”;;“doreadout,1”Ʋ€;“dogiveup”Œu
Experimente um resultado online!
O Codepoints of input.
Ż Prepend zero,
+⁹ add 256 to each,
B convert each to binary.
U Reverse each,
Ṗ€ remove last element from each,
Ḅ convert from binary.
_Ɲ Subtract all adjacent pairs,
%⁹ and modulo 256.
Ʋ€ Map:
; prepend to the number
“...» "please,1<-#1do,1sub#1<-#",
; append to that
“...» "doreadout,1".
;“...» Append "dogiveup" to the whole result
Œu and uppercase.