TTT: Cinta de texto de Turing
Introducción
Ah, INTERCAL ...
Por mucho que me gustaría animar a todos a que prueben en línea , la salida de texto es simplemente dolorosa.
Según los documentos , utiliza el "Modelo de texto de Turing". Si bien es un ... concepto interesante , usarlo es tan divertido como dispararse en el pie. ¿Y qué hacemos con una tarea como esta? Automatizarlo.
El modelo de texto de Turing
Los caracteres que conoce INTERCAL están impresos en una cinta circular que solo se puede mover en sentido positivo. La impresión se realiza pasando comandos de movimiento del cabezal de cinta en una matriz a la READ OUTinstrucción. Cada carácter ASCII está escrito en el interior de esa cinta (el exterior tiene los caracteres para la entrada, duh). Esto da como resultado que los bytes de los caracteres estén en la cinta al revés. Además, el cabezal de la cinta se mueve hacia atrás a lo largo de la lista de caracteres, porque su posición se basa en el exterior de la cinta.
La cabeza comienza en la posición 0.
Ahora comienza la magia. Voy a estar utilizando la explicación de Truttle1 sobre cómo lograr la salida .
- Configure una matriz con la longitud de salida.
- Llene las entradas de la matriz con valores de movimiento del cabezal de cinta.
- Encuentra el valor ASCII del personaje actual en binario
- Inviértelo y convierta un número
n. - Reste
nde la posición actual de la cabeza y el módulo por 256 si es necesario, lo que da como resultado un valorr res el valor que necesita almacenar en la matriz- La cabeza ahora está en posición
n.
DO READ OUTla matriz.
TENGA EN CUENTA
- La matriz está preinicializada con
0, el primer índice es1 - INTERCAL utiliza caracteres ASCII extendidos de 8 bits, de ahí la longitud de la cinta de 256.
- Entre 1/3 y 1/5 de todas las líneas deben comenzar
PLEASE. Tenga en cuenta que, en ese caso, elimina elDOforGIVE UPyREAD OUT, pero no para nada más, como se ve en los ejemplos.
Desafío
Dada una cadena de entrada, genera un programa INTERCAL válido que imprime esa cadena y termina.
Ejemplos
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
El espacio en blanco es opcional. Las siguientes impresiones "FIZZ"
DO,1<-#4DO,1SUB#1<-#158DO,1SUB#2<-#208DO,1SUB#3<-#312PLEASEREADOUT,1PLEASEGIVEUP
(Ejemplos robados descaradamente del programa FizzBuzz de Truttle1 del video).
Puede encontrar una implementación de referencia sin golf en python 3 aquí
Reglas
- Sin lagunas estándar
- Este es el código de golf , el código más corto gana.
- Puede esperar una entrada> = 1, solo caracteres ASCII.
- El programa no puede arrojar ningún error aparte de
ICL774I RANDOM COMPILER BUGyICL666I COMPILER HAS INDIGESTION. El primero ocurre al azar, el segundo es que C-Intercal se queda sin memoria y elude eso no es parte del desafío
Respuestas
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')
¡Pruébelo en línea!
Esto imprime \$n+3\$instrucciones, de las cuales \$\left\lfloor \frac{n+5}{4} \right\rfloor\$son educados. Esa proporción apenas encaja en el \$[1/5, 1/3]\$intervalo de cortesía para todos \$n \geq 1\$.
-1 byte gracias 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`
¡Pruébelo en línea!
¡Prueba la salida en INTERCAL!
¿Cómo?
Inversión de bits
Usamos una función recursiva para invertir los bits del carácter 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
Cortesía
Comenzando con i = 0, insertamos una declaración cortés siempre que la siguiente expresión sea falsa:
i++ && ~i & 3
Esto significa que insertamos un PLEASEpara el primer carácter procesado, y luego cada 4 caracteres comenzando con el tercero.
Ni la instrucción principal ni las dos instrucciones finales son corteses. Están marcados como Ly TTrespectivamente en la siguiente tabla.
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 la respuesta de Jelly de @ UnrelatedString , ¡así que asegúrate de votarlo!
Salidas con espacios en #1 DO,1 SUB#, DO READ OUT, y DO GIVE UP.
Pruébelo en línea o verifique algunos casos de prueba más .
Pruebe la salida en INTERCAL.
Explicación:
Ç # 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)
Vea este consejo mío 05AB1E (sección ¿Cómo usar el diccionario? ) Para comprender por qué ‘‚µ,1<-#1€·,1—¨#1<-#ÿ€·‚Ø€Ä,1‘es "PLEASE,1<-#1 DO,1 SUB#1<-#ÿ DO READ OUT"y ‘ÿ€·†¿€¾es "ÿ DO GIVE UP".
Carbón , 90 89 85 bytes
DO,1<-#ILθ⊞υ⁰⭆θ⪫⟦×PLEASE⊖﹪κ³DO,1SUB#⊕κ<-#﹪⁻⊟υΣ⊞Oυ⍘⮌◧⍘℅ι !⁸ !²⁵⁶⟧ω”Z1∨?AE₂-πK↷Y:γüD0←✂
¡Pruébelo en línea! El enlace corresponde a la versión detallada del código. Explicación:
DO,1<-#ILθ
Imprima la instrucción para establecer la longitud de la salida.
⊞υ⁰
Comience con el encabezado en la posición 0. El valor se almacena en la lista vacía predefinida, ya que podemos modificar el valor de la lista más tarde utilizando las funciones Pop y PushOperator en lugar de tener que recurrir a un comando.
⭆θ⪫⟦...⟧ω
Recorra los caracteres e imprima la concatenación de 5 expresiones para cada carácter. (Esto es un poco más golfista ya que la concatenación secuencia automáticamente los dos valores numéricos de la lista).
×PLEASE⊖﹪κ³
Sea cortés cada tercer carácter. También hay un PLEASEal final, de modo que la proporción de cortesía es ¹⁄₄, ¹⁄₅, ²⁄₆, ²⁄₇, ²⁄₈, ³⁄₉, ³⁄₁₀, ³⁄₁₁ ... después de lo cual la proporción de cortesía tiende a ¹⁄₃.
DO,1SUB#⊕κ<-#
Imprima el índice indexado 1 al comienzo de la instrucción para generar el carácter.
﹪⁻⊟υΣ⊞Oυ⍘⮌◧⍘℅ι !⁸ !²⁵⁶
Calcule el binario invertido del carácter actual, genere la diferencia de la cabeza y actualice la cabeza con el nuevo binario invertido, todo en una expresión. El binario se codifica usando espacio para 0que se pueda rellenar fácilmente a 8 bits, además el uso de cadenas evita separadores que de otro modo serían necesarios.
”Z1∨?AE₂-πK↷Y:γüD0←✂
Imprima las instrucciones finales comprimidas para generar la cadena y salir. La compresión de cadenas significa que no tengo que preocuparme por optimizar la cantidad de veces que produzco PLEASEmás.
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')
¡Pruébelo en línea!
Produce un resultado similar a mi solución Jelly, pero es también una modificación de la solución Python de Lynn.
Originalmente se usaba el operador "morsa" de Python 3.8 , pero resultó ser más corto, no por 2 bytes.
Gelatina , 62 59 bytes
OŻ+⁹BUṖ€Ḅ_Ɲ%⁹“!![ẓ,ȮFẈẋ⁹⁾V!ĖÐĊnß6ṛ»;;“Œ°þ[ṪȦṄ»Ʋ€;“©⁴Œ½OлŒu
¡Pruébelo en línea!
Utiliza una longitud de matriz de 1 e imprime repetidamente para ahorrar en la indexación, y establece la longitud en uno repetidamente para ahorrar en la lógica de cortesía: length-element-print forma una unidad muy conveniente de 3.
Sin compresión de cuerdas:
OŻ+⁹BUṖ€Ḅ_Ɲ%⁹“please,1<-#1do,1sub#1<-#”;;“doreadout,1”Ʋ€;“dogiveup”Œu
¡Pruebe un resultado en línea!
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.