Generator losowych kodów biletów

18

Firma loteryjna chce wygenerować losowy los o długości 10 znaków.

Napisz kod w dowolnym języku, aby utworzyć taki numer, w którym każda cyfra występuje tylko raz, na przykład 9354716208w tym numerze wszystkie liczby całkowite od 0 do 9 występują tylko raz. Ta liczba powinna być liczbą losową.

  • Wygenerowany numer powinien zostać wyświetlony na ekranie.
  • Musi być w stanie wygenerować wszystkie permutacje wszystkich dozwolonych znaków.
  • Kod musi być jak najmniejszy (w bajtach).
Ankush
źródło
3
Dlaczego powinien być w Javie lub PhP?
Fabinout
4
Ogólnie rzecz biorąc, dobrym pomysłem jest dopuszczenie dowolnego języka, zgodnie z opisem kodu golfa .
Konrad Borowski
10
Jak to się dzieje, że jedna z najdłuższych i najmniej golfowych odpowiedzi (odpowiedź SQL), nawet bez liczby znaków , jest akceptowaną odpowiedzią w golfowym kinie, gdy ludzie tacy jak @Howard mają odpowiedzi 5 lub 8 znaków?
Darren Stone
1
Tak, @marinus ma rozwiązanie 4-bajtowe (moje to 6 bajtów)
Timtech
4
-1 Wybór zwycięzcy jest niewłaściwy, biorąc pod uwagę, że było to wyzwanie polegające na grze w golfa.
DavidC

Odpowiedzi:

41

J (4 bajty)

Nie mogłem się oprzeć.

?~10

W J, jeśli Fjest dyadyczny, F~ xjest taki sam jak x F x.

marinus
źródło
3
+1 Myślę, że być może będę musiał spróbować czegoś nieco bardziej zwięzłego niż Python, aby to pokonać.
Joachim Isaksson
Czy pozwala to na hasło zaczynające się od zera? Zgodnie z zasadami program „musi być w stanie wygenerować wszystkie permutacje wszystkich dozwolonych znaków”
DavidC
@DavidCarraher: tak. Wybiera 10 niepowtarzalnych liczb losowych z przedziału [0..10), co w zasadzie oznacza losową permutację „0123456789”.
marinus
1
Widzę. Podniosłem to, ponieważ w większości języków „numer” 0123456789 zostanie automatycznie edytowany do postaci 123456789. Ciąg „0123456789” pozostaje nietknięty. Więc moje pytanie jest naprawdę następujące: czy twój wynik jest liczbą czy łańcuchem?
DavidC,
@DavidCarraher To tablica.
świst
12

J, 5 znaków i APL, 8 znaków

jot

10?10

J ma wbudowany operator transakcji ( ?). Zatem możemy wziąć 10 z 10 ( 10?10).

APL

1-⍨10?10

APL ma tego samego operatora, który niestety zaczyna się od jednego zamiast zera. W związku z tym odejmujemy jeden od każdego numeru ( 1-⍨Xoznacza X-1to operator dojeżdżania do pracy).

Howard
źródło
Och, wow, to miłe.
Konrad Borowski
Jeśli OP poprosiłby konkretnie o numer, a nie tablicę, powinieneś również przekonwertować go na numer base10, przy czym10#.
swish
Możesz założyć, że ⎕IO←0nie musisz odejmować jednego. Ponadto, zarówno dla J, jak i APL, możesz użyć dojazdy do zapisania bajtu z, ?~10a ?⍨10ponieważ monadyczna aplikacja funkcji pochodnej używa swojego prawego argumentu również jako lewego argumentu. Należy jednak pamiętać, że dzięki temu kod J jest identyczny z kodem Marinusa .
Adám
9

Python 2.7 ( 64 63 57)

Tu nie ma szans w porównaniu do ciężkich języków operatora i ze względu na brak domyślnie ładowanego losowego :) To jest najkrótszy jaki mogłem wymyślić;

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

Tworzy zakres i pobiera z niego 10 liczb bez zamiany.

