Matriz aleatória sem repetição

16

Eu estava respondendo a um desafio aqui e essa tarefa fazia parte do desafio. Eu tenho uma solução de 73 bytes em javascript. Mas acho que é demais para uma coisa simples.

Desafio

Dado como entrada dois números inteiros:

  • N o comprimento da matriz esperada
  • Ro intervalo do intervalo começando em um:, 1..Rnão0..R-1

Produza em cada execução do seu programa / função uma matriz diferente de comprimento Ncom valores entre 1..Rde tal maneira que nenhum valor ocorra mais de uma vez.

Você deve usar R-valueno seu código.

Restrições

Você pode assumir: 2 <= N <= R.

Eu realmente gostaria de ver uma solução javascript menor que a minha 73 bytes.

Mas é claro, está aberto a todas as línguas!

Se o seu idioma não puder retornar uma matriz, você poderá imprimir todos os números;)

removido
fonte
2
Outra coisa: eu não acho que você queira que eles sejam diferentes a cada corrida, mas apenas uniformemente aleatórios? (Caso contrário, não funcionaria R=N=1). Em seguida, recomendo permitir os intervalos 0..Rcomo alternativa, pois isso é mais natural para muitos idiomas.
flawr
Eu tinha recomendando inclusive que cada permutação ser igualmente provável (assumindo perfeita aleatoriedade), mais posso fazershuffle(0..N)
Nathan Merrill
Postei minha resposta de qualidade aleatória não uniforme antes de você fazer sua alteração de regra.
Conor O'Brien
1
Você diz uma solução uniformemente aleatória, mas new Dateproduz valores não uniformes. Além disso, eu acredito que você pode golfe para new Date%r+1;)
Conor O'Brien
A matriz de saída precisa ser um número inteiro? Parece óbvio, mas não o vejo explicitamente declarado #
Charlie Wynn

Respostas:

16

Dyalog APL, 1 byte

?

Apenas um builtin. Experimente aqui .

lirtosiast
fonte
3
Com uma resposta como esta, tive de rolar para trás para ver se você fosse o OP
lbstr
2
@lbstr Agora que você mencionou, meu identicon é bem parecido com o do OP.
lirtosiast
9

JavaScript (ES6), 68 66 bytes

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

Chamado como F(N)(R)(), onde Festá a atribuição da função e N/ Rsão os valores.

Você solicitou menos de 73 bytes em Js;)

EDIT: A resposta de @ C5H8NNaO4 funciona dentro do fato de que as regras não especificam os valores devem ser uniformes 1..R. Dado que, aqui está uma versão que funciona em 63 bytes (chamada comoF(R)(N) ):

r=>G=(n,s=[])=>n--?G((s[n]=n+1,n),s):s.sort(a=>new Date/a%1-.5)
Mwr247
fonte
Cara, isso é impressionante !! +1
removido
@WashingtonGuedes Thanks =) Acabei de remover outros 2 bytes.
Mwr247
7

Oitava, 22 19 9 bytes

@randperm

randperm(r,n)faz exatamente o que é solicitado. Observe que isso não funciona (pelo menos não nas versões mais antigas) no Matlab.

flawr
fonte
1
@(n,r)randperm(r,n)
Luis Mendo
1
randpermcom duas entradas funciona nas versões recentes do Matlab. Há também randsample, mas é preciso mais bytes, a menos que você pode se livrar do @(...)(acho que é permitido)
Luis Mendo
Oh, eu posso usar @randperm=)
flawr
5

TI-84 BASIC OS 4.0, 12 bytes

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

A TI-84 + CSE (2013) e a CE (2015) são essencialmente o mesmo dialeto BASIC limitado da TI-84 +, mas existem alguns novos recursos. Um deles é o terceiro argumento de randIntNoRep.

lirtosiast
fonte
1
Francamente, é meio bobo que eles não incluam esse recurso desde o início.
22716 SuperJedi224
Pensei imediatamente TI-Basic quando vi este desafio :)
Timtech
5

MATL , 2 bytes

Zr

As entradas são: primeiro Re depois N.

Experimente online!

Explicação

