Algunos consejos aquí:
Constantes:
La página de constantes de Esolangs tiene una lista extremadamente útil de las formas más cortas para crear valores específicos. Me encuentro consultando esta página al menos dos veces por programa.
El comienzo de todo:
+++[[<+>>++<-]>]
Esto configura la cinta en el formato 3 * n ^ 2, que se ve como
3 6 12 24 48 96192128 0 0 '
¿Por qué es esto tan importante?
Bajemos la lista:
- 3 y 6 son aburridos
- 12: Cerca de 10 (nueva línea) o 13 (retorno de carro). También se puede usar para el contador de 0-9
- 24: cerca de 26, el número de letras en el alfabeto
- 48: ASCII para
0
- 96: Cerca de 97, ASCII para
a
- 196 y 128: 196-128 = 64, cerca de 65, el ASCII para
A
.
A partir de este algoritmo, estamos al comienzo de prácticamente todas las secuencias en el rango ASCII, junto con un contador para cada una y una nueva línea de fácil acceso.
Un ejemplo práctico:
Imprimir todas las letras mayúsculas y minúsculas y dígitos.
Con algoritmo:
+++[[<+>>++<-]>]<<[-<->]<<<<++[->>+.>+.<<<]<--[>>.+<<-]
Sin:
+++++++++++++[->+++++++>++>+++++>++++>+<<<<<]>+++++>[-<+.>>.+<]>>---->---[-<.+>]
Pasamos la mayoría de los bytes simplemente inicializando la cinta en el segundo ejemplo. Algo de esto se compensa con los movimientos adicionales en el primer ejemplo, pero este método claramente tiene la ventaja.
Un par de otros algoritmos interesantes en la misma línea:
3 * 2 ^ n + 1:
+++[[<+>>++<-]+>]
Tape: 4 7 13 25 49 65 197 129 1 0'
Esto compensa los valores en 1, lo que logra algunas cosas. Hace que el 12 sea un retorno de carro, el 64 el comienzo real del alfabeto en mayúsculas y el 24 más cerca del 26.
2 ^ n:
+[[<+>>++<-]>]
Tape: 1 2 4 8 16 32 64 128
Debido a que 64 es bueno para letras mayúsculas, 32 es el ASCII para el espacio y 128 puede usarse como el contador para 26 (130/5 = 26). Esto puede ahorrar bytes en ciertas situaciones donde no se necesitan dígitos y letras minúsculas.
Elija la implementación que se adapte a la pregunta:
- Las células negativas son casi siempre útiles, y no hay razón para evitarlas (a menos que no cambie su bytecount)
- Casi exactamente lo mismo con las celdas de ajuste, aún más porque muchas constantes usan el ajuste.
- Los tamaños de celdas arbitrarias son útiles para secuencias matemáticas infinitas, como calcular la secuencia de Fibonacci infinitamente (
+[[-<+>>+>+<<]>]
) o procesar números más grandes / negativos. La desventaja es que algunos métodos comunes, como [-]
y [->+<]
no se puede confiar en ellos, en caso de que el número sea negativo.
- EOF como 0, -1 o sin cambio. Por lo general, es preferible 0, ya que puede recorrer una entrada completa sin verificaciones adicionales. -1 es útil al recorrer estructuras de matriz. Todavía no he encontrado un uso para ningún cambio :(.
Lleve un registro de lo que está pasando:
En todo momento debe tener comentarios sobre dónde debe estar el puntero en relación con los datos que lo rodean, y asegúrese de conocer el rango de valores posibles de cada celda. Esto es especialmente importante cuando ha dividido el puntero antes de un bucle, ya que después querrá unir las dos posibilidades.
En cualquier momento, mi código está plagado de comentarios en cada línea que se ve así:
*0 *dat a_1 ? 0' !0 0*
or
*0 *dat 0' ap1 0 !0 0*
Un consejo adicional es asignar símbolos a significados especiales. En el ejemplo anterior, '
es donde está el puntero, *
significa repetición en esa dirección, ?
significa una celda con valor desconocido, !0
significa una celda que no es cero, _
es un sustituto -
y p
es un sustituto de +
.or
implica que la cinta podría parecerse a cualquiera de las representaciones, y debe manejarse como tal.
Su esquema de símbolos no necesariamente tiene que ser el mismo que el mío (que tiene algunos defectos), solo tiene que ser consistente. Esto también es extremadamente útil al depurar, porque puede ejecutarlo hasta ese punto y comparar la cinta real con la que debería tener, lo que puede señalar posibles fallas en su código.