Consejos para jugar golf en Underload

11

Underload es un tarpit semi-funcional basado en pila creado por ais523 . Recientemente he estado intentando jugar golf, ya que es un lenguaje sorprendentemente elegante.

¿Qué consejos tienes para jugar al golf en Underload? (Un consejo por respuesta)

Fruta Esolanging
fuente
Me gusta que la única forma de flujo de control es un evalcomando, nunca antes había visto un lenguaje como ese.
ETHproductions

Respuestas:

3

Usar *para salida

Debido a que puede generar resultados dejando una cadena en la pila , puede ser útil acumular la cadena utilizando en *lugar de generar con S. Digamos que su desafío fue "tomar una cadena y agregar un espacio", la forma de hacerlo con la salida sería:

S( )S

La forma de hacerlo *, por otro lado, es un byte más corto:

( )*

El problema es que si su salida tiene mucha acumulación, puede costar bytes lidiar con el elemento de salida en la pila.

Fruta Esolanging
fuente
2

Use un diccionario de funciones reutilizadas repetidamente

Si necesita usar mucho un fragmento de código, tiene sentido almacenar ese código en la pila y duplicarlo y evaluarlo de vez en cuando. Hasta ahora, eso es solo la programación normal de Underload. Desafortunadamente, mantener un valor en la pila durante mucho tiempo es difícil y tiende a hacer que su código se vuelva detallado, y eso es cierto incluso si el valor es una función en lugar de datos. Esto empeora mucho si tiene varias funciones que deben reutilizarse repetidamente.

En el tipo de programa más grande que podría beneficiarse de varias funciones reutilizadas, una solución que puede usar es crear una función grande que pueda cumplir cualquiera de sus propósitos dependiendo de cómo se llame (ya sea en función de lo que está debajo de la pila, o mediante el uso de secuencias ya que sólo llamando ^; una función cuidadosamente escrita puede distinguir ^^del ^:^de ^*^de ^~^, que le da cuatro, secuencias cortas bastante distintas). También puede almacenar otras cosas útiles, como cadenas que usa varias veces, en este "diccionario". Tenga en cuenta que si usa mucho el diccionario, puede tener sentido hacerlo una especie de quine, empujando una copia de sí mismo en la pila, para que no necesite copiarlo manualmente con: para poder usarlo sin perder la capacidad de usarlo en el futuro.


fuente
Me volvería loco mucho antes de tener un programa lo suficientemente grande en Underload que esto se convirtiera en un problema: P
Esolanging Fruit
Una vez escribí algunos ejemplos en la página de esolangs de cómo hacer diccionarios con mi ^!!!!^búsqueda de estilo preferida (que también he usado en varios otros ejemplos en la página, especialmente en la sección de minimización). Aunque eso podría no dar la búsqueda más corta.
Ørjan Johansen
2

Elija formatos de datos especializados para las operaciones que el problema necesita

Como un ejemplo simple, la implementación más común de booleanos son !()para falso (es decir, entero 0) y la cadena nula para verdadero (es decir, entero 1), pero si tiene un problema que se basa en gran medida en XOR lógico, podría generar más tiene sentido usar la cadena nula para falso y ~para verdadero (este formato de datos se puede convertir a cualquier otro formato booleano usando (false)~(true)~^!, y permite la implementación muy concisa *para XOR.

Es posible llevar este principio general aún más lejos y usar funciones que su programa necesitará más adelante como parte de sus valores de datos; eso ahorra tener que almacenar las funciones y los datos por separado en la pila. Esto puede hacer que el control de flujo sea bastante más confuso, pero cuando se juega al golf, la mantenibilidad a menudo tiene que pasar a un segundo plano, y no es que Underload sea tan útil de todos modos.


fuente
Solía ​​usar (!)y (~!)para booleanos, pero tu camino parece mejor.
Esolanging Fruit
2

Decremento "sucio"

La forma funcionalmente pura de disminuir un número de la Iglesia es usar la función predecesora del cálculo lambda:

\n.n(\p.\z.z($(pT))(pT))(\z.z0[whatever you define the predecessor of 0 to be])

Donde 0 = \ x. \ Yy, T = \ x. \ Yx, y $ es el sucesor.

Reescrito en Underload, esto es 28 bytes:

(!())~(!())~(!:(:)~*(*)*~)~^!

Esto está bien, pero podemos explotar algunas de las propiedades útiles de Underload, a saber, que :!y ()*no son operaciones. Esto significa que, para un número n, :ⁿ!!()()*ⁿ(donde cⁿse crepite nveces) produce n-1. Por ejemplo, hacer esto para el número 3 de la Iglesia produce esto:

:::!!()()***

Al eliminar los pares no operativos, obtenemos:

:*

Que es 2.

Así que esta es la operación predecesora nueva y más corta:

:(:)~^(!!()())*~(*)~^*

Esto es 7 bytes más corto.

Fruta Esolanging
fuente
Sin embargo, eso se rompe en n = 0. Si necesita que funcione, (()~(:))~:(^!!())*~(*)~^** todavía es 3 bytes más corto.
Ørjan Johansen
@ ØrjanJohansen En general, tendría un caso especial para n = 0, porque con la disminución de los números de Underload 0 no tiene sentido de todos modos.
Esolanging Fruit
1

Poner valores de pila innecesarios en el espacio del programa

Underload en realidad tiene dos pilas: la pila de cadenas y la pila de comandos que forman el código fuente. Las ^instrucciones de Underload nos permiten mover cadenas de la primera pila a la segunda. Al hacer esto, podemos ahorrar mucha manipulación innecesaria de la pila.

Por ejemplo, supongamos que tenemos (a)(b)(c)en la pila principal y nos gustaría concatenar los dos elementos inferiores, ignorando (c), para obtener (ab)(c). La forma ingenua de hacer esto es rotar la pila para obtener (c)(a)(b)y luego concatenar e intercambiar:

a~a~*~a*^*~

Esto es malo. Usar a~a~*~a*^para rotar la pila de esta manera es extremadamente costoso y debe evitarse cuando sea posible. Al poner (c)en el espacio del programa, esto se puede hacer cuatro bytes más corto:

a(*)~*^

La idea es tomar las instrucciones que le gustaría ejecutar y luego agregar una instrucción para (c)retroceder al final, y luego evaluar el resultado. Esto significa que no tenemos que preocuparnos (c)hasta que se retrase una vez que hayamos terminado.

Fruta Esolanging
fuente
1
También puedes escribirlo como (*)~a*^, lo que creo que es un poco más composible. Esencialmente ~a*^es el dipcomando de Joy.
Ørjan Johansen