Python 3 - J'ai essayé de jouer au golf mon devoir

9

Remarque: Ce n'est pas autant un défi de golf; il s'agit plus de demander des suggestions de golf.

Récemment, j'ai eu une affectation Python pour ma classe de développement Web, afin de vérifier si nous pouvions coder. Comme je me sens déjà à l'aise en Python, j'ai décidé d'essayer de jouer au golf et je me demandais si les gens pouvaient signaler des choses qui m'ont manqué.

Je sais déjà qu'il y a des espaces supplémentaires à certains endroits, mais je suis plus intéressé par les choses conceptuelles, comme utiliser while r:quand r est une variable, puis attendre qu'elle "s'épuise"!

La tâche

import random
from collections import Counter
s=l=''
c=['yellow','blue','white','green','Black', 'purple', 'silver', 'cyan', 'magenta', 'red']
n=[10,15,1,10,6,15,10,25,1,12,5,10,4,6,5,12,0,10,1,1]
o=i=0
for y in c:l+=y[0]*(random.randint(n[o],n[o+1]));o+=2
l=list(l)              
print("Welcome to the CIMS Gumball Machine Simulator\nYou are starting with the following gumballs:")
for b in c:print(str(l.count(b[0])) + " "+b);random.shuffle(l)
print("Here are your random purchases:")
while 'r' in l:
    random.shuffle(l); r=l.pop(); s+=r
    for j in c:
        if j[0] == r:print(j.capitalize())
print("You purchased %i gumballs, for a total of $%.2f \nMost common gumball(s):" % (len(s),len(s)*25/100))
a=Counter(s).most_common()
m=[x[1] for x in a]
while m[0] == m[i]:
    for j in c:
        if j[0] == a[i][0]:print(j.capitalize(), end=" ")
if(i<(len(m)-1)):i+=1
else:break

Aussi: Je suis désolé si ce n'est pas une question appropriée pour la page de golf de code, car ce n'est pas un défi et le supprimera sur demande.

aks.
la source
En mettant de côté la question du sujet (car je ne suis pas sûr), jetez peut-être un coup d'œil à la page des conseils de golf Python ? De plus, quelle version de Python? (Je suppose que 3 en raison des parens autour print, mais juste pour vérifier)
Sp3000
5
Avez-vous déjà essayé de jouer au golf?
feersum
2
Ce code a encore beaucoup d'améliorations simples au golf. Je pense que vous apprendrez mieux si vous examiniez les conseils de golf et examiniez d'autres golfs Python, et que vous en faisiez plus pour raccourcir votre code par vous-même. Ensuite, si vous postez ce que vous obtenez, les gens peuvent donner des conseils plus perspicaces.
xnor

Réponses:

20

Voici tout un tas de micro-optimisations que vous pouvez faire:

Utilisez .split()pour créer une longue liste (-17 octets):

c=['yellow','blue','white','green','Black', 'purple', 'silver', 'cyan', 'magenta', 'red']
c='yellow blue white green Black purple silver cyan magenta red'.split()

Supprimer les crochets superflus (-2 octets):

l+=y[0]*(random.randint(n[o],n[o+1]))
l+=y[0]*random.randint(n[o],n[o+1])

Utilisez splat (-2 octets):

random.randint(n[o],n[o+1])
random.randint(*n[o:o+2])

Utilisez le déballage itérable étendu pour transformer quelque chose en liste (-4 octets):

l=list(l)
*l,=l

Importez toutes les choses (-15 octets):

import random;random.randint;random.shuffle;random.shuffle
from random import*;randint;shuffle;shuffle

Utilisez d'autres fonctions qui peuvent faire le même travail ici (-5 * 2 = -10 octets):

j.capitalize()
j.title()

print sépare par espace par défaut (-11 octets):

print(str(l.count(b[0])) + " "+b)
print(l.count(b[0]),b)

Plus de déballage (-3 octets):

r=l.pop()
*l,r=l

Effets secondaires des abus (-1 octet, plus les retraits):

if j[0]==r:print(j.capitalize())
r!=j[0]or print(j.capitalize())

Tout ce qui est réutilisé et plus de 5 caractères peut valoir la peine d'être enregistré en tant que variable (-1 octet):

len(s);len(s)
L=len(s);L;L

Simplifiez les fractions (-5 octets):

len(s)*25/100
len(s)/4

Abus unaire (-4 octets):

if(i<(len(m)-1)):i+=1
if~-len(m)>i:i+=1

Ou le plus grand de tous ...

Examinez votre algorithme et voyez s'il doit être complètement changé

from random import*
*s,P,S=print,shuffle
P("Welcome to the CIMS Gumball Machine Simulator\nYou are starting with the following gumballs:")
*l,c,C='yellow blue white green Black purple silver cyan magenta red'.split(),s.count
for x,y,z in zip(c,[10,1,6,10,1,5,4,5,0,1],[15,10,15,25,12,10,6,12,10,1]):n=randint(y,z);l+=[x]*n;P(n,x)
S(l)
P("Here are your random purchases:")
while'red'in l:S(l);*l,r=l;s+=r,;P(r.title())
L=len(s)
P("You purchased %i gumballs, for a total of $%.2f\nMost common gumball(s):"%(L,L/4))
for x in c:C(x)!=max(map(C,c))or P(x.title())

(Si vous vous retrouvez à importer Counterdans un code-golf, vous faites probablement quelque chose de très mal ...)

Sp3000
la source
Sensationnel!! Ceci est exactement ce que je cherchais. Merci beaucoup pour votre aide!
aks.
Vous pourriez probablement éviter le besoin de .title()tout en précapitalisant. Attribuez également s.countà une variable.
isaacg
@isaacg J'ai pensé que j'essaierais de conserver les fonctionnalités du programme d'origine. Si la spécification était tout ce qui comptait, je laisserais tomber quelques-unes des longues déclarations d'impression car, techniquement, l'affectation n'en a pas besoin;)
Sp3000
@ Sp3000 Dans ce cas, pourquoi ne pas mettre le .title () sur la chaîne initiale? Enregistre une utilisation de .title ().
isaacg
@isaacg Aussi, je l'ai fait en choisissant parmi un tableau de chacune des lettres de départ, et «b» représentait le bleu et «B» représentait le noir
aks.