Генератор випадкових квитків


18

Лотерейна компанія хоче створити випадковий номер лотерейного квитка довжиною 10 символів.

Напишіть код будь-якою мовою, щоб створити таке число, в якому кожна цифра надходить лише один раз, наприклад, 9354716208у цьому числі всі цілі числа від 0 до 9 надходять лише один раз. Це число повинно бути випадковим числом.

  • Згенерований номер повинен відображатися на екрані.
  • Він повинен бути здатний генерувати всі перестановки всіх допустимих символів.
  • Код повинен бути якомога меншим (у байтах).

3
Чому це має бути на Java або PHP?
Fabinout

4
Як правило, добре дозволити будь-яку мову, відповідно до опису коду-гольфу .
Конрад Боровський

10
Як виходить, що одна з найдовших і найменш відповідей на гольф (відповідь SQL), не маючи навіть підрахунку знаків, вважається прийнятою відповіддю в коді-гольф, коли такі люди, як @Howard, мають 5 або 8 відповідей символів?
Даррен Стоун

1
Так, у @marinus є 4-байтне рішення (у мене - 6 байт)
Timtech

4
-1 Вибір переможця є неправильним, враховуючи, що це було завданням з гольф-кодом.
DavidC

Відповіді:


41

J (4 байти)

Не втримався.

?~10

У J, якщо Fдіадичний, F~ xте саме, що x F x.


3
+1 Я думаю, що мені, можливо, доведеться спробувати щось трохи більш коротке, ніж Python, щоб перемогти це.
Йоахім Ісакссон

Чи дозволяє це пароль, який починається з нуля? Згідно з правилами, програма "повинна мати можливість генерувати всі перестановки усіх допустимих символів"
DavidC

@DavidCarraher: так. Він вибирає з інтервалу 10 повторюваних випадкових чисел [0..10), так що в основному означає випадкову перестановку '0123456789'.
marinus

1
Я бачу. Я підняв це, тому що в більшості мов "число", 0123456789, буде автоматично відредаговано у формі 123456789. Рядок "0123456789" залишається недоторканим. Отже, моє запитання справді таке: чи ваш вихідний номер чи рядок?
DavidC

@DavidCarraher Це масив.
швейцарський

12

J, 5 символів та APL, 8 символів

J

10?10

J має вбудований оператор угоди ( ?). Таким чином, ми можемо взяти 10 з 10 ( 10?10).

APL

1-⍨10?10

APL має того самого оператора, який, на жаль, починається з одного замість нуля. Тому ми віднімаємо одне з кожного числа ( 1-⍨Xозначає X-1за рахунок оператора маршруту).


О, вау, це приємно.
Конрад Боровський

Якщо ОП запитав би конкретно номер, а не масив, слід також перетворити його на базове число10, з10#.
swish

Ви можете припустити, що ⎕IO←0так вам не доведеться віднімати. Крім того, і для J, і для APL ви можете використовувати комутувати, щоб зберегти байт, ?~10і ?⍨10оскільки монадичне застосування похідної функції використовує його правильний аргумент також як лівий аргумент. Зауважте, що це робить J код ідентичним коду Марінуса .
Адам

9

Python 2.7 ( 64 63 57)

Тут не шанс порівняно з важкими мовами оператора і через відсутність завантажених за замовчуванням випадкових випадків :) Це найкоротший, який я міг придумати;

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

Він створює діапазон і вибирає з нього 10 номерів без заміни.

(Завдяки @xfix для більш короткого виправлення формату імпорту та @blkknght за вказівку мого дещо über складного діапазону вибірки)

Python 2.7 (40)

Якщо ви запустите його з інтерактивного підказки і можете прочитати розділені комами, ви можете поголити його до 40, але це трохи схоже на порушення духу правил;

from random import*
sample(range(10),10)

1
Ви можете використовувати from random import*для збереження одного символу. Це схоже на моє рішення Perl 6, але більш багатослівне, але чудово бачити, що щось подібне може працювати в Python, навіть якщо більш багатослівне.
Конрад Боровський

@xfix Так, на жаль, модулі в Python трохи довершені для порівняння :) Оновлено ваше виправлення на імпорт, зовсім нове в гольф-справі, так що не до «моменту» в моїх ідіомах.
Йоахім Ісакссон

Ви можете зберегти ще декілька символів, відібравши вибірки з рядка, "0123456789"а не використовуючи rangeта їхнє відображення str.
Blckknght

@Blckknght Дякую, оновлено вашу пропозицію :)
Йоахім Ісакссон

8

PHP, 29 чол

<?=str_shuffle('0123456789');

Для PHP закриваючий тег не потрібно. Але якщо це суперечить правилам, то можна замінити; з?> за 1 чисте збільшення.


Ви побили мене до цього рішення.
Shaun Bebbers

8

Рубі, 18

Виконайте це irb:

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

Якщо ви хочете, щоб це була окрема програма, з виходом на stdout(правила, схоже, цього не вимагають ), додайте ці 4 символи на початку:

$><<

Ви можете скоротити (0..9).to_aдо [*0..9].
Говард

Готово, сер. Спасибі!
Даррен Стоун

Ласкаво просимо. Але чому ви не використовуєте [*0..9].shuffleв першу чергу?
Говард

@Howard, тому що пізно і я німий. :) Спасибі!
Даррен Стоун

цей масив повернення з номером не номером

8

PHP - 37 символів

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

У мене було рішення з 18 символів, яке теоретично повинно працювати, але PHP дивно.

Або якщо ви хочете відповісти xkcd:

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

EDIT: Спасибі xfix, тепер вона на 5 символів коротша і повніша. EDIT ЗНОВУ: Живий приклад .


Напишіть повну програму, а не лише повну частину. Крім того, echoне потрібні паролі, і якщо echoце перший вислів у програмі, його можна замінити <?php echoна <?=. Також joinє псевдонімом для implode.
Конрад Боровський

@xfix Спасибі, я виправлю. :)
cjfaure

Вам навіть не потрібні <?=і ?>. Дійсний код PHP без них.
jeremy

@Jeremy Гольф вимагає, щоб номер відображався; до того ж, echo така ж довжина, що <?=і ?>комбінована, і без них у Codepad не працює. Спасибі, хоча. : P
cjfaure

1
@ Jeremy Ах, PHP, де не вбудовані реалізації, крім терміналу, є дефіцитними. : P
cjfaure

8

Perl 6 (18 16 символів)

print pick *,^10

Це генерує масив, що містить усі випадкові елементи ( pick *) від 0до 9та виводить результат ( print).

Вибірка зразка:

$ perl6 -e 'print pick *,^10'
4801537269
$ perl6 -e 'print pick *,^10'
1970384265
$ perl6 -e 'print pick *,^10'
3571684902

+1 Я думаю, що вам раніше не потрібен пробіл pick.
Говард

1
@Howard: Мені це справді потрібно. [~](який розбирається як листоп, згідно з граматикою Perl 6) вимагає пробілу (або батьківського) після нього, якщо він містить аргументи. В іншому випадку компілятор Perl 6 скаржиться на "два терміни підряд". Він не був потрібен у старих версіях Perl 6, але це минуле. Perl 6 все ще працює.
Конрад Боровський

1
@xfix: використовувати printзамість say [~]і зберегти 2 символи :)
Айко

@Ayiko: Дякую за покращення :).
Конрад Боровський

7

GolfScript, 12 символів

10,{;9rand}$

Просто генерує список цифр ( 10,) і сортує його {...}$за деякими випадковими ключами - що дає випадковий порядок цифр.

Приклади (спробуйте в Інтернеті ):

4860972315

0137462985

Я збирався опублікувати це: P
Doorknob

Це все-таки хитро скасування: наприклад, перша цифра приблизно втричі більше, ніж 0, ніж 1. Заміна 9randна 99rand(переважно) виправить це; 9.?randбуло б практично ідеальним .
Ільмарі Каронен

1
@IlmariKaronen Я знаю, але питання не говорило про рівномірний розподіл.
Говард

6

R (23 символи)

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

Вибірка зразка:

> cat(sample(0:9),sep="")
3570984216
> cat(sample(0:9),sep="")
3820791654
> cat(sample(0:9),sep="")
0548697132

6

TI-BASIC, 5 байт

