Случайный массив без повторений

16

Я отвечал на одну проблему здесь, и эта задача была частью проблемы. У меня есть решение 73 байта в JavaScript. Но я думаю, что это слишком много для простой вещи.

Вызов

Задано в качестве входных данных два целых числа:

  • N длина ожидаемого массива
  • Rдиапазон интервала, начинающийся с одного:, 1..Rне0..R-1

Выведите при каждом запуске вашей программы / функции один другой массив длины Nсо значениями 1..R, чтобы ни одно значение не встречалось более одного раза.

Вы должны использовать R-valueв своем коде.

ограничения

Можно предположить: 2 <= N <= R.

Я действительно хотел бы видеть решение javascript короче, чем мои 73 байта.

Но, конечно, он открыт для всех языков!

Если ваш язык не может вернуть массив, вы можете напечатать все числа;)

удален
источник
2
Другое дело: я не думаю, что вы хотите, чтобы они были разными с каждым пробегом, а просто равномерно случайными? (В противном случае это не сработает R=N=1). Тогда я рекомендую разрешить использование диапазонов 0..Rв качестве альтернативы, так как это более естественно для многих языков.
flawr
Я бы рекомендовал, чтобы каждая перестановка была одинаково вероятной (при условии идеальной случайности), иначе я могу это сделатьshuffle(0..N)
Натан Меррилл
Я опубликовал свой ответ с неоднородным случайным качеством, прежде чем вы изменили правило.
Конор О'Брайен,
1
Вы говорите равномерно случайное решение, но new Dateвыдает неоднородные значения. Кроме того, я считаю, что вы можете сыграть в гольф new Date%r+1;)
Конор О'Брайен,
Выходной массив должен быть целыми числами? Кажется очевидным, но я не вижу, что это прямо заявлено
Чарли Уинн

Ответы:

16

Дьялог АПЛ, 1 байт

?

Просто встроенный. Попробуй это здесь .

lirtosiast
источник
3
С ответом, подобным этому, мне пришлось прокрутиться назад, чтобы увидеть, был ли ты ОП
lbstr
2
@lbstr Теперь, когда вы упомянули об этом, мой идентификатор очень похож на OP.
lirtosiast
9

JavaScript (ES6), 68 66 байт

n=>r=>G=(s=new Set)=>s.size<n?G(s.add(Math.random()*r+1|0)):[...s]

Вызывается как F(N)(R)(), где Fэто назначение функции, и N/ Rявляются значениями.

Вы просили короче 73 байтов в Js;)

РЕДАКТИРОВАТЬ: Ответ @ C5H8NNaO4 работает в том факте, что правила не указывают значения должны быть одинаковыми по всему 1..R. Учитывая это, вот версия работает в 63 байта (называется F(R)(N)):

r=>G=(n,s=[])=>n--?G((s[n]=n+1,n),s):s.sort(a=>new Date/a%1-.5)
Mwr247
источник
Чувак, это впечатляет !! +1
удалено
@WashingtonGuedes Спасибо =) Просто сбрил еще 2 байта.
Mwr247
7

Октава, 22 19 9 байт

@randperm

randperm(r,n)делает именно то, что запрашивается. Обратите внимание, что это не работает (по крайней мере, в старых версиях) в Matlab.

flawr
источник
1
@(n,r)randperm(r,n)
Луис Мендо
1
randpermс двумя входами работает в последних версиях Matlab. Есть также randsample, но это занимает больше байтов, если вы не можете избавиться от @(...)(я думаю, что это разрешено)
Луис Мендо
О, я могу использовать @randperm=)
flawr
5

TI-84 BASIC OS 4.0, 12 байтов

Prompt N,R:randIntNoRep(1,R,N

TI-84 + CSE (2013) и CE (2015), по сути, представляют собой тот же ограниченный диалект BASIC, что и TI-84 +, но есть несколько новых функций. Одним из них является третий аргумент randIntNoRep.

lirtosiast
источник
1
Честно говоря, глупо, что они не включили эту функцию с самого начала.
SuperJedi224
Я сразу подумал TI-Basic, когда увидел этот вызов :)
Timtech
5

MATL , 2 байта

Zr

Входы: первый R , потом N.

Попробуйте онлайн!

объяснение

Функция Zrпринимает два входа (в данном случае неявно) и выполняет случайную выборку без замены. Первый вход, Rуказывает, что население [1,2,...,R]; и второй вход, Nуказывает количество образцов, взятых у населения.

Луис Мендо
источник
4

J, 4 3 байта

Один байт сохранен благодаря Zgarb! ( Вычеркнуто четыре все еще обычные четыре: D )

1+?

