Générateur de code de ticket aléatoire

18

Une société de loterie souhaite générer un numéro de ticket de loterie aléatoire de 10 caractères.

Écrivez un code dans n'importe quelle langue pour créer un tel nombre dans lequel chaque chiffre ne vient qu'une fois par exemple 9354716208dans ce nombre tous les entiers de 0 à 9 ne viennent qu'une seule fois. Ce nombre doit être un nombre aléatoire.

  • Le numéro généré doit être affiché à l'écran.
  • Il doit être capable de générer toutes les permutations de tous les caractères autorisés.
  • Le code doit être aussi petit que possible (en octets).
Ankush
la source
3
Pourquoi devrait-il être en Java ou en PhP?
Fabinout
4
Généralement, c'est une bonne idée d'autoriser n'importe quelle langue, selon la description du code-golf .
Konrad Borowski
10
Comment se fait-il que l'une des réponses les plus longues et les moins golfées (la réponse SQL), sans même un nombre de caractères, soit la réponse acceptée dans le code-golf lorsque des gens comme @Howard ont des réponses à 5 ou 8 caractères?
Darren Stone
1
Oui, @marinus a une solution à 4 octets (la mienne est à 6 octets)
Timtech
4
-1 La sélection du gagnant est incorrecte, étant donné qu'il s'agissait d'un défi de code-golf.
DavidC

Réponses:

41

J (4 octets)

Je n'ai pas pu résister.

?~10

En J, si Fest dyadique, F~ xest le même que x F x.

marinus
la source
3
+1 Je pense que je devrais peut-être essayer quelque chose d'un peu plus laconique que Python pour battre cela.
Joachim Isaksson
Cela permet-il un mot de passe commençant par zéro? Selon les règles, le programme "doit être capable de générer toutes les permutations de tous les caractères autorisés"
DavidC
@DavidCarraher: oui. Il sélectionne 10 nombres aléatoires non répétitifs dans l'intervalle [0..10), ce qui signifie essentiellement une permutation aléatoire de «0123456789».
marinus
1
Je vois. J'ai soulevé cela parce que dans la plupart des langues, le "nombre", 0123456789, sera automatiquement modifié sous la forme 123456789. La chaîne, "0123456789", reste intacte. Donc ma question est vraiment la suivante: votre sortie est-elle un nombre ou une chaîne?
DavidC
@DavidCarraher C'est un tableau.
swish
12

J, 5 caractères et APL, 8 caractères

J

10?10

J a l'opérateur de transaction intégré ( ?). Ainsi, nous pouvons prendre 10 sur 10 ( 10?10).

APL

1-⍨10?10

APL a le même opérateur qui commence malheureusement par un au lieu de zéro. Nous soustrayons donc un de chaque nombre ( 1-⍨Xmoyennes X-1dues à l'opérateur de navette).

Howard
la source
Oh, wow, c'est bien.
Konrad Borowski
Si OP aurait demandé spécifiquement le nombre et non un tableau, vous devriez également le convertir en nombre base10, avec10#.
swish
Vous pouvez supposer que ⎕IO←0 vous n'avez donc pas à en soustraire un. De plus, pour J et APL, vous pouvez utiliser commute pour enregistrer un octet avec ?~10et ?⍨10puisque l'application monadique de la fonction dérivée utilise également son argument droit comme argument gauche. Notez cependant que cela rend le code J identique à celui de Marinus .
Adám
9

Python 2.7 ( 64 63 57)

Pas une chance ici par rapport aux langages lourds de l'opérateur et en raison de l'absence de chargement aléatoire par défaut :) C'est le plus court que j'ai pu trouver;

from random import*
print''.join(sample("0123456789",10))

Il crée une plage et en échantillonne 10 numéros sans remplacement.

(Merci à @xfix pour le correctif de format d'importation plus court et à @blkknght pour avoir souligné ma plage d'échantillonnage un peu compliquée)

Python 2.7 (40)

Si vous l'exécutez à partir de l'invite interactive et pouvez lire les virgules séparées, vous pouvez le raser à 40, mais cela ressemble un peu à briser l'esprit des règles;