(Dzięki @xfix za krótszą poprawkę formatu importu i @blkknght za wskazanie mojego nieco über skomplikowanego zakresu próbkowania)

Python 2.7 (40)

Jeśli uruchomisz go z interaktywnego monitu i odczytasz przecinek, możesz go ogolić do 40, ale to trochę przypomina łamanie ducha reguł;

from random import*
sample(range(10),10)
Joachim Isaksson
źródło
1
Możesz użyć, from random import*aby uratować jedną postać. Wygląda to na moje rozwiązanie dla Perla 6, ale bardziej szczegółowe, ale wspaniale jest widzieć, że coś takiego może działać w Pythonie, nawet jeśli jest bardziej szczegółowe.
Konrad Borowski
@xfix Tak, niestety moduły w Pythonie są nieco gadatliwe, aby je porównać w porównaniu :) Zaktualizowano z poprawką dotyczącą importu, całkiem nową rzeczą w golfie, więc nie na równi z moimi idiomami.
Joachim Isaksson
Możesz zapisać kilka dodatkowych znaków, próbkując z łańcucha, "0123456789"a nie używając rangei mapując je str.
Blckknght
@Blckknght Dzięki, zaktualizowano o twoją sugestię :)
Joachim Isaksson
8

PHP, 29 znaków

<?=str_shuffle('0123456789');

W PHP tag zamykający nie jest wymagany. Ale jeśli jest to niezgodne z regułami, możesz je wymienić; z?> za 1 wzrost netto.

James S.
źródło
Pobiłeś mnie do tego rozwiązania.
Shaun Bebbers
8

Ruby, 18 lat

Uruchom to w irb:

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

Jeśli chcesz, aby był to samodzielny program z wyjściem na stdout (reguły nie wymagają tego), to dodaj te 4 znaki na początku:

$><<
Darren Stone
źródło
Możesz skrócić (0..9).to_ado [*0..9].
Howard
Zrobione i gotowe, proszę pana. Dzięki!
Darren Stone
Nie ma za co. Ale dlaczego nie używasz [*0..9].shufflew pierwszej kolejności?
Howard
@Howard, bo jest późno i jestem głupi. :) Dzięki!
Darren Stone
ta tablica zwrotna o numerze
8

PHP - 37 znaków

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

Miałem 18-znakowe rozwiązanie, które teoretycznie powinno działać, ale PHP jest dziwne.

Lub jeśli chcesz odpowiedź xkcd:

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

EDYCJA: Dzięki xfix, teraz jest o 5 znaków krótszy i kompletny. PONOWNIE EDYCJA: Przykład na żywo .

cjfaure
źródło
Napisz kompletny program, a nie tylko kompletne części. Ponadto, echonie wymaga nawiasów, a jeśli echoto pierwsza wypowiedź w programie, można zastąpić <?php echoz <?=. Ponadto, joinjest aliasem implode.
Konrad Borowski
@xfix Dzięki, naprawię. :)
cjfaure
Nawet nie potrzebujesz <?=i ?>. Bez nich jest to poprawny kod PHP.
Jeremy
@Jeremy Golf wymaga wyświetlenia numeru; poza tym echo ma tę samą długość <?=i jest ?>połączona, a bez nich nie działa w Codepad. W każdym razie dzięki. : P
cjfaure
1
@Jeremy Ah, PHP, gdzie nie ma wbudowanych implementacji poza terminalem. : P
cjfaure
8

Perl 6 (18 16 znaków)

print pick *,^10

Generuje tablicę zawierającą wszystkie losowe elementy ( pick *) od 0do 9i wyświetla wynik ( print).

Przykładowe dane wyjściowe:

