Conseils pour jouer au golf à Japt


18

Maintenant que je suis complètement accro au Code Golf, il est probablement temps que j'essaye de prendre quelques langues de golf.

Étant donné que je joue presque exclusivement en JavaScript, Japt semble être le langage logique pour commencer. Je plongerai dans la documentation à la prochaine occasion, mais en attendant, veuillez publier tous les conseils que vous avez pour Japt dans les réponses ci-dessous.

Comme je suis un débutant dans les langues Japt et le golf en général, si vous pouviez "traduire" vos conseils en JavaScript, si possible, ce serait une grande aide pour m'aider à comprendre les choses.


Hé, merci d'avoir posté ça. Je m'arrêtais de le faire parce que j'aimerais repenser Japt à un moment donné, mais cela ne se produira pas de sitôt, et cela ne gâchera probablement pas beaucoup de conseils de toute façon. Astuce pour moi: écrire un tutoriel: P
ETHproductions

N'oubliez pas de visiter le salon de discussion Japt :)
Oliver

Réponses:


11

Passer de JavaScript à Japt

Comme vous le savez peut-être, Japt est simplement une version raccourcie et étendue de JavaScript. J'ai créé Japt parce que j'étais fatigué des longs noms de propriété, comme String.fromCharCode(x)et Math.floor(x), et de la fastidieuse de faire des choses telles que la création d'une plage. Voici le strict minimum que vous devez savoir lorsque vous passez de JavaScript à Japt:

  • Japt est une langue transpilée ; Le code Japt est transpilé en JavaScript puis exécuté en tant que JS. (Je suppose que vous pourriez dire compilé , mais les sons transpilés sont plus hipster. Avertissement: je ne sais absolument rien d'être hipster)
  • Toutes les entrées sont des programmes complets par défaut. L'entrée est implicitement analysé, et les six premières entrées sont mis dans les variables U, V, W, X, Y, et Z; le tableau complet est stocké dans N. Le résultat de la dernière expression est automatiquement imprimé.
  • Toutes les lettres majuscules sont des variables et restent les mêmes lorsqu'elles sont transposées. La plupart ont des valeurs prédéfinies, que vous pouvez trouver dans la section "Variables" des documents Japt (à l' interpréteur ).
  • Toutes les lettres minuscules sont des fonctions ou méthodes prototypes . Japt ajoute les méthodes a- z(et à- ÿ) sur les nombres, les chaînes et les tableaux. Lorsque vous utilisez l'une de ces lettres, Japt remplit le .et (; Ucdans Japt est équivalent à U.c(dans JavaScript, ce qui pourrait signifier ceil, charCodeAt ou concat, selon le type de U. C'est de là que vient la majeure partie du pouvoir de Japt; vous pouvez trouver la liste complète de ces méthodes dans les sections "_____ fonctions" des documents Japt (à l' interpréteur ).
  • Un espace représente )et )représente )). En effet, lorsque j'ai conçu Japt pour la première fois, je voulais économiser autant d'octets que possible, et c'est comme ça que j'ai pensé à faire cela pour la première fois. (Bien que Us w ncela semble mieux que Us)w)n), à mon humble avis.)
  • Une fonction est désignée par ABC{...}, où le ABCpeut être n'importe quelle chaîne de variables. Les fonctions fonctionnent pour la plupart comme dans JS, la principale différence étant que la dernière expression est automatiquement renvoyée (plutôt que d'avoir à utiliser returnou à créer des parenthèses ES6).
  • 'désigne une seule chaîne de caractères (c'est-à 'a- dire est la même que "a"), et #prend le code de caractère suivant et devient ce nombre ( #eest le même que 101).
  • Tout ce qui se trouve entre les signes dollar $reste le même pendant le processus de transpilation. Vous pouvez l'utiliser pour implémenter des forboucles, par exemple, car Japt n'en a pas, mais je suggérerais d'utiliser d'autres méthodes (comme msur les chaînes et les tableaux, ou osur les nombres).
  • La plupart des autres caractères couramment utilisés dans JS - "", 0-9, (, +, =, etc. - restent les mêmes quand transpiled (pour la plupart, de toute façon).

Et c'est tout ce que vous devez savoir pour écrire du code Japt de base. Atteindre la puissance de golf maximale dans Japt nécessite plus de connaissances, mais cela peut être trouvé dans d'autres réponses.


Voici un exemple de base. Supposons que vous souhaitiez prendre une chaîne de caractères ASCII et remplacer chacun par son code de caractère hexadécimal. Voici comment procéder en JavaScript:

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

Maintenant, convertissez-vous en Japt. .split("")dans JS est équivalent à q""dans Japt, ou même plus court, juste q. .join("")est également juste q, la différence étant que l'objet est un tableau au lieu d'une chaîne. .map(est m, .charCodeAt(est cet .toString(est s. Notre code Japt pourrait donc ressembler à:

Uq mX{Xc0 s16} q 

Dans Japt, cependant, mfonctionne aussi bien sur les chaînes que sur les tableaux, nous pouvons donc supprimer les deux qs:

UmX{Xc0 s16}

Testez-le en ligne! Comme vous pouvez le voir dans la case "Code JS", cela se transforme directement en:

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

Au fur et à mesure que vous apprenez à travailler avec Japt, vous vous concentrerez de moins en moins sur la conversion aller-retour à partir de JavaScript et pourrez coder dans Japt comme son propre langage. Voici une explication en laissant de côté la partie JavaScript:

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

Il vaudrait peut-être mieux montrer une autre étape: les raccourcis unicode. Dans ce cas, nous pouvons enregistrer 2B avec eux. De plus, vous voudrez peut-être ajouter que vous pouvez omettre certaines choses à la fin. Cela permettrait d'économiser un autre octet.
Luke

Une excellente amorce, merci, ETH. Il y en a assez, je pense, pour me lancer dans quelques défis simples.
Shaggy

En combinant cela avec ce que j'ai glané du README jusqu'à présent, serais-je correct que l'exemple ci-dessus pourrait être encore raccourci Um_c s16?
Shaggy

Ou, plus court encore ¡Xc s16:?
Shaggy

1
@Shaggy Vous avez raison! Man, vous avez compris cela rapidement ;-) J'ajouterai quelques conseils de base sur le golf Japt (comme les raccourcis Unicode et autres), probablement comme d'autres réponses.
ETHproductions

8

Compression de tableaux de chaînes

MISE À JOUR: Les outils présentés dans cette astuce ont depuis été réécrits, améliorés et intégrés dans mon interpréteur Japt . Pour les meilleurs résultats, il est recommandé d'utiliser ce compresseur par rapport à ceux liés ci-dessous. Je reviendrai sur cette astuce quand j'aurai plus de temps et je la réécrirai en pensant au nouveau compresseur.

introduction

Si vous avez un tableau de chaînes dans votre code, le moyen le plus évident de le compresser serait d' exécuter chaque chaîneOc individuellement. Pour les besoins de cette astuce, nous allons travailler avec le tableau ["lollipop","marshmallow","nougat","oreo"], qui pèse initialement 42 octets. L'exécution de chaque chaîne Ocnous donne:

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

C'est maintenant 33 octets, une économie décente.


Étape 1

Mais nous pouvons faire mieux. Si nous joignons le tableau à une chaîne séparée par des sauts de ligne, nous pouvons nous débarrasser des crochets, des virgules et des raccourcis superflus et nous séparer sur le saut de ligne pour obtenir notre tableau. Appliquer cela à notre exemple de tableau nous donne ce qui suit:

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

Jusqu'à 26 octets maintenant.


Étape 2

Mais , on peut encore faire mieux! Nous pourrions utiliser une lettre minuscule pour délimiter les chaînes au lieu d'une nouvelle ligne, qui pourrait être incluse dans la compression. zn'est utilisé dans aucune de nos chaînes, alors allons-y et voyons comment nous allons.

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

Ah, les noix - aucune amélioration là-bas; notre nombre d'octets a augmenté de un! Il pourrait y avoir une autre lettre que vous pouvez utiliser , mais, en fonction de vos chaînes, il pourrait y avoir un assez grand nombre pour essayer - dans notre exemple , il y a 11: b,c,d,f,j,k,q,v,x,y,z. Essayer chacun serait assez fastidieux, c'est là que cet outil pratique entre en jeu; alimentez-le avec vos chaînes séparées par des sauts de ligne et il essaiera de délimiter les chaînes avec chaque lettre qui n'est contenue dans aucune d'entre elles et affichera:

  • la chaîne compressée la plus courte,
  • le délimiteur qu'il utilise, et
  • sa longueur.

L'exécution de nos exemples de chaînes montre que cela bdonne les meilleurs résultats:

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

Et voilà, nous sommes à seulement 24 octets.


Étape 3

Mais nous pouvons faire encore mieux! Si l'ordre des chaînes dans votre tableau n'a pas d'importance, il y a peut-être une permutation différente combinée à un délimiteur différent qui pourrait fonctionner encore plus court. Essayer chaque possibilité sera cependant beaucoup plus fastidieux. Avec nos 4 cordes, il y a 24 permutations différentes à essayer. Avec chacune des 11 lettres possibles cela devient 264! C'est là que cet outil entre en jeu. Encore une fois, alimentez-le avec vos chaînes séparées par une nouvelle ligne et il essaiera toutes les combinaisons de chaque permutation et de chaque lettre de délimitation, produisant:

  • l'ordre des chaînes dans la chaîne compressée la plus courte,
  • la chaîne compressée,
  • le délimiteur qu'il utilise, et,
  • sa longueur.

L'exécution de nos exemples de chaînes montre que "nougat","oreo","lollipop","marshmallow"avec bcomme délimiteur donne les meilleurs résultats, avec un nombre d'octets final de seulement 23:

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


Astuce bonus: Compression de tableau entier

Vous pouvez appliquer le même principe aux tableaux d'entiers en convertissant d'abord chacun en une base plus élevée. En utilisant cet exemple, tableau de 36 octets:

[588181,156859,595676,475330,680474]

Nous pouvons réduire cela à 29 octets en le convertissant d'abord en un tableau de chaînes de base 32, puis en l'exécutant via le premier programme de compression:

`huclt4p5r5ÛÊg62tkogq`qt mnH

Ou aussi peu que 27 octets en utilisant le deuxième programme:

`4p5Ïcl5ÛÊg62tkogq`qt mnH

Vous pouvez peut-être enregistrer un autre octet ou 2 en plus en déplaçant la conversion d'entier dans une méthode que vous exécutez déjà sur le tableau.


Remarques

  1. N'oubliez pas de prendre en compte les q<letter>(<space>)coûts de 1 ou 2 octets supplémentaires ·. Cependant, vous pouvez peut-être utiliser l'un des raccourcis Unicode pour récupérer un octet, en fonction de votre délimiteur ( identique à ql<space>, par exemple).
  2. Un mot de prudence lors de l'utilisation du dernier outil: plus vous avez de chaînes, plus il y aura de permutations et plus le programme s'exécutera lentement, jusqu'à ce qu'il finisse par craquer. Comme détaillé ci-dessus, avec nos 4 exemples de chaînes et 11 lettres possibles à essayer, il y a 264 combinaisons possibles, augmentez le nombre de chaînes de seulement 1 avec les mêmes 11 lettres et nous avons déjà 1320 combinaisons à essayer. (Vous pouvez utiliser cet outil pour compter le nombre de combinaisons, si vous le souhaitez).

Crédits

  • Oliver pour l'inspiration pour créer les outils trouvés dans cette astuce.
  • ETHproductions pour la relecture.

6

Compression des cordes

Japt (actuellement) utilise la bibliothèque shoco pour la compression de chaînes. Vous pouvez compresser une chaîne arbitraire en utilisant Oc, tant qu'elle contient des séries de lettres minuscules:

Oc"Hello, World!"

Cela produit HÁM, WŽld! (enfin, Žc'est techniquement un caractère non imprimable). Vous pouvez décompresser cela en l'enveloppant dans des crochets:

`HÁM, WŽld!`

Testez-le en ligne!

Vous pouvez également utiliser la Odfonction pour décompresser une chaîne arbitraire. Ce n'est généralement pas utile, mais il a ses objectifs ...


Donc, si je répondais au "Bonjour, monde!" défi, devrais-je utiliser juste HÁM, WŽld!ou devrait-il être enfermé dans des crochets? Je devine ce dernier.
Shaggy

2
@Shaggy Pour répondre à une question, vous devez inclure tout le code, ce serait donc `HÁM, WŽld! dans ce cas
Martijn Vissers

6

Raccourcir les nombres avec des codes de caractères

Dans Japt, vous pouvez utiliser #, suivi d'un caractère pour créer un code de caractère. Cela est utile lorsque vous raccourcissez des nombres plus longs.

Comme @ETHproductions l'a mentionné, cela ne fonctionne que sur des exécutions à trois chiffres dans la plage 100-255, sauf si vous êtes prêt à passer en UTF-8.

Exemples:

123 peut être raccourci en #{

101 peut être raccourci en #e

Vous pouvez même les enchaîner:

123101 peut être raccourci en #{#e

Vous pouvez utiliser String.fromCharCode(123)en JavaScript ou 123den Japt pour trouver le caractère approprié.

String.fromCharCode(123) Retour {


Merci, @obarakon, une excellente astuce pour lancer le bal; String.fromCharCode()est l'une de ces (nombreuses!) méthodes JS terriblement longues qui peuvent analyser votre nombre d'octets. Vraisemblablement, ceux-ci seraient considérés comme des entiers? c'est-à-dire, si j'ai besoin de l'entier 123dans une solution, je pourrais utiliser #{pour enregistrer un octet.
Shaggy

1
Oui, ce sont des entiers. Si vous ajoutez l' -Qindicateur dans votre fenêtre d'entrée, vous pouvez mieux visualiser le type de sortie: guillemets autour de chaînes , tableaux , etc.
Oliver

1
Vous devez mentionner que cela String.fromCharCode(123)fonctionne en JavaScript, mais vous pouvez le faire 123ddans Japt pour obtenir le même résultat ;-) En outre, cela ne fonctionne que sur des exécutions à trois chiffres de la plage 100- 255(sauf si vous êtes prêt à passer en UTF-8)
ETHproductions

@ETHproductions Bon appel, mis à jour!
Oliver

5

Conseil rapide: tableau vide []

Japt a une constante pour un tableau vide: A. Mais, pour y accéder, vous devez ajouter un point-virgule ;à votre programme pour utiliser les constantes alternatives de Japt, sinon ce Asera le cas 10. Donc , en utilisant ;Aoffre en fait un 0 octet d' économiser plus [], mais va vous faire économiser octets si vous devez affecter votre tableau à une variable (par exemple A=[]).

Cependant, si (et seulement si) votre programme ne prend aucune entrée, vous pouvez accéder au tableau vide avec seulement 1 octet en utilisant la Nvariable, qui est le tableau des entrées - sans entrée, il serait vide. Essayez-le ici .

Cela a également l'avantage supplémentaire de vous permettre d'utiliser les valeurs constantes par défaut dans votre programme et, dans certains cas, peut encore vous faire économiser des octets lors de l'utilisation ;Amême lorsque votre programme prend des entrées grâce aux raccourcis pour s1et s2.


2
Wow, je n'avais pas pensé à utiliser N, bonne idée.
ETHproductions

2
Bien joué, @Shaggy!
Oliver

4

Évaluation de JavaScript

Japt vous permet d'exécuter du JavaScript brut en l'enveloppant $...$.

Par exemple, $alert("hello world")$

Cela peut être raccourci en profitant de la fermeture automatique $et de Japt ).

$alert("hello world")$ peut être raccourci en $alert("hello world"

Compression de JavaScript

Vous pouvez également compresser JavaScript en utilisant Ox .

S'il existe une fonction JavaScript que vous souhaitez utiliser, par exemple screen.width, vous pouvez compresser la chaîne à l' "screen.width"aideOc , puis en insérant le résultat entre Ox` ... `

Notez que vous n'avez pas besoin de fermer les guillemets dans Japt lorsqu'il n'est suivi par rien d'autre.


@Shaggy Vous avez besoin de Oxpour évaluer la chaîne. Sinon, vous ne feriez que sortir le texte "screen.width". Exemple
Oliver

4

Connaissez les drapeaux

Selon le dernier méta-consensus (décembre 2017) , les indicateurs de ligne de commande ne sont plus comptés dans les octets. C'est vraiment une excellente nouvelle pour Japt car il a de nombreux indicateurs pour un traitement supplémentaire en entrée / sortie.

Tous les indicateurs disponibles dans Japt sont décrits ci-dessous, dans l'ordre d'évaluation . Les drapeaux du même groupe sont exclusifs les uns aux autres. Notez que les drapeaux de différents groupes peuvent être utilisés en combinaison, ce qui donne quelque chose comme ça :)

mdefæ

L'ensemble du programme est mappé sur le premier argument ( U).

Si plusieurs arguments sont présents, ils sont transmis tels quels (c'est-à-dire non mappés par paire). Sinon, le deuxième argument est l'index, et le troisième est le tableau entier, tout comme U.m. Si Uest un nombre, il est converti en plage; si chaîne, elle est convertie en tableau de caractères et les résultats sont réunis.

  • -m: Applique ce qui précède et rien d'autre.
  • -d: Retourne truesi un résultat est vrai, falsesinon.
  • -e: Renvoie truesi tous les résultats sont véridiques, falsesinon.
  • -f: Renvoie le tableau des éléments Udont les résultats sont véridiques.
  • : Applique -fet renvoie son premier élément.

gh

Prend un élément à l'index spécifié.

  • -g: Prend le premier élément (index 0).
  • -gX: Prend l'élément à l'index X(peut être n'importe quel entier positif).
  • -h: Prend le dernier élément.

Convertissez le résultat en booléen.

  • -!: Appliquer booléen pas.
  • : Appliquer booléen pas deux fois (retourne la véracité).

N

Convertissez le résultat en nombre. Le plus unaire est utilisé.

PRSQ

Convertissez en chaîne quelconque.

  • -P: Rejoignez le tableau avec "".
  • -R: Rejoignez le tableau avec "\n".
  • -S: Rejoignez le tableau avec " ".
  • -Q: Appliquer JSON.stringify(peut être n'importe quel objet, pas seulement un tableau). Exemple .

x

Applique la fonction xà la sortie. (Ce n'est littéralement xpas "une seule fonction de l'alphabet minuscule".)

  • Tableau: somme.
  • Chaîne: couper des deux extrémités.
  • Nombre: arrondi à un entier.

2
Notez cependant que l'utilisation de drapeaux ne compte pas comme une soumission Japt, elle compte comme une soumission Japt-with-those-specific-flags-language.
Nit

3

Raccourcis Unicode

Il y a beaucoup de structures communes dans Japt qui ne peut pas être stockés dans un seul char ASCII, tels que qS , p2 , mX{, , etc. Donc , pour contourner ce problème, Japt a « raccourcis Unicode », qui sont des caractères dans la plage \xA1- \xDE( ¡- Þ) qui s'étendent à ces structures communes. Vous pouvez trouver une liste complète de ceux-ci dans la documentation de l' interpréteur .

En outre, @signifie XYZ{et _signifie pour Z{Zaider à créer des fonctions. Jouons donc notre exemple de programme à partir d' une autre réponse :

UmX{Xc0 s16}

Tout d'abord, nous pouvons remplacer X{Xpar _, ce qui nous donne:

Um_c0 s16}

Ensuite, nous pouvons remplacer m_par l' ®enregistrement d'un autre octet:

U®c0 s16}

Ou nous pourrions remplacer X{par @, ce qui nous donne:

Um@Xc0 s16}

Cela nous permet ensuite d'utiliser le ¡raccourci pour économiser deux octets:

¡Xc0 s16}

L'un de ces deux chemins peut être raccourci d'un octet de plus que l'autre. Pouvez-vous comprendre lequel?


1
®c s16pour 6 octets - est-ce que je gagne un cookie?!
Shaggy

@Shaggy Vous pouvez économiser 1 octet de plus si vous regardez assez fort ...;)
ETHproductions

Serait-ce ®c sG?
Shaggy

1
Oui! Je pense que c'est aussi bas que possible. Bien joué! :-)
ETHproductions

2
Incroyable en y repensant, en voyant la progression de Japt en quelques mois. Cela peut maintenant être réalisé avec csG.
Shaggy

3

Profitez des variables prédéfinies

Variables A- Ssont prédéfinies à des valeurs communes qui prennent plus d'un octet à représenter dans Japt:

  • A- Gsont 10- 16.
  • Hest 32, Iest 64, Jest -1, Lest 100.
  • Kest défini comme new Date(), que vous pouvez manipuler de différentes manières.
  • Met Osont des objets avec diverses fonctions utiles. Vous pouvez en savoir plus dans la documentation.
  • Pest la chaîne vide, Qest un guillemet, Rest un saut de ligne et Sest un espace.
  • Test défini sur 0, vous pouvez donc l'utiliser comme accumulateur si nécessaire.

Si le premier caractère du programme est un point-virgule ;, A-Lsont réinitialisés comme suit:

  • Aest le tableau vide [].
  • Best "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
  • Cest "abcdefghijklmnopqrstuvwxyz".
  • Dest "QWERTYUIOP\nASDFGHJKL\nZXCVBNM".
  • Eest "[a-z]", et Fest"[A-Za-z]" (utile avant de les ajouter comme fonctionnalités d'expression régulière)
  • Gest 36, Hest 65et Iest 91(utile pour les plages alphabétiques).
  • Jest une seule virgule; L, une seule période.

Aujourd'hui seulement A, B, Cet Dde cette liste sont vraiment utiles. Je prévois d'ajouter un meilleur système qui autorise jusqu'à 256 variables à deux octets, qui seront prédéfinies à ces valeurs et bien plus encore.


3

Utiliser les fonctions automatiques

Vous le savez probablement déjà @et ce _sont des raccourcis pour XYZ{et Z{Z, respectivement (couverts dans la réponse des raccourcis Unicode ). Mais parfois, vous pouvez raccourcir les fonctions.

Supposons que vous disposiez d'un tableau de caractères et que vous vouliez mapper chaque caractère à son code de caractère. Vous pouvez le faire avec l'un ou l'autre de ces éléments:

mX{Xc} 
m_c} 

Mais il y a une meilleure façon. Si une méthode ou un opérateur est le premier élément après une autre méthode ou un (, il est transformé en chaîne. Ces deux lignes sont donc équivalentes:

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

Mais comment cela aide-t-il avec nos fonctions? Eh bien, la plupart des méthodes qui acceptent des fonctions, si elles reçoivent une chaîne représentant une méthode ou un opérateur, l'interpréteront comme une fonction. Ce qui signifie que vous pouvez également le faire:

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

J'appelle ces "fonctions automatiques". Il existe plusieurs variétés différentes:

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

J'espère que vous avez l'idée. Pour permuter les arguments, préfixez simplement la méthode ou l'opérateur avec !.


Vaut-il la peine de noter ici que l'utilisation des fonctions automatiques peut également permettre des économies supplémentaires grâce à l'utilisation de raccourcis? par exemple, m@2pXÃm!p2<space>m!².
Shaggy

Woah! Je n'ai pas pensé à utiliser une chaîne dans la carte, je ne savais même pas que c'était possible. Je vais peut-être économiser quelques octets grâce à cela à l'avenir.
RedClover

Hé @Soaku, j'ai en quelque sorte manqué que vous ayez répondu avec Japt, alors permettez-moi de vous souhaiter la bienvenue! J'espère que vous l'avez apprécié jusqu'à présent. Si vous avez des questions, des suggestions ou si vous voulez simplement parler, n'hésitez pas à nous rejoindre dans le salon de discussion Japt (Github fonctionne généralement aussi pour les deux premiers;))
ETHproductions

3

Affectation implicite de variable

Chaque fois que vous démarrez une nouvelle ligne dans Japt, le résultat de la ligne précédente est automatiquement affecté à l'une des variables d'entrée ( U- Z), la première ligne étant Ula deuxièmeV , etc.

Prenons un exemple: supposons que vous vouliez créer 2 tableaux avec lesquels travailler, l'un contenant les nombres 1-10 et l'autre contenant leurs carrés. Le long chemin à parcourir serait le suivant:

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

Cependant, en utilisant l'affectation automatique des variables, cela peut être raccourci:

Aõ
Um²
[do something with the arrays]

Nous y avons enregistré 4 octets. Mais, dans ce cas, nous pouvons enregistrer un octet de plus car le tableau de 1 à 10 est affecté à Uet Upeut être omis dans certains scénarios :

Aõ
m²
[do something with the arrays]

Mise en garde

Une chose à laquelle vous devez faire attention avec cette astuce est que vous n'écrasez pas les variables d'entrée dont vous pourriez avoir besoin plus tard dans votre programme. Cela peut être évité en laissant une ou plusieurs lignes vides au début. Dans l'exemple suivant, les 2 tableaux seront affectés aux variables V& W, au lieu de U& V:


Aõ
Vm²
[do something with the arrays]

3

Connaître le Javascript

Étant donné que tout code Japt s'exécute en tant que JS transpilé, une bonne compréhension des opérateurs JS et des méthodes intégrées aide beaucoup à jouer au golf des morceaux de code Japt.

Conseils JS pertinents

[]Vm@...
...
  • Court-circuit
  • Fractionner avec des nombres
    • Cela peut être généralisé à toute méthode acceptant des chaînes mais pas des nombres. Un nombre qui y est passé sera implicitement transtypé en chaîne, enregistrant souvent un octet (par exemple, au- 0dessus '0).

Fonctions intégrées JS pertinentes

Examinez attentivement les paramètres passés aux arguments de fonction.

Pour les méthodes de chaîne, il est bon de savoir comment les comportements diffèrent entre le passage d'une chaîne ou d'une expression régulière avec ou sans gindicateur.


3

Utilisez plusieurs lignes si nécessaire

Pour la plupart des défis pas trop difficiles, vous pouvez exprimer la solution dans une seule ligne de Japt, sous la forme d'une séquence d'application de fonctions intégrées. Mais les plus complexes nécessiteront l'utilisation de constructions en boucle, la récursivité ou la réutilisation de gros morceaux de code. C'est là qu'intervient la programmation multi-lignes.

Supprimer les parens de fermeture

Tâche : étant donné un tableau de nombres, associez chaque élément à l'index au carré et triez-le par la somme.

[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 solution à une ligne l'est íUm@Yp2})ñx, mais })coûte deux octets (et il n'y a pas de raccourci d'un octet). Vous pouvez supprimer })en déplaçant simplement ñxla dernière ligne vers la ligne suivante, de sorte que le code ressemble à ceci:

íUm@Yp2
ñx

et le JS transpilé devient:

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

Vous pouvez clairement voir que cela fait la même chose que la solution à une ligne, en attribuant simplement le résultat intermédiaire à U.

Recurse avec des arguments implicites

La fonction de récursivité ßprend tout UVWXYZcomme paramètre implicite, si elle n'est pas spécifiée. Uest évidemment l'entrée principale, mais vous pouvez utiliser n'importe laquelle VWXYZpour garder une trace des autres valeurs dont vous avez besoin. Par exemple, vous pouvez faire quelque chose comme ceci:

(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)

Alternativement, si tout ce que vous voulez est une variable temporaire, vous pouvez utiliser l'affectation en ligne, comme (T=...), comme variableT (0) est rarement utilisée telle quelle.

Réutiliser une fonction longue

Pour cela, je ne pense pas que je puisse trouver un bon exemple de tâche, donc je vais faire référence à la seule solution que cette astuce a été utilisée , et juste décrire quelques idées générales.

  • Pour réutiliser une fonction, vous devez la stocker dans une variable. Démarrage d'une ligne avec l'ouvre-fonction {, @ou _fait le travail. Alternativement, vous pouvez également faire quelque chose comme(T=@...}) pour incorporer l'affectation de fonction dans une ligne plus complexe.
  • Ce n'est en fait pas trivial d'appeler la fonction stockée. Supposons que Vc'est une fonction et que nous voulons appeler V(U)en JS. VUne fonctionne pas car cela signifie simplement V,U. V(Unon plus; c'est V,(U). Même les méthodes de fonction ne sont pas très utiles. La meilleure façon que nous avons trouvée est:
    • [U]xV (carte et somme) si le résultat est un nombre
    • UmVsi Uest un seul caractère et Vrenvoie une chaîne, ou
    • $V($Uou [U]mV gen général.
  • Cependant, la cartographie ou la boucle avec elle est plutôt facile. Pour mapper sur un tableau, utilisez UmV. Pour trouver le premier entier satisfaisant V, utilisez Va.

2

Amusant avec les fonctions automatiques

Dans le prolongement de l'astuce générale de l'ETH sur les fonctions automatiques , cette astuce fournira quelques exemples spécifiques de trucs d'économie d'octets que vous pouvez réaliser avec eux, que j'ajouterai en y réfléchissant davantage.


Obtenez le plus grand entier d'un tableau.

Supposons que le tableau soit [3,1,4,2]affecté à la variable Uet que nous en récupérions le plus grand nombre. Nous pourrions le faire en 4 octets en triant le tableau puis en éclatant le dernier élément:

Un o

L'inconvénient est que nous avons modifié le tableau d'origine; Uest maintenant [1,2,3]ce qui n'est pas toujours souhaitable. Heureusement, il existe un moyen de le faire sans modifier le tableau qui est également un octet plus court:

Urw

Ce que nous y avons fait est de réduire le tableau en utilisant la wméthode qui, lorsqu'elle est utilisée sur un entier, renvoie le plus grand de l'entier et l'argument de la méthode (par exemple, 2w5renvoie 5). Donc, ce qui précède est l'équivalent de UrÈwYou UrXY{XwY}. Notez cependant que cette astuce ne fonctionnera pas si tous les entiers du tableau sont négatifs.


1
Note latérale: je prévois d'ajouter des fonctions pour obtenir le minimum et le maximum d'un tableau, mais probablement uniquement dans la v2.
ETHproductions

2

Quand non pas utiliserí

íest un outil intégré utile qui associe (ou zips) deux tableaux ou chaînes, et mappe éventuellement chaque paire via une fonction. Cependant, il présente actuellement quelques problèmes mineurs lorsqu'il est donné des tableaux ou des chaînes inégaux:

  • Si le premier tableau a plus d'éléments que le second, les éléments inexistants dans le second seront donnés comme undefined.
  • Si le deuxième tableau contient plus d'éléments que le premier, il arrêtera le traitement à la fin du premier tableau.

Cela peut rendre difficile, par exemple, la comparaison de deux chaînes inégales et de prendre le caractère avec le point de code le plus élevé de chaque paire. Même si vous savez que ce Usera le plus long, il faut encore beaucoup d'octets pour résoudre cette tâche simple:

UíUç hV @[XY]n o

Ce que vous pourriez faire à la place serait de prendre l'entrée comme un tableau de deux chaînes, de transposer le tableau avec y, puis de mapper chaque ligne au résultat correct:

Uy m_q n o

Cela a l'avantage de toujours remplir la chaîne la plus courte avec des espaces, ce qui en fait un morceau de gâteau pour parcourir l'intégralité des deux chaînes.

Exemples concrets: 1 , 2


2

Générer la plage ASCII

Mise à jour: Japt a maintenant une constante pour la plage ASCII; la valeur alternative pour E, accessible avec ;. Voir cette astuce pour en savoir plus sur les constantes de Japt.

Bien que Japt n'ait pas (encore) de fonction intégrée pour la plage ASCII, vous pouvez générer un tableau de caractères en seulement 5 octets:

95odH

Essayez-le


Comment ça fonctionne

95ocrée la plage [0,95)avec chaque élément passant par la fonction automatique d qui, lorsqu'elle est utilisée sur un nombre, renvoie le caractère à ce point de code. Passez un nombre comme argument aud méthode, dans ce casH , la constante Japt pour 32, et elle sera ajoutée au nombre d'origine avant d'être convertie.

Une solution équivalente en JavaScript serait:

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

Caractères aléatoires

Pour obtenir un caractère aléatoire dans la plage ASCII, utilisez à la öplace, qui renvoie un nombre aléatoire de la plage [0,X), où Xest le numéro sur lequel il est exécuté.

95ö dH

Ou, pour obtenir un tableau de plusieurs caractères aléatoires, passez le nombre de caractères dont vous avez besoin comme argument de ö. Les éléments suivants renvoient 10 caractères:

95öA mdH

1

Supprimez les caractères structurels inutiles

En caractères structuraux, je veux dire {}, (), $, même "et `. Vous pouvez généralement supprimer ces caractères chaque fois qu'ils surviennent à la fin d'un programme (par exemple UmX{Xc +"; "} -> UmX{Xc +"; ).

De plus, vous pouvez supprimer des parens ou des espaces chaque fois qu'ils apparaissent aux endroits suivants:

  • Contre un point-virgule ;(ou la fin du programme);
  • À droite de {(et par extension, @) ou [, ou à gauche de ]ou }.

En outre, les virgules sont très rarement nécessaires pour séparer les arguments. Si vous écrivez AB, par exemple, Japt sait que vous voulez dire Aet Bséparément. Vous n'avez vraiment besoin que d'une virgule pour séparer deux littéraux numériques, tels queUs2,5 .

Enfin, s'il y a un Uau début d'un programme ou après un {ou ;suivi d'un appel de méthode (lettre minuscule ou raccourci Unicode liés) ou tout opérateur binaire hors +et -( *, &, ==, etc.), vous pouvez supprimer le Upour enregistrer un octet et Japt l'insérera pour vous.


J'ai trouvé quelques autres cas où Upeuvent être omis même quand ce n'est pas au début du programme.
Shaggy

@Shaggy Oh oui, ça marche aussi après un { ou ;. Y en a-t-il d'autres que vous connaissez? (Cela fait un moment que je n'ai pas codé cette fonctionnalité: P)
ETHproductions

Je ne peux pas penser à eux du haut de ma tête; Je vérifierai à nouveau quand je reviendrai à mon ordinateur demain.
Shaggy

1

Modifier le dernier élément d'un tableau

Parfois, vous devrez peut-être modifier le dernier élément d'un tableau, alors voici une explication d'une manière courte de le faire. Nous allons travailler avec le tableau [2,4,8,32]affecté à la variable d'entrée Uet diviser le dernier entier (32 ) par 2.

La manière évidente d'y parvenir serait avec cette solution de 9 octets ( démo ):

UhJUgJ /2
  • hnxdéfinit l'élément à l'index nsur x.
  • gnrenvoie l'élément à l'index n.
  • J est la constante Japt pour -1 qui, grâce au support de Japt pour un indice négatif, nous permet de travailler avec le dernier élément d'un tableau; pratique lorsque vous ne connaissez pas la taille du tableau.
  • Et /2est simplement une division par 2.

Donc, ce qui précède définit l'élément à l'index -1 dans le tableau à l'élément à l' index -1dans le tableau divisé par 2. Ou en JavaScript: U[3]=U[3]/2. Lorsque vous l'écrivez comme ça, cela semble être une manière beaucoup trop longue de s'y prendre. Heureusement, il existe un chemin plus court; nous pourrions extraire le dernier élément du tableau, le modifier et le repousser dans le tableau. L'exécution de chacune de ces opérations individuellement prendrait plus de 9 octets, mais nous pouvons les faire toutes à la fois pour seulement 7 octets, une économie de 2 octets ( Démo )

UpUo /2

Traduit en JS, c'est l'équivalent de:

U.push(U.pop()/2)&&U
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.