Consejos para jugar al golf en Pyth

46

Pyth es un lenguaje de programación procesal inspirado en Python, creado por el usuario PPCG isaacg .

¿Qué consejos generales tienes para jugar al golf en Pyth? Estoy buscando ideas que se puedan aplicar a los problemas de golf de código en general que sean al menos algo específicos de Pyth.

Un consejo por respuesta, por favor.

isaacg
fuente

Respuestas:

25

Escribe el código en Python primero

Pyth es tan similar a Python que es bastante fácil traducir programas de Python a Pyth. Sin embargo, debido a que Pyth es un lenguaje de una sola letra por comando, a veces es difícil escribir Pyth directamente. Al escribir en Python primero, hay menos en qué pensar a la vez (ya que Python es un lenguaje bastante fácil de codificar).

Justin
fuente
1
También podría mencionar que aún puede usar la sintaxis de Python en Pyth, por lo que puede convertir partes del programa individualmente o simplemente usar python si es necesario. (Como hiciste aquí )
FryAmTheEggman
@ mbomb007 Descargue el intérprete de Pyth y lea los documentos. Esa es la única forma confiable que conozco para escribir un programa Pyth.
Justin
@ mbomb007 Lo siento; así aprendí a escribir Pyth (mirando el código fuente). Básicamente no hay documentación sobre Pyth; básicamente tiene que aprender la sintaxis por prueba y error.
Justin
22

Conoce tus variables

Pyth tiene 3 categorías de variables: variables genéricas preinicializadas, variables preinicializadas basadas en la entrada del usuario y variables que generan implícitamente una asignación al primer uso.

Variables genéricas

b = "\n"
d = " "
k = ""
G = "abcdefghijklmnopqrstuvwxyz"
H = {}                            # (empty dict)
N = '"'
T = 10
Y = []
Z = 0

Variables inicializadas de entrada:

Q = eval(input())
z = input()

Tenga en cuenta que estas inicializaciones solo se ejecutarán en un programa dado si la variable asociada se usa fuera de una cadena en el código. Además, el orden es Q, entonces z, si se usan ambos.

Asignación de variables de primer uso:

Jy K. Si desea inicializar ambos al mismo valor, puede hacerlo con una expresión como KJ0, que es equivalente a la más larga J0K0.

isaacg
fuente
18

Use el intérprete en línea aún más nuevo para evaluar sus respuestas.

Tenga en cuenta que este es un software nuevo, por lo que puede tener errores. Por favor repórteme cualquier problema.

isaacg
fuente
2
¡Increíble! No pude encontrar esto con google, ¡justo lo que necesitaba!
theonlygusti
12

Las cadenas al final de la línea no necesitan comillas finales. Por ejemplo:

"Hello, world!

es un programa Hello World completamente válido.

isaacg
fuente
Muy obvio realmente, es el primer resultado de Google para el "lenguaje de programación Pyth". ¿Creaste tu propia página en esolangs?
theonlygusti
3
@theonlygusti Sí, lo hice. Además, no fue el primer resultado en octubre pasado.
isaacg
9

Usar Cpara compresión base

Esto es en realidad indocumentado, C en una cadena es en realidad no chr directa -> int pero en lugar de base 256 -> base 10 (que es el mismo en las cadenas de un carbón de leña). Esto es muy útil para comprimir un int, podemos usar este script para comprimir:

sCMjQ256

Toma 12345678910, da como resultado ßÜ>(algunos no imprimibles allí).

También con una variedad de entradas, puede concatenarlas y con cadenas grandes convirtiéndolas en puntos de código y tratándolas como número base 128.

Otro uso de C, gracias @xnor por mostrarme esto, es hacer un gran número arbitrario. La forma ingenua es:

^TT

Pero podemos mejorar un byte con:

CG

Esta base 256 deconvierte todo el alfabeto. Resultados 156490583352162063278528710879425690470022892627113539022649722= ~ 1.56e62.

Maltysen
fuente
Añadido al documento ahora.
isaacg
8

Utilice las funciones funcionales cortas ... err ...

Cuando el argumento lambda para mapo reducesimplemente aplica una operación a los argumentos ,, puede utilizar las formas cortas, My F. fMxes equivalente a mfdx, y fFxes lo mismo que .UfbZx. Por ejemplo, supongamos que tomamos una lista de números como entrada y salida cada uno incrementado. Un primer enfoque podría ser:

mhdQ

Sin embargo, eso puede reescribirse como:

hMQ

Algo similar se aplica a reducecon F. Como ejemplo, digamos que hay un desafío para calcular el producto de una lista de enteros. Nuevamente, un primer intento puede ser:

.U*bZQ

Sin embargo, con Feso se puede acortar a:

*FQ

Afeita tres bytes ... ¡no está mal!

kirbyfan64sos
fuente
Y no es necesario Q, ya que se complementa cuando la función no se encuentra una entrada, por lo que es*F
Stan Strum
7

Mantenga su implementación de Pyth actualizada.

Estoy mejorando bastante regularmente Pyth, eliminando características menos útiles y agregando más útiles, así que esté atento a las novedades y actualice su copia de la implementación regularmente.

Algunas características agregadas recientemente: (a partir del 19/10/14)

y: Actúa como *2en números y como lista de todos los subconjuntos en cadenas y listas. Por ejemplo:

pyth -c 'y"abc'
['', 'a', 'b', 'c', 'ab', 'ac', 'bc', 'abc']

f: fes normalmente el comando de filtro. Ahora, cuando se llama con un número como segundo argumento, se filtrará sobre la secuencia infinita comenzando con ese número y contando por unos, luego devolverá el primer elemento de la secuencia resultante.

Por ejemplo, aquí está el código para encontrar el primo más pequeño de más de mil millones:

pyth -c 'f!tPT^T9'
1000000007
isaacg
fuente
Parecen adiciones útiles, pero ¿qué puedes usar en lugar de las viejas yz? mvdczdno puede ser el camino más corto ...
Dennis
1
@Dennis Descarté el viejo yporque no creo que Pyth necesite tener múltiples formatos de entrada analizados de manera muy fácil, solo uno, por ejemplo, el formato Python. Entonces, sí, creo que mvdczdtendrá que hacerlo, desafortunadamente.
isaacg
@Dennis Problema resuelto, acabo de agregar esto a rla suite de procesamiento de cadenas.
isaacg
rSe ve muy útil.
Dennis
@isaacg Lo siento si esto está fuera de tema, pero me pregunto cómo usar la operación raíz @en Fdr1 + 1 @ Q2Iq% Qd0d para hacer una calculadora de factores. Cuando intento usarlo, el valor predeterminado es el indexsignificado. ¿Hay alguna forma de evitar este comportamiento?
StardustGogeta
5

Argumentos nombrados en funciones (ya no se admiten)

A veces, los valores predeterminados en las funciones pueden ser útiles para jugar al golf. Pyth realmente apoya esto (para mi sorpresa). Por ejemplo:

DC=Z1RZ;C;C5

Imprimirá:

1
5

También puede usar J y K para guardar caracteres al hacer esto:

DgJ1K1R+JKg;g2;g2 3

huellas dactilares:

2
3
5

Esto suele ser útil para algoritmos recursivos.

Esto ya no funciona, pero lo he dejado aquí en caso de que alguien quiera jugar golf usando una versión antigua de Pyth.

FryAmTheEggman
fuente
16
Wow - ¡Incluso no me di cuenta de que Pyth apoyaba esto y escribí el lenguaje!
isaacg
Desafortunadamente, esto ya no funciona en versiones más recientes de Pyth.
isaacg
¿Debería eliminarse este consejo como uno de los otros consejos desactualizados? De lo contrario, tal vez debería estar marcado con las versiones a las que se aplica esta sugerencia.
mbomb007
@ mbomb007 He querido encontrar la versión, pero he sido demasiado vago. Lo eliminaré si crees que es mejor así hasta que lo encuentre.
FryAmTheEggman
@FryAmTheEggman Creo que depende de ti, ya que dice en el título que no es compatible.
mbomb007
5

Desempacando tuplas de 2 elementos con F

Supongamos que tiene una tupla de 2 elementos J = (a, b), y desea r(a,b), para alguna función de aridad de 2 r.

La forma ingenua de hacer esto es rhJeJ.

La mejor manera de hacerlo es r.*Jutilizando el operador de desempaquetado.

La forma realmente elegante de hacer esto es rFJusar el operador de plegado.

