Empecé un desafío de golf de código recientemente y parece que el ganador es GolfScript (¡sorpresa, sorpresa!). Lo interesante es que había otro competidor muy fuerte que tenía todas las posibilidades de ganarse a GolfScript. Se llama APL. Veo muchas respuestas escritas en APL aquí. Parece que este lenguaje es bastante eficiente para el golf de código, por lo que decido pedir cualquier consejo de golf de código que conozca para los programas APL. Siéntase libre de publicar algunos ejemplos de código. Suele ser muy interesante ver el lenguaje en acción.
Trenes
fuente
Trucos para tratar
/
y⌿
en trenesAl usar trenes, es posible que desee usar reducciones
f/
como la suma+/
o incluso replicar la reducción//
. Sin embargo, si su tren tiene más partes a la izquierda de la reducción, necesita paréntesis para crear una cima. Aquí hay algunos trucos para guardar bytes.Usar en
1∊
lugar de matrices monádicas∨/
o∨⌿
booleanasTarea: Dadas dos cadenas de igual longitud A y B, devuelve 2 si alguno de los caracteres correspondientes de A y B son iguales, 0 de lo contrario. Por ejemplo,
A←'abc'
yB←'def'
da0
yA←'abc'
yB←'dec'
da2
.Puede ser una solución dfn
A{2×∨/⍺=⍵}B
pero desea acortarla tácitamente.A(2×∨/=)B
no va a funcionar porque las reglas de formación de trenes analizan esto como2 (× ∨/ =)
quieres2 × (∨/=)
.Observe que
∨/
o∨⌿
en un vector booleano (∨/,
o∨⌿,
para matrices de rango superior) pregunta si hay 1 presente, es decir1∊
, para que podamos escribir nuestro tren como2×1∊=
.Tenga en cuenta que
∊
descifra su argumento correcto, por lo que no puede usarlo para reducir cada fila o columna por separado.Usar en
1⊥
lugar de monádico+/
o+⌿
Tarea: Dada una lista de listas L y un índice N, devuelve tres veces la suma de la enésima lista. Por ejemplo
L←(3 1 4)(2 7)
yN←1
da24
.Puede ser una solución dfn
N{3×+/⍺⊃⍵}L
pero desea acortarla tácitamente.N(3×+/⊃)L
no va a funcionar porque las reglas de formación de trenes analizan esto como3(× +/ ⊃)
quieres3 × (+/⊃)
.Observe que evaluar una lista de números en unario (base-1) es equivalente a sumar la lista porque ∑ { a , b , c , d } = a + b + c + d = ( a × 1³) + ( b × 1² ) + ( c × 1¹) + ( d × 1⁰). Por
+/a b c d
lo tanto, es lo mismo que1⊥a b c d
, y podemos escribir nuestro tren como3×1⊥⊃
.Tenga en cuenta que en argumentos de rango superior,
1⊥
es equivalente a+⌿
.Usar en
f.g
lugar def/g
con argumentos escalares y / o vectorialesTarea: Dada una lista L y un número N, devuelve el rango 1 a través del número de división mínima restante cuando los elementos de L se dividen por NEg
L←31 41 59
yN←7
da1 2 3
.Puede ser una solución dfn
N{⍳⌊/⍺|⍵}L
pero desea acortarla tácitamente.N(⍳⌊/|)L
no va a funcionar porque las reglas de formación de trenes analizan esto como⍳ (⌊/) |
quieres⍳ (⌊/|)
.El producto interno
A f.g B
de dos funciones escalares cuando los argumentos son escalares y / o vectores es el mismo quef/ A g B
porque ambos son(A[1] g B[1]) f (A[2] g B[2]) f (A[3] g B[3])
etc., por lo que podemos escribir nuestro tren como⍳⌊.|
.Tenga en cuenta que esto no funciona para matrices de rango superior.
Use en
∊⊆
lugar de/
con argumentos booleanos izquierdo y simple vector derechoTarea: Dada una lista L y un número N, filtre la lista para que solo queden números mayores que N. Por ejemplo
L←3 1 4
yN←1
da3 4
.Puede ser una solución dfn
N{(⍺<⍵)/⍵}L
pero desea acortarla tácitamente.N(</⊢)L
no funcionará porque las reglas de enlace analizarán esto como(</) ⊢
pero desea/
que la función se replique en lugar de que el operador reduzca .Dyadic
⊆
con un argumento izquierdo booleano divide el argumento derecho de acuerdo con corridas de 1s en el argumento izquierdo, dejando caer elementos indicados por 0s. Esto es casi lo que queremos, salvo la partición no deseada. Sin embargo, podemos deshacernos de la partición aplicando monadic∊
. Así{(⍺<⍵)/⍵}
puede convertirse{∊(⍺<⍵)⊆⍵}
y así podemos escribir nuestro tren como∊<⊆⊢
.Tenga en cuenta que esto no funciona para matrices de rango superior.
Usar en
0⊥
lugar de⊢/
o⊢⌿
con argumentos numéricosTarea: Dada una lista L y un número N, multiplique el N con el elemento más a la derecha de LEg
L←3 1 4
yN←2
da8
.Puede ser una solución dfn
N{⍺×⊢/⍵}L
pero desea acortarla tácitamente.N(⊣×⊢/⊢)L
no va a funcionar porque las reglas de formación de trenes analizan esto como⊣ (× ⊢/ ⊢)
quieres⊣ × (⊢/⊢)
.Observe que
0⊥
en una matriz numérica es lo mismo que⊢⌿
, por lo que podemos escribir nuestro tren como⊣×0⊥⊢
.Tenga en cuenta que esto selecciona la última celda principal de las matrices de rango superior.
fuente
Se usa
⊥
para combinar multiplicación con sumaSuposiciones
a
yb
son términos que no requieren más paréntesis cuando se usan como argumento izquierdoC
es una expresión que puede necesitar paréntesis cuando se usa como argumento izquierdoa
b
C
evaluar a escalares numéricosfuente
Números complejos
A menudo pasados por alto, presentan oportunidades maravillosas para acortar expresiones relacionadas con cuadrículas, laberintos, fractales o geometría.
fuente
Longitud del vector del módulo de indexación
⊃i⌽a
a menudo es más corto que el ingenuo⊃a[(≢a)|i]
oa⊃⍨i|⍨≢a
(dondea
es un vector yi
es un entero, y⎕io
es 0)Una variación útil de esto (gracias EriktheOutgolfer por señalar) es:
I↑Y⌽⍨I×X
dóndeY
está la concatenación de algunosI
vectores de longitud yX
es el índice del que queremos elegir, por ejemplo:3↑'JanFeb...Dec'⌽⍨3×month
fuente
Funciones constantes
=⍨
y≠⍨
gracias a ngn.A veces solo necesita un valor único para cada elemento de una lista. Si bien puede tener la tentación de usarlo
{value}¨
, es más corto de usar,value⊣¨
pero para algunos valores comunes, puede ser aún más corto (usar⎕IO←0
):¯1
s con⍬⍸list
0
s con⍬⍳list
1
s con⍬⍷list
Tenga en cuenta que estos solo funcionan en listas (aunque pueden estar anidados). Para las matrices de rango superior, puede usar lo siguiente para obtener todos los 0 y todos los 1:
1
s con=⍨
0
s con≠⍨
Si establece
⎕ML←0
, todos los números se pueden convertir en ceros (como si0×
) con:∊
Si solo necesita un solo número, puede usar monadic
≡
para obtener 1 o 0 en lugar de usar1⊣
o0⊣
.fuente
⊣\
⊣
y⊢
con/
y⌿
merecen una publicación propia.Utilizar
⍨
Evitar paréntesis
⍨
(Conmutar) puede ahorrarle bytes al evitar los paréntesis. Siempre que tenga una función en la que el argumento izquierdo necesite estar entre paréntesis y el argumento derecho no, puede guardar un byte, por ejemplo,(A<B)÷C
→C÷⍨A<B
.Matrices dobles
Para agregar una copia de una matriz a su fin, use
,⍨A
o⍪⍨A
.Números dobles
En lugar de usar
2∘×
para doblar, puede usarlo+⍨
ya que agrega el argumento a sí mismo:1+2∘×
→1++⍨
.Números cuadrados
En lugar de usar
2*⍨Y
un cuadrado, puede usarlo×⍨Y
ya que multiplica el argumento consigo mismo:2*⍨A+B
→×⍨A+B
.Permutación aleatoria
?⍨N
te dará una permutación aleatoria de longitudN
.Autoclasificar
Encuentre los índices de la primera aparición de cada celda principal con
⍳⍨A
Cuente los 1s finales en un vector booleano
En lugar de
+/∧\⌽B
contar la cantidad de 1s finalesN
que puede usar⊥⍨
.Composición inversa
A f∘g B
esA f g B
, pero si quieres(g A) f B
, úsalof⍨∘g⍨
.Reducción inversa
f/ a1 a2 a3
esa1 f (a2 f a3)
. Si quieres(a1 f a2) f a3
, úsalof⍨/⌽
.Exploración inversa
f\ A B C
esA (A f B) (A f (B f C))
.f⍨/∘⌽¨,\ A B C
esA (A f B) ((A f B) f C)
.f⍨\⌽ A B C
es((A f B) f C) (B f C) C
.⌽f/∘⌽¨,\⌽ A B C
. es(A f (B f C)) (B f C) C
.fuente
Enumerar los caracteres en una cadena sin
⍳≢
Tarea: Dadas dos cadenas, S y T, enumere los índices de su concatenación. Por ejemplo
S←'abcd'
yT←'xyz'
da1 2 3 4 5 6 7
.Puede ser una solución dfn
S{⍳≢⍺,⍵}T
pero desea acortarla tácitamente.⍳≢,
no va a funcionar porque las reglas de análisis del tren analizarán esto como(⍳)≢(,)
quieras(⍳≢),
.Dyadic
⍋
con un argumento izquierdo vacío califica las matrices de caracteres simples de acuerdo con su orden actual, que es el mismo que⍳≢
. Así{⍳≢⍺,⍵}
puede convertirse{⍬⍋⍺,⍵}
, así podemos escribir nuestro tren como⍬⍋,
.Tenga en cuenta que esto no funciona para matrices numéricas o mixtas.
fuente