называют как N (1+?) R, например, 3 (1+?) 10. При этом используется оператор «Roll», и он делает именно то, что описано, кроме как в 0...n-1. Если бы нам было позволено сделать это, то ответ был бы 1 байт,

?
Конор О'Брайен
источник
@tac Ах, Готка
Конор О'Брайен
4

Pyth, 6 байт

<.SSQE

Попробуй это здесь!

Диапазон идет в первой строке, а длина - во второй.

объяснение

<.SSQE # Q = диапазон, E = длина

   SQ # генерирует диапазон 1 ... Q
 .S # перемешать список
<E # взять первые элементы E

Неконкурентная 5-байтовая версия

Последнее добавление к Pyth добавляет неявные Qs в конце программы, если это необходимо. Мы можем использовать это здесь, изменив формат ввода, поэтому сначала идет длина, а затем диапазон.

<.SSE

Попробуй это здесь!

Вот Eдиапазон, с которым мы превращаемся в список на основе 1 S, перетасовываем его .Sи берем первые Qэлементы <. <ожидает целое число, которое неявно добавляется с Q.

Denker
источник
4

Reng v.2.1, 140 103 98 97 байт

Это должно работать и в более ранних версиях.

v      v      $/$'l#y0#z>(:)):(ez+#z zt>a$;!
>i#ci#x>cu1+lxetv    j21\!q   yy#-1y($/^
>n?~v
^oW <

Вы можете попробовать это здесь! Ввод есть maximum length, например 10 3.

Я так горжусь этим, вы даже не знаете. Если кто-то победит меня с ответом Java, это сделает мой день. Если я опередил ответ на Java, считай, что мой день тоже сделан.

Я объясню это позже, когда выздоровею. Как правило, хотя:

v         v      $/$r$
>i#bbi1+#x>:u1+lxet

Это генерирует случайные числа. Другая часть проверяет, есть ли дубликаты, и, если они есть, процесс повторяется. В противном случае результаты печатаются с пробелами, соединяющими результаты.

Вот некоторые примеры:

длинный гиф

Конор О'Брайен
источник
3

CJam, 8 байт

{,:)mr<}

Попробуй это здесь!

Это безымянный блок, который ожидает диапазон в верхней части стека и длину в нижней части и оставляет список в стеке.

объяснение

, диапазон на основе e # 0
:) e # инкремент каждого элемента списка, поэтому его 1 на основе
мистер э # перемешать список
<e # взять первые n элементов
Denker
источник
Это одна счастливая программа :)
Конор О'Брайен,
1
@ CᴏɴᴏʀO'Bʀɪᴇɴ Я был бы счастлив, если бы у CJam была встроенная функция для диапазонов на основе 1, поэтому мне не понадобился бы этот чертов смайлик: P
Denker
2

Common Lisp, 90

52 только для выражения

