MATL est un langage golfique créé par Luis Mendo . MATL s'est avéré très compétitif, battant souvent les soumissions dans d'autres langues de golf telles que Pyth, CJam et Jelly.
Quels sont les conseils utiles pour jouer au golf en MATL? (Comme toujours, un conseil par réponse, s'il vous plaît!)
- Pour mémoire, MATL peut être testé en ligne ici .
- La documentation peut être trouvée sur Github
accumarray
(XQ
) puisse être assez puissant (peut-être même plus que dans MATLAB / Octave car ces poignées de fonction de longueur ont des codes numériques pratiques), mais je ne le connais pas assez bien pour illustrer avec de bons exemples. Si c'est réellement utile, quelqu'un pourrait-il créer une réponse avec des idées sur la façon de l'utiliser?Réponses:
Connaître les littéraux prédéfinis
Bien que certains d'entre eux conservent des informations lorsqu'ils sont copiés dans le presse-papiers, ils ont tous une valeur prédéfinie.
F
, pousse 0 (en fait Faux )T
, pousse 1 (en fait True )H
, pousse 2 (valeur prédéfinie du presse-papiers)I
, pousse 3 (valeur prédéfinie du presse-papiers)K
, pousse 4 (valeur prédéfinie du presse-papiers)J
, pousse 0 + 1j (valeur prédéfinie du presse-papiers)Je ne sais pas si j'ai couvert toutes les valeurs prédéfinies.
la source
L
également une valeur prédéfinie, mais ils sont destinés à des usages spéciaux (plutôt que des valeurs générales communes). Par exemple,1L
donne[1 0]
(qui est utilisé comme index1:end
),2L
donne[0 -1 1]
(pour1:-1:end
). Fonctionne égalementl
etO
prend 0 entrées par défaut et produit0
et1
respectivement4
?1
, alors4
,14
ne le fera pas. Vous en auriez besoin1 4
. Ou1K
pour économiser un octetK
au lieu de4
est pratique est:1-4
signifie: pousser1
, puis pousser-4
; alors que1-K
signifie: pousser1
, soustraire de tout ce qui est en dessous dans la pile, puis pousser4
La
&
méta-fonction (spécification alternative d'entrée / sortie)La manière traditionnelle de spécifier le nombre d'arguments d'entrée à passer à une fonction consiste à utiliser la
$
méta-fonctionDe même, pour spécifier le nombre d'arguments de sortie, vous pouvez utiliser la
#
méta-fonction spécifiant soit le nombre d'arguments de sortie,ou si vous passez un nombre supérieur au nombre d'arguments de sortie définis pour une fonction, seule la
mod(N, numberOfOutputs) + 1
sortie est fournie.Vous pouvez en outre spécifier un tableau logique comme entrée
#
pour récupérer uniquement des arguments de sortie spécifiques.Toutes ces spécifications d'entrée / sortie sont pratiques mais elles augmentent très rapidement le nombre d'octets. Pour y faire face, MATL a introduit la
&
méta-fonction dans la version 17.0.0 . Cette&
méta-fonction agit comme un raccourci pour une spécification d'entrée ou de sortie particulière pour une fonction. Voyons ce que cela signifie.Dans notre exemple ci-dessus, nous voulions utiliser la version à deux entrées de
:
(crée un vecteur de valeurs également espacées). Alors que le nombre par défaut d'arguments d'entrée:
est1
(crée un tableau à partir de[1...N]
), il est très courant qu'un utilisateur veuille spécifier la valeur de début de la plage qui nécessite la deuxième entrée. Donc, pour:
, nous avons défini&
un raccourci pour2$
.Devient maintenant le suivant, économisant un octet !
Comment déterminer le nombre alternatif d'arguments?
La spécification d'entrée / sortie qui se
&
traduit par est spécifique à la fonction de sorte que nous optimisons les économies d'octets.La section des arguments d'entrée / sortie de la description de l'aide pour chaque fonction a été mise à jour pour indiquer quel est ce nombre alternatif d'entrées / sorties (le cas échéant). Le nombre possible d'arguments d'entrée ou de sortie est affiché sous forme de plage et les valeurs par défaut pour chacun sont affichées entre parenthèses. La spécification d'entrée / sortie qui peut être remplacée par
&
est indiquée après le/
caractère entre parenthèses.Voici la section des arguments d'entrée / sortie de la description de l'aide pour
:
Comment avez-vous déterminé ce que
&
signifie pour chaque fonction?Très soigneusement. En utilisant l' API StackExchange , nous avons pu télécharger toutes les réponses MATL qui ont déjà été utilisées dans un défi PPCG. En analysant chacune des réponses, nous avons ensuite pu déterminer la fréquence à laquelle chaque spécification d'entrée / sortie était utilisée pour chaque fonction. En utilisant ces informations, nous avons ensuite pu identifier objectivement la spécification d'entrée / sortie que la
&
méta-fonction devrait représenter pour chaque fonction. Parfois, il n'y avait pas de gagnant clair, donc de nombreuses fonctions ne sont actuellement pas&
définies.Voici le script que nous avons utilisé (malheureusement, il est écrit en MATLAB et non MATL).
Et voici un exemple de l'histogramme de
$
/#
usagela source
&
signifiait "augmenter le nombre d'entrées de 1 par rapport à la valeur par défaut". Sa suggestion s'est avérée beaucoup plus utileFamiliarisez-vous avec les définitions de vérité / fausse de MATL
Alors que
true
(T
) etfalse
(F
) représentent clairement la sortie vérité et fausse, respectivement, la définition largement acceptée de vérité / fausse nous donne un peu plus de flexibilité dans MATL.La définition stipule:
Nous pouvons donc écrire un test MATL de vérité / fausse rapide qui parcourra toutes les entrées et affichera si elles ont été considérées comme véridiques ou fausses
Voici une version en ligne.
Ce que cela signifie en MATL
Ce que cela se traduit réellement dans MATL (et donc dans MATLAB et Octave), c'est qu'une condition est considérée comme vraie si, si elle n'est pas vide et que les composants réels de toutes ses valeurs sont non nuls . Il y a deux parties à souligner.
Non nul : cela signifie précisément cela, différent de zéro (
==
). Cela inclut les nombres positifs, les nombres négatifs, les caractères non nuls, etc. Vous pouvez facilement vérifier en convertissant une valeur donnée en unelogical
valeur (g
) ou vous pouvez utiliser~~
Toutes les valeurs : en général, nous pensons que les scalaires sont vrais ou faux, mais dans MATL, nous pouvons évaluer les scalaires, les vecteurs de ligne, les vecteurs de colonne ou même les matrices multidimensionnelles et ils sont considérés comme véridiques si et seulement si chaque valeur unique est non nul (tel que défini ci-dessus), sinon ils sont faux. Voici quelques exemples pour démontrer
Le cas à un bord, comme mentionné ci-dessus, est un tableau vide
[]
, qui est toujours considéré comme faux ( exemple )Comment puis-je l'utiliser pour mieux jouer au golf?
Si le défi mentionne simplement que votre sortie doit être véridique ou fausse, vous pouvez probablement exploiter la définition ci-dessus pour raser quelques octets de votre réponse. Pour éviter toute confusion, il est recommandé d'inclure un lien vers le test de vérité / fausse en ligne ci-dessus dans votre réponse pour aider à expliquer le fonctionnement des valeurs MATL de vérité / fausse.
Quelques exemples spécifiques:
Une réponse se terminant par
A
. Si le défi nécessite une sortie véridique ou fausse et que vous terminez votre réponse enall
(A
) pour créer un scalaire, vous pouvez supprimer ce dernier octet et votre réponse restera correcte (à moins que la sortie ne soit[]
depuis[]
estfalse
mais[]A
esttrue
).S'assurer qu'un tableau ne contient qu'une seule valeur unique : utilise
&=
à la place deun1=
. Si toutes les valeurs d'un tableau sont égales, une comparaison d'égalité diffusée par élément produira uneN x N
matrice de toutes les valeurs . Si toutes les valeurs ne sont pas égales, cette matrice contiendra certaines0
valeurs et sera donc considérée comme fausse.la source
Entrée implicite
La plupart des fonctions acceptent un certain nombre d'entrées. Ces entrées proviennent du haut de la pile. Si le haut de la pile ne contient pas suffisamment d'arguments, il tirera l'argument restant de l'entrée. (Voir la section 7.3 dans la documentation) Je voudrais citer l'explication originale:
la source
Les tableaux logiques peuvent souvent être utilisés comme tableaux numériques
Vous pouvez souvent utiliser la
TF
notation " " au lieu des tableaux de zéros et de uns. Par exemple,FTF
est le même que[0,1,0]
, seulement quiFTF
produit deslogical
valeurs, pas desdouble
valeurs. Ce n'est généralement pas un problème, car toute opération arithmétique traitera les valeurs logiques comme des nombres. Par exemple,FTFQ
donne[1,2,1]
(Q
est "augmenter de 1").Dans certains cas, la conversion d'un nombre en binaire peut être plus courte. Par exemple,
[1,0,1]
,TFT
et5B
sont les mêmes; encore une fois avec la prudence que les deux derniers sont deslogical
valeurs.Un cas où la différence entre
TF
(logique) et[1 0]
(numérique) importe est lorsqu'il est utilisé comme indices. Un tableau de typelogical
utilisé comme index signifie: choisir les éléments correspondant àT
, éliminer ceux correspondant àF
. Donc[10 20]TF)
produit10
(sélectionner le premier élément), alors que[10 20][1 0])
produit[10 20]
(l'indice[1 0]
a l'interprétation de1:end
, qui, tous les éléments de choisir le tableau).la source
Pour boucle de taille n-1
Envisager de remplacer
avec
pour enregistrer jusqu'à un octet entier ou plus .
la source
@
/X@
dans la boucle ou non. Vous pouvez peut-être simplement dire "pour économiser des octets"Déplacez les choses depuis la boucle vers l'intérieur de la boucle, pour exploiter la fin implicite
Les
end
instructions de boucle ,,]
peuvent être omises s'il n'y a pas de code après elles. Ils sont implicitement remplis par l'analyseur MATL.Donc, si vous pouvez déplacer des éléments depuis la boucle vers l'intérieur de la boucle, vous pouvez enregistrer la finale
]
.À titre d'exemple spécifique, le code suivant recherche le nombre de zéros de fin dans la factorielle d'un nombre
N
(voir ici ):1
àN
.5
est présent.5
apparaît (cela fonctionne car pour chacun5
il y en a au moins un2
).La première idée était
:"@Yf5=]vs
(notez qu'il y a des instructions après la boucle):Puisque
v
par défaut concatène tout le contenu de la pile, il peut être déplacé dans la boucle. Et comme l'addition est associative, elles
peut aussi être déplacée. Cela laisse]
à la fin du code, et donc il peut être omis:"@Yf5=vs
:la source
Manière plus courte de définir un tableau numérique vide, si la pile est vide
Pour pousser un tableau numérique vide que vous utilisez normalement
[]
. Cependant, si la pile est vide, vous pouvez enregistrer un octet en utilisantv
. Par défaut, cette fonction concatène verticalement tout le contenu de la pile, donc si la pile est vide, elle produit le tableau vide.Vous pouvez le voir en action par exemple ici .
la source
Certaines fonctions sont étendues par rapport à MATLAB ou Octave
Si vous venez de MATLAB ou Octave, vous trouverez que de nombreuses fonctions MATL sont similaires aux fonctions de ces langages. Mais dans bon nombre d'entre eux, la fonctionnalité a été étendue.
Par exemple, considérons la
reshape
fonction de MATLAB , à laquelle correspond MATLABe
. Les extraits de codereshape([10 20 30 40 50 60], 2, 3)
etreshape([10 20 30 40 50 60], 2, [])
respectivement signifient «remodeler le vecteur ligne[10 20 30 40 50 60
en une matrice 2 × 3» ou «en une matrice 2 lignes avec autant de colonnes que nécessaire». Ainsi, le résultat, dans les deux cas, est le tableau 2DQuelque chose comme
reshape([10 20 30 40 50 60], 2, 2)
oureshape([10 20 30 40 50 60], 5, [])
donnerait une erreur en raison de tailles incompatibles. Cependant, MATL supprimera les éléments dans le premier cas ( essayez-le en ligne! ) Ou remplira de zéros dans le second ( essayez-le en ligne! ) Pour produire, respectivement,et
Les autres fonctions qui ont des fonctionnalités étendues par rapport à leurs homologues MATLAB sont (liste non exhaustive)
S
(sort
),Yb
(strsplit
),m
(ismember
),h
(horzcat
),v
(vertcat
),Zd
(gcd
),Zm
(lcm
),YS
(circshift
),YA
(dec2base
),ZA
(base2dec
),Z"
(blanks
).la source
Récupère l'index du premier élément non nul, le cas échéant
La
f
fonction donne les indices de tous les éléments non nuls d'un tableau. Souvent, vous voulez l'index du premier élément différent de zéro. Ce seraitf1)
: appliquerf
et choisir son premier élément. Mais si le tableau d'origine ne contient aucune valeur non nullef
, un tableau vide sera généré ([]
) , et essayer de choisir son premier élément donnera une erreur.Une exigence courante et plus robuste consiste à obtenir l'indice du premier élément s'il y en a au moins un et
[]
sinon. Cela pourrait être fait avec uneif
branche aprèsf
, mais cela coûte cher. Une meilleure façon est d'fX<
appliquer la fonction minimaleX<
à la sortie def
.X<
renvoie un tableau vide lorsque son entrée est un tableau vide.Essayez-le en ligne! (Notez qu'un tableau vide ne s'affiche pas du tout). Ou voyez un exemple de ceci au travail ici .
la source
Générer une plage tant qu'un tableau donné
TL; WR : utilisez à la
f
place den:
si le tableau n'a que des éléments non nuls.Il est souvent nécessaire de générer un tableau
[1 2 ... L]
oùL
est le nombre d'éléments d'un tableau donné. La façon standard de le faire estn:
. Par exemple, le codetn:*
prend un vecteur numérique en entrée et calcule chaque entrée multipliée par son index.Si le tableau donné est garanti pour ne contenir que des entrées non nulles (par exemple, il est formé d'entiers positifs ou est une chaîne avec des caractères imprimables),
n:
peut être remplacé parf
, qui produit un tableau avec les indices des entrées non nulles. Ainsi, le code ci-dessus devienttf*
, ce qui économise 1 octet.Quelques exemples plus élaborés: 1 , 2 , 3 .
la source
Définition efficace des littéraux de tableau numérique
Voici quelques méthodes qui peuvent être utilisées pour économiser des octets lors de la définition des littéraux de tableau numérique. Des liens sont donnés vers des exemples de réponses qui les utilisent. Ceux-ci ont été obtenus en utilisant le script d'analyse créé par @Suever .
Concaténation et littéraux prédéfinis
Pour les tableaux avec de petits nombres, vous pouvez parfois utiliser la concaténation (fonctions
h
etv
), ainsi que des littéraux prédéfinis pour éviter d'utiliser des espaces comme séparateurs: comparer[2 4]
,2 4h
et2Kh
, qui définissent tous le tableau[2 4]
. De même,2K1v
avec une pile vide définit[2; 4; 1]
. Exemple .Lettres dans les littéraux de tableau numérique
Pour des nombres légèrement plus grands, vous pouvez économiser des espaces en exploitant le fait que certaines lettres ont des significations numériques dans les littéraux de tableau. Donc, au lieu de
[3 5 2 7;-4 10 12 5]
vous pouvez utiliser[IAHC;dX12A]
. Exemple .Plus précisément, dans les littéraux de tableau,
O
,l
,H
I
K
Ont leurs significations habituelles0
, ...,4
A
, ...,E
signifie5
, ...,9
X
veux dire10
a
, ...d
signifie-1
, ...,-4
J
etG
méchant1j
et-1j
P
veux direpi
Y
veux direinf
N
signifieNaN
.Chaîne et différences consécutives
Pour de plus grands nombres, définir une chaîne et calculer ses différences consécutives (avec
d
) peut aider: au lieu de[20 10 35 -6]
vous pouvez utiliser'!5?b\'d
. Cela fonctionne card
utilise les points de code des caractères pour calculer les différences. Exemple .la source