randIntNoRep(1,10

Відображає список, а не число. Ви шукаєте randIntNoRep(0,9:.1sum(Ans10^(cumSum(1 or Ans.
lirtosiast

2
Я не думаю, що для цього виклику потрібен цілий тип, а лише те, що "Згенероване число повинно бути показане на екрані".
Timtech

Хм, я подумав, що питання задає номер (як і інші, але, здається, наміри автора виклику так і не були з'ясовані. Деякі інші рішення у будь-якому випадку виводяться як список (J та APL).
lirtosiast

Ну, я б не припускав, що якщо я не був впевнений, тому що цей метод коротший.
Timtech

5

Октава (14)

randperm(10)-1

randperm на жаль створює виділення з 1..n, тому доведеться відняти 1 в кінці, щоб отримати 0-9.


5

На сервері 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))

Див. Демо

АБО щось подібне (люб’язно надано @manatwork) з використанням рекурсії та 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
Людина, ти любиш CTEs ... Але так як це проблема з кодовим гольфом , краще скоротити її максимально. Мій кращий складає 186 символів: 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, чудовий трюк, що newid().)
маніпуляція

1
Гаразд, ти маєш рацію. Коротше з CTE. 106 символів: with c as(select 0i union all select i+1from c where i<9)select i+0from c order by newid()for xml path('').
манатство

Ви можете спростити cte за допомогою(VALUES (1),(2),...)
ypercubeᵀᴹ

5

Javascript ( 79 78 68 символів)

Замість того, щоб створити масив із числами 0-9 та сортувати його, я вирішив генерувати випадкові числа. Коли він з'явив число, яке вже не було в масиві, додав його. Це повторюється десять разів, а потім попереджає результат.

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


Ви можете зберегти 1 байт, використовуючи ||оцінку короткого замикання, а не if: for(a="";!a[9];){b=Math.floor(Math.random()*10);~a.indexOf(b)||(a+=b)}alert(a)
Стівен Палінкас

1
@StevenPalinkas Спасибі, чудова ідея! Я відповідно оновив публікацію.
scribblemaniac

Ми також могли б зберегти 2 байти з трохи перестановкою коду:for(a="";!a[9];){~a.indexOf(b=Math.floor(Math.random()*10))||(a+=b)}alert(a)
Стівен Палінкас,

Ми можемо зберегти додаткові 8 байт за допомогою "стенограми" для Math.floor, наприклад:for(a="";!a[9];){~a.indexOf(b=~~(Math.random()*10))||(a+=b)}alert(a)
Стівен Палінкас,



4

JavaScript, 82 символи

EDIT: Завдяки Rob W , довжина коду скорочується до 90 символів.

EDIT: Завдяки Джорджу Рейту довжина коду скорочується до 82 символів (використовуючи цикл).

Досить простий спосіб: виберіть випадковий елемент [0,1,2,3,4,5,6,7,8,9]масиву та додайте його до виводу, а потім зменшіть масив та повторіть.

Стара версія (106 символів):

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)

Читаема версія:

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

Краща версія (90 символів):

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

Остання версія (82 символи):

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
Я golfed вниз ваш метод до 90 символів: a='0123456789'.split(t=''),l=10;while(l--)t+=a[r=0|Math.random()*l],a.splice(r,1);alert(t). Великі заощадження: Math.random(x)=== 0|x. Фігурні дужки та крапки з комою замініть комами. Безпосередньо використовуйте результат призначення як значення, а не використовуйте проміжну змінну. Нарешті, ініціалізуйте початковий масив за допомогою .split(r=''). Це коротше, ніж створення масиву з використанням літералів масиву та призначення значення рядка в окремому виразі.
Роб Ш

@RobW Дякую за поради. Я оновив свою відповідь. PS Думаю, ти мав на увазі Math.floor(x) === 0|x.
gthacoder

1
Це завжди 9 в кінці. Щоб виправити, ініціалізуйте l=11та переключіть стан циклу while наwhile(--l)
Грег

@Greg Добре. Дякую. Я оновив відповідь.
gthacoder

1
82 Символи: a="0123456789".split(t='');for(l=11;--l;t+=a.splice(0|Math.random()*l,1));alert(t)- Ваш код ідеально вписується в аргументи для ініціалізації циклів, умови та виразів. rЗмінної є зайвим.
Джордж Рейт

4

C #, 145 байт

Безумовно

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

Гольф

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

1
Ви можете використовувати Enumerable.Range(0,10), і вам не потрібні фігурні дужки в foreachциклі.
Рик

3

JavaScript (80 символів)

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

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


3
Зауважте, що можна продовжити гольф, скориставшись функцією стрілки (яка наразі працює лише у FF, але незабаром з'являється для усних перекладачів):alert("0123456789".split("").sort(n=>.5-Math.random()).join(""))
apsillers

1
Вам не потрібно пробіл між returnі.5
Тибос

1
@Greg Shhhh! Чи маєте ви уявлення, скільки символів займає реальна функція перемішування? ;)
IQAndreas

1
@Greg Це випадковий розподіл (якщо припустимо, що Math.random є досить випадковим), він просто не є рівномірним.
SuperJedi224

1
Оригінальної публікації в блозі немає, додавши Інтернет-архів для нащадків: web.archive.org/web/20150212083701/http://sroucheray.org/blog/…
Грег

3

К / Кона (6)

-10?10

Як і J, ?є оператором угоди; що -сили значення , які не повторюються.


3

Математика 40

Число створюється у вигляді рядка, щоб дозволити нулю відображатися як перший символ, коли це необхідно.

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

Вихідні приклади

"0568497231"
"6813029574"

Пояснення

"0"~CharacterRange~"9" - це позначення інфіксації для `CharacterRange [" 0 "," 9 "]". Будь-який із них повертає список, {"0", "1", "2", "3", "4", "5", " 6 "," 7 "," 8 "," 9 "}.

RandomSample[list]за замовчуванням повертає перестановку списку. (Він також може бути використаний для інших видів вибірки, якщо параметри включені. Наприклад RandomSample[list, 4], повернеться Випадкова вибірка з 4 символів без повторів.


Але навіщо відображати 0 як перший символ?
Анкуш

Згідно з ОП, програма "повинна вміти генерувати всі перестановки усіх допустимих символів".
DavidC

@Ankush Це позначення інфіксу, тому "0" не завжди є першим символом.
Аяджа

Аджаджа правильна. Програма може генерувати будь-яку перестановку. Я додав вище зауваження, щоб уточнити це.
DavidC


2

По-четверте, 72

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

Кімната ще для гольфу, можливо, але Форт зробив це важким. Я думаю.


2

Пролог, 177/302 символів

Я початківець у Prolog, тому, напевно, це не самий ущільнений код.

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

Повернення:

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

Якщо ви хочете, щоб він повернув ціле число:

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

Повернення:

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

Використовуючи замість цього:

labeling([down],N)

Дає числа у зворотному порядку:

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

На відміну від деяких інших розміщених кодів, це повертає всі можливості (без повторень).


2

q / kdb [6 символів]

-10?10

буде генерувати 10 унікальних випадкових чисел.



2

Clojure, 42

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

6209847315


Згенероване число повинно бути показане на екрані, а не його частини.
Сільвестер

2

Javascript, 83 символи

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

Поки працює, поки масив не містить 10 елементів.

Генеруючи випадкове число від 0 до 9, тоді перевірте, чи масив! Включає це число і додайте його до масиву.


1
Ласкаво просимо на сайт! :)
DJMcMayhem

1

Це не набагато менше, ніж відповідь JMK, але ось трохи менший C-рішення (135):

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

Ущільнений (134):

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

Альтернативна версія (135):

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

Ущільнено:

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

Вони однакові за довжиною, але це дійсно залежить лише від того, чи потрібно використовувати функцію ForEach Linq або функцію приєднання String's. Я зміг видалити 10 символів довжиною, написавши діапазон "0123456789" в рядку, замість того, щоб використовувати Enumerable.Range (0, 10).


1

ЛОГО , 64 символи

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

Вибрати повертає випадковий елемент із поданого списку. butmember повертає список зі всіма входженнями вказаного елемента видалено. Примітка: Не всі версії логотипу підтримують butmemberкоманду.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.