$ perl6 -e 'print pick *,^10'
4801537269
$ perl6 -e 'print pick *,^10'
1970384265
$ perl6 -e 'print pick *,^10'
3571684902
Konrad Borowski
źródło
+1 Myślę, że wcześniej nie potrzebujesz białych znaków pick.
Howard
1
@ Howard: Potrzebuję tego. [~](który jest parsowany jako listop, zgodnie z gramatyką Perla 6) wymaga po nim spacji (lub paren), jeśli zawiera jakiekolwiek argumenty. W przeciwnym razie kompilator Perla 6 narzeka na „dwa warunki z rzędu”. Nie był potrzebny w starszych wersjach Perla 6, ale to już przeszłość. Nad Perlem 6 wciąż trwają prace.
Konrad Borowski
1
@xfix: użyj printzamiast say [~]i zapisz 2 znaki :)
Ayiko
@Ayiko: Dzięki za poprawę :).
Konrad Borowski
7

GolfScript, 12 znaków

10,{;9rand}$

Po prostu generuje listę cyfr ( 10,) i sortuje ją{...}$ według losowych kluczy - co daje losową kolejność cyfr.

Przykłady (spróbuj online ):

4860972315

0137462985
Howard
źródło
Właśnie
To rodzaj tragiczne shuffle choć na przykład: pierwsza cyfra jest około trzy razy bardziej narażone na 0 od 1. Wymiana 9randz 99randbyłoby (w większości) naprawić; 9.?randbyłoby praktycznie idealne .
Ilmari Karonen
1
@IlmariKaronen Wiem, ale pytanie nie mówiło nic o jednolitej dystrybucji.
Howard
6

R (23 znaki)

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

Przykładowe dane wyjściowe:

> cat(sample(0:9),sep="")
3570984216
> cat(sample(0:9),sep="")
3820791654
> cat(sample(0:9),sep="")
0548697132
djhurio
źródło
6

TI-BASIC, 5 bajtów

