Consejos para jugar al golf en 05AB1E


28

¿Tiene algún consejo para el en 05AB1E , un lenguaje de golf creado por Adnan ?

Sus consejos deben ser al menos algo específicos para 05AB1E.

Por favor, publique un consejo por respuesta.


2
De la opinión: Las preguntas de consejos son sobre el tema.
mbomb007

Respuestas:


20

Como no formaba parte del Wiki en las páginas de GitHub de 05AB1E (creo que debería), lo agregaré aquí ahora que lo entiendo mejor.

¿Cómo usar el diccionario?

05AB1E tiene el siguiente archivo de diccionario words.ex que contiene todas las palabras que conoce. Pero, ¿cómo accedemos a las palabras en este diccionario? Tomemos la palabra "testing"como ejemplo:

"testing"se puede encontrar en la fila 1453 del archivo de diccionario. Como las dos primeras líneas no son palabras, y necesitamos la palabra indexada en 0, restamos 3.
Entonces, ahora tenemos el índice ( 1450), pero ¿cómo usarlo?

Abrimos y comenzamos una cadena comprimida con . Luego miramos la segunda columna del archivo info.txt . (Así es 00; es 01; etc.)
En el caso de "testing"esto significa î(14) y »(50).

Por "testing"lo tanto, la cadena comprimida es: “ Pruébelo en línea. Al igual que con casi todas las piezas de código 05AB1E, el seguimiento es opcional si no accede a la cadena, por lo que sin obras también funciona en este caso .

Algunas cosas a tener en cuenta:

Todos los caracteres que no tienen ningún índice en el archivo info.txt se pueden usar como están. Esto puede ser útil para agregar un sresultado de una palabra plural en lugar de singular o utilizar signos de puntuación como, ,.?!por ejemplo.
ÿ(interpolación de cadenas) también se puede usar cuando desea insertar valores de la pila dentro de la cadena.
NOTA: Cada carácter suelto que no tiene ningún índice en el archivo info.txt cuenta como una palabra para los tipos de compresión a continuación.

Existen diferentes tipos de cadenas comprimidas que puede usar:

  • ': Tome una sola palabra comprimida tal cual (no se 'requiere seguimiento ) - 'î»: "prueba"
  • : Toma dos palabras comprimidas con delimitador de espacio (no se requiere seguimiento ) - „î»î»: "prueba de prueba"
  • : Toma tres palabras comprimidas con delimitador de espacio (no se requiere seguimiento ) - …î»î»î»: "prueba prueba prueba"
  • : Tome la cadena comprimida con delimitador de espacio - “î»î»“: "prueba de prueba"
  • : Tome la cadena comprimida como está sin espacios implícitos - ’î»î»’: "testingtesting"
  • : Tome la cadena comprimida en el título del caso con delimitador de espacio - ”î»î»”: "Pruebas de prueba"
  • : Tome la cadena comprimida en mayúscula completa con delimitador de espacio - ‘î»î»‘: "PRUEBA PRUEBA"

Aquí un programa útil para obtener la cadena comprimida basada en una entrada de palabras delimitada por espacios:

'“? lAð«Ã#¸˜ vyU "€‚ƒ„…†‡ˆ‰Š‹ŒŽ•–—™š›œžŸ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîï" Dâ vy"“ÿ“".V XlQi y?1#] '“,

Pruébalo en línea.