isaacg
fuente
¿Todavía es posible usar .upara eso? .uParece ser acumulativo reducir ahora.
Ven
.u ->. * este fue un cambio que se realizó hace un tiempo, pero nunca se actualizó.
isaacg
4

Usa las funciones aritméticas cortas

h: Además de devolver el primer elemento de una lista, incrementa un número, por ejemplo, hTevalúa a 11. Más corto que +1T.

t: Esto disminuye un número (que no sea devolver la cola de una lista), por ejemplo, tTevalúa a 9. Más corto que -T1.

y: Esto duplica un número, por ejemplo, yTevalúa a 20, más corto que *T2o +TT.

Jakube
fuente
4

Use mappara generar listas

Básicamente es un equivalente de la lista de fantasías de Python. Use una lista existente o un rango para iterar y mapear cada valor, incluso si el valor no importa.

Dos ejemplos:

  • Genere una lista de 8 ceros.

    mZ8 en lugar de *8]Z

  • Genere una lista de 5 números aleatorios entre 0 y 9:

    mOT5 en lugar de V5~Y]OT)

    El segundo asigna automáticamente la lista a Y(bueno, en realidad se agrega a Y), pero incluso =YmOTU5es más corta.

Jakube
fuente
4

Q implícito en EOF

Este es un nuevo cambio, a partir de hoy.

Qes la variable que se inicializa automáticamente en la entrada evaluada. Se adjunta implícitamente al final del programa Pyth, tantas veces como sea necesario para que el arity funcione. Para ver un ejemplo de cómo usar esto para jugar al golf, digamos que queremos calcular la función Collatz de la entrada.

La forma más corta de escribirlo es así:

@,/Q2h*3QQ

Sin embargo, dado que los Qs están implícitos al final del archivo, simplemente podemos escribir:

@,/Q2h*3

Ahorro de 2 bytes.

Tenga en cuenta que las funciones con argumentos no obligatorios no tendrán esos argumentos rellenados. Por ejemplo, c"12 12"no tendrán un implícito Q, ya que csolo requiere 1 argumento.

isaacg
fuente
3

Use reducir para aplicar una función repetidamente.

Suponga que necesita establecer una variable para alguna función de sí misma y repetir un cierto número de veces. Tomemos, por ejemplo, el problema de encontrar el número 100 más tarde en la secuencia de Collatz a partir de la entrada. La forma más corta de encontrar el siguiente número en la secuencia, si el número inicial es Q, es

@,/Q2h*Q3Q

La forma más obvia de aplicar esto 100 veces e imprimir el resultado sería

V100=Q@,/Q2h*Q3Q;Q

Haga un bucle 100 veces, actualizando el valor de Q cada vez, luego finalice el bucle e imprima Q.

En cambio, podemos usar una función de reducción que ignora la variable de secuencia ( H).

u@,/G2h*G3GU100Q

Esto es 2 caracteres más corto. Tiene 3 caracteres más cortos si está intentando recorrer tantas veces como haya elementos en una secuencia.

isaacg
fuente
3

Por lo general, hay alternativas más cortas a Cualquiera

Cuando desee encontrar si alguna secuencia satisface una condición, generalmente la usaría .Em. Por ejemplo, si desea averiguar si alguno en una lista es mayor o igual que 5:

.Emgd5Q

Pero, si solo necesita ser un verdadero / falso, no verdadero / falso, smfuncionaría ya que sum funciona en bools.

smgd5Q

Incluso podemos hacer uno más corto, con filter:

fgT5Q

Sin embargo, el último se ve realmente feo.

Para .All, lo único que se me ocurre es usar la condición opuesta y negarla para un ahorro de un carácter .Am:

!f<T5Q
Maltysen
fuente
3

Mira todas las opciones de flujo de control

Bucles:

F: En bucle. Al igual que Python.

V: Para bucle en un rango. No se deben proporcionar variables ni rangos, por lo que 2 caracteres son más cortos.

W: Mientras bucle. Al igual que Python.

#: Bucle infinito mientras. Escape con error o ruptura explícita. Solo try ... exceptaparece ahora en Pyth.

Funciones:

D: Definición general. Al igual que Python.

L: 1 argumento, sin función de asignación, como la lambda de Python, pero con nombre. El nombre de la función, el nombre de la variable y return ( R) no necesitan ser dados, entonces 3 caracteres más cortos.

