Quand Numpy vous sauve la vie

Bon, pas à ce point, mais j'ai gagné !

Vous connaissez déjà le principe des « Clash of Code » , je suppose. Eh bien je viens d’en gagner un haut la main grâce à Numpy !

L’exercice à résoudre en 15 min ? On te donne un entier start, un entier end et un entier count, à toi de générer une liste de count entiers entre start et end. Exactement ce que fait la fonction linspace de Numpy. :diable:

Et si jamais ça marchait ? Et si je pouvais utiliser Numpy sur CodinGame ? Le cœur battant la chamade, les doigts transpirants, je tape import numpy as np en haut de mon code et là miracle ! le code compile parfaitement. Ni une ni deux, je finis mon code, qui est fort peu lisible car le but était de faire le code le plus court possible.

1
2
3
4
import numpy as n
s,e,c=[int(i) for i in input().split()]
if (s,e,c)==(0,0,0):print('NONE')
else:print(' '.join([str(y) for y in list(n.linspace(start=s,stop=e,num=c,dtype=int))]))

Je suis sympa, voici une version plus aérée.

1
2
3
4
5
6
7
8
9
import numpy as np

start, end, count = (1, 100, 10)

if (start, end, count) == (0, 0, 0):
    print('NONE')
else:
    r = list(np.linspace(start = start, stop = end, num = count, dtype = int))
    print(' '.join([str(y) for y in r]))
Parce que je suis un gros prétentieux vantard, arogant et insupportable, je ne résiste pas à l’envie de faire une capture d’écran.

En conclusion

  • Je ne sais pas si faire du C est très courageux ou suicidaire.
  • En JavaScript y’a que dalle, faut quasiment tout recoder à la main.
  • La plupart des exercices en rapport avec les maths sont remportés haut la main en Ruby, parce que ce langage est cool et inclut de façon standard pleins de trucs mathématiques : PPCM, nombres premiers, etc.


46 commentaires

Si je peux me permettre, tu peux encore économiser un tiers des caractères avec quelques astuces :

  • Écrire as n prend plus de caractères que rajouter umpy ) l’appel.
  • Les map sont généralement plus courts que les listes en intension, mais il faut en Python 3 les convertir en listes pour les itérer plusieurs fois.
  • Tu peux tester l’égalité à (0,0,0) avec un any.
  • linspace peut prendre des arguments positionnels.
  • map(int,...) est plus court que ,dtype=int.
  • Un ternaire est plus court qu’une condition habituelle, et tu n’aurais pas à répéter print.
  • Un ternaire and/or fait encore gagner un caractère par rapport à if/else.
  • On peut omettre pas mal d’espaces autour de ces opérateurs.

Au final, ça donne ça, en 117 caractères :

1
2
3
import numpy
x=list(map(int,input().split()))
print(any(x)and' '.join(map(str,map(int,numpy.linspace(*x))))or'NONE')

Mais c’est quoi l’énoncé exact du coup ? Parce que comme tu l’as écrit c’est juste range(s,s+c) (et je devine qu’il faut éventuellement afficher NONE plus souvent). linspace c’est quand même un peu plus puissant (mais quand même assez verbeux comme utilisation, surtout en comptant le import :p).

D’ailleurs je pense que tu peux gagner quelques caractères (et un peu de clarté) en utilisant map (et autres artifices) :

1
2
3
import numpy as n
s,e,c=map(int,input().split())
print('NONE'if s==e==c==0 else' '.join(map(str,n.linspace(s,e,c,dtype=int))))

Je ne sais pas si faire du C est très courageux ou suicidaire.

Je comprends pas trop comment fonctionne la fiche de score, mais j’ai l’impression que rien qu’en faisant un code juste t’as déjà un résultat honorable…

Et je veux pas dire mais il est deux fois plus court que le tien ^^ (et même en faisant un truc bien standard c’est plus court) :

1
i,s,e,c;main(){scanf("%d%d%d",&s,&e,&c);while(i++<c)printf("%d%c",s+i*(e-s)/c," \n"[i==c]);}

Bon ça n’a pas exactement le même comportement que linspace (mais en même en temps "evenly spaced" c’est pas bien défini).

+0 -0

J’imagine qu’il fallait une condition d’équirépartition entre les entiers ? Sinon print(' '.join([str(s)]*c)) marchait assez bien. :p

J’en profite pour enlever encore une trentaine de caractères (on tombe à 146 au lieu de 180), notamment sur l’usage de linspace (pas besoin de nommer les premières variables, et array est itérable), et avec une ternaire :

1
2
3
import numpy as n
s,e,c=[int(i)for i in input().split()]
print('NONE'if(s,e,c)==(0,0,0)else' '.join([str(y)for y in n.linspace(s,e,c,dtype=int)]))

On peut encore faire plus court (126) en recodant linspace nous-mêmes pour se passer de l’import :

