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


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 .


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)

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.


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.


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.



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.


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


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

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.


2

Ruby, 27 23 bytes

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

-4 bytes de @manatwork

->n,r{[*1..r].sample n}

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

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.


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.


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

1

Clojure, 38 bytes

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

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


1

Perl 6, 32 bytes

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

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.


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)

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


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


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


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)

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


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.