Este programa:

  1. Tome la entrada en minúsculas, elimine los caracteres no alfabéticos (excepto los espacios), y luego divide las palabras por espacios ( lAð«Ã#), o ajusta las palabras en una lista si solo se ingresó una sola palabra ( ¸˜)
  2. Recorre cada palabra ( vyU)
  3. Luego tiene un bucle interno sobre cada palabra comprimida del diccionario ( "€...ï"Dâvy), que intentará ejecutar como programa 05AB1E ( "“ÿ“".V)
  4. Y si es igual a la palabra actual, la imprimirá y romperá el bucle interno. XlQiy?1#

Con una entrada good bye world, por lo tanto, la salida sería “‚¿Þ¡‚ï“. Pruébalo en línea.

NOTA: Aún tendrá que ver si la palabra existe en el diccionario para que este generador funcione, e ignorará los caracteres especiales o las palabras en plural. Solo se encontrarán las palabras que son exactamente iguales en el diccionario.

Aquí un ejemplo donde uso …Ÿ™‚ï!para la cadena "hola mundo!" y ’‚¿Þ¡ ÿ ‚ï!’para la cadena "adiós ÿ mundo!". Tenga en cuenta cómo se usan los espacios y el signo de exclamación tal como están, porque no tienen índices en el archivo info.txt. Además, se utiliza ÿpara insertar el "cruel" que estaba en la parte superior de la pila, que desafortunadamente no era parte del diccionario (pero que todavía estaba comprimido usando el método en la sección a continuación).

¿Cómo comprimir cadenas que no forman parte del diccionario?

Aunque el archivo de diccionario words.ex es bastante grande (10,000 palabras para ser exactos), puede suceder que necesites una palabra que no sea parte de ella, o una cadena que sea simplemente un galimatías. Entonces, ¿hay alguna manera de comprimirlos también?
Ciertamente, mediante el uso .•, se trata de una cadena basada en un alfabeto comprimido de base 255. NOTA: Este método solo puede usarse para caracteres en el alfabeto en minúscula y espacios.

Aquí hay un programa útil para convertir una palabra / cadena a la cadena basada en alfabeto comprimido base-255:

vAyk})> 27β 255B ".•ÿ•"

Pruébalo en línea. .

Lo que hace este programa arriba es:

  • vAyk})>: Tome los índices alfabéticos indexados en 1 de las letras individuales de la entrada, con espacios convirtiéndose en índice 0
  • 27β: Convierta estos índices de la base 27 a un solo número
  • 255B: Convierta este número a Base-255 usando la página de códigos propia de 05AB1E
  • ".•ÿ•": Coloca un inicio .•y un final antes de esta cadena comprimida

Aquí un ejemplo de respuesta donde @Kaldo usa .•zíΘ•para comprimir la palabra "ganso".

¿Cómo comprimir enteros grandes?

Digamos que queremos usar un número muy grande para algo, pero en realidad no se puede recuperar mediante cálculos de pow. Por ejemplo, supongamos que queremos acceder al número entero grande 18238098189071058293por cualquier motivo.

En este caso, podemos usar tanto el inicio como el final para comprimir un número en el formato [1-9][0-9]+.
El número de ejemplo anterior se convertirá •15Y₁Ò'Θpc•. Pruébalo en línea. Nuevamente, al igual que con la cadena de diccionario comprimida, el final puede eliminarse opcionalmente .

Opcionalmente, cuando el número entero es lo suficientemente pequeño, por lo que solo se deben usar 2 caracteres comprimidos, podemos usarlos Ž, en cuyo caso no necesitaremos un byte final para cerrarlo y el número entero se comprime en 3 bytes en lugar de 4. Para ejemplo, el entero 13562daría como resultado •rl•, pero como solo usa dos caracteres, puede serlo Žrl.

Además, los números en el rango [101, 355]se pueden comprimir en 2 bytes usando Ƶmás un carácter adicional de la página de códigos de 05AB1E. Entonces, por ejemplo, Ƶ–se puede usar para el entero 250. Aquí una descripción general de todos los números disponibles. Estos caracteres se convierten de Base-255 a Base-10, y luego se agrega 101 (ya que los números en el rango [0,100]ya son 1 o 2 bytes).

¿Cómo son estos 15Y₁Ò'Θpcy se rlcrean? Muy simple, el número se convierte a Base-255 usando la página de códigos propia de 05AB1E. Así que usted puede utilizar el programa siguiente para obtener un número de comprimido, para lo cual utilizará entonces Ƶ., Ž..o •...•dependiendo del tamaño del entero comprimido:

101 355Ÿså i 101-255B"Ƶÿ" ë 255B Dg2Qi "Žÿ" ë "•ÿ•"

Pruébalo en línea.

Aquí un ejemplo de respuesta donde @Emigna usa •3Èñ•para el entero 246060.

¿Cómo comprimir listas enteras?

A veces, desea comprimir una lista completa de enteros en lugar de un solo número. Por ejemplo, digamos que queremos la lista [5,93,17,83,4,44,32,19,4,45,83,90,0,14,3,17,17,81]por cualquier razón. En este caso, podemos usar lo siguiente: •4βŸ{©£MG]q‡dZΘp•94в Pruébelo en línea.

Aquí un programa útil para generar este número comprimido y la Base a la que queremos convertir:

Z>© β 255B ®s"•ÿ•ÿв"

Pruébalo en línea.

Lo que hace este programa arriba es:

  • Z>: Obtenga el número máximo + 1 de la lista de entrada ( ©: y guárdelo en el registro)
  • β: Convierte la lista de entrada de la base max+1a un solo número
  • 255B: Comprime este número único (como hicimos en la sección anterior)
  • ®s"•ÿ•ÿв": Devuelve el resultado en el formato: número inicial, comprimido , max + 1, finalв

Aquí un ejemplo de respuesta donde uso •4Œ”dóŒfÝŸĀTUÕáOyÖOÀÁàu¼6¹₆Žr‡_›y³eß₂©ǝ²ƶ"SAÎAñ'¡û†Ø(•91вpara comprimir la lista [85,30,29,39,28,37,33,88,31,40,34,89,35,41,32,90,36,38,42,43,44,60,45,61,46,62,47,63,48,64,49,65,81,50,66,51,67,52,68,53,69,86,54,70,87,55,71,56,72,82,57,73,79,80,58,74,59,75,76,77,78,83,84].
PD: En esta respuesta •6j|eDEJÞó(ÍêΓλùÄÞKüzHÇ-ø`JδŠ₂+Öηôî®À8†6/ðÎ6ùøΓ°ÓĆ;ˆ©Ā•2ôhay una alternativa de bytes iguales (57), ya que todos los números tienen exactamente dos dígitos. En algunos casos (especialmente en listas pequeñas), esta puede ser una alternativa más corta.

Compresión entera vs Compresión de lista entera:

Con estos dos puede ir en cualquier dirección. A veces, una lista comprimida es más corta, a veces un número entero comprimido, a veces una alternativa completamente diferente es más corta. Por lo tanto, use siempre su propio juicio y habilidades de golf para posiblemente jugar más cosas, en lugar de confiar completamente en los generadores anteriores. Aquí algunos ejemplos:

[44, 59]( utilizado en esta respuesta de @Emigna ):

[2,4,6,0]( utilizado en esta respuesta de @Emigna ):

  • •3ā•7в es de 6 bytes (generado por el generador de lista de enteros comprimido)
  • Ž3ā7в es de 5 bytes
  • Pero en este caso, Ž9¦Scon 4 bytes sería la mejor opción (número entero comprimido 2460 en una lista de dígitos)

10101001100101001( utilizado en esta respuesta mía ):

  • •a½₄Ƶ6®í• es de 9 bytes (generado por un generador entero grande comprimido)
  • •1∊}•2вJ es de 8 bytes (generado por un generador de listas enteras comprimido con unión agregada)
  • Pero en este caso •1∊}•bcon 6 bytes sería la mejor opción (lista entera comprimida, con un binario en lugar de , que se une implícitamente)

[85,30,29,39,28,37,33,88,31,40,34,89,35,41,32,90,36,38,42,43,44,60,45,61,46,62,47,63,48,64,49,65,81,50,66,51,67,52,68,53,69,86,54,70,87,55,71,56,72,82,57,73,79,80,58,74,59,75,76,77,78,83,84]( utilizado en esta respuesta mía ):


12

Entrada implícita

En los días en que se lanzó 05AB1E, la entrada implícita era bastante nueva y elegante. Hoy en día parece ser necesario para mantenerse al día con otros lenguajes competitivos (como Jelly, MATL, Pyth, etc.).

Por ejemplo, cuando desea agregar dos números, puede hacer II+:

I    # Input_1.
 I   # Input_2.
  +  # Add them up.

Pruébalo aquí


Sin embargo, utilizando la entrada implícita , podemos acortar a solo 1 byte, a saber +:

+    # Take two numbers implicitly and add them up.

Pruébalo aquí


Esto solo ocurre cuando la longitud de la pila es menor que la aridad del operador. Un último ejemplo es 3+. La aridad del +operador es 2, mientras que solo hay 1 elemento en la pila:

3    # Push the number 3 on top of the stack.
 +   # Request implicit input and add to the 3.

Pruébalo aquí


8

Subcadenas

£es el comando para tomar los primeros bcaracteres de la cadena a.
ex: "hello_world"5£ -> "hello"

Pero si bes una lista de índices, en su lugar divide la cadena en partes de (hasta) esos tamaños.
ex: "hello_world"5L£ -> ['h', 'el', 'lo_', 'worl', 'd']


8

Variables predefinidas

Están un poco escondidos en 05AB1E. Aquí hay una lista de todas las variables predefinidas:

  • ¾, empuja 0si la variable counter_variable no se cambia antes de este comando.
  • X, empuja 1si la variable X no se cambia antes de este comando con U.
  • Y, empuja 2si la variable Y no cambia antes de este comando con V.
  • ®, empuja -1si el registro no se cambia antes de este comando con ©.
  • ¯, empuja [](matriz vacía) si no se agrega nada a global_array antes de este comando.
  • ¸, empuja [""]una pila vacía si no hay entrada. (Gracias @Emigna por encontrar este.)

25
¾empuja 0 => eso es lo más no mnemotécnico posible
Fatalize

66
@Fatalize: 0 empuja a 0 también. ¾empuja una variable de contador que se inicializa como 0. Si solo quiere empujar 0, 0 es, por supuesto, más natural, pero si quiere empujar 5,0,7, 5¾7es 2 bytes más corto que 5 0 7.
Emigna

77
En mi día, ¾quise decir .75, y una vez vencí a Pyth con ese hecho . Estos nuevos lenguajes de golf no tienen ni idea de mnemotecnia ...
ETHproductions

31
No tengo idea de lo que están hablando: p. print(3 / 4)en Python 2 me da 0.
Adnan

2
Si al principio, Mempuja -Inf.
mbomb007

7

Usando el lienzo ( Λo )

Como no formaba parte de los documentos, y @Adnan actualmente está demasiado ocupado para escribirlo, solicité permiso para agregarlo como una sugerencia aquí por ahora.

La función Canvas ( Λo ) se puede usar para dibujar líneas ASCII en la pantalla. Tiene tres parámetros requeridos:

  • a Longitud: El tamaño de la (s) línea (s). Esto puede ser un entero único o una lista de enteros
  • b Cadena: los caracteres que queremos mostrar. Esto puede ser un solo carácter, una cadena, una lista de caracteres o una lista de cadenas (en los últimos tres casos los usará uno por uno, incluido el ajuste)
  • c Dirección: la dirección en la que se deben dibujar las líneas de caracteres. En general, tenemos los dígitos[0,7]para las direcciones, para lo cual podemos usar uno o varios. También hay algunas opciones especiales que requieren un cierto carácter (más sobre eso más adelante).

Los dígitos de dirección se [0,7]asignan a las siguientes direcciones:

7   0   1
  ↖ ↑ ↗
6 ← X → 2
  ↙ ↓ ↘
5   4   3

Algunos ejemplos 05AB1E responden donde se usa el Canvas:

Hagamos algo similar al último, así que supongamos que usamos la Λfunción Canvas con los siguientes tres parámetros:

  • a :[3,3,5,5,7,7,9,9]
  • b :!@#
  • c :[0,2,4,6]

Esto dará el siguiente resultado:

  !@#!@#!
  #     @
  @ #!@ #
  ! @ # !
  # ! ! @
  @   @ #
  !#@!# !
        @
@!#@!#@!#

Pruébalo en línea.

¿Entonces, cómo funciona? Bueno, aquí están los pasos con estas entradas anteriores:

  1. Dibujar 3caracteres ( !@#) hacia arriba (dirección 0)
  2. Dibuja 3-1caracteres ( !@) hacia la derecha (dirección 2)
  3. Dibujar 5-1caracteres ( #!@#) hacia abajo (dirección 4)
  4. Dibujar 5-1caracteres ( !@#!) hacia la izquierda (dirección 6)
  5. Dibujar 7-1caracteres ( @#!@#!) hacia arriba (dirección 0)
  6. Dibuja 7-1caracteres ( @#!@#!) hacia la derecha (dirección 2)
  7. Dibujar 9-1caracteres ( @#!@#!@#) hacia abajo (dirección 4)
  8. Dibujar 9-1caracteres ( !@#!@#!@) hacia la izquierda (dirección 6)

La -1están allí porque las líneas se superponen. Entonces los dos primeros pasos son:

#
@
!

Y

 !@

Lo que combinado es:

#!@
@
!

Algunas notas menores:


1
¡Ni siquiera sabía que 05AB1E tenía un lienzo!
MilkyWay90

¿Cómo ... cómo resolviste esto? ¿Código fuente?
Urna de pulpo mágico

1
@MagicOctopusUrn La mayoría de esta respuesta de @Adnan (PD: su última respuesta también está bastante bien explicada ). Por el hecho de +×8que he buscado en el código fuente.
Kevin Cruijssen

5

Pop or get

Al igual que en otros lenguajes basados en la pila, funciones de 05AB1E generalmente pop (consumen) sus entradas de la pila y empujan a sus salidas en la pila.

Sin embargo, algunas funciones obtienen sus entradas de la pila sin consumirlas. Un ejemplo es la headfunción, ¬que produce el primer elemento de la lista de entrada. Ver un programa de ejemplo aquí: ¬+. Esto agrega el primer número de la lista de entrada a cada número de esa lista.

Para saber qué funciones aparecen y cuáles se obtienen, consulte la columna correspondiente en el archivo de información de funciones .


@NeilA. ¡Gracias! Enlace actualizado
Luis Mendo

3

Condicionales y bucles

Los bucles y condicionales reciben automáticamente corchetes de cierre al final de un programa, por lo que solo necesita agregarlos en el código si necesita algo fuera del bucle / condicional.

Por ejemplo, este programa (sin golf) que crea una lista de los primeros nnúmeros primos no necesita corchetes. [¹¾Q#NpiNˆ¼

Pero si quisiéramos realizar alguna operación en la lista resultante, por ejemplo, tomando delta, primero tendríamos que cerrar el ciclo. [¹¾Q#NpiNˆ¼]¯¥


3

Pequeños consejos de golf 05AB1E

Ampliaré esto con pequeños consejos de golf que aprendí en el camino. (Solo acabo de comenzar 05AB1E personalmente).

  • D(duplicar) y Ð(triplicar) en combinación con s(swap) y Š(triple-swap a,b,cto c,a,b) suelen ser más cortos que usar ©(save in global_variable ) y ®(push global_variable ) dentro de los bucles. Esto salvó un byte en esta respuesta mía , así como dos en esta respuesta mía .
  • ½(si es 1, entonces aumentar counter_variable en 1) no es necesario al final de a µ(while counter_variable ! = a, do ...), ya que se hace implícitamente ( guardó un byte en esta respuesta mía ).
  • .Bse divide implícitamente en nuevas líneas. Esto fue útil en esta respuesta mía cuando buscábamos una alternativa para ¡(dividir) sin dejar de mantener elementos vacíos (NOTA: la solución en la respuesta vinculada no funciona cuando los elementos contienen espacios finales después de la división). agregarse a dividir pero mantener líneas vacías en el futuro
  • (cuál de los dígitos del entero de entrada puede dividir equitativamente el entero de entrada) contendrá el número mismo para los dígitos 0(en lugar de los errores de división por cero). Por ejemplo, 1053resultará en[1,1053,0,1] (1053 es divisible por 1 y 3; no es divisible por 5; y da un error de división por cero para 0). Esto fue bastante útil en esta respuesta mía al tomar el poder de la lista, ya que solo 1es verdad en 05AB1E y todo lo demás es falso. SÖPresultando en verdadero ( 1) significa que un entero de entrada es divisible por cada uno de sus dígitos.
  • Después de ver û(palindromizar una cadena dada) me sorprendió que no haya un is_palindrome incorporado. Pero más tarde me di cuenta de que solo se necesitan 2 bytes para lograr eso, que son ÂQ(donde Âestá bifurcado, que es la abreviatura de DR: Copia duplicada e inversa; y Qes verificar si los dos valores superiores en la pila son iguales).
  • Cuando desea filtrar una lista por varias cosas, generalmente es más barato tener varios filtros sueltos en lugar de todos combinados en uno. Porque cuando tiene dos filtros, necesitará algo en la línea de Ds*(duplicar, intercambiar, multiplicar para actuar como AND lógico) vs (cerrar el primer filtro, volver a filtrar) cuando use dos filtros. Por ejemplo: en este desafío tenemos que enumerar todos los números de cuatro dígitos, que contengan al menos uno 0y con una suma de dígitos igual a 9. El uso de un rango [1000,10000]cubre el número de cuatro dígitos, pero luego le quedan dos filtros más. Inicialmente usé ₄4°ŸʒD0åsSO9Q*(14 bytes), pero al usar dos filtros se puede guardar un byte: ₄4°Ÿʒ0å}ʒSO9Q(13 bytes). (Que más tarde se convirtió en golf ₄4°ŸεW°ö9Q(10 bytes) por @Grimy.)
  • Cuando desee comprimir con un entero 0como relleno, puede usarlo . Sin embargo, un problema con esto es que el relleno 0se convertirá en una cadena "0", por lo que si luego trata de ordenar con cadenas mixtas y enteros, lo más probable es que no obtenga el resultado que desea. Aquí un ejemplo de cómo se va a ordenar las listas interior con cremallera: 0ζ€{. Esto se puede solucionar mediante la adición de una conversión explícita a int ( ï) después de la cremallera, y sólo entonces para ordenar: 0ζï€{. Sin embargo, usar el ¾as constante 0con el relleno de zip, hará que siga siendo un número entero en lugar de una cadena durante el zip. Así ¾ζ€{guardará un byte aquí. Este consejo fue proporcionado por @ Mr.Xcoder para guardar un byte en esta respuesta mía .
  • Si desea sumar los dígitos de varios números en una lista, puede usar €SO. Sin embargo, está usando Shorter , que se vectoriza automáticamente Este consejo fue proporcionado por @Grimy para guardar un byte aquí (y 2 bytes aquí ).
  • Si solo está tratando con números enteros no negativos y desea verificar dentro de un filtro si es 0 o 1, por supuesto, puede usar lo obvio 2‹. Sin embargo, usar !(factorial) también solo dará como resultado 1 (verdad) para 0y 1, y cualquier otro valor dará como resultado algo más alto (y por lo tanto falso, ya que solo 1es verdad en 05AB1E). Este consejo fue proporcionado por @Grimy para guardar un byte aquí .

2

Vectorización automática

Tenga en cuenta que algunos operadores en 05AB1E se vectorizan automáticamente en matrices. Por ejemplo, el código 5L3+, que se desmonta al siguiente pseudocódigo:

[1, 2, 3, 4, 5] + 3

se convertiría:

[4, 5, 6, 7, 8]

Si no se vectoriza automáticamente, también puede usar el operador. Toma un comando de un solo carácter y realiza ese operador (monádico) en cada elemento. Un ejemplo para dividir cada elemento es el siguiente código ( pruébelo aquí ):

€S

Mientras que el Soperador normal dividiría cada elemento en la matriz y lo aplanará en una sola matriz ( pruébelo aquí ).


¿Cómo se asigna al enésimo elemento en una matriz?
Andrew Savinykh

@AndrewSavinykh En este momento, no hay nada incorporado para eso, pero es algo que quiero implementar.
Adnan

@Adnan, encontré una manera de hacerlo. Cree otra lista que tenga el valor para asignar también en el enésimo índice. Luego, combine las listas usando ñprecedidas por el valor de n(el índice). tio.run/nexus/05ab1e#@2/iw2XiE2Tio81ldHjj//8A
mbomb007

@ mbomb007 Eso es posible, el único problema es que no puede modificar la matriz después, ya que el comando de fusión solo toma cadenas como argumentos (y convierte la lista en una cadena).
Adnan

2

Orden de las entradas

El orden en que ingresa puede tener un efecto drástico en su código y, a menudo, si está utilizando spara intercambiar la parte superior de la pila con el siguiente elemento más alto de la pila, no está pensando en el problema correctamente. Intente reordenar las entradas y vea si puede deshacerse de la necesidad de intercambiar intercambiando las entradas con anticipación, agregándolas a la pila anteriormente o duplicándolas en alguna parte. La I&O más obvia puede ser la respuesta 05AB1E menos exitosa.


2

05AB1E Golf ASCII-Art

El siguiente código ayuda a convertir el arte ASCII en 05AB1E utilizando una conversión de base personalizada.

|»©ÐÙSDŠ¢øΣθ}R€н¬®sÅ?iD2£RDŠKsì}J©žLR‡®gö₅B®s"•ÿ•“ÿ“ÅвJ"

Pruébalo en línea.

Esto se logra mediante:

  1. Listado de los caracteres únicos en el dibujo ASCII.
  2. Ordénelos por la cantidad de veces que ocurren en la cadena en orden descendente (la mayoría ocurre con los caracteres menos ocurridos).
  3. Invierta los dos primeros elementos si el dibujo ASCII comienza con el carácter más frecuente (para evitar los ceros a la izquierda en el entero comprimido).
  4. Asigne los caracteres de la entrada 0-9A-Za-zen ese orden, cada carácter distinto obtiene su propio carácter de mapeo, hasta que todos hayan sido reemplazados.
  5. Base, comprímalo, utilizando la base más alta que necesita para reemplazar (según la cantidad de caracteres únicos).
  6. Base conviértalo nuevamente a base-255 (para la compresión 05AB1E).
  7. Formato todo en el formato: •<compressed_integer>•“<sorted_distinct_characters>“ÅвJ.

El también le permite comprimir comillas "; la Åвutilizará esta cadena a la base-convertir el número entero generado utilizando la cadena como base personalizado; y Junirá todos estos caracteres en una sola cadena, que se emite implícitamente.

Acepta patrones con hasta 62 caracteres únicos incluidos, buenos para el arte ASCII.
Cuanta menos cantidad de caracteres únicos, mejor será la compresión.


Ejemplo de salida para Dibujar el diagrama de temporización digital XNOR (214 bytes, 9 caracteres únicos):

    ┌─┐ ┌─┐ ┌─────┐ ┌─┐ ┌─┐ ┌───┐  
A ──┘ └─┘ └─┘     └─┘ └─┘ └─┘   └──
  ┌───┐ ┌───┐ ┌─┐ ┌─────┐   ┌─┐ ┌─┐
B ┘   └─┘   └─┘ └─┘     └───┘ └─┘ └
    ┌─────┐   ┌─┐   ┌─┐   ┌───┐   
X ──┘     └───┘ └───┘ └───┘   └────

Sería:

05AB1E , 106 bytes

•I£.µ*:]ó±øqaµb₄ΘYQmœ¹µû₄p´ζÂĆ_5ŠKÑ×ðòË|₄#¹¶úôÂ-Í|¯ε¼É₂ïδ&é–9»ÞFò1î×HÃBjý2ĆÉ≠FYÂÂèC j‘£Å₅Œ•“─ └┘┐┌
XBA“ÅвJ

Pruébalo en línea.

(106/214) * 100 = 49.53% del tamaño de la cadena de arte ASCII original.

Que es el mismo número de bytes que mi envío real para ese desafío en 05AB1E (legado).


Explicación del código:

NOTA: El código no es absolutamente golfista. Está escrito rápidamente para convertir el arte ASCII en la compresión más eficiente, por lo que es bastante feo y largo.

               # Take multi-line input
  ©              # Store it in the register to reuse later                         
ÐÙS              # Only leave unique characters (as list)
   DŠ¢ø          # Map it with the count for each of those characters
       Σθ}R      # Sort it based on that count (highest to lowest)
           €н    # Remove the count again, so the sorted characters remain
¬®sÅ?i           # If the input starts with the most occurring character:
      D2£RDŠKsì} #  Swap the first two characters in the list
J©               # Join everything together, and store it in the register to reuse later
  žLR           # Map each character to [0-9A-Za-z]
      ®gö        # Get the amount of unique characters, and convert it to that Base
         B      # And then convert that to Base-255
®s               # Push the string and swap so the compressed integer is at the top again
  "•ÿ•“ÿ“ÅвJ"    # Insert it in the correct output format
                 #  `•<compressed_integer>•“<sorted_distinct_characters>“ÅвJ`
"•ÿ•"            # (after which the result is output implicitly with trailing newline)

1
Por cierto, dado que 05AB1E ha cambiado la página de códigos, la base máxima cambia de 214 a 255 .
Adnan

1
Tal vez algo para agregar a su respuesta (o modificar el generador con), pero si se utilizan menos de 10 caracteres distintos en el arte ASCII, puede jugarlo en dos bytes. Es decir, su generador le da este byte 22 , pero puede ser este byte 20 en su lugar .
Kevin Cruijssen

@KevinCruijssen la idea era lo que estaba tratando de transmitir, sin afirmar realmente que el generador es algo bueno: P. Sinceramente, dudo que incluso se ejecute en osabie. ¡Lo escribí hace mucho tiempo!
Urna mágica del pulpo

@MagicOctopusUrn No estoy seguro de si se ejecuta en la reescritura de Elixir, pero ciertamente todavía funciona en la versión heredada. Ya he editado la Base-214 a la Base-255 hace aproximadamente un año, como se mencionó en el comentario de Adnan anterior. Aparte de eso, funciona muy bien y lo he usado varias veces (aunque lo jugué cada vez más.;)). ¡La generación tanto de la cadena como del número funciona muy bien!
Kevin Cruijssen

Aquí hay una versión mejorada. (Muy feo y rápido escrito, pero funciona). Haría su ejemplo 108 bytes en lugar de 113. Las mejoras que hice son: ordenar primero los caracteres distintos en la ocurrencia más alta (a menos que la ocurrencia más alta sea el primer carácter, en cuyo caso intercambiará los dos caracteres superiores) para que el comprimido entero es lo más pequeño posible; usando en <str><compr_int><int>вèJlugar de tu <compr_int><int>BžLR<str>‡; y usar en lugar de "comillas, por lo que "puede ser parte de la entrada.
Kevin Cruijssen

1

Las cadenas y las entradas son tipos iguales

No es algo con lo que todos estén de acuerdo, pero funciona.

Considere los siguientes dos programas:

4 5+
"4""5"+

Ambos resultan en 9 . Esto se debe a que cada valor se evalúa primero (con ast.literal_eval). Por eso, podemos realizar todos los operadores de manipulación de cadenas en ints y todos los operadores de manipulación int en cadenas.

Por ejemplo, 12345ûpalindromiza el número 12345, lo que resulta en 123454321. Después de eso, podemos hacer los cálculos regulares de este número.

12345û50000-

Esto daría como resultado: 123404321 .


0

Bucles e iteradores ocultos

05AB1E tiene los siguientes bucles e iteradores normales:

  • F, que itera a través de 0 .. n-1 .
  • G, que itera a través de 1 .. n-1 .
  • ƒ, que itera a través de 0 .. n .
  • v, que itera sobre cada elemento s [0], s [1], .., s [n] .
  • ʒ, que no es exactamente un bucle, sino un comando de filtro por . Abusamos de este comando porque es un comportamiento involuntario de recorrer cada elemento.

Con estos bucles, podemos derivar los siguientes bucles ocultos :

  • En lugar de gF, puede usar el vque también tiene un Níndice que puede usarse.
  • El vy -> ʒreemplazo es un poco más complicado:
    • Necesita imprimir inmediatamente los resultados. Esto elimina la impresión automática de imprimir la parte superior de la pila.
    • El fragmento de código se ejecuta en una nueva pila temporal . Esto significa que no se pueden usar fragmentos dependientes de la pila.
    • Invocar yno es posible en este tipo de bucles.

Sé que esto se publicó hace un año, pero no lo es [, µy εtambién es parte de los bucles / iteraciones normales.
Kevin Cruijssen

Además, la invocación yes posible con algunos de estos ahora.
Urna mágica del pulpo
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.