1
2
s,e,c=[int(i)for i in input().split()]
print('NONE'if(s,e,c)==(0,0,0)else' '.join([str(s+(x*(e-s))//(c-1))for x in range(c)]))

D’ailleurs, c’est bizarre qu’on ne doive écrire NONE que dans le cas où s=e=c=0, il ne faudrait pas l’écrire dès que c=0 ? En plus ça fait gagner des caractères. ^^

Edit : complètement cramé par entwanne et Lucas !

Edit 2 : Du coup, en prenant les améliorations ci-haut, j’arrive à 112.

1
2
s,e,c=map(int,input().split())
print(s==e==c==0and'NONE'or' '.join([str(s+(x*(e-s))//(c-1))for x in range(c)]))
+1 -0

Désolé si l’énoncé n’était pas assez clair. Pour donner un exemple, avec les trois paramètres valant 1 10 10, il fallait obtenir 1 2 3 4 5 6 7 8 9 10. Donc non Lucas-84, un simple range n’y suffit pas.

En tout cas merci pour vos astuces. :)

EDIT : et concernant le score, ça prend d’abord en compte le pourcentage de résolution de l’exercice, puis la taille du code, puis la vitesse de résolution. Si tu as 50 caractères mais 100% de réussite, tu sera mieux classé que si t’en a 12 mais seulement 80% de tests qui passent.

Désolé si l’énoncé n’était pas assez clair. Pour donner un exemple, avec les trois paramètres valant 1 10 10, il fallait obtenir 1 2 3 4 5 6 7 8 9 10. Donc non Lucas-84, un simple range n’y suffit pas.

C’est toujours ambigu, le range marche sur cet exemple. ^^

Qu’est-ce qu’on doit renvoyer sur 1 10 11, est-ce que 1 2, 1 10, 5 10, 5 8 sont des sorties valables pour 1 10 2 ?

+0 -0

Si je me fie au fait que le code d’informaticienzero a eu 100% de réussite, c’est probable que les réponses étaient

1
2
3
4
5
6
> 1 10 11
1 1 2 3 4 5 6 7 8 9 10
> 1 10 2
1 10
> 1 2 5
1 1 1 1 2

Autrement dit, des réels équirépartis, tronqués à l’entier inférieur, dont la séquence commence par start et finit par end (si count > 1). Non ?

Edit : tronqués, pas arrondis.

+0 -0

Bon … C’est moyen mais en C :

1
int a,b,c,i;main(){scanf("%d %d %d",&a,&b,&c);for(c--;i<c;i++)printf("%d ",lround(a+(b*1.-a)/c*i-.5));printf("%d",b);}

119 octets ? x)

+0 -0

Et les #include ? :)

informaticienzero

C’est vrai que c’est pas exactement du C, c’est le langage $\mathcal{L}$ compilé par une version non dégénérée de gcc. Mais ça passerait probablement les tests.

On peut descendre à 100 caractères la version de @che.

1
i,s,e,c;main(){scanf("%d%d%d",&s,&e,&c);for(;i<c;i++)printf("%d%c",s+i*(e-s)/(c-1)," \n"[i==c-1]);}

Mais bon, bravo aux courageux et suicidaires qui font du Python ! :)


Je me suis reconnecté sur Codingame pour la première fois depuis 3 ou 4 ans, ça a vraiment évolué. Fin 2013 y avait 2000 membres, maintenant quasiment 1 million ! O_o À l’époque c’était pas très dur de gagner les challenges ; j’ai 4 t-shirts Codingame à la maison. ^^

Bien vu ! :D

J’ai fais la même il y a un mois … C’est fou comme ça a évolué. C’est tant mieux ^^

@informaticienzero : Ça passe sur coding game il me semble. Certains compilos sont capablent d’inclure les headers standards automatiquement. Même math.h ^^

+0 -0

Faudrait qu’on fasse du clash of code tout mode de jeu ensemble avec le choix des armes pour voir si tu tiens le même discours après 20 parties. :)

Ge0

Ça m’a énervé, du coup j’ai fait 60 challenges depuis hier (md5 mon pseudo). :p Et donc je confirme j’ai fait environ 70% de "code le plus court" en C (et ~95% pour les autres challenges). Pour certains trucs vraiment spécifiques, ça reste indéniablement plus court en Ruby, et parfois en Bash ou en Python. Mais ça marche pas si mal que ça, je suis 15ème dans "Monde" (et je reste à peu près sain d’esprit, même si l’enchaînement de codes non indentés ne fait pas que du bien).

+0 -0

Euh … Par-contre y a du progres à faire niveau sécurité sur le site codingame.com O_o

Lorsque qu’on se connecte la requète envoye en claire le login et le mot de passe en champs GET. Non, c’est pas une blague. L’email, c’est déjà considérée comme une donnée privée et le mdp c’est carrément illégale de le stocker en BDD, donc normalement, ils ont pas besoin du mdp en claire.

O_o C’est fou comme c’est la misère niveau sécurité. C’est du HTTPS mais le S c’est juste pour avoir le cadena vert quoi. N’importe-qui qui écoute le réseau (c’est valide en Wifi hein, si y a une clé KRACK est là pour écouter le réseau justement) à le mdp et le login d’un coup !

o_O J’ai pas le temps de leur envoyer un email mais c’est limite scandaleux.

+0 -2

codingame du coup. Le site des Clash of Code. Le sujet de ce billet quoi ^^" C’était pas claire ? J’édite.

+0 -0

O_o

Ok donc j’ai modifié la User agent string …

Si on prend celle de base ça marche bien avec du POST, si on la change pour PS4, google bot ou wget on obtient des comportements bizarres …

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte