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

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.


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


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)

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.


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:

$><<

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 .


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

+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


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

6

TI-BASIC, 5 bajtów

randIntNoRep(1,10

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.


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('')

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)


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

Shell / Coreutils, 23

shuf -i0-9|paste -sd ''

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


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

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/


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


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


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,


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


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




2

Clojure, 42

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

6209847315


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.


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


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 .


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.