Pyth est un langage de programmation procédural inspiré de Python, créé par isaacg, un utilisateur de PPCG .
Quels conseils généraux avez-vous pour jouer au golf à Pyth? Je cherche des idées pouvant être appliquées aux problèmes de code de golf en général, qui sont au moins quelque peu spécifiques à Pyth.
Un pourboire par réponse, s'il vous plaît.
Connaissez vos variables
Pyth a trois catégories de variables: les variables génériques pré-initialisées, les variables pré-initialisées en fonction des entrées de l'utilisateur et les variables générant implicitement une affectation lors de la première utilisation.
Variables génériques:
Variables initialisées en entrée:
Notez que ces initialisations ne seront exécutées dans un programme donné que si la variable associée est utilisée en dehors d'une chaîne dans le code. De plus, la commande est
Q
alorsz
si les deux sont utilisés.Affectation sur les variables de première utilisation:
J
etK
. Si vous souhaitez initialiser les deux à la même valeur, vous pouvez le faire avec une expression telle queKJ0
, qui équivaut à la plus longueJ0K0
.la source
Utilisez le plus récent interprète en ligne pour tester vos réponses.
Notez qu'il s'agit d'un nouveau logiciel, il est donc peut-être buggé. S'il vous plaît signaler tout problème à moi.
la source
Les chaînes en fin de ligne n'ont pas besoin de guillemets. Par exemple:
est un programme Hello World complètement valide.
la source
Utiliser
C
pour la compression de baseCeci est en réalité non documenté, C sur une chaîne n'est pas direct chr -> int mais à la base 256 -> base 10 (ce qui est identique pour une chaîne de caractères ). Ceci est extrêmement utile pour compresser un int, nous pouvons utiliser ce script pour compresser:
Prenez
12345678910
, il en résulteßÜ>
(certains non imprimables là-bas).De même, avec un tableau d'ints, vous pouvez les concaténer, ainsi qu'avec des chaînes de grande taille, en les convertissant en points de code et en les traitant comme un nombre de base 128.
Un autre usage de
C
, merci @xnor de me l'avoir montré, est de faire un grand nombre arbitraire. La manière naïve est:Mais nous pouvons mieux faire un octet avec:
cette base 256 déconvertit l'alphabet entier. Résultats
156490583352162063278528710879425690470022892627113539022649722
= ~1.56e62
.la source
Il existe maintenant un tutoriel en ligne pour Pyth.
Une documentation complète sera ajoutée plus tard.
la source
Utilisez les fonctions fonctionnelles courtes ... err ...
Lorsque l'argument lambda à
map
oureduce
applique simplement une opération aux arguments, vous pouvez utiliser les formes abrégées,M
etF
.fMx
est équivalent àmfdx
, etfFx
est la même chose que.UfbZx
. Par exemple, supposons que nous prenions une liste de nombres en entrée et en sortie, chacun incrémenté. Une première approche pourrait être:Cependant, cela peut être réécrit comme:
Une chose similaire s'applique à
reduce
avecF
. Par exemple, supposons qu'il soit difficile de calculer le produit d'une liste d'entiers. Encore une fois, un premier essai peut être:Cependant, avec
F
, cela peut être réduit à:Rase trois octets ... pas mal!
la source
Q
, car elle est complétée lorsque la fonction manque une entrée, ce qui la rend*F
Gardez votre implémentation Pyth à jour.
J'améliore assez régulièrement Pyth, supprime des fonctionnalités moins utiles et en ajoute d'autres, donc gardez un œil sur les nouveautés et mettez à jour régulièrement votre copie de la mise en œuvre.
Quelques fonctionnalités récemment ajoutées: (au 19/10/14)
y
: Agit comme un*2
nombre et comme une liste de tous les sous-ensembles de chaînes et de listes. Par exemple:f
:f
est normalement la commande de filtre. Maintenant, lorsqu'il est appelé avec un nombre en tant que deuxième argument, il filtre sur la séquence infinie en commençant par ce nombre et en comptant par 1, puis renvoie le premier élément de la séquence résultante.Par exemple, voici le code pour trouver le plus petit nombre premier sur un milliard:
la source
yz
?mvdczd
ça ne peut pas être le chemin le plus court ...y
parce que je ne pense pas que Pyth doit disposer de plusieurs formats d'entrée très facilement analysables, un seul, par exemple le format Python. Donc, oui, je pense que je devraimvdczd
le faire, malheureusement.r
la suite de traitement de chaînes.r
semble très utile.@
dans Fdr1 + 1 @ Q2Iq% Qd0d pour créer un calculateur de facteurs. Lorsque j'essaie de l'utiliser, leindex
sens par défaut est utilisé . Y a-t-il un moyen de contourner ce comportement?Arguments nommés dans les fonctions (non pris en charge)
Parfois, les valeurs par défaut dans les fonctions peuvent être utiles pour le golf. Pyth le supporte réellement (à ma grande surprise). Par exemple:
Imprimera:
Vous pouvez également utiliser J et K pour sauvegarder des caractères en procédant comme suit:
impressions:
Ceci est généralement utile pour les algorithmes récursifs.
Cela ne fonctionne plus, mais je l'ai laissé ici au cas où quelqu'un voudrait jouer au golf avec une ancienne version de Pyth.
la source
Déballage de tuples 2 éléments avec
F
Supposons que vous avez un tuple à 2 éléments
J = (a, b)
, et que vous voulezr(a,b)
, pour une fonction à 2 arités r.La façon naïve de le faire est
rhJeJ
.Pour ce faire
r.*J
, utilisez l’opérateur de décompression.La façon la plus simple de procéder consiste à
rFJ
utiliser l’opérateur de pliage.la source
.u
pour cela?.u
semble être cumulatif réduire maintenant.Utiliser les fonctions arithmétiques courtes
h
: En plus de renvoyer le premier élément d'une liste, il incrémente un nombre, par exemple,hT
évalue11
. Plus court que+1T
.t
: Ceci décrémente un nombre (autre que renvoyer la queue d'une liste), par exemple,tT
évalue9
. Plus court que-T1
.y
: Ce double un certain nombre, par exempleyT
évalue à20
plus court que*T2
ou+TT
.la source
Utiliser
map
pour générer des listesC'est fondamentalement un équivalent de la compréhension de liste fantaisie de python. Utilisez une liste existante ou une plage sur laquelle itérer et mapper chaque valeur, même si la valeur n'a pas d'importance.
Deux exemples:
Générez une liste de 8 zéros.
mZ8
au lieu de*8]Z
Générez une liste de 5 nombres aléatoires compris entre 0 et 9:
mOT5
au lieu deV5~Y]OT)
Le second attribue automatiquement la liste à
Y
(eh bien en fait il s’ajoute à Y), mais=YmOTU5
est même plus court.la source
Q implicite à EOF
C'est un nouveau changement, à compter d'aujourd'hui.
Q
est la variable qui est auto-initialisée à l'entrée évaluée. Il est implicitement ajouté à la fin du programme Pyth, autant de fois que nécessaire pour résoudre le problème d'arité. Pour voir un exemple d'utilisation de cette méthode pour le golf, supposons que nous voulions calculer la fonction Collatz de l'entrée.Une façon la plus rapide de l’écrire est la suivante:
Cependant, les
Q
s étant implicites à la fin du fichier, on peut simplement écrire:Enregistrement de 2 octets.
Notez que ces arguments ne seront pas renseignés dans les fonctions avec des arguments non requis. Par exemple, ils
c"12 12"
n'auront pas d'impliciteQ
, car ilsc
ne nécessitent qu'un seul argument.la source
Utilisez réduire pour appliquer une fonction à plusieurs reprises.
Supposons que vous deviez définir une variable sur une fonction d'elle-même et la répéter un certain nombre de fois. Prenons, par exemple, le problème de trouver le nombre 100 plus tard dans la séquence de Collatz à partir de l'entrée. Le moyen le plus rapide de rechercher le prochain numéro de la séquence, si le numéro initial est
Q
, estLa manière la plus évidente d’appliquer ces 100 fois et d’imprimer le résultat serait
Boucle 100 fois, en mettant à jour la valeur de Q à chaque fois, puis terminez la boucle et imprimez Q.
Au lieu de cela, nous pouvons utiliser une fonction de réduction qui ignore la variable de séquence (
H
).C'est 2 caractères plus court. Il est plus court de 3 caractères si vous essayez de boucler autant de fois qu'il y a d'éléments dans une séquence.
la source
Il existe généralement des alternatives plus courtes à
Lorsque vous voulez rechercher si une séquence satisfait à une condition, vous utiliserez généralement
.Em
. Par exemple, si vous voulez savoir si certains éléments d'une liste sont supérieurs ou égaux à 5:Mais, si cela doit seulement être une vérité / falsey, pas vrai / faux,
sm
cela fonctionnerait puisque sum travaille sur bools.On peut même en faire un plus court, avec
f
ilter:Le dernier a l'air vraiment moche cependant.
Pour
.A
ll, la seule chose à laquelle je peux penser est d'utiliser la condition opposée et de la nier pour une sauvegarde d'un caractère.Am
:la source
Regardez toutes les options de flux de contrôle
Boucles:
F
: Pour la boucle. Tout comme Python.V
: Pour une boucle sur une plage. Aucune variable ni plage ne doit être donnée, donc 2 caractères plus courts.W
: En boucle. Tout comme Python.#
: Infini en boucle. Échapper avec une erreur ou une pause explicite.Seuletry ... except
fonctionnalité maintenant en Pyth.Les fonctions:
D
: Définir général. Tout comme Python.L
: 1 argument, pas de fonction d’assignation, comme le lambda de Python, mais nommé. Le nom de la fonction, le nom de la variable et return (R
) n'ont pas besoin d'être indiqués, donc 3 caractères plus courts.Programmation fonctionnelle:
f
: Filter - sélectionne les éléments de la séquence d’entrée qui retournent la vérité sur l’entrée lambda.f
: Premier entier supérieur ou égal à l'entrée qui donne le résultat du filtre de vérité.m
: Map - transforme les éléments de la séquence d'entrée en utilisant l'entrée lambda.u
: Réduit - plie la séquence d'entrée sur l'entrée lambda, initialisant l'accumulateur sur le troisième argument.o
: Order - les éléments les plus anciens de la séquence d'entrée utilisant l'entrée lambda comme clé.Habituellement, il y a de multiples possibilités pour un problème donné, et ce n'est qu'en écrivant des solutions de test avec chacun d'eux que vous pouvez déterminer laquelle est la plus courte.
la source
.x
peut plus récemment être utilisé pour les blocs try-except..x{some_statments}{except_block - can this be empty}
.# ... B
peut être utilisé de cette façon si vous n'êtes pas dans une expressionChanger deux éléments dans une liste
Changer deux éléments peut être une tâche assez coûteuse. Donc, voici deux approches que vous voulez utiliser.
Approche tmp-variable
En préparation, nous définissons une liste
Y
et la remplissons de chiffres. L'objectif est de passer du deuxième au troisième élément.Nous affectons simplement la variable tmp
J = Q[G]
, faisons la première affectation de listeY[G] = Y[H]
puis l’avant-dernière affectationY[H] = J
. Le truc ici consiste à imbriquer les deux assignations de liste, de sorte que vous n’ayez pas à supprimer l’impression ni à utiliser le renvoi à deux foisY
.au lieu de
Approche traductive
Si les éléments que vous souhaitez activer sont uniques dans la liste, utilisez cette approche. C'est vraiment court. Donc, cette fois, nous commutons les premier et troisième éléments (les valeurs
1
et5
sont uniques).Ceci utilise la fonctionnalité de traduction de la liste:
Cette traduction remplace chaque élément
Y[0]
avecY[1]
etY[1]
avecY[0]
. Donc, si les valeurs ne sont pas uniques, de mauvaises choses se produisent. Par exemple,K,1 2
résulte en[1, 5, 3, 5, 6, 7]
.Notez que les parenthèses fermantes sont facultatives, si l’instruction est la dernière de votre code.
la source
Débogage avec
<newline>
Si votre code est écrit dans un style de programmation impératif, il est assez facile de déboguer, car vous pouvez facilement imprimer des résultats intermédiaires. ( permalien )
Cependant, un grand nombre de programmes Pyth utilisent des éléments de programmation fonctionnelle, tels que mappage, filtrage et réduction, qui ne permettent pas une impression aussi simple. Mais c'est toujours possible, en utilisant la
\n
commande.Le même code utilisant
u
(réduire) serait: ( permalien )Si vous souhaitez imprimer les valeurs intermédiaires, il vous suffit d'insérer
\n
: ( permalien )\na
imprimea
sur une nouvelle ligne et retournea
. Ainsi, vous pouvez l'insérer n'importe où sans vous soucier de modifier les fonctionnalités du programme.la source
Trouver le maximum de deux entiers
Par exemple, supposons que vous avez
J=5
etK=12
. Alorsg#JK
= 12, etg#KJ
= 12 aussi.Ceci a été découvert par @ Pietu1998, qui l'a exprimé ainsi:
Je ne suis pas sûr que quelqu'un l'ait déjà trouvé, mais il existe un moyen pratique de faire max (A, B) sur 2 octets, inutile d'utiliser 3 pour
eS,AB
.g#AB
fait la même chose. (C'est très inefficace, cependant, car il boucle max (1, A-B + 1) fois. Une optimisation consiste à mettre le nombre susceptible d'être plus grand que B.)la source
La
join
méthode de PythLa
join
méthode en Python peut être souvent un peu gênante, car elle ne fait que joindre des chaînes. Pyth'sjoin
est plus généreux. Il transforme tous les objets en chaînes par défaut.Par exemple,
jkUT
donne0123456789
oujb["abc"4,5\f]7
donnela source
j2\a\b
->"a2b"
Dire si un nombre est un nombre entier
Une astuce consiste à utiliser
I
nvariant pour savoir si un nombre est un nombre entier en tant que tel:Ceci vérifie si le nombre ne change pas lorsque vous le tronquez, ce qui ne sera pas le cas s'il s'agit d'un nombre entier.
Par exemple, vous pouvez utiliser ceci comme vérification carrée parfaite:
la source
Utilisez Packed Pyth
Packed Pyth est un nouveau "langage de programmation" qui est identique à Pyth, à la différence qu’il utilise 7 bits par caractère au lieu de 8 bits par caractère.
Pour l'utiliser, clonez le référentiel pyth . Le fichier
packed-pyth.py
est l'interprète.Dites que votre code est
"Hello, world!
.Tout d'abord, mettez-le dans un fichier:
echo -n '"Hello, world!' > code.pyth
Ensuite, compressez le code Pyth dans un fichier Packed Pyth:
python3 packed-pyth.py -p code.pyth code.ppyth
Enfin, lancez le code Packed Pyth:
python3 packed-pyth.py code.ppyth
Lorsque vous exécutez du code, vous pouvez indiquer à l'
-d
indicateur quel est le code Pyth en cours d'exécution, ainsi que le deuxième argument de ligne de commande après le fichier contenant le code.Upside:
Inconvénient:
ASCII seulement.
Aucune entrée interactive.
Les options de débogage complètes ne sont pas disponibles.
Pire rapport d'erreurs.
la source
Test de divisibilité avec
I
et GCDAvertissement: Cela ne fonctionne que pour les entiers non négatifs.
Pour vérifier si deux entiers non négatifs sont divisibles, vous pouvez procéder comme suit:
Si a est divisible par b et a ≥ b ≥ 0 , alors gcd (a, b) = b .
Cela ne économise pas nécessairement plus d'octets
!%<dividend><divisor>
, mais cela peut vous apporter une économie, car:Q
) lorsque vous travaillerez avec le dividende.<pfn>
, puisqu'il s'agit d'une fonction à part entière.0
.Essayez le!
la source
iI
est une fonction en elle-même, alors qu’elle!%
ne l’est pas, vous pouvez donc l’utiliser comme fonction de préfixe.Assigner une variable à une fonction appliquée à elle-même
Si vous avez une fonction d'arité 1 et que vous souhaitez l'appliquer à une variable et l'appliquer à elle-même, vous pouvez utiliser la syntaxe suivante:
Au lieu de:
Par exemple, si vous voulez incrémenter la variable
Z
, vous pouvez faire:Ce qui sauve un octet fini
=ZhZ
.la source