MATL es un lenguaje de golf creado por Luis Mendo . MATL ha demostrado ser altamente competitivo, a menudo superando las presentaciones en otros idiomas de golf como Pyth, CJam y Jelly.
¿Cuáles son algunos consejos útiles para jugar golf en MATL? (Como siempre, un consejo por respuesta, ¡por favor!)
- Para el registro, MATL se puede probar en línea aquí .
- La documentación se puede encontrar en Github
accumarray
(XQ
) puede ser bastante potente (posiblemente incluso más que en MATLAB / Octave, ya que esos controladores de función de longitud tienen códigos numéricos útiles), pero no lo sé lo suficientemente bien como para ilustrar con buenos ejemplos. Si realmente es útil, ¿alguien podría crear una respuesta con ideas sobre cómo usarla?Respuestas:
Conoce los literales predefinidos
Aunque algunos de ellos guardan información cuando se copian en el portapapeles, todos tienen un valor predefinido.
F
, empuja 0 (en realidad falso )T
, empuja 1 (realmente cierto )H
, empuja 2 (valor del portapapeles predefinido)I
, empuja 3 (valor del portapapeles predefinido)K
, empuja 4 (valor del portapapeles predefinido)J
, empuja 0 + 1j (valor del portapapeles predefinido)Sin embargo, no estoy seguro de si he cubierto todos los valores predefinidos.
fuente
L
también tiene un valor predefinido, pero están destinados a usos especiales (en lugar de valores generales comunes). Por ejemplo,1L
give[1 0]
(que se usa como índice1:end
),2L
give[0 -1 1]
(para1:-1:end
). Además, funcional
yO
toma 0 entradas por defecto y produce0
y1
respectivamente4
?1
, entonces4
,14
no lo harás. Se necesitaría1 4
. O1K
para guardar un byteK
lugar de4
es útil es:1-4
significa: empujar1
, luego empujar-4
; mientras que1-K
significa: empujar1
, restar de lo que esté debajo en la pila, luego empujar4
La
&
metafunción (especificación alternativa de entrada / salida)La forma tradicional de especificar el número de argumentos de entrada para pasar a una función es usar la
$
metafunciónDel mismo modo, para especificar el número de argumentos de salida, puede usar la
#
metafunción que especifica el número de argumentos de salida,o si pasa un número que es mayor que el número de argumentos de salida definidos para una función, solo
mod(N, numberOfOutputs) + 1
se proporciona el resultado.También puede especificar una matriz lógica como entrada
#
para recuperar solo argumentos de salida específicos.Todas estas especificaciones de entrada / salida son útiles, pero aumentan su recuento de bytes muy rápidamente. Para lidiar con esto, MATL introdujo
&
la metafunción en la versión 17.0.0 . Esta&
metafunción actúa como un acceso directo para una especificación de entrada o salida particular para una función. Veamos qué significa eso.En nuestro ejemplo anterior, queríamos usar la versión de dos entradas de
:
(crea un vector de valores equidistantes). Si bien el número predeterminado de argumentos de entrada:
es1
(crea una matriz a partir de[1...N]
), es muy común que un usuario desee especificar el valor inicial del rango que requiere la segunda entrada. Entonces:
, hemos definido&
como un atajo para2$
.Ahora se convierte en lo siguiente, ¡ guardando un byte !
¿Cómo podemos determinar cuál es el número alternativo de argumentos?
La especificación de entrada / salida a la que se
&
traduce es específica de la función, de modo que optimizamos el ahorro de bytes.La sección de argumento de entrada / salida de la descripción de ayuda para cada función se ha actualizado para indicar cuál es este número alternativo de entradas / salidas (si corresponde). El número posible de argumentos de entrada o salida se muestra como un rango y los valores predeterminados para cada uno se muestran entre paréntesis. La especificación de entrada / salida con la que se puede sustituir
&
se muestra después del/
carácter entre paréntesis.Aquí está la sección de argumento de entrada / salida de la descripción de ayuda para
:
¿Cómo determinó qué
&
significa para cada función?Muy cuidadosamente. Usando la API StackExchange , pudimos descargar todas las respuestas MATL que alguna vez se utilizaron en un desafío PPCG. Al analizar cada una de las respuestas, pudimos determinar la frecuencia con la que se utilizó cada especificación de entrada / salida para cada función. Con esta información, pudimos identificar objetivamente la especificación de entrada / salida que la
&
metafunción debería representar para cada función. A veces no había un ganador claro, por lo que muchas funciones actualmente no se han&
definido.Aquí está el script que usamos (desafortunadamente está escrito en MATLAB y no en MATL).
Y aquí hay un ejemplo del histograma de
$
/#
usofuente
&
iba a significar "aumentar el número de entradas en 1 con respecto al valor predeterminado". Su sugerencia resultó ser mucho más útilFamiliarícese con las definiciones de verdad / falsedad de MATL
Mientras que
true
(T
) yfalse
(F
) representan claramente la salida de verdad y falsedad, respectivamente, la definición ampliamente acordada de verdad / falsedad nos da un poco más de flexibilidad en MATL.La definición dice:
Por lo tanto, podemos escribir una prueba MATL verdadero / falso que pasará por todas las entradas y mostrará si se consideraron verdaderas o falsas
Aquí hay una versión en línea.
Lo que esto significa en MATL
En realidad, esto se traduce en MATL (y, por lo tanto, en MATLAB y Octave) es que una condición se considera verdadera si no está vacía y los componentes reales de todos sus valores no son cero . Hay dos partes en esto que deben enfatizarse.
No cero : Esto significa precisamente eso, no igual a cero (
==
). Esto incluye números positivos, números negativos, caracteres no nulos, etc. Puede verificar fácilmente convirtiendo un valor dado en unlogical
valor (g
) o puede usar~~
Todos los valores : normalmente pensamos que los escalares son verdaderos o falsos, pero en MATL, podemos evaluar escalares, vectores de fila, vectores de columna o incluso matrices multidimensionales y se consideran verdaderos si y solo si cada valor es no es cero (como se definió anteriormente), de lo contrario son falsos. Aquí hay algunos ejemplos para demostrar
El caso de un borde, como se mencionó anteriormente, es una matriz vacía
[]
, que siempre se considera falsa ( ejemplo )¿Cómo puedo usar esto para jugar mejor al golf?
Si el desafío simplemente menciona que su salida debe ser verdadera o falsa, es probable que pueda explotar la definición anterior para reducir algunos bytes de su respuesta. Para evitar confusiones, se recomienda que incluya un enlace a la prueba de verdad / falsedad en línea en su respuesta para ayudar a explicar cómo funcionan los valores de verdad / falsedad de MATL.
Un par de ejemplos específicos:
Una respuesta que termina en
A
. Si el desafío requiere una salida verdadera o falsa y finaliza su respuesta enall
(A
) para crear un escalar, puede eliminar este último byte y su respuesta seguirá siendo correcta (a menos que la salida sea[]
ya que[]
esfalse
pero[]A
estrue
).Asegurarse de que una matriz contiene solo un valor único : Usos
&=
en lugar deun1=
. Si todos los valores en una matriz son iguales, una comparación de igualdad de elementos emitida emitirá unaN x N
matriz de todos. Si todos los valores no son iguales, esta matriz contendrá algunos0
valores y, por lo tanto, se considerará falsa.fuente
Entrada implícita
La mayoría de las funciones aceptan algún número de entrada. Estas entradas se toman de la parte superior de la pila. Si la parte superior de la pila no contiene suficientes argumentos, extraerá el argumento restante de la entrada. (Consulte la Sección 7.3 de la documentación) Me gustaría citar la explicación original:
fuente
Las matrices lógicas a menudo se pueden usar como matrices numéricas
A menudo puede usar "
TF
" la notación en lugar de los literales de matriz de ceros y unos. Por ejemplo,FTF
es lo mismo que[0,1,0]
, solo queFTF
producelogical
valores, nodouble
valores. Esto generalmente no es un problema, ya que cualquier operación aritmética tratará los valores lógicos como números. Por ejemplo,FTFQ
da[1,2,1]
(Q
es "aumentar en 1").En algunos casos, la conversión de un número a binario puede ser más corta. Por ejemplo,
[1,0,1]
,TFT
y5B
son los mismos; nuevamente con la precaución de que los dos últimos sonlogical
valores.Un caso en el que la diferencia entre
TF
(lógico) y[1 0]
(numérico) es cuando se usa como índices. Una matriz de tipological
utilizada como índice significa: seleccionar elementos correspondientes aT
, descartar los correspondientes aF
. Entonces[10 20]TF)
produce10
(seleccione el primer elemento), mientras que[10 20][1 0])
produce[10 20]
(el índice[1 0]
tiene la interpretación de1:end
, es decir, elige todos los elementos de la matriz).fuente
Para lazo de tamaño n-1
Considere reemplazar
con
para guardar hasta un byte completo o más .
fuente
@
/X@
dentro del ciclo o no. Tal vez solo puedas decir "para guardar bytes"Mover cosas desde después del ciclo hasta dentro del ciclo, para explotar el fin implícito
Las
end
declaraciones de bucle]
se pueden omitir si no hay código después de ellas. Los llena el analizador MATL implícitamente.Por lo tanto, si puede mover las cosas desde después del ciclo hasta dentro del ciclo, puede guardar el final
]
.Como ejemplo específico, el siguiente código encuentra cuántos ceros finales hay en el factorial de un número
N
(ver aquí ):1
aN
.5
está presente.5
aparece (esto funciona porque para cada uno5
hay al menos uno2
).La primera idea fue
:"@Yf5=]vs
(tenga en cuenta que hay declaraciones después del ciclo):Como
v
de forma predeterminada concatena todo el contenido de la pila, se puede mover al bucle. Y como la suma es asociativa, tambiéns
se puede mover. Eso deja]
al final del código y, por lo tanto, se puede omitir:"@Yf5=vs
:fuente
Forma más corta de definir una matriz numérica vacía, si la pila está vacía
Para empujar una matriz numérica vacía que normalmente usa
[]
. Sin embargo, si la pila está vacía, puede guardar un byte conv
. Esta función concatena por defecto todo el contenido de la pila verticalmente, por lo que si la pila está vacía, produce la matriz vacía.Puedes verlo en acción, por ejemplo, aquí .
fuente
Algunas funciones se extienden en comparación con MATLAB u Octave
Si vienes de MATLAB u Octave, encontrarás que muchas funciones de MATL son similares a las funciones en esos idiomas. Pero en algunos de ellos se ha ampliado la funcionalidad.
Como ejemplo, considere la
reshape
función de MATLAB , que en MATL correspondee
. Los fragmentos de códigoreshape([10 20 30 40 50 60], 2, 3)
yreshape([10 20 30 40 50 60], 2, [])
respectivamente significan "remodelar el vector de fila[10 20 30 40 50 60
en una matriz de 2 × 3" o "en una matriz de 2 filas con tantas columnas como sea necesario". Entonces, el resultado, en ambos casos, es la matriz 2DAlgo como
reshape([10 20 30 40 50 60], 2, 2)
oreshape([10 20 30 40 50 60], 5, [])
daría un error debido a tamaños incompatibles. Sin embargo, MATL eliminará elementos en el primer caso (¡ pruébelo en línea! ) O rellene con ceros en el segundo (¡ pruébelo en línea! ) Para producir, respectivamente,y
Otras funciones que tienen una funcionalidad extendida en comparación con sus contrapartes de MATLAB son (lista no exhaustiva)
S
(sort
),Yb
(strsplit
),m
(ismember
),h
(horzcat
),v
(vertcat
),Zd
(gcd
),Zm
(lcm
),YS
(circshift
),YA
(dec2base
),ZA
(base2dec
),Z"
(blanks
)fuente
Obtenga el índice del primer elemento distinto de cero, si lo hay
La
f
función proporciona los índices de todos los elementos distintos de cero de una matriz. A menudo desea el índice del primer elemento distinto de cero. Eso seríaf1)
: aplicarf
y elegir su primer elemento. Pero si la matriz original no contiene ningún valor distinto de cero,f
generará una matriz vacía ([]
), e intentar seleccionar su primer elemento dará un error.Un requisito común y más sólido es obtener el índice del primer elemento si hay al menos uno , y de lo
[]
contrario. Esto podría hacerse con unaif
sucursal despuésf
, pero eso es costoso en bytes. Una mejor manera esfX<
, es decir, aplicar la función mínimaX<
a la salida def
.X<
devuelve una matriz vacía cuando su entrada es una matriz vacía.Pruébalo en línea! (Tenga en cuenta que una matriz vacía no se muestra en absoluto). O vea un ejemplo de esto en el trabajo aquí .
fuente
Generar un rango siempre que una matriz dada
TL; WR : use en
f
lugar den:
si la matriz solo tiene elementos distintos de cero.A menudo es necesario generar una matriz
[1 2 ... L]
dondeL
está el número de elementos de una matriz dada. La forma estándar de hacerlo esn:
. Por ejemplo, el códigotn:*
toma un vector numérico como entrada y calcula cada entrada multiplicada por su índice.Si se garantiza que la matriz dada solo contiene entradas distintas de cero (por ejemplo, está formada por enteros positivos o es una cadena con caracteres imprimibles),
n:
se puede reemplazar porf
, lo que produce una matriz con los índices de las entradas distintas de cero. Entonces el código anterior se conviertetf*
, lo que ahorra 1 byte.Algunos ejemplos más elaborados: 1 , 2 , 3 .
fuente
Definición eficiente de literales de matriz numérica
Aquí hay algunas formas que se pueden usar para guardar bytes al definir literales de matriz numérica. Los enlaces se dan a ejemplos de respuestas que los usan. Estos se han obtenido utilizando el script de análisis creado por @Suever .
Concatenación y literales predefinidos
Para matrices con números pequeños a veces se puede utilizar de concatenación (funciones
h
yv
), así como literales predefinidos para evitar el uso de espacios como separadores: comparar[2 4]
,2 4h
y2Kh
, todos los cuales definen la matriz[2 4]
. Del mismo modo,2K1v
con una pila vacía define[2; 4; 1]
. Ejemplo .Letras dentro de literales de matriz numérica
Para números ligeramente mayores, puede ahorrar espacios aprovechando el hecho de que algunas letras tienen significados numéricos dentro de los literales de matriz. Entonces, en lugar de
[3 5 2 7;-4 10 12 5]
que pueda usar[IAHC;dX12A]
. Ejemplo .Específicamente, dentro de los literales de matriz,
O
,l
,H
I
K
Tienen sus significados habituales0
, ...,4
A
, ...,E
malo5
, ...,9
X
medio10
a
, ...d
significa-1
, ...,-4
J
yG
malo1j
y-1j
P
mediopi
Y
medioinf
N
significaNaN
.Cadena y diferencias consecutivas
Para números más grandes, definir una cadena y calcular sus diferencias consecutivas (con
d
) puede ayudar: en lugar de[20 10 35 -6]
usar'!5?b\'d
. Esto funciona porqued
usa los puntos de código de los caracteres para calcular las diferencias. Ejemplo .fuente