A função Zrrecebe duas entradas (implicitamente neste caso) e faz uma amostragem aleatória sem substituição. A primeira entrada,, Respecifica que a população é [1,2,...,R]; e a segunda entrada,, Nindica o número de amostras a serem coletadas da população.

Luis Mendo
fonte
4

Pitão, 6 bytes

<.SSQE

Experimente aqui!

O alcance vem na primeira linha e o comprimento na segunda.

Explicação

<.SSQE # Q = intervalo, E = comprimento

   SQ # gera o intervalo 1 ... Q
 .S # embaralha a lista
<E # pegue os primeiros elementos E

Versão não concorrente de 5 bytes

A última adição ao Pyth adiciona Qs implícitos no final do programa, se necessário. Podemos usar isso aqui revertendo o formato de entrada, para que o comprimento chegue primeiro e depois o intervalo.

<.SSE

Experimente aqui!

Aqui Eestá o intervalo, com o qual transformamos em uma lista baseada em 1 S, embaralha-o .Se pega os primeiros Qelementos <. <espera um número inteiro que é implicitamente adicionado com a Q.

Denker
fonte
4

Reng v.2.1, 140 103 98 97 bytes

Isso deve funcionar em versões anteriores também.

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

Você pode tentar aqui! A entrada é maximum length, como 10 3.

Estou tão orgulhoso disso que você nem sabe. Se alguém me vencer com uma resposta Java, isso fará o meu dia. Se eu vencer uma resposta Java, considere meu dia também.

Vou explicar mais tarde, depois que eu me recuperar. Geralmente, porém:

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

Isso gera os números aleatórios. A outra parte verifica se há duplicatas e, se houver, o processo é repetido. Senão, os resultados são impressos, com espaços unindo os resultados.

aqui estão alguns exemplos:

gif longo

Conor O'Brien
fonte
3

CJam, 8 bytes

{,:)mr<}

Experimente aqui!

Este é um bloco sem nome que espera o intervalo no topo da pilha e o comprimento na parte inferior e deixa uma lista na pilha.

Explicação

, e # 0-based range
:) e # imprima cada elemento da lista para que seja baseado em 1
Sr. e # embaralhe a lista
<e # pega os primeiros n elementos
Denker
fonte
Este é um programa de feliz :)
Conor O'Brien
1
@ CᴏɴᴏʀO'Bʀɪᴇɴ eu seria mais feliz se CJam tinha um builtin para 1 baseados em faixas, então eu não preciso disso smileyface Damm: P
Denker
2

Lisp comum, 90

52 apenas para a expressão

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

Como outras respostas, se eu não contar o pacote de uso e o lambda , a expressão restante será (coerce(subseq(shuffle(iota R :start 1))0 N)'vector)52 bytes.

coredump
fonte
2

Ruby, 27 23 bytes

Função anônima, razoavelmente curta e doce.

-4 bytes de @manatwork

->n,r{[*1..r].sample n}
Value Ink
fonte
->n,r{[*1..r].sample n}Use a marcação do bloco de código em vez da marcação embutida, para que scripts como o Code Golf UserScript Enhancement Pack possam inserir o tamanho do código ao lado.
Manatwork
Tudo bem, está consertado agora.
Value Ink
2

, 10 caracteres / 13 bytes

Ѩŝ⩤⁽1í)ą-î

Try it here (Firefox only).

Explicação

           // implicit: î=input1, í=input2
  ⩤⁽1í)    // Inclusive range from 1 to í
Ѩŝ         // Shuffle resulting range
       ą-î // Get last îth items
Mama Fun Roll
fonte
2

Bash + coreutils, 16

Eu acho que isso é auto-explicativo:

seq $2|shuf -n$1

Entrada Ne Rcomo parâmetros de linha de comando.

Ou como @rici aponta, para a mesma pontuação:

shuf -n$1 -i1-$2

Ideone.

Trauma Digital
fonte
1
ou shuf -n$1 -i1-$2(mesmo comprimento, no entanto).
rici 26/03
@rici muito bom. muito limpo :)
Digital Trauma
1

PowerShell v2 +, 30 bytes

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

