GolfScript se sale con la suya con demasiada frecuencia y creo que un depósito de consejos prácticos para jugar golf en J podría ayudar en la lucha contra el imperio del mal. ¿Qué consejos tienes para acortar este lenguaje ya conciso?
Para aquellos que quieran aprender J, el lugar obvio para comenzar es el sitio jsoftware y particularmente el vocabulario , la guía Learning J y la guía J for C para programadores .

GolfScript gets its own way far too oftenen 2019.Respuestas:
Hay una serie de sutilezas para exprimir los últimos caracteres en J. Para lo siguiente, suponga que cada letra mayúscula es un verbo primitivo (es decir, estoy eliminando los espacios que de otro modo serían necesarios para delimitar nombres).
Cuando tienes un tren en marcha, y necesitas aplicar una función encima de otra a mitad de camino,
([:FLGR)y(LF@:GR)tener el mismo número de caracteres, pero(LF@GR)guarda uno. Si el marco de G es mayor o igual que el rango de mónada de F, esta es una transformación válida. Notablemente, todos los trenes tienen un rango infinito, al igual que la, ,. ,: ~. /: \: [ ]mayoría de los usos de#y|..Si tiene que elegir cadenas de una lista, y estas cadenas no tienen espacios, use
>i{ab`cd`ef. Está sucio, pero guarda caracteres para cada nueva cadena con la que tiene que lidiar, a menos que solo extraiga caracteres individuales, e incluso entonces la lista de caracteres debe ser de longitud 4 para ser más corta. Lo que sucede es que los nombres indefinidos se tratan como referencias a los verbos, y cuando tomas los gerundios de esos verbos obtienes una cadena encuadrada del nombre. Cualquier nombre que ya esté definido como que tenga tipo de sustantivo, adverbio o conjunción no se puede usar de esta manera, porque esos nombres se resuelven antes y`pueden tenerlos.Si tiene la suerte de tener una expresión con la que trabajar y no solo un verbo tácito, casi siempre vale la pena asignar los bits que reutiliza a las variables, ya sean sustantivos, verbos o adverbios. Los padres a veces se pagan a sí mismos al ajustarse directamente a donde tenía espacios antes, y la mayoría de esas definiciones valen la pena si se reutilizan una vez más.
Las conjunciones como
(FGH)^:(u`v`w)se pueden reescribiru`v`w(FGH^:). Esto funciona para cualquier longitud de tren, incluso 1, aunque solo guarda algo si este truco elimina a los padres del argumento correcto. Este truco solo funciona cuando precarga el operando izquierdo. (¿No tiene idea de lo que acaba de pasar? Busque 'adverbios tácitos' y estudie la sección Análisis y ejecución del Diccionario J).¡No uses
a.&i., usau:!{&a.y3&u:son equivalentes en longitud, sin embargo, y el primero podría ser más útil en una conjunción (dependiendo de la conjunción).Cosas como
(2%~F)y(F%2:)son equivalentes en longitud. Esto es útil porque a veces, dependiendo de cómo se vea el resto de tu tren, puedes reestructurarlo con@trucos como están escritos en el primer punto, para salvar a algunos personajes desesperados. (Y, por supuesto, siFes así]y el tren es una mónada, usando%&2salva un char, duh).Trenes en forma de gancho con
]o[como el verbo más a la izquierda, p(]FGH).]le permite romper una aplicación diádica y usar solo el argumento correcto. (Cambia a la izquierda con(]FGH)~una penalización de al menos 1 personaje, tal vez más). ¡Salva un char(FGH)@], y es muy útil en gerundios![en un gancho aplicado de forma monádica le permite hacer algo por los efectos secundarios en el lado derecho, luego devolver el argumento nuevamente. El uso más común es con1!:2, posiblemente con formato de basura.I / O es una mierda. Acelere el proceso haciendo bucles de todo lo que pueda.
1!:1tiene rango0, y ambos1!:2 3tienen rango_ 0, por ejemplo, así que utilícelo haciendo matrices de 1s y corra1!:1directamente sobre ellos. Tenga en cuenta que".también tiene rango 1, por lo que generalmente puede colocarlo directamente después1!:1, y no tener que adjuntarlo a través de@travesuras de rango.No es fácil encontrar lugares para colocar esto, pero
::puede ser útil.::]^:_es una combinación particularmente poderosa, por ejemplo, que te permite hacer algo peligroso hasta que ya no puedas hacerlo. (Sujeto a las^:_advertencias habituales como un bucle).Esto también le permite usar
{en listas que no tienen el índice deseado, porque arroja un error de dominio cuando eso sucede. Útil para, por ejemplo, tomar el encabezado de una lista solo si existe (intente usar::]para devolver la lista vacía, o::_1:para devolver un código de error, y así sucesivamente).]`($:@u)@.vgeneralmente se puede hacer más corto queu^:v^:_, especialmente en las definiciones deuy con lasvque se puede jugar. Un caso similar es válido para el condicional comou^:(1-v)vs]`[email protected]. Considere sus opciones, especialmente cuando tiene muchos verbos nombrados flotando. También es un poco más flexible, pero recuerde, si lo usa$:, hay una profundidad de recursión con la que es fácil toparse. (¿Suele ser algo así como 1800 iteraciones?)fuente
%&2salva un char, duh". ¡Y-:salva a otro!Lo más importante al jugar golf en J es no solo entender el problema, sino reducirlo a una serie de transformaciones de matriz. Debe comprender esta forma de pensar para tener éxito con el código J.
Por ejemplo, un desafío reciente pidió resolver el mayor problema de subarreglos . El algoritmo estándar para resolver este problema es el algoritmo de Kadane que tiene la siguiente descripción informal:
Una traducción al código imperativo es sencilla:
Este algoritmo parece complicado para J de un vistazo, ya que hay un ciclo explícito que al principio no parece una reducción. Si se da cuenta de lo que está haciendo el algoritmo, puede desenredar los pasos individuales y ver que realmente realiza dos operaciones de matriz simples:
Ahora estos dos pasos son muy fáciles de implementar en J. Aquí hay una traducción:
(0 >. +)/\. y , 0- Este paso opera desde el otro extremo de la matriz para adaptarse mejor al paradigma de J.0 >. +es tácito0 >. x + y.>./ yEn conjunto, obtenemos una implementación muy concisa del algoritmo:
Si aprende esta forma de abordar la implementación de algoritmos, sus soluciones serán tan claras como este código.
Aquí hay algunos trucos que acumulé con el tiempo. Esta lista se ampliará a medida que obtenga más conocimiento en J golf.
=es extraño al principio, pero es muy útil en los desafíos de arte ASCII.&en contextos tácitos cuando desee una conjunción de poder. El vocabulario sugiereu@[&0como un reemplazo tácito4 : 'u^:x yy yo también.[:o@:en una secuencia comou@vsi eligiera una varianteuque tenga un argumento izquierdo. Por ejemplo, para descartar el primer elemento del resultado dev, use en1}.vlugar de[:}.vsi}.@vno es posible por alguna razón.] va menudo es más corto quev@]si desea usar monádicoven un contexto diádico. Esto resulta útil especialmente cuando sevtrata de un largo tren de verbos.m (n v w) ylugar de(n v m&w) y. Esto puede hacer posible evitar espacios y paréntesis.#\en lugar de>:@i.@#.u &. vEs útil cuandovtiene un anverso. Cuando no, es posible que desee utilizar[: vinv u & vo en suu & (v :. vinv)lugar.^:_es extremadamente útil para algoritmos en los que desea alcanzar la convergencia, como un relleno de inundación o simulaciones.=.y=:se puede incrustar en cualquier parte de una frase. Use esto para hacer frases donde la notación tácita no sea suficiente.,reducciones monádicas en lugar de múltiples cuando reduzca arreglos multidimensionales.fuente
Tenga cuidado con el uso de bucles.
Mientras que J ha estructuras de bucle (
for. do. end.,while. do. end.y variaciones), si usted se encuentra usarlos hay una posibilidad de que su algoritmo no está jugando al golf fortalezas de J y que hay un ahorro de caracteres que se harán.^:La conjunción de poder es tu amigo. Para ejecutar un verboxveces:Si necesita el resultado de cada iteración en una lista:
También puedes usar
^:para ejecutar un verbo condicionalmente:Duplique
+:si^:el elemento es mayor que 33<]("0cambia el rango del verbo para que funcione un elemento a la vez).fuente
(i.x)ejemplo,f^:(<x)es decir, es equivalente af^:(i.x).Entrada
1!:1[1tomará una línea de entrada terminada presionando la tecla enter.1!:1[3tomará una serie de líneas de entrada (terminadas por Ctrl-D en mi Mac, Ctrl-C en Windows).Si está tratando de ingresar números, el uso
".evaluará la cadena y devolverá una lista de números listos para ser manipulados. Si toma un número pero necesita operar los dígitos individualmente".,.(gracias al comentario de Jan Dvorak por esto) o"."0dividirá la cadena en dígitos separados:Si está leyendo en cadenas, la forma más corta de obtener una lista en caja de cadenas separadas es usar
;:. Esto funciona mejor para cadenas separadas por espacios:fuente
1!:1[2funcionaría (si acaso)?1!:página (no soy un experto en J) 2 es la pantalla, por lo que la entrada desde la pantalla no tiene mucho sentido.2no es válido? No tengo mi computadora J en mí para probarlo en este momento. Donde veo2, justo debajo de las notas sobre1!:1, es para1!:2.".es rango 1-xx y,.siempre produce una matriz 2D,".,' ',.(puntada con espacio, deshilachado y evaluación; 8 caracteres) puede reemplazarse por solo".,.(deshilachado y evaluación; 4 caracteres).Usando iteración para calcular secuencias
Típicamente, resolver un desafío de secuencia OEIS requerirá usar una de las fórmulas dadas en su página. Algunos de estos se adaptan bien para J, y otros no tanto. Las fórmulas recursivas son sencillas, sin embargo, la iteración podría no ser simple. Un patrón que comencé a usar es
donde
ses el primer valor de la secuencia,fes un verbo que calculará el siguiente término dado el término anterior, ynes el índice basado en cero del término que desea calcular. Este método se basa en el hecho de que al calcular el poder de una díada, el LHS está unido a la díada para formar una nueva mónada, y esa mónada se anida en el valor inicial. La diada dada al adverbio de potencia es un gancho donde(]f)se le da el índicenen el LHS y el valor de un término en la secuencias. El gancho se aplicaráfenscomo una mónada, y luego ignorarna devolver el resultado def s.Biblioteca estándar
A veces, puede encontrar que J tendrá soporte para un verbo en su biblioteca estándar . Por ejemplo, la mayoría de las operaciones enteras a nivel de bits están vinculadas a nombres que son más cortos que el uso de la llamada primitiva.
Fecha y hora incorporadas también están disponibles.
Rangos
Si tiene un conjunto de valores
[a, b, c]y desea formar un rango basado en su producto[0, 1, 2, ..., a*b*c-1], el enfoque típico sería encontrar su producto y luego formar un rango que podría[:i.*/costar 6 bytes. Una forma más corta es,@i.para 4 bytes, ya quei.puede formar matrices multidimensionales mientras sigue contando, y al aplanarla producirá un rango equivalente.Imprimir continuamente
Una forma tácita de imprimir un valor y continuar usándolo sin un ciclo explícito es
([echo)para un caso monádico.echoes un verbo en la biblioteca estándar que imprime sus contenidosstdouten el mismo formato utilizado en el intérprete. El gancho luego pasa el mismo valor de entrada usando el[verbo izquierdo .Base 10 dígitos de un entero
¡La forma estándar de adquirir los 10 dígitos básicos de un entero es lo
10#.inv]que cuesta 8 bytes, demasiado! Una alternativa es convertirlo en una cadena y analizarlo en el rango 0"."0@":que guarda un byte, pero una forma aún mejor es,.&.":que guarda otro byte haciendo que el costo final sea de 6 bytes en lugar de 8.fuente
Considere usar una definición explícita en lugar de escribir un verbo tácito; seguro
3 :'y'cuesta 5 bytes, pero puede ahorrar mucho@,@:y de[:esa manera.fuente
Algunos trucos (bastante) comunes que he visto
Estoy compartiendo algunas cosas que me han sido útiles. Básicamente, todos estos son consejos que he recibido, pero no tengo créditos para la mayoría.
Suma de una matriz de rango uno
En lugar de usar el
+/@:(FGH)uso(1#.FGH). Esto significa degradar a la base 1, lo que efectivamente significa sumar una matriz. Aunque es más largo que+/, no requiere una tapa o composición, lo que a menudo lo hace mucho más corto que el uso+/.Contando verdades finales
Si tiene una lista booleana y desea contar el número de verdades finales, use
#.~. Vea aquí . La respuesta APL proporciona una buena explicación de cómo funciona esto. De acuerdo, esto solo me ha sido útil dos veces, pero pensé que lo compartiría de todos modos.Debajo (&.)
No es un truco específico, sino solo una sugerencia general: el adverbio
&.debajo a menudo conduce a soluciones elegantes y (más importante) cortas. Tenlo en cuenta cuando juegues al golf.Muchas veces es útil para desafíos de conversión de base y otros binarios , por ejemplo, este código que elimina el bit más significativo de un número:
}.&.#:(convertir a la lista de dígitos binarios, eliminar el primer dígito, luego deshacer la conversión a una lista de dígitos binarios y convertir volver al decimal). La solución directa es dos bytes más:#.@}.@#:.Under también es útil para desafíos en los que necesita trabajar con dígitos decimales, ya que puede usarlos
u&.":. Por ejemplo, el camino corto que las millas dan para dividir en dígitos decimales se usa en:,.&.":.Un último ejemplo es encontrar la magnitud de un vector:
+/&.:*:tenga en cuenta que necesita recopilar todos los resultados de*:-square con&.:-under ya que*:-square es rango cero.fuente
Formas más cortas de meterse con los rangos
A veces, tendrá un código como
<"0 i.3 3, donde desea aplicar un verboven el rangor. Sin embargo, si usa un sustantivo (como0), a menudo tendrá que incluir un espacio. Para evitar esto, puede usar otro verboude rango equivalente y usaru"ven su lugar. Por ejemplo, dado que+tiene rango0 0 0, podemos usarlo en<"+lugar de<"0.Aquí hay una tabla de todos los verbos y sus rangos (que se pueden obtener mediante el uso
v b. 0):Para usar esta tabla, encuentre el rango deseado
ren el lado izquierdo, luego elija un verbo apropiadovdel lado derecho. Por ejemplo, si necesito vectorizar un verboven profundidad2 _ 2, entonces encuentro ese rango a la izquierda y elijo%.desde la derecha. Luego uso env"%.lugar dev"2 _ 2.fuente
stringsbiblioteca: consejos de golfLa biblioteca de cadenas es muy útil para hacer cualquier cosa con la manipulación de cadenas. Claro, toma
include'strings'(lo cual es muy costoso, considerando J), pero a veces puede cosechar los beneficios.stringreplace¿Te encuentras usando el reemplazo de cuerdas? Observe que
A stringreplace Bes lo mismo queB rplc A.De hecho, así es como
rplcse implementa:cutsEl verbo
cutsproporciona así:Entonces, realmente está cortando una cuerda.
fuente
Obtener números del 0 al 4
Si hay una restricción en el uso de números en su código:
0
%_: uno dividido por infinito.1
#_: ¿cuántos infinitos?2
#_ _: dos infinitos.3
verb: hay un incorporado.4
dyad: otro incorporado.Obtener números del 10 al 35
Literales Base-Inifinity: 11 :
_bb, 26 :_bqetc.fuente
Programación tácita
Lo esencial
Verbo diádico
Verbo monádico
Misceláneos
Trucos
(F x) G (H y)Solución tácito:
(G~F)~H; dependiendo de los verbos reales, considere reorganizar los argumentos izquierdo y derecho para eliminar~.Reemplazos monádico-diádicos
fuente
(G~F)~Hes pura bondad burbujeante!&es tu amigo, úsalo sabiamenteves un verbo,nes un sustantivoxyyson argumentos izquierdo y derecho, respectivamente.Mónada
&: Introducir~dentro del adverbio / cadena de conjunciónUna cadena de adverbio / conjunción se evalúa desde la izquierda. Entonces, algo así
_2&+/\&.>no funcionará porque se analiza(_2&+)/\&.>mientras queramos_2&(+/\)&.>. En este caso, intercambiar la izquierda / derecha de+/\puede guardar un byte,+/\~&_2&.>ya que este se analiza como((+/\)~)&_2&.>. Para ver por qué esto funciona:Pareja
&: repetirxtiempos¿Sabías que si le das un argumento
xa la izquierda&, la función se aplica axvecesy? Muchos desafíos le piden que realice ciertas operacionesxtiempos de . Se puede lograr principalmente de dos maneras:^:sin el operando correctoSi la operación es
v, entonces sev^:convierte en un tren adverbio que, cuando se le da un operando izquierdo, se convierte en un verbo monádico. Por lo tantov, se aplica ay,xveces.&como la conjunción más externaPara usar esto, debe identificar un
nverbo constante y un verbo diádicou, de modo quen u yoy u nsea equivalente av. Luego puedes escribirn&uou&nresolver toda la tarea. Esta forma es más efectiva cuando la elección de la constante es obvia, por ejemplo, 3 in3 u:(convertir caracteres a valores ASCII).Además,
u&nse prefiere un pocon&ucuando la estructura más externa deues una conjunción o un adverbio (en cuyo cason&udebería sern&(u); puede hacerlo en suu~&nlugar).Tenga en cuenta que puede colocar la diádica
&en cualquier lugar de un tren para lograr la repetición de funciones arbitrarias a argumentos arbitrarios, en el mismo sentido que dinámico^:.fuente