A aleatoriedade é divertida. Desafios sem sentido são divertidos.
Escreva uma função que, dada a entrada inteira n
, produza um conjunto (não ordenado, exclusivo) de n
números inteiros exatamente aleatórios entre 1
e n^2
(inclusive), de modo que a soma de todos os números inteiros seja igual a n^2
.
A aleatoriedade não precisa ser uniforme, desde que cada conjunto válido tenha uma chance diferente de zero.
A resposta mais curta em bytes (por cada idioma) vence.
Exemplos
Input (n) = 1, Target (n^2) = 1
Sample of possible outputs:
1
Input = 2, Target = 4
Sample of possible outputs:
3, 1
1, 3
Input = 3, Target = 9
Sample of possible outputs:
6, 1, 2
3, 5, 1
4, 3, 2
Input = 4, Target = 16
Sample of possible outputs:
1, 3, 5, 7
2, 4, 1, 9
8, 3, 1, 4
Input = 5, Target = 25
Sample of possible outputs:
11, 4, 7, 1, 2
2, 3, 1, 11, 8
6, 1, 3, 7, 8
Input = 8, Target = 64
Sample of possible outputs:
10, 3, 9, 7, 6, 19, 8, 2
7, 16, 2, 3, 9, 4, 13, 10
7, 9, 21, 2, 5, 13, 6, 1
Tarefa bônus: Existe uma fórmula para calcular o número de permutações válidas para um determinado n
?
code-golf
random
combinatorics
Skidsdev
fonte
fonte
Respostas:
Brachylog (v2), 15 bytes (aleatório) ou 13 bytes (todas as possibilidades)
Aleatória
Experimente online!
Envio de função (visto no TIO com um wrapper transformando-o em um programa completo).
Explicação
Todas as possibilidades
Experimente online!
Envio de função, que gera todas as saídas possíveis.
Explicação
Estou bastante surpreso que
∧≜
funcione (você normalmente teria que escrever∧~≜
para forçar a saída em vez da entrada), mas acontece que≜
tem uma suposição de entrada = saída, portanto, não importa o caminho que você executá-lo.Tarefa bônus
Para ter uma ideia da sequência do número de possibilidades, criei um wrapper TIO diferente que executa o programa em números inteiros sucessivos para fornecer a sequência das contagens de saída:
Uma viagem ao OEIS descobre que essa já é uma sequência conhecida, A107379 , descrita praticamente como na pergunta (aparentemente, você obtém a mesma sequência se a restringir a números ímpares). A página lista várias fórmulas para a sequência (embora nenhuma seja particularmente simples; a segunda parece uma fórmula direta para o valor, mas eu não entendo a notação).
fonte
x^(n*(n-1)/2)
na expansão da série deProduct_{k=1..n} 1/(1 - x^k)
" (não directa em todos, infelizmente)A≠≜₁ᵐ
) torna o tempo de execução muito mais rápido, em média.05AB1E , 11 bytes
Experimente online ou verifique todos os casos de teste .
Explicação:
fonte
Python (2 ou 3), 85 bytes
Experimente online!
fonte
R ,
68, 7548 bytes (aleatório) e 70 bytes (determinístico)@ Método de amostragem por rejeição de Giuseppe:
Experimente online!
Original de golfe:
Experimente online!
O
*!!1:2
negócio é evitar a maneira estranha desample
agir quando o primeiro argumento tiver comprimento 1.fonte
p
diretamente como um índice em vez de calculá-lo e reutilizá-lo deve economizar alguns bytes.function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
para 48, bem ...sample(2,1)
que acontecen=2
. Portanto,rep
apenas garante que isso nunca acontecerá. Pode haver uma maneira melhor, mas isso foi rápido e eu estava com raivasample
.x*!!1:2
overrep(x,2)
se sua meta questão receber um não.Geléia , 9 bytes
Experimente online!
Gere todas as n combinações da lista [1..n²], filtre para manter as que possuem a soma n² e escolha uma aleatória.
fonte
Java 10,
250242222 bytes-20 bytes graças a @nwellnhof .
Cuidado, o Java está chegando .. É 'apenas' cinco vezes, enquanto as outras quatro respostas combinadas, então não é tão ruim, eu acho .. rofl.
Ele
n=1
atravessan=25
(combinado) em menos de 2 segundos, então eu provavelmente vou postar uma versão modificada para a versão de velocidade deste desafio (que é actualmente ainda no Sandbox) também.Experimente online.
Explicação:
No pseudo-código, fazemos o seguinte:
1) Gerar uma matriz de tamanho
n+1
contendo:0
,n
quadrado, en-1
quantidade de números inteiros aleatórios no intervalo[0, n squared)
2) Separar esta matriz
3) Criar uma segunda gama de tamanho
n
contendo as diferenças para a frente de paresEstes três primeiros passos nos dará uma matriz contendo
n
aleatório números inteiros (no intervalo[0, n squared)
que soma aon
quadrado.4a) Se nem todos os valores aleatórios forem únicos, ou se algum deles for 0: tente novamente a partir da etapa 1
4b) Outro: retorne essa matriz de diferenças como resultado
Quanto ao código real:
fonte
n=25
em menos de 2 segundos é impressionante! Vou ter que ler a explicação e ver como isso acontece. Ainda é um método de força bruta?[0, n squared)
primeiro e depois calcula as diferenças entre esses valores aleatórios classificados (incluindo inicial0
e finaln squared
. Por isso, tenho certeza de que essas diferenças também são uniformes. , eu não sei como provar isso Uniformidade na aleatoriedade não é realmente a minha experiência tbh..d
ou estou perdendo alguma coisa?Perl 6 , 41 bytes
Experimente online!
(1 .. $_²)
é o intervalo de números de 1 ao quadrado do número de entrada.pick($_)
escolhe aleatoriamente um subconjunto distinto desse intervaloxx *
replica a expressão anterior infinitamentefirst *.sum == $_²
seleciona o primeiro desses conjuntos de números que soma ao quadrado do número de entradafonte
Pitão,
1312 bytesExperimente online aqui . Observe que o intérprete online executa um MemoryError para entradas maiores que 5.
Editar: salvou um byte usando uma abordagem alternativa. Versão anterior:
Of&qQlT{IT./*
fonte
Python 3 ,
136 134 127 121114 bytesExperimente online!
Um comentarista me corrigiu, e isso agora atinge a profundidade máxima da recursão em f (5) em vez de f (1). Muito mais perto de ser uma resposta real e competitiva.
Eu já vi fazer (5) uma vez e estou tentando implementar isso com o shuffle.
Tentei criar algumas expressões lambda para
s=...
, mas isso não ajudou em bytes. Talvez alguém possa fazer algo com isso:s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)
Obrigado a Kevin por remover outros 7 bytes.
fonte
f(1)
, a única matriz possível que deve ser geráveln=1
é.[1]
Também há muito espaço em branco estranho a ser removido aqui. Recordar que este é um desafio code-golfe, de modo que o objetivo é conseguir o menor bytecountrange(1,n)
->range(n)
Eu acredito que deveria resolver o bug.return len(s)==n and sum(s)==n*n and s or f(n)
( Experimente on-line 114 bytes ).APL (Dyalog Unicode) , SBCS de 20 bytes
Prefixo anônimo lambda.
Experimente online!
{
...}
"dfn";⍵
é argumento⍵*2
esquadrar o argumentos←
atribuir as
(para s quare)⍵?
encontren
índices aleatórios de 1…s
sem substituiçãoc←
atribuir ac
(para c andidate)+/
somar eless=
comparado as
:
se igualc
devolver o candidato⋄
outro∇⍵
recuar sobre o argumentofonte
APL (Dyalog Classic) , 18 bytes
Experimente online!
usa
⎕io←1
⍳
gera os números1 2 ... n
(
...)⍣(
...)
continue aplicando a função à esquerda até que a função à direita retorne verdadeira≢
comprimento, ien
≢?≢×≢
escolhan
números inteiros aleatoriamente distintos entre 1 en
2+.-∘≢
subtrair o comprimento de cada número e soma0=
se a soma for 0, pare de repetir, caso contrário, tente novamentefonte
MATL ,
1813 bytesExperimente online!
fonte
Japonês, 12 bytes
Tente
fonte
à
deve ser razoável.Java (JDK) , 127 bytes
Experimente online!
Loop infinito até que um conjunto com os critérios corresponda.
Espero que você tenha tempo, porque é muito sloooooow! Não pode nem chegar a 10 sem tempo limite.
fonte
if(r.size()==n&s==0)
paraif(r.size()+s==n)
.s>0
, para que o tamanho possa ser maior quen
. Ok, nesse caso, de fato não funciona.n
é uma constante, mas infelizmente ambass
er.size()
são variáveis que podem estar abaixo ou acima0
en
respectivamente.Lote,
182145 bytesExplicação: Calcula a seleção mínima e máxima permitida, considerando que os números devem ser selecionados em ordem decrescente e escolhe um valor aleatório dentro do intervalo. Exemplo para uma entrada de
4
:fonte
JavaScript,
647291261260259251239 bytesObrigado a @Veskah por -10 bytes na versão original e "Ah, sim, você está produzindo todos os conjuntos, enquanto o desafio pede que um aleatório seja retornado"
Experimente online!
Crie uma matriz de
n^2
índices baseados em 1, classifique a matriz aleatoriamente, corten
elementos da matriz. Enquanto a soma dos elementos aleatórios não é igual àn^2
matriz de loop de elementos aleatórios; se a soma dos elementos da matriz for maior quen^2
e o elemento atual-1
não for igual a zero ou o elemento atual-1
não estiver na matriz atual, subtraia1
; se a soma da matriz for menor quen^2
e o elemento atual+1
não estiver na matriz, adicione1
ao elemento Se a soma da matriz for igual aon^2
loop de interrupção, imprima a matriz.fonte
k++
while
loops provavelmente também podem ser reduzidos ao corpo de uma única função que aceita parâmetros; e poderia substituir operadores condicionais (ternários) pelasif..else
declarações; entre outras partes do código que provavelmente poderiam ser ajustadas para o golfe; ieg, removendolet
instruções.if..else
n
?" . testando resultado esperado se o algoritmo consistentemente devolvido paran^2
matrizes de saída gerados em uma única chamada para a função, e considerando simultaneamente as semelhanças com esta questão N N-dimensional ^ N matriz preenchido com N .Japonês , 20 bytes
Experimente online!
Extremamente tira proveito da aleatoriedade "Não uniforme", quase sempre gera os primeiros
n
números ímpares, que somamn^2
. Em teoria, ele pode gerar qualquer outro conjunto válido, embora eu tenha sido capaz de confirmar isso apenas para pequenosn
.Explicação:
fonte
Ruby , 46 bytes
Experimente online!
fonte
C (gcc) ,
128125 bytesExperimente online!
-3 bytes graças a ceilingcat
NOTA: A probabilidade está muito longe de ser uniforme. Veja a explicação do que quero dizer e um meio melhor de testar se ele funciona (tornando a distribuição mais próxima do uniforme [mas ainda muito longe disso]).
Quão?
A idéia básica é escolher apenas números crescentes para não se preocupar com duplicatas. Sempre que escolhemos um número, temos uma chance diferente de zero de ignorá-lo, se permitido.
Para decidir se podemos pular um número, precisamos sabery+ ( y+ 1 ) + ( y+ 2 ) + . . . adicionado ao valor atual. Em particular, exigimos que a expressão acima seja menor que k ( k + 1 )2+ k ( y+ 1 ) + y< x Infelizmente, temos que ter um pouco de cuidado em reorganizar essa fórmula devido ao truncamento inteiro em C, por isso não consegui realmente encontrar uma maneira de jogar golfe.
x
o total restante a ser atingido,k
o número de elementos que ainda precisamos usar ey
o valor atual do candidato. O menor número possível que ainda poderíamos escolher consistiria emx
. A fórmula seráNo entanto, a lógica é ter a chance de descartar qualquer
y
que satisfaça a equação acima.O código
O truque que mencionei para testar melhor o código envolve a substituição
rand()&&
por,rand()%2&&
para que haja uma chance de 50 a 50 de que qualquer y seja ignorado, em vez de 1 emRAND_MAX
chance de que qualquer y seja usado.fonte
p(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;
vez de){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
Limpo , 172 bytes
Experimente online!
fonte
Python (2 ou 3), 84 bytes
Experimente online!
Atinge a profundidade máxima de recursão em torno de l (5)
fonte
Kotlin , 32 bytes
Experimente online!
fonte
Mathematica 40 bytes
fonte
RandomChoice@IntegerPartitions[#^2,{#}]&
Wolfram Language (Mathematica) , 49 bytes
Experimente online!
Versão Golfed por @ J42161217.
Wolfram Language (Mathematica) , 62 bytes
Experimente online!
Como funciona
Principalmente com base em esta questão Math.SE . Para obter partições den2 para dentro n partes distintas, obtenha partições de n2- ( n2- n ) / 2 = ( n2+ n ) / 2 em vez disso e adicione 0 ⋯ n - 1 para cada elemento. Como o Mathematica fornece as partições em ordem decrescente,n - 1 ⋯ 0 é adicionado em seu lugar.
A resposta para a tarefa de bônus
Sim. Definirp a r t ( n , k ) como o número de partições de n exatamente k peças. Em seguida, ele satisfaz a seguinte relação de recorrência:
Você pode entendê-lo como "Se uma partição contiver 1, remova-a; caso contrário, subtraia 1 de cada termo". Mais explicações aqui na outra pergunta Math.SE . Combinado com as condições iniciaisp a r t ( n , 1 ) = 1 e n < k ⇒ p a r t ( n , k ) = 0 , você pode computá-lo com um programa. A resposta desejada será:
ou seja, no Mathematica:
Experimente online!
fonte
(While[Tr[s=RandomSample[Range[#^2],#]]!=#^2];s)&