Recebe entrada $ne $r, constrói um intervalo 1..$r, canaliza Get-Randomcom um -Count de $n, que selecionará$n elementos exclusivos do intervalo. A saída é deixada no pipeline como uma matriz implícita.

AdmBorkBork
fonte
1

Sério, 5 bytes

,,R╨J

Experimente online!

Explicação:

,,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
fonte
1

Clojure, 38 bytes

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

Uma função anônima que leva N primeiro e R segundo.

MattPutnam
fonte
1

Perl 6, 32 bytes

{(^$^a).permutations.pick[^$^b]}
Ven
fonte
1

Python 3.5 - 54 53 bytes:

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

Isso usa a sample()função do módulo aleatório para retornar uma matriz com o comprimento "a" que consiste em elementos únicos e aleatórios no intervalo 1 => c.

R. Kap
fonte
1

D, 29 bytes (apenas expressão)

Supondo que std.random e std.range tenham sido importados e que n e r sejam definidos como variáveis, o programa pode ser resolvido na expressão única:

iota(1,r).randomCover.take(n)
Ben Perlin
fonte
1

ES6, 72

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

Como na resposta do @ Mwr247 , você pode chamá-lo com F(R)(N), Fsendo a expressão da função

C5H8NNaO4
fonte
0

Mathcad, 67 "bytes"

cria um vetor de coluna de números inteiros consecutivos no intervalo 1..R, une-o a um vetor de coluna de comprimento R de números aleatórios (uniformes), classifica a matriz Rx2 resultante na coluna de número aleatório e extrai os primeiros n números do coluna aleatória de números inteiros.

insira a descrição da imagem aqui

Stuart Bruff
fonte
Existe um lugar para testar isso?
Conor O'Brien
Você pode baixar versões de teste do Mathcad 15 e Mathcad Prime 3.1 (o sucessor do Mathcad 15). Ambos os testes são executados por 30 dias, após os quais o M15 para de funcionar, mas o Prime 3.1 ainda é executado, embora com funcionalidade reduzida (por exemplo, sem programação - portanto, o acima não funcionará ... mas o loop for pode ser reescrito para usar variáveis ​​de intervalo para criar v fora da instrução augment)
Stuart Bruff
As versões de teste estão em: Matcad 15 - ptc.com/engineering-math-software/mathcad/free-trial ; Mathcad Prime 3.1 - ptc.com/engineering-math-software/mathcad/free-download
Stuart Bruff
E como você conta esses bytes?
Rɪᴋᴇʀ
Observando-o da perspectiva de entrada do usuário e igualando uma operação de entrada do Mathcad (normalmente o teclado, clique na barra de ferramentas, se não houver atalho do kbd) em um caractere e interpretando-o como um byte. csort = 5 bytes, pois é digitado char-by-char, assim como outros nomes de variáveis ​​/ funções. O operador for é uma construção especial que ocupa 11 caracteres (incluindo 3 "espaços reservados" em branco e 3 espaços), mas é inserida por ctl-shft- #, portanto = 1 byte (semelhante aos tokens em alguns idiomas). Digitar '(aspas) cria parênteses balanceados (geralmente) e conta como 1 byte. Indexação v = 3 bytes (tipo v [k).
precisa
0

Python, 56 (o caminho óbvio)

lambda N,R:__import__('random').sample(range(1,R+1),k=N)
shooqie
fonte
from random import*;lambda N,R:sample(range(1,R+1),k=N)é mais curto por um byte
Mego 24/03
Eu pensei from random import*, deve ter estragado a contagem.
shooqie
0

Perl 5, 51 43 bytes

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

Sub anônimo bastante direto que gera uma matriz de 1 a R e, em seguida, emenda N elementos aleatórios a partir dela para retornar. Ligue com ->(N, R).

Oleg V. Volkov
fonte
0

TI-84 BASIC, 21 bytes

Prompt R,N:randIntNoRep(1,R→A:N→dim(ʟA:ʟA
SuperJedi224
fonte
Não se pode mais usar Anscomo entrada, conforme uma meta post recente.
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ ... por que não?
SuperJedi224
Esse foi o consenso sobre a meta . Vote nele se você não concordar.
Conor O'Brien