randIntNoRep(1,10
Timtech
źródło
Wyświetla listę zamiast liczby. Szukasz randIntNoRep(0,9:.1sum(Ans10^(cumSum(1 or Ans.
lirtosiast
2
Nie sądzę, aby to wyzwanie wymagało liczby całkowitej, tyle że „Wygenerowana liczba powinna być wyświetlana na ekranie”.
Timtech
Hmm, myślałem, że pytanie wymaga podania numeru (podobnie jak inni, ale wydaje się, że intencja autora wyzwania nigdy nie została wyjaśniona. Niektóre inne rozwiązania są generowane jako lista (J i APL) w każdym razie.
lirtosiast
Cóż, nie zakładałbym tego, chyba że byłbym pewien, ponieważ ta metoda jest krótsza.
Timtech
5

Oktawa (14)

randperm(10)-1

randperm niestety tworzy selekcję od 1..n, więc odejmij 1 na końcu, aby uzyskać 0-9.

Joachim Isaksson
źródło
5

Na serwerze 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))

Zobacz demo

LUB coś podobnego (dzięki uprzejmości @manatwork) przy użyciu rekurencji i 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
źródło
1
Człowieku, kochasz CTE… Ale ponieważ jest to wyzwanie związane z golfem , lepiej skróć je w jak największym stopniu. Moja najlepsza jest 186 znaków: 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, świetna sztuczka newid().)
manatwork
1
Ok masz rację. Jest krótszy z CTE. 106 znaków: 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
Możesz uprościć cte za pomocą(VALUES (1),(2),...)
ypercubeᵀᴹ
5

JavaScript ( 79 78 68 znaków)

Zamiast tworzyć tablicę z liczbami 0–9 i sortować ją, postanowiłem wygenerować liczby losowe. Kiedy pojawił się numer, który nie był jeszcze w tablicy, dodał go. Powtarza się to dziesięć razy, a następnie powiadamia o wynikach.

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

scribblemaniac
źródło
Możesz zapisać 1 bajt za pomocą ||analizy zwarć zamiast if: for(a="";!a[9];){b=Math.floor(Math.random()*10);~a.indexOf(b)||(a+=b)}alert(a)
Steven Palinkas
1
@StevenPalinkas Dzięki, świetny pomysł! Zaktualizowałem odpowiednio post.
scribblemaniac
Możemy również zaoszczędzić 2 bajty z odrobiną rearanżacji w kodzie:for(a="";!a[9];){~a.indexOf(b=Math.floor(Math.random()*10))||(a+=b)}alert(a)
Steven Palinkas
Możemy zapisać dodatkowe 8 bajtów za pomocą „stenografii” dla Math.floor, na przykład: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
źródło
Miły sposób na uniknięcie sznurków!
DavidC
4

Shell / Coreutils, 23

shuf -i0-9|paste -sd ''
Hasturkun
źródło
Jeśli nie potrzebujemy końca nowej linii, możesz ją ogolić do 20 za pomocąshuf -i0-9|tr -d \\n
joeytwiddle
a coshuf -zi0-9
marcosm
@marcosm: To daje linie zakończone zerami, co jest nieco dziwne.
Hasturkun
4

JavaScript, 82 znaki

EDYCJA: Dzięki Rob W długość kodu jest zmniejszona do 90 znaków.

EDYCJA: Dzięki George'owi Reithowi długość kodu jest zmniejszona do 82 znaków (przy użyciu pętli).

Całkiem prosty sposób: wybierz losowy element [0,1,2,3,4,5,6,7,8,9]tablicy i dołącz go do wyniku, a następnie zmniejsz tablicę i odtwórz ponownie.

Stara wersja (106 znaków):

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)

Wersja do odczytu:

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);

Lepsza wersja (90 znaków):

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

Ostatnia wersja (82 znaków):

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
źródło
1
Ja grałem w dół swoją metodę do 90 znaków: a='0123456789'.split(t=''),l=10;while(l--)t+=a[r=0|Math.random()*l],a.splice(r,1);alert(t). Wielcy oszczędzający: Math.random(x)=== 0|x. Zastąp nawiasy klamrowe i średniki przecinkami. Bezpośrednio użyj wyniku przypisania jako wartości, zamiast używać zmiennej pośredniej. Na koniec zainicjuj tablicę początkową za pomocą .split(r=''). Jest to krótsze niż tworzenie tablicy za pomocą literałów tablicowych i przypisywanie wartości ciągu w osobnym wyrażeniu.
Rob W
@RobW Dzięki za wskazówki. Zaktualizowałem swoją odpowiedź. PS Chyba miałeś na myśli Math.floor(x) === 0|x.
gthacoder
1
To zawsze ma 9 na końcu. Aby naprawić, zainicjować l=11i zmienić warunek pętli while nawhile(--l)
Greg
@Greg Dobry punkt. Dziękuję Ci. Zaktualizowałem odpowiedź.
gthacoder
1
82 znaków: a="0123456789".split(t='');for(l=11;--l;t+=a.splice(0|Math.random()*l,1));alert(t)- Twój kod idealnie pasuje do argumentów inicjalizacji pętli for, warunku i wyrażenia. rZmienna jest zbędny.
George Reith
4

C #, 145 bajtów

Bez golfa

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

Grał w golfa

using System;using System.Linq;class P{static void Main(){Enumerable.Range(0,10).OrderBy(g => Guid.NewGuid()).ToList().ForEach(Console.Write);}}
JMK
źródło
1
Możesz użyć Enumerable.Range(0,10)i nie potrzebujesz nawiasów klamrowych w foreachpętli.
Rik
3

JavaScript (80 znaków)

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

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

IQAndreas
źródło
3
Zauważ, że można to jeszcze pograć w golfa za pomocą funkcji strzałki (która obecnie działa tylko w FF, ale wkrótce będzie dostępna wszędzie dla tłumaczy):alert("0123456789".split("").sort(n=>.5-Math.random()).join(""))
apsillers
1
Nie potrzebujesz odstępu między returni.5
Tibos
1
@Greg Shhhh ! Czy masz pojęcie, ile znaków bierze prawdziwa funkcja tasowania? ;)
IQAndreas
1
@Greg Jest to rozkład losowy (przy założeniu, że Math.random jest wystarczająco losowy), po prostu nie jest jednolity.
SuperJedi224,
1
Oryginalny post na blogu zniknął, dodając archiwum internetowe dla potomności: web.archive.org/web/20150212083701/http://sroucheray.org/blog/…
Greg
3