from random import*
sample(range(10),10)
Joachim Isaksson
la source
1
Vous pouvez utiliser from random import*pour enregistrer un caractère. Cela ressemble à ma solution Perl 6, mais plus verbeuse, mais c'est génial de voir que quelque chose comme ça peut fonctionner en Python, même si plus verbeux.
Konrad Borowski
@xfix Oui, malheureusement, les modules en Python sont un peu verbeux pour être comparés :) Mis à jour avec votre correctif d'importation, assez nouveau pour le golf, donc pas à la hauteur de mes idiomes.
Joachim Isaksson
Vous pouvez enregistrer quelques caractères supplémentaires en échantillonnant à partir de la chaîne "0123456789"plutôt qu'en utilisant rangeet en les mappant str.
Blckknght
@Blckknght Merci, mis à jour avec votre suggestion :)
Joachim Isaksson
8

PHP, 29 caractères

<?=str_shuffle('0123456789');

Avec PHP, la balise de fermeture n'est pas requise. Mais si c'est contraire aux règles, vous pouvez remplacer; avec?> pour 1 augmentation nette.

James S
la source
Vous m'avez battu pour cette solution.
Shaun Bebbers
8

Rubis, 18

Exécutez ceci dans irb:

[*0..9].shuffle*''

Si vous voulez que ce soit un programme autonome, avec une sortie vers stdout(les règles ne semblent pas l' exiger ), ajoutez ces 4 caractères au début:

$><<
Darren Stone
la source
Vous pouvez raccourcir (0..9).to_aà [*0..9].
Howard
Fait et fait, monsieur. Merci!
Darren Stone
Je vous en prie. Mais pourquoi ne l'utilisez-vous pas [*0..9].shuffleen premier lieu?
Howard
@Howard, car il est tard et je suis stupide. :) Merci!
Darren Stone
ce tableau de retour avec un numéro et non un numéro
8

PHP - 37 caractères

<?=join('',array_rand(range(0,9),10))

J'avais une solution à 18 caractères qui devrait théoriquement fonctionner mais PHP est bizarre.

Ou, si vous voulez une réponse xkcd:

<?="5398421706" // Chosen by program above; guaranteed to be random ?>

EDIT: Merci xfix, il est maintenant 5 caractères plus court et complet. MODIFIER ENCORE: Exemple en direct .

cjfaure
la source
Écrivez un programme complet, au lieu de simplement des pièces complètes. En outre, echon'a pas besoin de parens, et s'il echos'agit de la première instruction du programme, vous pouvez la remplacer <?php echopar <?=. Est également joinun alias pour implode.
Konrad Borowski
@xfix Merci, je vais réparer. :)
cjfaure
Vous n'avez même pas besoin du <?=et ?>. C'est du code PHP valide sans ceux-ci.
jeremy
@Jeremy Le golf nécessite que le numéro soit affiché; en outre, echo est de la même longueur <?=et ?>combinée, et sans ceux-ci, cela ne fonctionne pas dans Codepad. Merci quand même. : P
cjfaure
1
@Jeremy Ah, PHP, où les implémentations non intégrées en plus d'un terminal sont rares. : P
cjfaure
8

Perl 6 (18 16 caractères)

print pick *,^10

Cela génère un tableau contenant tous les éléments aléatoires ( pick *) de 0vers 9et génère le résultat ( print).

Exemple de sortie:

$ perl6 -e 'print pick *,^10'
4801537269
$ perl6 -e 'print pick *,^10'
1970384265
$ perl6 -e 'print pick *,^10'
3571684902
Konrad Borowski
la source
+1 Je pense que vous n'avez pas eu besoin d'espace avant pick.
Howard
1
@Howard: J'en ai réellement besoin. [~](qui est analysé en tant que listop, selon la grammaire de Perl 6) nécessite un espace (ou paren) après s'il contient des arguments. Sinon, le compilateur Perl 6 se plaint de "deux termes consécutifs". Il n'était pas nécessaire dans les anciennes versions de Perl 6, mais c'est le passé. Le Perl 6 est toujours en cours d'élaboration.
Konrad Borowski
1
@xfix: utilisez printau lieu de say [~]et enregistrez 2 caractères :)
Ayiko
@Ayiko: Merci pour une amélioration :).
Konrad Borowski
7

