J'ai essayé de raccourcir petit à petit le FizzBuzz de Python

Déclencheur

Je créais FizzBuzz pour une raison quelconque, mais je me suis soudainement demandé: "Et si j'essayais d'écrire FizzBuzz aussi court que possible?"

C'est peut-être un article courant dans les rues, mais je l'écrirai pour ma propre étude.

environnement

Python 3.8.2

Règles FizzBuzz

Partie 1 (pour déclaration)

FizzBuzz avec une instruction for, qui est généralement celle-ci.

--Nombre de caractères: 212 caractères

for i in range(1, 101):
    if ((i % 3 == 0) & (i % 5 == 0)):
        print("FizzBuzz")
    elif (i % 5 == 0):
        print("Buzz")
    elif (i % 3 == 0):
        print("Fizz")
    else:
        print(i)

commentaire

Comme Python, c'est très facile à voir.

Partie 2 (instruction while)

Depuis que j'ai écrit FizzBuzz et pour statement ver. En utilisant la déclaration while, j'ai également écrit while statement ver.

--Nombre de caractères: 223 caractères

i = 1
while(i < 101):
    if ((i % 3 == 0) & (i % 5 == 0)):
        print("FizzBuzz")
    elif (i % 5 == 0):
        print("Buzz")
    elif (i % 3 == 0):
        print("Fizz")
    else:
        print(i)
    i += 1

commentaire

Le nombre de caractères est 11 de plus que l'instruction for ver.

C'est dommage, mais dans le cas d'une simple opération répétitive comme celle ci-dessus, l'instruction while semble être plus lente lorsque l'on compare les vitesses d'exécution de l'instruction for et de l'instruction while.

L'instruction while n'est pas une source simple comme FizzBuzz, mais jouons un rôle actif à un autre endroit (lancer rond).

Partie 3 (opérateur ternaire)

FizzBuzz en utilisant l'opérateur ternaire, je pouvais l'écrire en une phrase, mais c'était trop long, j'ai donc commencé une nouvelle ligne avec un deux-points.

--Nombre de caractères: 126

for i in range(1, 101):
    print("FizzBuzz" if (i % 15 == 0) else "Buzz" if (i % 5 == 0) else "Fizz" if (i % 3 == 0) else i)

commentaire

En utilisant l'opérateur ternaire, l'expression est devenue beaucoup plus propre.

Gardons-le de plus en plus court avec cette condition.

Supplément: À propos de l'opérateur ternaire

Pliez-le car c'est un supplément.

L'opérateur ternaire est un opérateur souvent utilisé lorsque vous souhaitez décrire une branche conditionnelle telle qu'une instruction if ~ else dans une instruction.

(Valeur lorsque la condition est vraie) if (conditions) else (conditionsがFalseのときの値)

L'instruction if ~ else suivante peut être écrite en utilisant l'opérateur ternaire comme suit.

# if~autre déclaration
if number == 0:
    print("number is 0")
else:
    print("number is NOT 0")
#Opérateur triangulaire
print("number is 0" if number == 0 else "number is NOT 0")

Partie 4 (opérateur ternaire, expression de générateur)

FizzBuzz en utilisant l'opérateur ternaire et l'expression du générateur, vous pouvez afficher de force une ligne.

--Nombre de caractères: 130 caractères (car il dépasse 80 caractères, une pause est en fait nécessaire)

print("\n".join("FizzBuzz" if i % 15 == 0 else "Buzz" if i % 5 == 0 else "Fizz" if i % 3 == 0 else str(i) for i in range(1, 101)))

commentaire

En l'utilisant en combinaison avec l'opérateur ternaire mentionné précédemment, j'ai pu l'écrire proprement en une phrase.

Rendons cette description encore plus courte ensuite.

Supplément: type de générateur

Pliez-le car c'est un supplément.

En guise d'explication approximative, afin d'expliquer l'expression du générateur, je vais d'abord expliquer la notation d'inclusion de liste.

  • Désolé pour ceux qui veulent connaître les détails de la formule du générateur, mais essayez google avec notation d'inclusion de liste, générateur, etc.

Notation d'inclusion de liste

La notation d'inclusion de liste est une description spécifique à Python et se présente comme suit.

print([i for i in range(0,10)])  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

En utilisant la notation d'inclusion de liste et le separator .join ([list]), vous pouvez obtenir le résultat comme si vous utilisiez une instruction for normale.

print("\n".join([i for i in range(0,10)]))

Sur la base de ce qui précède, passons au type de générateur.

Type de générateur

Pour expliquer brièvement, il est dans [] de la notation d'inclusion de liste, et il s'agit de créer une fonction entre parenthèses et de l'utiliser pour effectuer le traitement.

Voyons ce que renvoie l'expression du générateur.

print(i for i in range(0,10))  # <generator object <genexpr> at 0x000001C52B998BA0>

Puisque le résultat de sortie ci-dessus renvoie "quelque chose comme une fonction qui renvoie une liste", les humains ne peuvent pas le comprendre tel quel.

  • Dans la notation d'inclusion de liste, en recevant la valeur de retour de l'expression du générateur dans la liste [], le contenu peut être compris par les humains.

Cependant, vous pouvez obtenir le résultat de l'utilisation de l'instruction for normale en utilisant le separator .join ([list]) dans l'expression du générateur ainsi que la notation d'inclusion de liste.

Dans ce FizzBuzz, le nombre de caractères est plus petit lors de l'utilisation de l'expression du générateur que lors de l'utilisation de la notation d'inclusion de liste, donc ceci est adopté et décrit.

Partie 5 (type de générateur, fonctionnement de la chaîne de caractères, évaluation des courts-circuits)

FizzBuzz utilisant le type de générateur et l'évaluation des courts-circuits (fonctionnement de chaîne partielle) est devenu considérablement plus court.

print("\n".join("Fizz"*(i % 3 == 0)+"Buzz"*(i % 5 == 0)or str(i) for i in range(1, 101)))

commentaire

C'est très court, moins de 100 caractères.

Le FizzBuzz le plus court auquel je suis arrivé était ici.

Cependant, lorsque je l'ai recherché, il y avait une description plus courte de FizzBuzz (la plus courte du monde), je vais donc la présenter ensuite.

Supplément: opération de chaîne

Pliez-le car c'est un supplément.

Dans le cas de cette description, dans " Fizz "* (i% 3 == 0) et " Buzz "* (i% 5 == 0), utilisez la description de chaîne de caractères * boolean. J'ai fait.

En Python, le type booléen est une sous-classe du type int, et les types booléens «True» et «False» sont respectivement équivalents à «0» et «1».

Il existe également un moyen de répéter une chaîne: string * number (int).

Ici, ʻABC * 3 est ʻABCABCABC, et ʻABC * 0 est un caractère vide "" `.

Autrement dit, si le nombre à juger est un multiple de 3, booléen est vrai et Fizz * 1 => Fizz s'affiche, et s'il est un multiple de 15,"Fizz" * 1 + "Buzz" * 1 => "Fizz" + Buzz => "FizzBuzz".

Supplément: évaluation des courts-circuits

Pliez-le car c'est un supplément.

En ce qui concerne l'évaluation des courts-circuits, le site suivant était très bien organisé (j'y ai aussi fait référence).

Référence: opérateurs logiques Python et, ou, non (produit logique, somme logique, refus)

En termes simples, les valeurs de retour de et et ou suivent un algorithme fixe, comme indiqué ci-dessous.

Ici, la description de x (vrai) signifie que «x lui-même est vrai».

    x(vrai) and y(faux) => y
    x(faux) and y(vrai) => x
    x(vrai) or y(faux) => x
    x(faux) or y(vrai) => y
    x(vrai) and y(vrai) => y
    x(faux) and y(faux) => x
    x(vrai) or y(vrai) => x
    x(faux) or y(faux) => y

À propos, si x ou y est faux, alors:

--Type de booléen False

  • None --Valeurs numériques (type int et type float) 0, 0.0 --Chaîne vide''
  • Conteneurs vides (listes, tapples, dictionnaires, etc.) [], (), {},

Tout le reste est considéré comme vrai.

En d'autres termes, dans ce cas, dans la formule (" Fizz "* (i% 3 == 0) +" Buzz "* (i% 5 == 0) ou i, FizzBuzz est établi par le calcul suivant. ..

--Lorsque le nombre à juger est un multiple de 3

"Fizz"*(i % 3 == 0)+"Buzz"*(i % 5 == 0)or i => "Fizz" + "" or i => "Fizz" or i => "Fizz"

  • "Fizz" est considéré comme vrai parce que "" n'est pas vide et "Fizz" est renvoyé par l'algorithme x (true) ou y (true) => x.

--Lorsque le nombre à juger n'est pas un multiple de 3, 5 ou 15

"Fizz"*(i % 3 == 0)+"Buzz"*(i % 5 == 0)or i => "" or i => i

  • En raison de "", il est considéré comme faux, et i est renvoyé par l'algorithme de x (faux) ou y (vrai) => y.

Partie 6: Description la plus courte au monde FizzBuzz (pour déclaration, évaluation de court-circuit, inversion de bits)

FizzBuzz, la description la plus courte au monde, j'ai un peu changé la description selon cette règle, mais elle est étonnamment courte!

Référence: Implémenter FizzBuzz en 1 octet> Python3 (59 octets)

--Nombre de caractères: 64 caractères

for i in range(100):print(i % 3//2*"Fizz"+i % 5//4*"Buzz"or -~i)

commentaire

C'est court. Je n'ai pas remarqué cette déclaration, mais c'est très simple (apparemment uniquement pour et imprimer les déclarations).

La syntaxe / les techniques utilisées étaient pour l'instruction, l'évaluation des courts-circuits, la troncature / division et l'inversion de bits.

Supplément: Division de la troncature

Pliez-le car c'est un supplément.

J'avais peur quand je l'ai vu pour la première fois, c'est donc un supplément.

En définissant ʻi% 3 // 2`, 0 est renvoyé si i est 0 ou 1, et 1 est renvoyé si i est 2.

Par conséquent, l'instruction for est «range (100)», n'est-ce pas?

Il semble que cela et l'évaluation du court-circuit soient utilisés pour raccourcir la minute entière.

Supplément: inversion de bits

Pliez-le car c'est un supplément.

J'utilisais l'inversion de bits avec l'opérateur ~.

Dans le cas de Python, il semble que ~ x devienne- (x + 1), pas simplement la valeur avec les bits inversés.

Référence: opérations arithmétiques et bit par bit sur un seul terme

Par conséquent, si vous écrivez - ~ x, ce sera - (- (x + 1)), c'est-à-dire (x + 1), et la plage de l'instruction for serarange (100). Cela semblait être là.

Résumé

C'était une bonne occasion de reconfirmer le type de générateur, l'évaluation des courts-circuits, l'inversion des bits, etc.

FizzBuzz est profond!

La prochaine fois, j'aimerais savoir si la vitesse d'exécution changera si le nombre de caractères dans FizzBuzz diminue.

Recommended Posts

J'ai essayé de raccourcir petit à petit le FizzBuzz de Python
J'ai essayé de programmer la bulle de tri par langue
J'ai essayé de gratter
J'ai essayé d'obtenir une image en grattant
J'ai essayé PyQ
J'ai essayé l'analyse technique FX par AI "scikit-learn"
J'ai essayé AutoKeras
J'ai essayé de toucher la bibliothèque GUI de Python "PySimple GUI"
J'ai essayé la sortie de caractères "*" de Python dans une autre langue
J'ai essayé le moulin à papier
J'ai essayé django-slack
J'ai essayé Django
J'ai essayé spleeter
J'ai essayé cgo
J'ai essayé de classer les boules de dragon par adaline
J'ai essayé d'augmenter ou de diminuer le nombre en programmant
J'ai essayé d'utiliser paramétré
J'ai essayé d'utiliser argparse
J'ai essayé d'utiliser la mimesis
J'ai essayé d'exécuter pymc
J'ai essayé le spoofing ARP
J'ai essayé d'utiliser aiomysql
J'ai essayé d'utiliser Summpy
J'ai essayé Python> autopep8
J'ai essayé d'utiliser Pipenv
J'ai essayé d'utiliser matplotlib
J'ai essayé d'utiliser ESPCN
J'ai essayé PyCaret2.0 (pycaret-nightly)
J'ai essayé d'utiliser openpyxl
J'ai essayé le deep learning
J'ai essayé AWS CDK!
J'ai essayé d'utiliser Ipython
J'ai essayé de déboguer.
J'ai essayé d'utiliser PyCaret
J'ai essayé d'utiliser cron
J'ai essayé la mapview de Kivy
J'ai essayé d'utiliser ngrok
J'ai essayé d'utiliser face_recognition
J'ai essayé d'utiliser Jupyter
J'ai essayé de déplacer EfficientDet
J'ai essayé la programmation shell
J'ai essayé d'utiliser doctest
J'ai essayé Python> décorateur
J'ai essayé d'exécuter TensorFlow
J'ai essayé d'utiliser du folium
J'ai essayé d'utiliser jinja2
J'ai essayé AWS Iot
J'ai essayé l'optimisation bayésienne!
J'ai essayé d'utiliser du folium
J'ai essayé d'utiliser la fenêtre de temps
J'ai essayé d'implémenter la détection d'anomalies par apprentissage de structure clairsemée
J'ai essayé d'accélérer la création vidéo en traitant en parallèle
[Introduction à la simulation] J'ai essayé de jouer en simulant une infection corona ♬
[Django] J'ai essayé d'implémenter des restrictions d'accès par héritage de classe.
[Introduction à Pandas] J'ai essayé d'augmenter les données d'échange par interpolation de données ♬
J'ai essayé de classer MNIST par GNN (avec PyTorch géométrique)
J'ai essayé un peu le comportement de la fonction zip