K / Kona (6)

-10?10

Podobnie jak w przypadku J, ?operator transakcji; gdy -siły te wartości, aby nie powtarzać.

Kyle Kanos
źródło
3

Mathematica 40

Liczba jest tworzona jako ciąg znaków, aby w razie potrzeby wyświetlać zero jako pierwszy znak.

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

Przykłady wyników

„0568497231”
„6813029574”

Wyjaśnienie

"0"~CharacterRange~"9" to notacja infix dla „CharacterRange [„ 0 ”,„ 9 ”]”. Każda z tych zwraca listę, {„0”, „1”, „2”, „3”, „4”, „5”, „ 6 ”,„ 7 ”,„ 8 ”,„ 9 ”}.

RandomSample[list]domyślnie zwraca permutację listy. (Może być również użyty do innych rodzajów próbkowania, gdy uwzględnione są parametry. Np. Zwróci losową RandomSample[list, 4]próbkę 4 znaków, bez powtórzeń.

DavidC
źródło
Ale po co wyświetlać 0 jako pierwszy znak?
Ankush
Według PO program „musi być w stanie wygenerować wszystkie permutacje wszystkich dopuszczalnych znaków”.
DavidC,
@Ankush To notacja infiksowa, więc „0” nie zawsze jest pierwszym znakiem.
Ajasja
Ajasja ma rację. Program może wygenerować dowolną permutację. Dodałem kilka uwag powyżej, aby to wyjaśnić.
DavidC,
3

Scala, 37

util.Random.shuffle(0 to 9).mkString
Soldier.moth
źródło
2

Czwarty, 72

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

Może jeszcze pole do gry w golfa, ale Forth utrudnił mu grę. Myślę.

Darren Stone
źródło
2

Prolog, 177/302 znaków

Jestem początkującym w Prologu, więc prawdopodobnie nie jest to najbardziej skondensowany kod.

:- 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).

Zwroty:

| ?- 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

Jeśli chcesz, aby zwracał liczbę całkowitą:

:- 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.

Zwroty:

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

Zamiast tego użyj:

labeling([down],N)

Podaje liczby w odwrotnej kolejności:

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

W przeciwieństwie do niektórych innych kodów, zwraca wszystkie możliwości (bez powtórzeń).

Edu
źródło
2

q / kdb [6 znaków]

-10?10

wygeneruje 10 unikalnych liczb losowych.

nyi
źródło
2

√ å ı ¥ ® Ï Ø ¿ , 4 bajty

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
Cairney Coheringaahing
źródło
2

Clojure, 42

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

6209847315

claj
źródło
Wygenerowany numer powinien być pokazany na ekranie, a nie jego części.
Sylwester
2

JavaScript, 83 znaki

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

Podczas pracy, aż tablica ma 10 elementów.

Generując losową liczbę od 0 do 9, sprawdź, czy tablica! Zawiera ten numer i dodaj go do tablicy.

David
źródło
1
Witamy na stronie! :)
DJMcMayhem
1

To niewiele mniej niż odpowiedź JMK, ale oto nieco mniejsze rozwiązanie C # (135):

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

Zagęszczony (134):

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

Alternatywna wersja (135):

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

Zagęszczony:

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

Są równej długości, ale tak naprawdę zależy to tylko od tego, czy chcesz użyć funkcji ForEach Linqa, czy funkcji Dołączenia ciągu. Byłem w stanie usunąć 10 znaków, przeliterując zakres „0123456789” w ciągu zamiast używać Enumerable.Range (0, 10).

Cameron Tinker
źródło
1

LOGO , 64 znaki

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

wybierz zwraca losowy element z dostarczonej listy. butmember zwraca listę z usuniętymi wszystkimi wystąpieniami określonego elementu. Uwaga: Nie wszystkie butmemberpolecenia obsługujące implementacje logo .

Sandman4
źródło
1

Rakieta 45 43

(map print(shuffle'(0 1 2 3 4 5 6 7 8 9)))
Sylwester
źródło