Programación funcional:

f: Filtro: seleccione elementos de la secuencia de entrada que devuelven la verdad en la entrada lambda.

f: Primer entero mayor o igual a la entrada que da un resultado de filtro verdadero.

m: Mapa - transforma los elementos de la secuencia de entrada usando lambda de entrada.

u: Reduce - pliega la secuencia de entrada en la entrada lambda, inicializando el acumulador al tercer argumento.

o: Orden: elementos más antiguos de la secuencia de entrada utilizando la entrada lambda como clave.

Por lo general, habrá múltiples posibilidades para cualquier problema dado, y solo escribiendo soluciones de prueba con cada una de ellas puede determinar cuál es la más corta.

isaacg
fuente
.xpuede usarse más recientemente para bloques try-except.
mbomb007
@ mbomb007, ¿hay alguna forma de descuidar, excepto el bloque? Quiero decir, ¿se puede dejar vacío? Por ejemplo: .x{some_statments}{except_block - can this be empty}.
Gurupad Mamadapur
@GurupadMamadapur # ... Bse puede usar de esta manera si no está dentro de una expresión
isaacg
3

Cambiar dos elementos en una lista

Cambiar dos elementos puede ser una tarea bastante costosa. Así que aquí hay dos enfoques que quieres usar.

Enfoque variable-tmp

En preparación definimos una lista Yy la llenamos con algunos números. El objetivo es cambiar el segundo y tercer elemento.

=Y[1 3 5 3 6 7)AGH,1 2

Simplemente asignamos la variable tmp J = Q[G], hacemos la primera asignación de lista Y[G] = Y[H]y luego la segunda última asignación Y[H] = J. El truco aquí es anidar las dos asignaciones de la lista, para que no tenga que suprimir la impresión y no tenga que usar referir dos veces Y.

J@YGXXYG@YHHJ

en lugar de

J@YG XYG@YHXYHJ

Enfoque de traducción

Si los elementos, que desea cambiar, son únicos en la lista, utilice este enfoque. Es muy corto Así que esta vez cambiamos el primer y tercer elemento (los valores 1y 5son únicos).

=Y[1 3 5 3 6 7)K,Z2

Esto utiliza la funcionalidad de traducción de la lista:

XYm@YdK)

Esta traducción reemplaza cada elemento Y[0]con Y[1]y cada Y[1]con Y[0]. Entonces, si los valores no son únicos, suceden cosas malas. Por ejemplo K,1 2resultados en [1, 5, 3, 5, 6, 7].

Observe que los paréntesis de cierre son opcionales, si la declaración es la última en su código.

Jakube
fuente
3

Depuración con <newline>

Si su código está escrito en un estilo de programación imperativo, es bastante fácil de depurar, ya que puede imprimir fácilmente resultados intermedios. ( enlace permanente )

FN.:Q2                loop
      =Y+-Y-FNhN      some random command
                Y     print intermediate result
                 ;Y   end for loop and print result

Pero una gran cantidad de programas Pyth utilizan elementos de programación funcional, como mapear, filtrar y reducir, que no permiten una impresión tan simple. Pero aún es posible, usando el \ncomando.

El mismo código que usa u(reducir) sería: ( enlace permanente )

u        .:Q2Y   reduce .:Q2, start with G = Y
 +-G-FHhH        random command

Si desea imprimir los valores intermedios, simplemente inserte \n: ( enlace permanente )

u         .:Q2Y   reduce
   \nG             print(G)
 +-\nG-FHhH        random command

\naimprime aen una nueva línea y regresa a. Para que pueda insertarlo en cualquier lugar sin preocuparse de cambiar la funcionalidad del programa.

Jakube
fuente
Hoy en día puede usar la nueva línea para esto, que también imprime una nueva línea.
PurkkaKoodari
@ Pietu1998 Sí, lo uso todo el tiempo. Hora de actualizar la publicación.
Jakube
3

Encontrar el máximo de dos enteros

g#

Por ejemplo, suponga que tiene J=5y K=12. Entonces g#JK= 12, y g#KJ= 12 también.

Esto fue descubierto por @ Pietu1998, quien lo expresó de esta manera:

No estoy seguro de si alguien ya lo ha encontrado, pero hay una manera genial de hacer max (A, B) en 2 bytes, no es necesario usar 3 para eS,AB. g#ABhace lo mismo (Sin embargo, es muy ineficiente, ya que realiza un bucle máximo (1, A-B + 1) veces. Una optimización es poner el número que probablemente sea mayor como B).

isaacg
fuente
@Jakube Esto es cierto. Aparentemente pensé mal algo mientras escribía esto en el chat.
PurkkaKoodari
2

Pyth del joinmétodo

El joinmétodo en Python a menudo puede ser un poco molesto, ya que solo une cadenas. Pyth's joines más generoso. Transforma todos los objetos en cadenas de forma predeterminada.

Ej. jkUTDa 0123456789o jb["abc"4,5\f]7da

abc
4
(5, 'f')
[7]
Jakube
fuente
Recientemente, se agregó aún más funcionalidad de transformación en cadena: el primer argumento también se coacciona a una cadena, por ejemplo, j2\a\b->"a2b"
isaacg
1

Decir si un número es un número entero

Un buen truco es usar Invariante para saber si un número es un número entero como tal:

sI

Esto verifica si el número no cambia cuando lo trunca, lo que no cambiará si es un número entero.

Por ejemplo, puede usar esto como un cheque cuadrado perfecto:

sI@Q2
Maltysen
fuente
1

Use Pyth empaquetado

Packed Pyth es un nuevo "lenguaje de programación" que es exactamente el mismo que Pyth, excepto que utiliza 7 bits por carácter en lugar de 8 bits por carácter.

Para usarlo, clone el repositorio pyth . El archivo packed-pyth.pyes el intérprete.

Digamos que tu código es "Hello, world!.

Primero, póngalo en un archivo: echo -n '"Hello, world!' > code.pyth

A continuación, empaquete el código Pyth en el archivo Pyth empaquetado: python3 packed-pyth.py -p code.pyth code.ppyth

Finalmente, ejecute el código Pyth empaquetado: python3 packed-pyth.py code.ppyth

Al ejecutar el código, puede proporcionar el -dindicador para ver cuál es el código Pyth que realmente se está ejecutando, y puede proporcionar información como un segundo argumento de línea de comando después del archivo que contiene el código.

Al revés:

  • El código es más corto en 1/8.

Abajo:

  • Solo ASCII.

  • No hay entrada interactiva.

  • Las opciones completas de depuración no están disponibles.

  • Peor informe de errores.

isaacg
fuente
1
como lo hicimos para el modo seguro, ¿podemos moverlo a una bandera?
Maltysen
Esto es impresionante por cierto: D
Maltysen
@Maltysen Creo que eso aumentaría la puntuación de bytes en uno.
isaacg
¿No se puede empaquetar más Pyth ya que solo usa ASCII imprimible?
lirtosiast el
1

Pruebas de divisibilidad usando Iy GCD

Descargo de responsabilidad: esto solo funciona para enteros no negativos.

Para verificar si dos enteros no negativos son divisibles, puede hacer lo siguiente:

iI<divisor><dividend>

Si a es divisible por b y a ≥ b ≥ 0 , entonces mcd (a, b) = b .

No necesariamente guarda los bytes !%<dividend><divisor>, pero puede generar un ahorro, porque:

  • Es posible que pueda modificar las cosas implícitas al final de un programa Pyth (como soltar Q), cuando trabaje con el dividendo.
  • Puede usarlo como un <pfn>, ya que es una función en sí misma.
  • Maneja módulo por 0.

¡Intentalo!

Sr. Xcoder
fuente
Una ventaja más: iIes una función en sí misma, mientras !%que no lo es, por lo que puede usarla como una función de prefijo.
Erik the Outgolfer
@EriktheOutgolfer Gracias, agregado a la lista de ventajas :)
Sr. Xcoder
0

Asignación de una variable a una función aplicada a sí misma

Si tiene una función de arity 1 y desea aplicarla a una variable y aplicarla a sí misma, puede usar la siguiente sintaxis:

=<function><variable>

En lugar de:

=<variable><function><variable>

Por ejemplo, si desea incrementar la variable Z, puede hacer:

=hZ

Lo que ahorra un byte =ZhZ.

Sr. Xcoder
fuente