(use-package :alexandria)(lambda(R N)(coerce(subseq(shuffle(iota R :start 1))0 N)'vector))

Ungolfed

;; Well known library
(use-package :alexandria)

(lambda(R N)
  (coerce                   ; make a vector from a list 
    (subseq                 ; take the sublist from 0 to N
      (shuffle              ; shuffle a list
        (iota R :start 1))  ; build a list from 1 to R
    0 N)
    'vector))

Как и другие ответы, если я не считаю use-package и lambda , оставшееся выражение (coerce(subseq(shuffle(iota R :start 1))0 N)'vector)для 52 байтов.

CoreDump
источник
2

Руби, 27 23 байта

Анонимная функция, достаточно короткая и сладкая.

-4 байта от @manatwork

->n,r{[*1..r].sample n}
Значение чернил
источник
->n,r{[*1..r].sample n}Пожалуйста, используйте разметку блока кода вместо встроенной разметки кода, чтобы такие сценарии, как Code Golf UserScript Enhancement Pack, могли вставлять размер кода рядом с ним.
Манатворк
Хорошо, сейчас все исправлено.
Стоимость чернил
2

𝔼𝕊𝕄𝕚𝕟, 10 символов / 13 байтов

Ѩŝ⩤⁽1í)ą-î

Try it here (Firefox only).

объяснение

           // implicit: î=input1, í=input2
  ⩤⁽1í)    // Inclusive range from 1 to í
Ѩŝ         // Shuffle resulting range
       ą-î // Get last îth items
Mama Fun Roll
источник
2

Баш + coreutils, 16

Я думаю, что это говорит само за себя:

seq $2|shuf -n$1

Ввод Nи Rпараметры командной строки.

Или, как указывает @rici, для того же результата:

shuf -n$1 -i1-$2

Ideone.

Цифровая травма
источник
1
или shuf -n$1 -i1-$2(такой же длины, хотя).
Ричи
@rici очень мило. очень чисто :)
Цифровая травма
1

PowerShell v2 +, 30 байт

param($n,$r)1..$r|Random -c $n

Принимает входные данные $nи $rсоздает диапазон 1..$r, каналы Get-Randomс -Cколичеством элементов $n, которые будут выбирать $nуникальные элементы из диапазона. Выходные данные остаются в конвейере в виде неявного массива.

AdmBorkBork
источник
1

Серьезно, 5 байт

,,R╨J

Попробуйте онлайн!

Объяснение:

,,R╨J
,,R    push N, range(1, R+1)
   ╨   push a list containing all N-length permutations of range(1, R+1)
    J  select a random element from the list
Mego
источник
1

Clojure, 38 байт

#(take %1(shuffle(map inc(range %2))))

Анонимная функция, берущая N первым и R вторым.

MattPutnam
источник
1

Perl 6, 32 байта

{(^$^a).permutations.pick[^$^b]}
Вен
источник
1

Python 3,5 - 54 53 байта:

from random import*;lambda a,c:sample(range(1,c+1),a)

При этом sample()функция случайного модуля возвращает массив длиной «а», состоящий из случайных уникальных элементов в диапазоне 1 => c.

Р. Кап
источник
1

D, 29 байт (только выражение)

Предполагая, что std.random и std.range были импортированы и что n и r определены как переменные, программу можно решить одним выражением:

iota(1,r).randomCover.take(n)
Бен Перлин
источник
1

ES6, 72

r=>n=>[...Array(-~r).keys()].sort(a=>new Date/a%1-.5).filter(a=>a&&n-->0)

Как и в @ Mwr247 в ответ , вы можете назвать его F(R)(N), Fбудучи выражением функции

C5H8NNaO4
источник
0

Mathcad, 67 "байтов"

создает вектор столбца последовательных целых чисел в диапазоне 1..R, присоединяет его к вектору столбца длины R (равномерных) случайных чисел, сортирует полученную матрицу Rx2 по столбцу случайных чисел и затем извлекает первые n чисел из рандомизированный столбец целых чисел.

введите описание изображения здесь

Стюарт Бруфф
источник
Есть ли место, где мы можем это проверить?
Конор О'Брайен,
Вы можете скачать пробные версии Mathcad 15 и Mathcad Prime 3.1 (преемник Mathcad 15). Оба испытания выполняются в течение 30 дней, после чего M15 перестает работать, но Prime 3.1 все еще работает, хотя и с ограниченной функциональностью (например, без программирования - так что вышеописанное не будет работать ... но цикл for можно переписать для использования переменных диапазона) создать v вне оператора augment)
Стюарт Бруфф,
Пробные версии находятся по адресу: Matcad 15 - ptc.com/engineering-math-software/mathcad/free-trial ; Mathcad Prime 3.1 - ptc.com/engineering-math-software/mathcad/free-download
Стюарт
И как вы считаете эти байты?
2016 года
Рассматривая его с точки зрения пользовательского ввода и приравнивая одну операцию ввода Mathcad (обычно с клавиатуры, щелчок мыши на панели инструментов, если нет ярлыка kbd) к символу и интерпретируя его как байт. csort = 5 байт, поскольку он набирается символ за символом, как и другие имена переменных / функций. Оператор for - это специальная конструкция, которая занимает 11 символов (включая 3 пустых "заполнителя" и 3 пробела), но вводится с помощью ctl-shft- #, следовательно, = 1 байт (аналогично токенам в некоторых языках). Ввод '(цитата) создает сбалансированные скобки (обычно), поэтому считается 1 байт. Индексирование v = 3 байта (тип v [k).
Стюарт Бруфф
0

Python, 56 (очевидный путь)

lambda N,R:__import__('random').sample(range(1,R+1),k=N)
shooqie
источник
from random import*;lambda N,R:sample(range(1,R+1),k=N)короче на байт
Mego
Да, я подумал from random import*, наверное, облажался со счетом.
Shooqie
0

Perl 5, 51 43 байта

sub{@a=1..pop;map{splice@a,rand@a,1}1..pop}

Довольно простая анонимная подпрограмма, которая генерирует массив от 1 до R, а затем склеивает из него N случайных элементов для возврата. Позвонить с->(N, R) .

Олег В. Волков
источник
0

TI-84 BASIC, 21 байт

Prompt R,N:randIntNoRep(1,R→A:N→dim(ʟA:ʟA
SuperJedi224
источник
Больше нельзя использовать в Ansкачестве входных данных согласно недавнему мета-посту.
Конор О'Брайен,
@ CᴏɴᴏʀO'Bʀɪᴇɴ ... почему бы и нет?
SuperJedi224
Это был консенсус по мета . Проголосуйте, если вы не согласны.
Конор О'Брайен