GolfScript, 12 caractères

10,{;9rand}$

Génère simplement la liste des chiffres ( 10,) et la trie {...}$selon certaines clés aléatoires - ce qui donne un ordre aléatoire des chiffres.

Exemples (essayez en ligne ):

4860972315

0137462985
Howard
la source
J'étais sur le point de poster ceci: P
Poignée de porte
C'est une sorte de mélange aléatoire, par exemple: par exemple, le premier chiffre est environ trois fois plus susceptible d'être 0 que 1. Le remplacement 9randpar 99randcorrigerait (principalement) cela; 9.?randserait pratiquement parfait .
Ilmari Karonen
1
@IlmariKaronen Je sais, mais la question ne disait rien sur la distribution uniforme.
Howard
6

R (23 caractères)

cat(sample(0:9),sep="")

Exemple de sortie:

> cat(sample(0:9),sep="")
3570984216
> cat(sample(0:9),sep="")
3820791654
> cat(sample(0:9),sep="")
0548697132
djhurio
la source
6

TI-BASIC, 5 octets

randIntNoRep(1,10
Timtech
la source
Affiche une liste plutôt qu'un nombre. Vous cherchez randIntNoRep(0,9:.1sum(Ans10^(cumSum(1 or Ans.
lirtosiast
2
Je ne pense pas que ce défi nécessite un type entier, seulement que "Le numéro généré doit être affiché à l'écran" ce qu'il est.
Timtech
Hmm, je pensais que la question demandait un nombre (comme d' autres, mais il semble que l'intention de l'auteur du défi n'ait jamais été clarifiée. D'autres solutions sont sorties sous forme de liste (J et APL) dans tous les cas.
lirtosiast
Eh bien, je ne le supposerais pas sauf si j'étais sûr, car cette méthode est plus courte.
Timtech
5

Octave (14)

randperm(10)-1

randperm crée malheureusement une sélection de 1..n, il faut donc soustraire 1 à la fin pour obtenir 0-9.

Joachim Isaksson
la source
5

Dans le serveur SQL

DECLARE @RandomNo varchar(10)
SET @RandomNo = ''

;WITH num as (
SELECT 0 AS [number]
Union 
select 1
Union 
select 2
Union 
select 3
Union 
select 4
Union 
select 5
Union 
select 6
Union 
select 7
Union 
select 8
Union 
select 9
)
SELECT Top 9 @RandomNo = COALESCE(@RandomNo + '', '') + cast(n.number AS varchar(1))
FROM numbers n
ORDER BY NEWID()

SELECT cast(@RandomNo AS numeric(10,0))

Voir la démo

OU quelque chose de similaire (gracieuseté de @manatwork) en utilisant récursivité et xml.

with c as(select 0i union all select i+1from c where i<9)select i+0from c order by newid()for xml path('')
vhadalgi
la source
1
Mec, tu aimes les CTE… Mais comme c'est un défi de code-golf , mieux vaut le raccourcir autant que possible. Mon meilleur est de 186 caractères: select i+0from(select 0i union select 1union select 2union select 3union select 4union select 5union select 6union select 7union select 8union select 9)f order by newid()for xml path(''). (BTW, super truc qui newid().)
manatwork
1
Ok, tu as raison. Est plus court avec CTE. 106: caractères with c as(select 0i union all select i+1from c where i<9)select i+0from c order by newid()for xml path('').
manatwork
Vous pouvez simplifier le cte avec(VALUES (1),(2),...)
ypercubeᵀᴹ
5

Javascript ( 79 78 68 caractères)

Plutôt que de créer un tableau avec les nombres 0-9 et de le trier, j'ai décidé de générer des nombres aléatoires. Quand il est venu avec un nombre qui n'était pas déjà dans le tableau, il l'a ajouté. Cela se répète dix fois, puis alerte la sortie.

for(a="";!a[9];){~a.indexOf(b=~~(Math.random()*10))||(a+=b)}alert(a)

scribblemaniac
la source
Vous pouvez enregistrer 1 octet en utilisant l' ||évaluation des courts-circuits au lieu de if: for(a="";!a[9];){b=Math.floor(Math.random()*10);~a.indexOf(b)||(a+=b)}alert(a)
Steven Palinkas
1
@StevenPalinkas Merci, bonne idée! J'ai mis à jour le message en conséquence.
scribblemaniac
Nous pourrions également économiser 2 octets avec un peu de réarrangement dans le code:for(a="";!a[9];){~a.indexOf(b=Math.floor(Math.random()*10))||(a+=b)}alert(a)
Steven Palinkas
Nous pouvons enregistrer 8 octets supplémentaires en utilisant le "raccourci" pour Math.floor comme:for(a="";!a[9];){~a.indexOf(b=~~(Math.random()*10))||(a+=b)}alert(a)
Steven Palinkas
4

Mathematica, 27

Row@RandomSample@Range[0,9]

enter image description here

Ajasja
la source
Belle façon d'éviter les cordes!
DavidC
4

Coquille / Coreutils, 23

shuf -i0-9|paste -sd ''
Hasturkun
la source
Si nous n'avons pas besoin d'un saut de ligne, vous pouvez le raser à 20 avecshuf -i0-9|tr -d \\n
joeytwiddle
qu'en est-ilshuf -zi0-9
marcosm
@marcosm: Cela vous donne des lignes terminées par des zéros, ce qui est légèrement étrange.
Hasturkun
4

JavaScript, 82 caractères

EDIT: Grâce à Rob W , la longueur du code est réduite à 90 caractères.

EDIT: Merci à George Reith , la longueur du code est réduite à 82 caractères (en utilisant pour la boucle).

Méthode assez simple: choisissez un élément aléatoire du [0,1,2,3,4,5,6,7,8,9]tableau et ajoutez-le à la sortie, puis réduisez le tableau et relisez.

Ancienne version (106 caractères):

a=[0,1,2,3,4,5,6,7,8,9],l=11,t="";while(--l){r=Math.floor(Math.random()*l);t+=a[r];a.splice(r,1);}alert(t)

Version lisible:

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], l = 10,t = "";
while(l--) {
  r = Math.floor(Math.random() * l);
  t += a[r];
  a.splice(r, 1);
}
alert(t);

Meilleure version (90 caractères):

a="0123456789".split(t=""),l=11;while(--l)t+=a[r=0|Math.random()*l],a.splice(r,1);alert(t)

Dernière version (82 caractères):

a="0123456789".split(t='');for(l=11;--l;t+=a.splice(0|Math.random()*l,1));alert(t)

JSFiddle: http://jsfiddle.net/gthacoder/qH3t9/ .

gthacoder
la source
1
Je votre méthode joué au golf à 90 caractères: a='0123456789'.split(t=''),l=10;while(l--)t+=a[r=0|Math.random()*l],a.splice(r,1);alert(t). Grands épargnants: Math.random(x)=== 0|x. Remplacez les accolades et les points-virgules par des virgules. Utilisez directement le résultat d'une affectation comme valeur, au lieu d'utiliser une variable intermédiaire. Enfin, initialisez le tableau initial à l'aide de .split(r=''). Cela est plus court que la création d'un tableau à l'aide de littéraux de tableau et l'affectation de la valeur de chaîne dans une expression distincte.
Rob W
@RobW Merci pour les conseils. J'ai mis à jour ma réponse. PS je suppose que vous vouliez dire Math.floor(x) === 0|x.
gthacoder
1
Cela a toujours 9 à la fin. Pour corriger, initialiser l=11et basculer votre condition de boucle while surwhile(--l)
Greg
@Greg Bon point. Je vous remercie. J'ai mis à jour la réponse.
gthacoder
1
82 Caractères: a="0123456789".split(t='');for(l=11;--l;t+=a.splice(0|Math.random()*l,1));alert(t)- Votre code s'intègre parfaitement dans les arguments d'initialisation, de condition et d'expression des boucles for. La rvariable est redondante.
George Reith
4

C #, 145 octets

Non golfé

using System;
using System.Linq;
class P
{
    static void Main()
    {
        Enumerable.Range(0,10).OrderBy(g => Guid.NewGuid()).ToList().ForEach(Console.Write);
    }
}

Golfé

using System;using System.Linq;class P{static void Main(){Enumerable.Range(0,10).OrderBy(g => Guid.NewGuid()).ToList().ForEach(Console.Write);}}
JMK
la source
1
Vous pouvez utiliser Enumerable.Range(0,10)et vous n'avez pas besoin des accolades dans la foreachboucle.
Rik
3

JavaScript (80 caractères)

alert("0123456789".split("").sort(function(){return .5-Math.random()}).join(""))

JS-Fiddle: http://jsfiddle.net/IQAndreas/3rmza/

IQAndreas
la source
3
Notez que cela peut être approfondi en utilisant une fonction de flèche (qui ne fonctionne actuellement qu'en FF, mais qui sera bientôt disponible pour les interprètes partout):alert("0123456789".split("").sort(n=>.5-Math.random()).join(""))
apsillers
1
Vous n'avez pas besoin de l'espace entre returnet.5
Tibos
1
@Greg Shhhh! Avez-vous une idée du nombre de caractères qu'une vraie fonction de mélange prend? ;)
IQAndreas
1
@Greg C'est une distribution aléatoire (en supposant que Math.random est suffisamment aléatoire), ce n'est tout simplement pas uniforme.
SuperJedi224
1
Le blog d'origine a disparu, ajoutant les archives Internet pour la postérité: web.archive.org/web/20150212083701/http://sroucheray.org/blog/…
Greg
3

K / Kona (6)

-10?10

Comme avec J, ?est l'opérateur de transaction; la -force les valeurs à ne pas se répéter.

Kyle Kanos
la source
3

Mathematica 40

Le nombre est créé sous forme de chaîne de manière à permettre d'afficher zéro en tant que premier caractère, si nécessaire.

""<>RandomSample["0"~CharacterRange~"9"]

Exemples de sortie

"0568497231"
"6813029574"

Explication

"0"~CharacterRange~"9" est la notation infixe pour `CharacterRange [" 0 "," 9 "]". L'une ou l'autre renvoie la liste, {"0", "1", "2", "3", "4", "5", " 6 "," 7 "," 8 "," 9 "}.

RandomSample[list]renvoie par défaut une permutation de la liste. (Il peut également être utilisé pour d'autres types d'échantillonnage, lorsque des paramètres sont inclus. Par exemple, RandomSample[list, 4]il renverra un échantillon aléatoire de 4 caractères, sans répétition.

DavidC
la source
Mais pourquoi afficher 0 comme premier caractère?
Ankush
Selon l'OP, le programme "doit pouvoir générer toutes les permutations de tous les caractères autorisés".
DavidC
@Ankush C'est la notation infixe, donc "0" n'est pas toujours le premier caractère.
Ajasja
Ajasja a raison. Le programme peut générer n'importe quelle permutation. J'ai ajouté quelques remarques ci-dessus pour clarifier cela.
DavidC
3

Scala, 37

util.Random.shuffle(0 to 9).mkString
soldat.moth
la source
2

Forth, 72

needs random.fs : r ': '0 do i loop 9 for i 1+ random roll emit next ; r

Peut-être encore au golf, mais Forth a rendu celui-ci difficile. Je pense.

Darren Stone
la source
2

Prolog, 177/302 caractères

Je suis un débutant sur Prolog, donc ce n'est probablement pas le code le plus condensé.

:- use_module(library(clpfd)).
sort(N) :-
    N = [N0,N1,N2,N3,N4,N5,N6,N7,N8,N9],
    domain([N0],1,9),
    domain([N1,N2,N3,N4,N5,N6,N7,N8,N9],0,9),
    all_different(N),
    labeling([],N).

Retour:

| ?- sort2(N).                                         
N = [1,0,2,3,4,5,6,7,8,9] ? ;
N = [1,0,2,3,4,5,6,7,9,8] ? ;
N = [1,0,2,3,4,5,6,8,7,9] ? ;
N = [1,0,2,3,4,5,6,8,9,7] ? ;
N = [1,0,2,3,4,5,6,9,7,8] ? 
yes

Si vous voulez qu'il renvoie un entier:

:- use_module(library(clpfd)).
sort(M) :-
    N = [N0,N1,N2,N3,N4,N5,N6,N7,N8,N9],
    domain([N0],1,9),
    domain([N1,N2,N3,N4,N5,N6,N7,N8,N9],0,9),
    all_different(N),
    labeling([],N),
    M is (N0*1000000000)+(N1*100000000)+(N2*10000000)+(N3*1000000)+
         (N4*100000)+(N5*10000)+(N6*1000)+(N7*100)+(N8*10)+N9.

Retour:

| ?- sort(N).
N = 1023456789 ? ;
N = 1023456798 ? ;
N = 1023456879 ? ;
N = 1023456897 ? ;
N = 1023456978 ? 
yes

Utiliser à la place:

labeling([down],N)

Donne les nombres dans l'ordre inverse:

| ?- sort(N).                                        
N = 9876543210 ? n
N = 9876543201 ? n
N = 9876543120 ? n
N = 9876543102 ? n
N = 9876543021 ? 
yes

Contrairement à certains autres codes publiés, cela renvoie toutes les possibilités (sans répétitions).

Edu
la source
2

q / kdb [6 caractères]

-10?10

générera 10 nombres aléatoires uniques.

nyi
la source
2

√ å ı ¥ ® Ï Ø ¿ , 4 octets

XrśO

X    › Push 10 to the stack
 r   › Push the range from [1...10]
  ś  › Shuffle the stack
   O › Output the whole stack separated by spaces
caird coinheringaahing
la source
2

Clojure, 42

(println (apply str (shuffle (range 10))))

6209847315

claj
la source
Le numéro généré doit être affiché à l'écran, pas ses parties.
Sylwester
2

Javascript, 83 caractères

a=[];while(!a[9]){b=Math.floor(Math.random()*10);!a.includes(b)&&a.push(b)}alert(a)

Pendant l'exécution jusqu'à ce que le tableau comporte 10 éléments.

Générez un nombre aléatoire de 0 à 9, puis vérifiez si le tableau! Inclut ce nombre et ajoutez-le au tableau.

David
la source
1
Bienvenue sur le site! :)
DJMcMayhem
1

Ce n'est pas beaucoup plus petit que la réponse de JMK, mais voici une solution C # légèrement plus petite (135):

using System;
using System.Linq;
class P { 
    static void Main() 
    { 
        Console.Write(string.Join("", "0123456789".OrderBy(g => Guid.NewGuid()))); 
    } 
}

Compacté (134):

using System;using System.Linq;class P{static void Main(){Console.Write(string.Join("", "0123456789".OrderBy(g => Guid.NewGuid())));}}

Version alternative (135):

using System;
using System.Linq;
class P { 
    static void Main() 
    { 
        "0123456789".OrderBy(g => Guid.NewGuid()).ToList().ForEach(Console.Write); 
    } 
}

Compacté:

using System;using System.Linq;class P{static void Main(){"0123456789".OrderBy(g => Guid.NewGuid()).ToList().ForEach(Console.Write);}}

Ils sont de longueur égale, mais cela dépend vraiment de si vous souhaitez utiliser la fonction ForEach de Linq ou la fonction Join de String. J'ai pu supprimer 10 caractères en épelant la plage "0123456789" dans une chaîne au lieu d'utiliser Enumerable.Range (0, 10).

Cameron Tinker
la source
1

LOGO , 64 caractères

make "d 1234567890
repeat 10 [
    make "n pick d
    show n
    make "d butmember n d
]

pick renvoie un élément aléatoire de la liste fournie. butmember renvoie une liste avec toutes les occurrences de l'élément spécifié supprimées. Remarque: toutes les implémentations de logo ne prennent pas en charge la butmembercommande.

Sandman4
la source
1

Raquette 45 43

(map print(shuffle'(0 1 2 3 4 5 6 7 8 9)))
Sylwester
la source