Consejos para jugar al golf en Japt


18

Ahora que soy completamente adicto al Code Golf, probablemente sea hora de que intente aprender algunos idiomas de golf.

Dado que juego casi exclusivamente en JavaScript, Japt parece ser el lenguaje lógico para empezar. Voy a sumergirme en la documentación en la próxima oportunidad que tenga pero, mientras tanto, publique cualquier consejo que tenga para Japt en las respuestas a continuación.

Como soy un principiante en Japt y en los idiomas de golf en general, si pudiera "traducir" sus consejos a JavaScript, siempre que sea posible, sería una gran ayuda para ayudarme a entender las cosas.


Je, gracias por publicar esto. Había estado esperando hacer esto porque me gustaría rediseñar Japt en algún momento, pero eso no sucederá pronto, y de todos modos probablemente no arruinará muchos de los consejos. Consejo para mí: escribir un tutorial: P
ETHproductions

No olvides visitar la sala de chat de Japt :)
Oliver

Respuestas:


11

Mudarse de JavaScript a Japt

Como ya sabrás, Japt es simplemente una versión reducida y extendida de JavaScript. Creé Japt porque estaba cansado de los nombres largos de propiedades, como String.fromCharCode(x)y Math.floor(x), y de lo tedioso de hacer cosas como crear un rango. Aquí está lo mínimo que necesita saber al pasar de JavaScript a Japt:

  • Japt es un lenguaje transpilado ; El código de Japt se transpira a JavaScript y luego se ejecuta como JS. (Supongo que se podría decir compilado , pero transpilado suena más hipster. Descargo de responsabilidad: no sé absolutamente nada acerca de ser hipster)
  • Todas las entradas son programas completos por defecto. La entrada se analiza implícitamente, y las primeras seis entradas se ponen en las variables U, V, W, X, Y, y Z; la matriz completa se almacena en N. El resultado de la última expresión se imprime automáticamente.
  • Todas las letras mayúsculas son variables y permanecen igual cuando se transpiran. La mayoría tiene valores preestablecidos, que puede encontrar en la sección "Variables" de los documentos de Japt (en el intérprete ).
  • Todas las letras minúsculas son funciones prototipo o métodos . Japt agrega los métodos a- z(y à- ÿ) en números, cadenas y matrices. Cuando usa una de estas letras, Japt completa el .y (; Ucen Japt es equivalente a U.c(en JavaScript, lo que podría significar ceil, charCodeAt o concat, dependiendo del tipo de U. De aquí proviene la mayor parte del poder de Japt; puede encontrar listas completas de estos métodos en las secciones "_____ funciones" de los documentos de Japt (en el intérprete ).
  • Un espacio representa )y )representa )). Esto se debe a que cuando diseñé Japt por primera vez, quería guardar tantos bytes como fuera posible, y así fue como pensé en hacer esto. (Aunque Us w nse ve mejor que Us)w)n), en mi humilde opinión).
  • Una función se denota como ABC{...}, donde ABCpuede ser cualquier cadena de variables. Las funciones funcionan en su mayor parte como lo hacen en JS, la diferencia principal es que la última expresión se devuelve automáticamente (en lugar de tener que usar returno imaginar paréntesis ES6).
  • 'denota una sola cadena de caracteres ( 'aes decir, es lo mismo que "a"), #toma el siguiente código de caracteres y se convierte en ese número ( #ees el mismo que 101).
  • Cualquier cosa entre signos de dólar $permanece igual durante el proceso de transpilación. Puede usar esto para implementar forbucles, por ejemplo, ya que Japt no los tiene, pero sugeriría usar otros métodos (como men cadenas y matrices, o oen números).
  • La mayoría de los otros caracteres comúnmente utilizados en JS - "",0-9 , (, +, =, etc - siendo el mismo cuando transpiled (en su mayor parte, de todos modos).

Y eso es todo lo que necesita saber para escribir código básico de Japt. Lograr la máxima potencia de golf en Japt requiere más conocimiento, pero eso se puede encontrar en otras respuestas.


Aquí hay un ejemplo básico. Digamos que desea tomar una cadena de caracteres ASCII y reemplazar cada uno con su código hexadecimal char. Así es como puedes hacer eso en JavaScript:

U.split("").map(x=>x.charCodeAt(0).toString(16)).join("")

Ahora para convertir a Japt. .split("")en JS es equivalente a q""en Japt, o incluso más corto, solo q. .join("")también es justo q, la diferencia es que el objeto es una matriz en lugar de una cadena. .map(es m, .charCodeAt(es cy .toString(ess . Entonces nuestro código Japt podría verse así:

Uq mX{Xc0 s16} q 

Sin embargo, en Japt mfunciona tan bien en cadenas como en matrices, por lo que podemos eliminar ambos qs:

UmX{Xc0 s16}

¡Pruébelo en línea! Como puede ver en el cuadro "Código JS", esto se transmite directamente a:

U.m(function(X){return X.c(0).s(16)})

A medida que aprenda a trabajar con Japt, se centrará cada vez menos en la conversión de JavaScript y podrá codificar en Japt como su propio idioma. Aquí hay una explicación que omite la parte de JavaScript por completo:

UmX{Xc0 s16}
               // Implicit: U = input string
UmX{       }   // Take U, and replace each character X with the result of this function:
    Xc0        //   Take the char-code at index 0 in X (the first and only one).
        s16    //   Convert this to a hexadecimal string.
               // Implicit: output result of last expression

Sería mejor mostrar otro paso: los accesos directos unicode. En este caso, podríamos ahorrar 2B con ellos. Además, es posible que desee agregar que puede dejar de lado ciertas cosas al final. Eso ahorraría otro byte.
Lucas

Una excelente cartilla, gracias, ETH. Creo que hay suficiente para comenzar con algunos desafíos simples.
Shaggy

Combinando esto con lo que he obtenido del archivo README hasta ahora, ¿estaría en lo correcto de que el ejemplo anterior podría acortarse aún más Um_c s16?
Shaggy

O, más corto todavía: ¡Xc s16?
Shaggy

1
@ Shaggy Tienes razón! Hombre, has descubierto esto rápidamente ;-) Agregaré algunos consejos básicos de golf de Japt (como atajos Unicode y demás), probablemente como otras respuestas.
ETHproductions

8

Comprimir matrices de cadenas

ACTUALIZACIÓN: desde entonces, las herramientas incluidas en este consejo se han reescrito, mejorado e integrado en mi intérprete Japt . Para obtener los mejores resultados, se recomienda que use ese compresor sobre cualquiera de los que se relacionan a continuación. Revisaré este consejo cuando tenga más tiempo y lo reescribiré con el nuevo compresor en mente.

Introducción

Si tiene una serie de cadenas en su código, la forma más obvia de comprimirla sería ejecutar cada cadenaOc individualmente. Para los fines de este consejo, trabajaremos con la matriz ["lollipop","marshmallow","nougat","oreo"], que inicialmente pesa 42 bytes. Ejecutar cada cadena Ocnos da:

[`lo¥ipop`,`Ú\hÚaow`,`Í`,`eo`]

Eso es ahora 33 bytes, un ahorro decente.


Paso 1

Pero podemos hacerlo mejor. Si unimos la matriz a una cadena separada por una nueva línea, podemos deshacernos de los corchetes, comas y backticks extraños y dividirnos en una nueva línea para obtener nuestra matriz. La aplicación de eso a nuestra matriz de ejemplo nos da lo siguiente:

`lo¥ipop
Ú\hÚaow
Í
eo`·

Hasta 26 bytes ahora.


Paso 2

Pero , ¡podemos hacerlo mejor aún! Podríamos usar una letra minúscula para delimitar las cadenas en lugar de una nueva línea, que podría incluirse en la compresión. zno se usa en ninguna de nuestras cadenas, así que dejemos eso y veamos cómo nos llevamos.

`lo¥ipopzÚ\hÚaowzÍzeo`qz

Ah, loco, no hay mejora allí; ¡Nuestro número de bytes ha aumentado en uno! Puede haber otra carta se puede usar, pero, dependiendo de sus cadenas, no puede haber un buen número para tratar - en nuestro ejemplo hay 11: b,c,d,f,j,k,q,v,x,y,z. Probar cada uno sería bastante tedioso, que es donde entra esta práctica herramienta ; alimente sus cadenas separadas de nueva línea e intentará delimitar las cadenas con cada letra que no esté contenida en ninguna de ellas y generará:

  • la cuerda comprimida más corta,
  • el delimitador que usa, y
  • su longitud

Ejecutar nuestras cadenas de muestra a través de él muestra que bda los mejores resultados:

`lo¥ipáæqrÚaowbÍÞo`qb

Y ahí lo tienes, tenemos solo 24 bytes.


Paso 3

¡Pero podemos hacerlo aún mejor! Si el orden de las cadenas en su matriz no importa, tal vez haya una permutación diferente combinada con un delimitador diferente que podría funcionar incluso más corto. Sin embargo, probar cada posibilidad será mucho más tedioso. Con nuestras 4 cadenas, hay 24 permutaciones diferentes para probar. ¡Con cada una de las 11 letras posibles que se convierte en 264! Ahí es donde entra en juego esta herramienta . Nuevamente, alimente sus cadenas separadas de nueva línea e intentará cada combinación de cada permutación y cada letra delimitadora, dando como resultado:

  • el orden de las cadenas en la cadena comprimida más corta,
  • la cuerda comprimida
  • el delimitador que usa, y
  • su longitud

Ejecutar nuestras cadenas de muestra a través de él muestra que "nougat","oreo","lollipop","marshmallow"con bun delimitador se obtienen los mejores resultados, con un recuento final de bytes de solo 23:

`ÍÞo½o¥ipáæqrÚaow`qb


Consejo adicional: Compresión de matriz de enteros

Puede aplicar el mismo principio a las matrices de enteros convirtiendo primero cada una a una base más alta. Con esta muestra, matriz de 36 bytes:

[588181,156859,595676,475330,680474]

Podemos reducirlo a 29 bytes convirtiéndolo primero en una matriz de cadenas de base 32 y luego ejecutándolo a través del primer programa de compresión:

`huclt4p5r5ÛÊg62tkogq`qt mnH

O tan bajo como 27 bytes usando el segundo programa:

`4p5Ïcl5ÛÊg62tkogq`qt mnH

Es posible que pueda guardar otro byte o 2 además de eso moviendo la conversión entera a un método que ya esté ejecutando en la matriz.


Notas

  1. No olvide tener en cuenta el q<letter>(<space>)costo adicional de 1 o 2 bytes adicionales ·. Sin embargo, es posible que pueda usar uno de los accesos directos de Unicode para recuperar un byte, dependiendo de su delimitador ( es lo mismo queql<space> , por ejemplo).
  2. Una palabra de precaución al usar la última herramienta: cuantas más cadenas tenga, más permutaciones habrá y más lento se ejecutará el programa, hasta que finalmente se caiga. Como se detalla anteriormente, con nuestras 4 cadenas de muestra y 11 letras posibles para probar, hay 264 combinaciones posibles, aumente el número de cadenas en solo 1 con las mismas 11 letras y ya tenemos 1320 combinaciones para probar. (Si lo desea, puede usar esta herramienta para contar la cantidad de combinaciones).

Créditos

  • Oliver por la inspiración para crear las herramientas que se encuentran en este consejo.
  • ETHproducciones para corrección de pruebas.

6

Cuerdas de compresión

Japt (actualmente) usa la biblioteca shoco para la compresión de cadenas. Puede comprimir una cadena arbitraria utilizando Oc, siempre que contenga series de letras minúsculas:

Oc"Hello, World!"

Esto genera HÁM, WŽld! (bueno, Žtécnicamente es un carácter no imprimible). Puede descomprimir esto envolviéndolo en comillas invertidas:

`HÁM, WŽld!`

¡Pruébelo en línea!

Alternativamente, puede usar la Odfunción para descomprimir una cadena arbitraria. Esto no suele ser útil, pero tiene sus propósitos ...


Entonces, si estuviera respondiendo el "¡Hola Mundo!" desafío, ¿usaría solo HÁM, WŽld!o tendría que estar entre comillas? Estoy adivinando lo último.
Shaggy

2
@Shaggy Al responder una pregunta, necesitarías incluir todo el código, por lo que sería 'HÁM, WŽld! en este caso
Martijn Vissers

6

Acortar números con códigos de caracteres

En Japt, puedes usar # , seguido de un personaje para crear un código de caracteres. Esto es útil al acortar números más largos.

Como mencionó @ETHproductions, esto solo funciona en ejecuciones de tres dígitos en el rango de 100-255, a menos que esté dispuesto a cambiar a UTF-8.

Ejemplos:

123 se puede acortar a #{

101 se puede acortar a #e

Incluso puedes encadenarlos:

123101 se puede acortar a #{#e

Puede usarlo String.fromCharCode(123)en JavaScript o 123den Japt para encontrar el carácter apropiado.

String.fromCharCode(123) devoluciones {


Gracias, @obarakon, un gran consejo para que la pelota ruede; String.fromCharCode()es uno de esos (¡muchos!) métodos JS desagradablemente largos que pueden acumular el recuento de bytes. Presumiblemente, ¿se considerarían enteros? es decir, si necesito el entero 123en una solución, podría usarlo #{para guardar un byte.
Shaggy

1
Sí, estos son enteros. Si agrega el -Qindicador en su ventana de entrada, puede ver mejor el tipo de salida: comillas alrededor de cadenas , matrices , etc.
Oliver

1
Debe mencionar que String.fromCharCode(123)funciona en JavaScript, pero puede hacerlo 123den Japt para obtener el mismo resultado ;-) Además, esto solo funciona en ejecuciones de tres dígitos en el rango 100- 255(a menos que esté dispuesto a cambiar a UTF-8)
ETHproductions

@ETHproductions ¡Buena llamada, actualizada!
Oliver

5

Consejo rápido: matriz vacía []

Japt tiene una constante para una matriz vacía: A. Pero, para acceder a él, debe anteponer un punto y coma ;a su programa para usar las constantes alternativas de Japt, de lo contrario Aserá 10. Por lo tanto, el uso en ;Arealidad ofrece un ahorro de 0 bytes [], pero le ahorrará bytes si necesita asignar su matriz a una variable (por ejemplo, A=[]).

Sin embargo, si (y solo si) su programa no toma ninguna entrada, puede acceder a la matriz vacía con solo 1 byte utilizando la Nvariable, que es la matriz de entradas; sin entradas, estaría vacía. Pruébalo aquí .

Esto también tiene el beneficio adicional de permitirle usar los valores constantes predeterminados en su programa y, en algunos casos, aún puede ahorrarle bytes de uso ;Aincluso cuando su programa está recibiendo información gracias a los accesos directos para s1y s2.


2
Wow, no había pensado en usar N, buena idea.
ETHproductions

2
¡Buena, @Shaggy!
Oliver

4

Evaluando JavaScript

Japt le permite ejecutar JavaScript sin formato envolviéndolo $...$.

Por ejemplo, $alert("hello world")$

Esto se puede acortar mediante el aprovechamiento de auto-cierre de Japt $y ).

$alert("hello world")$ se puede acortar a $alert("hello world"

Comprimir JavaScript

También puedes comprimir JavaScript usando Ox.

Si hay una función de JavaScript que desea usar, por ejemplo screen.width, puede comprimir la cadena "screen.width"usandoOc , luego insertando el resultado entre Ox` ... `

Tenga en cuenta que no necesita cerrar las comillas en Japt cuando no le sigue nada más.


@Shaggy Necesita el Oxpara evaluar la cadena. De lo contrario, simplemente generaría el texto "screen.width". Ejemplo
Oliver

4

Conoce las banderas

Según el último meta consenso (diciembre de 2017) , los indicadores de línea de comandos ya no se cuentan para los bytes. Es realmente una gran noticia para Japt, ya que tiene muchos indicadores para un tratamiento adicional en la entrada / salida.

Todos los indicadores disponibles en Japt se describen a continuación, en el orden de evaluación . Las banderas en el mismo grupo son exclusivas entre sí. Tenga en cuenta que las banderas en diferentes grupos se pueden usar en combinación, lo que resulta en algo como esto :)

mdefæ

Todo el programa se mapea sobre el primer argumento ( U).

Si hay más argumentos presentes, se pasan como están (es decir, no asignados por pares). De lo contrario, el segundo argumento es el índice, y el tercero es toda la matriz, al igual que U.m. Si Ues un número, se convierte en rango; si es una cadena, se convierte en una matriz de caracteres y los resultados se unen.

  • -m: Aplica lo anterior y nada más.
  • -d: Devuelve truesi algún resultado es verdadero, de lo falsecontrario.
  • -e: Devuelve truesi todos los resultados son verdaderos, de lo falsecontrario.
  • -f: Devuelve la matriz de elementos Ucuyos resultados son verdaderos.
  • : Aplica -fy devuelve su primer elemento.

gh

Toma un elemento en el índice especificado.

  • -g: Toma el primer elemento (índice 0).
  • -gX: Toma el elemento en el índice X(puede ser cualquier número entero positivo).
  • -h: Toma el último elemento.

Convierta el resultado a booleano.

  • -!: Aplicar booleano no.
  • : Aplicar booleano no dos veces (devuelve la veracidad).

N

Convierte el resultado en número. Se utiliza el plus unario.

PRSQ

Convertir a cadena de algún tipo.

  • -P: Únete a la matriz con "".
  • -R: Únete a la matriz con "\n".
  • -S: Únete a la matriz con " ".
  • -Q: Aplicar JSON.stringify(puede ser cualquier objeto, no solo una matriz). Ejemplo .

x

Aplica la función xa la salida. (Literalmente x, no es "ninguna función de alfabeto en minúsculas").

  • Matriz: Suma.
  • Cadena: Recorte desde ambos extremos.
  • Número: Redondear a entero.

2
Tenga en cuenta que el uso de banderas no cuenta como un envío de Japt, sino que cuenta como un envío de lenguaje de Japt con esos indicadores específicos.
Nit

3

Atajos Unicode

Hay muchas estructuras comunes en Japt que simplemente no se pueden almacenar en un único carbón ASCII, tales como qS , p2 , mX{, , etc Así que para evitar esto, Japt tiene atajos "Unicode", que son caracteres del rango \xA1- \xDE( ¡- Þ) que se expanden a estas estructuras comunes. Puede encontrar una lista completa de estos en los documentos del intérprete .

Además, @representa XYZ{, y _representa Z{Z, para ayudar a construir funciones. Así que vamos a jugar a nuestro programa de ejemplo con otra respuesta :

UmX{Xc0 s16}

En primer lugar, podemos reemplazar X{Xcon _, lo que nos da:

Um_c0 s16}

Entonces podemos reemplazar m_con ®guardar otro byte:

U®c0 s16}

O podríamos reemplazar X{con @, lo que nos da:

Um@Xc0 s16}

Esto nos permite usar el ¡acceso directo para guardar dos bytes:

¡Xc0 s16}

Uno de estos dos caminos se puede acortar 1 byte más que el otro. ¿Puedes averiguar cuál?


1
®c s16por 6 bytes - ¿gano una cookie?
Shaggy

@Shaggy Puede guardar 1 byte más si mira lo suficiente ...;)
ETHproductions

¿Lo sería ®c sG?
Shaggy

1
¡Sí! Creo que es lo más bajo que puedes llegar. ¡Bien hecho! :-)
ETHproductions

2
Increíble mirar hacia atrás, ver la progresión de Japt en unos pocos meses. Esto ahora se puede lograr con csG.
Shaggy

3

Aproveche las variables preestablecidas

Variables A: Sestán preestablecidas en valores comunes que toman más de un byte para representar en Japt:

  • A- Gson 10- 16.
  • Hes 32, Ies 64, Jes -1, Les 100.
  • Kse define como new Date(), que puede manipular de varias maneras.
  • My Oson objetos con varias funciones útiles. Puedes obtener más información en los documentos.
  • Pes la cadena vacía, Qes una comilla, Res una nueva línea y Ses un espacio.
  • Testá configurado en 0, por lo que puede usarlo como acumulador si es necesario.

Si el primer carácter en el programa es un punto y coma ;, A-Lse restablecen de la siguiente manera:

  • Aes la matriz vacía [].
  • Bes "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
  • Ces "abcdefghijklmnopqrstuvwxyz".
  • Des "QWERTYUIOP\nASDFGHJKL\nZXCVBNM".
  • Ees "[a-z]"y Fes "[A-Za-z]"(útil antes de agregarlos como funciones de expresiones regulares)
  • Ges 36, Hes 65y Ies 91(útil para rangos alfabéticos).
  • Jes una coma simple; L, un solo período.

Hoy en día solamente A, B, C, y Dde esta lista son realmente útiles. Estoy planeando agregar un mejor sistema que permita hasta 256 variables de dos bytes, que se preajustarán a estos valores y mucho más.


3

Usar funciones automáticas

Lo más probable es que ya lo sepas @y que _sean atajos paraXYZ{ y Z{Z, respectivamente (cubiertos en la respuesta de atajos Unicode ). Pero a veces puedes hacer funciones aún más cortas.

Suponga que tiene una serie de caracteres y desea asignar cada carácter a su código de caracteres. Puede hacer esto con cualquiera de estos:

mX{Xc} 
m_c} 

Pero hay una mejor manera. Si un método u operador es el primer elemento después de otro método o un( , se convierte en una cadena. Entonces estas dos líneas son equivalentes:

r'a'b  // Replace all "a"s with "b"s; transpiles to .r("a","b")
ra'b   // Does the same thing, 1 byte less; transpiles to the same thing

Pero, ¿cómo ayuda eso con nuestras funciones? Bueno, la mayoría de los métodos que aceptan funciones, si se les da una cadena que representa un método u operador, la interpretarán como una función. Lo que significa que también puedes hacer esto:

m_c}  // Map each item to its char code
m'c   // Does the same thing, 1 byte less
mc    // Also does the same thing, 2 bytes less

Yo llamo a estas "funciones automáticas". Hay varias variedades diferentes:

  • m@Xc}mc
  • m@Xc1}mc1
  • m@X+1}m+1
  • m@1+X}m!+1
  • m@2pX}m!p2

Con suerte se entiende la idea. Para intercambiar los argumentos, simplemente prefije el método u operador con !.


¿Vale la pena señalar aquí que el uso de funciones automáticas también puede permitir mayores ahorros mediante el uso de atajos? por ejemplo, m@2pXÃm!p2<space>m!².
Shaggy

Woah! No pensé en usar una cadena en el mapa, ni siquiera sabía que era posible. Quizás ahorre algunos bytes gracias a esto en el futuro.
RedClover

Hola @Soaku, de alguna manera extrañé que hayas respondido con Japt, ¡así que permíteme darte una bienvenida tardía! Espero que hayas disfrutado usándolo hasta ahora. Si tiene alguna pregunta, sugerencia o simplemente quiere hablar, siéntase libre de unirse a nosotros en la sala de chat de Japt (Github generalmente funciona igual de bien para los primeros dos;))
ETHproductions

3

Asignación de variable implícita

Cada vez que comienza una nueva línea en Japt, el resultado de la línea anterior se asigna automáticamente a una de las variables de entrada ( U- Z), siendo la primera línea U, la segunda V, etc.

Tomemos un ejemplo: digamos que desea crear 2 matrices para trabajar, una que contenga los números del 1 al 10 y la otra que contenga sus cuadrados. El largo camino para hacer esto sería así:

U=Aõ V=Um² [do something with the arrays]

Sin embargo, el uso de la asignación automática de variables se puede acortar a:

Aõ
Um²
[do something with the arrays]

Hemos guardado 4 bytes allí. Pero, en este caso, podemos guardar un byte más porque la matriz de 1-10 está asignada Uy Upuede omitirse en ciertos escenarios :

Aõ
m²
[do something with the arrays]

Precaución

Una cosa a tener en cuenta con este consejo es que no sobrescribe ninguna variable de entrada que pueda necesitar más adelante en su programa. Esto se puede evitar dejando una o más líneas vacías al comienzo. En el siguiente ejemplo, las 2 matrices se asignarán a las variables V& W, en lugar de U& V:


Aõ
Vm²
[do something with the arrays]

3

Conoce el Javascript

Dado que cualquier código Japt se ejecuta como JS transpilado, una buena comprensión de los operadores JS y los métodos incorporados ayuda mucho en las piezas de golf del código Japt.

Consejos relevantes de JS

[]Vm@...
...
  • Cortocircuito
  • Partiendo con números
    • Esto se puede generalizar a cualquier método que acepte cadenas pero no números. Un número pasado allí se convertirá implícitamente en una cadena, a menudo guardando un byte (por ejemplo, 0sobre '0).

Funciones incorporadas relevantes de JS

Observe detenidamente qué parámetros se pasan a los argumentos de la función.

Para los métodos de cadena, es bueno saber cómo difieren los comportamientos entre pasar una cadena o expresión regular con o sin gbandera.


3

Use varias líneas cuando sea necesario

Para la mayoría de los desafíos no demasiado difíciles, puede expresar la solución en una sola línea de Japt, como una secuencia de aplicación de funciones integradas. Pero los más complejos requerirán el uso de construcciones en bucle, recursividad o reutilización de grandes fragmentos de código. Aquí es donde entra la programación multilínea.

Eliminar parens de cierre

Tarea : Dada una matriz de números, empareje cada elemento con el índice al cuadrado y ordénelo por la suma.

[5,1,17,9,3] => [[5,0],[1,1],[17,4],[9,9],[3,16]] => [[1,1],[5,0],[9,9],[3,16],[17,4]]

La solución de una línea es íUm@Yp2})ñx, pero })cuesta dos bytes (y no hay un acceso directo de un byte). Puede eliminar })simplemente moviendo el final ñxa la siguiente línea, para que el código se vea así:

íUm@Yp2
ñx

y el JS transpuesto se convierte en:

U = U.í(U.m(function(X, Y, Z) { return Y.p(2) })); U.ñ("x")

Puede ver claramente que esto hace lo mismo que la solución de una línea, simplemente asignando el resultado intermedio nuevamente U.

Recurrir con argumentos implícitos

La función de recursión ßtoma todo UVWXYZcomo parámetro implícito, si no se especifica. Uobviamente es la entrada principal, pero puede usar cualquiera de ellos VWXYZpara realizar un seguimiento de otros valores que necesita. Por ejemplo, puede hacer algo como lo siguiente:

(modify input and implicit assign to U)
(modify V and implicit assign to V)
(test something and call ß without arguments; U and V are passed automatically)

Alternativamente, si todo lo que desea es una variable temporal, puede usar la asignación en línea, como (T=...), ya que la variable T(0) rara vez se usa tal cual.

Reutiliza una función larga

Para esto, no creo que se me ocurra una buena tarea de ejemplo, por lo que haré referencia a la única solución que se usó este consejo , y solo describiré algunas ideas generales.

  • Para reutilizar una función, debe almacenarla en una variable. Comienza una línea con el abridor de funciones {, @o _hace el trabajo. Alternativamente, también puede hacer algo como (T=@...})incrustar la asignación de funciones dentro de una línea más compleja.
  • En realidad no es trivial llamar a la función almacenada. Supongamos que Ves una función y queremos llamar V(U)a JS. VUno funciona ya que simplemente significa V,U. V(Utampoco lo hace; es V,(U). Incluso los métodos de función no son de mucha ayuda. La mejor manera que encontramos es:
    • [U]xV (mapa y suma) si el resultado es número
    • UmVif Ues un único carácter y Vdevuelve una cadena, o
    • $V($Uo [U]mV gen general
  • Sin embargo, mapearlo o recorrerlo es bastante fácil. Para mapear sobre una matriz, use UmV. Para encontrar el primer entero que satisfaga V, use Va.

2

Diversión con funciones automáticas

Como seguimiento a la sugerencia general de ETH sobre funciones automáticas , esta sugerencia proporcionará algunos ejemplos específicos de trucos para guardar bytes que puede lograr con ellos, a lo que agregaré a medida que piense más.


Obtenga el entero más grande en una matriz.

Supongamos que tenemos la matriz [3,1,4,2]asignada a la variable Uy que queremos recuperar el mayor número de ella. nos podía hacerlo en 4 bytes por la clasificación de la matriz y luego hacer saltar el último elemento:

Un o

La desventaja de eso es que hemos modificado la matriz original; Ues ahora[1,2,3] que no siempre es deseable. Afortunadamente, hay una manera de hacerlo sin modificar la matriz que también es un byte más corto:

Urw

Lo que hemos hecho allí es reducir la matriz usando el wmétodo, que, cuando se usa en un número entero, devuelve el número entero más grande y el argumento del método (por ejemplo, 2w5retornos 5). Entonces lo anterior es el equivalente de UrÈwYo UrXY{XwY}. Sin embargo, tenga en cuenta que este consejo no funcionará en el caso de que todos los enteros en la matriz sean negativos.


1
Nota al margen: estoy planeando agregar funciones para obtener el mínimo y el máximo de una matriz, aunque probablemente solo en v2.
ETHproductions

2

Cuando no usarí

íes un útil incorporado que empareja (o zips) dos matrices o cadenas, y opcionalmente asigna cada par a través de una función. Sin embargo, actualmente tiene algunos problemas menores cuando se le dan matrices o cadenas desiguales:

  • Si la primera matriz tiene más elementos que la segunda, los elementos inexistentes en la segunda se darán como undefined.
  • Si la segunda matriz tiene más elementos que la primera, detendrá el procesamiento al final de la primera matriz.

Esto puede dificultar, por ejemplo, comparar dos cadenas desiguales y tomar el carácter con el punto de código más alto de cada par. Incluso si sabe que Userá el más largo, aún se necesitan muchos bytes para resolver esta tarea simple:

UíUç hV @[XY]n o

Lo que podría hacer en su lugar sería tomar la entrada como una matriz de dos cadenas, transponer la matriz con y, y luego asignar cada fila al resultado correcto:

Uy m_q n o

Esto tiene la ventaja de rellenar siempre la cadena más corta con espacios, por lo que es muy fácil pasar por la totalidad de ambas cadenas.

Ejemplos de la vida real: 1 , 2


2

Generar el rango ASCII

Actualización: Japt ahora tiene una constante para el rango ASCII; El valor alternativo para E, accesible con ;. Vea este consejo para más información sobre las constantes de Japt.

Si bien Japt (todavía) no tiene incorporado un rango ASCII, puede generar una matriz de caracteres en solo 5 bytes:

95odH

Intentalo


Cómo funciona

95ocrea el rango [0,95)con cada elemento que se pasa a través de la función automática d que, cuando se usa en un número, devuelve el carácter en ese punto de código. Pase un número como argumento al dmétodo, en este casoH , la constante Japt para 32, y se agregará al número original antes de convertirse.

Una solución equivalente en JavaScript sería:

[...Array(95)].map((_,x)=>String.fromCharCode(x+32))

Personajes al azar

Para obtener un carácter aleatorio en el rango ASCII, use öen su lugar, que devuelve un número aleatorio del rango [0,X), donde Xes el número en el que se ejecuta.

95ö dH

O, para obtener una matriz de múltiples caracteres aleatorios, pase el número de caracteres que necesita como argumento ö. Lo siguiente devolverá 10 caracteres:

95öA mdH

1

Eliminar caracteres estructurales innecesarios

Por caracteres estructurales, es decir {}, (), $, incluso "e `. Por lo general, puede eliminar estos caracteres siempre que ocurran justo al final de un programa (por ejemplo UmX{Xc +"; "} -> UmX{Xc +"; ).

Además, puede eliminar parens o espacios cuando aparezcan en los siguientes lugares:

  • Contra un punto y coma ;(o el final del programa);
  • A la derecha de {(y por extensión @) o [, o a la izquierda de ]o }.

Además, rara vez se necesitan comas para separar los argumentos. Si escribe AB, por ejemplo, Japt sabe que quiere decir Ay Bseparadamente. Realmente solo necesita una coma para separar dos literales numéricos, comoUs2,5 .

Finalmente, si hay un Ual comienzo de un programa o después de un {o ;, seguido de una llamada al método (letra minúscula o acceso directo Unicode relacionado) o cualquier operador binario que excluya +y -( *,& , ==, etc.), se puede quitar la Ude Parada Byte y Japt lo insertarán por usted.


He encontrado algunas otras instancias en las que Use pueden omitir incluso cuando no se encuentra al comienzo del programa.
Shaggy

@ Shaggy Ah, claro, también funciona después de un {o ;. ¿Hay otros que conozcas? (Ha pasado un tiempo desde que codifiqué esta función: P)
ETHproductions

No puedo pensar en ellos fuera de mi cabeza; Lo revisaré de nuevo cuando regrese a mi computadora mañana.
Shaggy

1

Modificar el último elemento en una matriz

A veces puede que necesite modificar el último elemento en una matriz, así que aquí hay una explicación de una forma corta de hacerlo. Trabajaremos con la matriz [2,4,8,32]asignada a la variable de entrada Uy dividiremos el último entero (32 ) por 2.

La forma obvia de lograr esto sería con esta solución de 9 bytes ( Demo ):

UhJUgJ /2
  • hnxestablece el elemento en el índice nenx .
  • gn devuelve el elemento en el índice n .
  • J es la constante de Japt para -1 , que, gracias al soporte de Japt para el índice negativo, nos permite trabajar con el último elemento en una matriz; útil cuando no conoce el tamaño de la matriz.
  • Y /2 es simplemente división por 2.

Por lo que los juegos por encima del elemento en el índice -1de la matriz con el elemento en el índice -1de la matriz dividida por 2. O en JavaScript: U[3]=U[3]/2. Cuando lo escribes así, parece una forma demasiado larga de hacerlo. Por suerte, no es un camino más corto; podríamos extraer el último elemento de la matriz, modificarlo y devolverlo a la matriz. Realizar cada una de esas operaciones individualmente tomaría más de 9 bytes, pero podemos hacerlas todas a la vez por solo 7 bytes, un ahorro de 2 bytes ( Demo )

UpUo /2

Traducido a JS, es el equivalente de:

U.push(U.pop()/2)&&U
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.