O princípio do pombo afirma que
Se N itens forem colocados em caixas M , com N > M , pelo menos uma caixa deverá conter mais de um item.
Para muitos, esse princípio tem um status especial em comparação com outros enunciados matemáticos. Como EW Dijkstra escreveu ,
Está cercado por alguma mística. As provas de usá-lo são frequentemente consideradas algo especial, algo particularmente engenhoso.
O desafio
O objetivo deste desafio é ilustrar o princípio do buraco de pombo usando representações de arte ASCII. Especificamente:
- Tome como entrada
N
(número de itens) eM
(número de caixas), comN
não negativo eM
positivo.N
pode ser menor queM
(mesmo que o princípio não se aplique nesse caso). - Selecione aleatoriamente uma das possíveis atribuições de itens para caixas. Cada tarefa deve ter uma probabilidade diferente de zero de ser escolhida.
Produza uma representação artística ASCII da tarefa da seguinte maneira:
- Existem
M
linhas, cada uma correspondendo a uma caixa. - Cada linha começa com um caractere que não seja um espaço em branco, como
|
. - Após esse caractere, há outro caractere que não é de espaço em branco, como
#
, repetido quantas vezes houver itens nessa caixa.
- Existem
Considere, por exemplo N = 8
, M = 5
. Se o assigment selecionado de itens para caixas é 4
, 1
, 0
, 3
, 0
, a representação é
|####
|#
|
|###
|
Uma execução diferente (resultando em uma atribuição diferente) do mesmo programa pode dar
|#
|##
|#
|#
|###
Existe alguma flexibilidade em relação à representação; ver abaixo.
Regras específicas
O código deve teoricamente ser executado para quaisquer valores de N
e M
. Na prática, pode ser restringido pelo tamanho da memória ou pelas limitações do tipo de dados.
Como a observação da saída não é suficiente para determinar se todas as atribuições têm probabilidade diferente de zero , cada envio deve explicar como o código alcança isso, se não óbvio.
As seguintes variações de representação são permitidas:
- Qualquer par de caracteres diferentes, que não sejam espaços em branco, pode ser escolhido. Eles devem ser consistentes nas execuções do programa.
- Rotações de 90 graus da representação são aceitáveis. Novamente, a escolha deve ser consistente.
- Espaço em branco à direita ou à direita é permitido.
Como exemplo com um formato de representação diferente, para N = 15
, M = 6
os resultados de duas execuções do programa podem ser
VVVVVV
@@@@@@
@@ @@@
@ @@
@
ou
VVVVV
@@@ @
@@@ @
@ @ @
@ @ @
@
Da mesma forma, N = 5
, M = 7
poderia dar, usando uma outra variação da representação,
*
* * * *
UUUUUUU
ou
*** **
UUUUUUU
ou
*
* *
* *
UUUUUUU
Observe como o princípio não é aplicável neste caso, porque N
< M
.
Regras gerais
Programas ou funções são permitidos, em qualquer linguagem de programação . As brechas padrão são proibidas.
A entrada pode ser obtida por qualquer meio razoável ; e com qualquer formato, como uma matriz de dois números ou duas seqüências diferentes.
Os meios e o formato de saída também são flexíveis. Por exemplo, a saída pode ser uma lista de cadeias ou uma cadeia com novas linhas; retornado como argumento de saída da função ou exibido em STDOUT. Neste último caso, não é necessário se preocupar com a quebra de linha causada pela largura limitada da exibição.
O menor código em bytes vence.
Respostas:
Geléia ,
98 bytesEsse é um link diádico que toma M como à esquerda e N como seu argumento à direita. A saída é uma matriz de números inteiros, em que 0 representa pombos e 1 representa buracos.
Experimente online!
Como funciona
fonte
Mathematica, 68 bytes
Uma função sem nome que recebe dois argumentos inteiros, o número de caixas, seguido pelo número de itens.
Primeiro, calcula todas as partições possíveis
N+M
emM
partes exatamente positivas e subtrai1
de cada partição posteriormente. Isso nos dá todas as partições possíveisN
emM
partes não negativas (queIntegerPartitions
não seriam geradas de outra forma). Em seguida, escolha uma partição aleatória e embaralhe-a. Isso garante que todas as partições ordenadas possíveis com zeros sejam permitidas. Por fim, converta cada compartimento da partição em uma linha de saída aumentando 10 para a potência correspondente (de modo que cada linha fique1000...
comk
zeros). Um exemplo de saída pode parecer com:fonte
PadRight
que não iriaM
zerar seN
<M
.PadRight
a não listabilidade demoraria muito mais.PadRight
seriaIntegerPartitions[#,{#2},0~Range~#]
.Python 2,
7786 bytesGera um número em [0, n], imprime muitos itens e o subtrai de n. Faz isso m vezes.
Isso torna muito improvável que algo chegue à última caixa, mas a pergunta apenas pedia que toda saída fosse possível , e não igualmente provável .
fonte
Lote, 164 bytes
Eu acho que 7
%
sinais consecutivos podem ser um novo melhor pessoal! Nota: isso produz uma saída ímpar, se alguma vez atribuir mais de 9 itens à mesma caixa; se isso é um problema, então para 180 bytes:Sim, são 28
%
s no total na segunda linha.fonte
C, 102 bytes
Aceita stdin, por exemplo:
Não gera cada saída com igual probabilidade, mas é capaz de gerar todas as combinações possíveis.
Demolir:
Baseia-se na manipulação pelo GCC do comportamento indefinido de
%0s
- normalmente%0
irá zerar um número inteiro ou flutuar, mas só pode ser preenchido (nunca truncar), portanto, não é possível imprimir um espaço em branco. Mas o comportamento das seqüências de caracteres não está definido, e o GCC decidiu torná-lo com zero pad da mesma maneira, de modo que este zero preenche uma sequência vazia para poder escrever zero ou mais0
s.fonte
a(b,c){...}
vez demain
escanf
.Python 2,
102999790 bytesm-1
vezes, escolha uma quantidade aleatóriax
entre0
en
, inclusive e subtraia-a de n. Depois imprima um1
e'0'*x
.Por fim, imprima
1
e o restante de0
s. Sem chances iguais, mas todas as configurações são possíveis.(Código reutilizado da resposta Python quebrada.)
fonte
Haskell,
11494 bytesUm pouco de abordagem de força bruta: gera uma lista infinita de números aleatórios, pega n números do início da lista, resume-os e verifica se são iguais a m. Caso contrário, retire o primeiro elemento da lista e repita.
Experimente online!
Nota: 73 bytes sem a importação
EDIT: salvou alguns bytes com o truque 10 ^ ( Experimente a nova versão online! )
fonte
REXX, 74 bytes
Saída (8 5):
Saída (8 5):
fonte
C,
175138 bytesObrigado a @Dave por salvar 37 bytes!
Experimente online!
fonte
calloc
fornecerão a memória inicializada com 0 (não é necessário definir todos os 0s), vocêstrchr
poderá encontrar o final de uma string, a vírgula poderá encadear operações, evitando a necessidade{}
ex[0] == *x
. Também atente; você não terámalloc
memória suficiente se todos os itens estiverem na mesma caixa.AHK, 66 bytes
Segui o mesmo princípio que o orlp usava números aleatórios de 0 a N e subtraí-o de N. Infelizmente, não pude salvar bytes usando 10 ^ r devido à maneira como a função Send funciona. Infelizmente e de novo. Aqui estão algumas saídas para n = 8, m = 5:
fonte
CJam,
303121 bytesA entrada tem dois números
n m
na pilha. Usa1
para o caractere da coluna e0
para o caractere repetido.Explicação:
fonte
Röda , 79 bytes
Experimente online!
Isso cria uma matriz de zeros e os incrementa em locais aleatórios.
fonte
PHP, 100 bytes
Demolir :
Saídas para
m=7
en=5
:Primeira execução:
Segunda execução:
Experimente online!
fonte
[,$m,$n]=$argv;
do PHP 7.1 para salvar alguns caracteres. Você pode substituir\n
por uma quebra de linha real para economizar 1 byte. você pode usarfor(;$m-->0;)$a[rand(0,$n-1)].=a;
para salvar as quebras, um$m
e um ponto e vírgula.[,$m,$n]=$argv;$a=array_fill(0,$n,z);for(;$m-->0;)$a[rand()%$n].=a;echo join("\n",$a);
85 byte[,$m,$n]=$argv;for(;$m--;)${rand()%$n}.=a;for(;$n--;)echo"z${$n}\n";
67 bytes.[,$m,$n]=$argv;
em outros código-golfes, mas não foi capaz de fazê-lo funcionar tanto no meu ambiente dev ou em eval.inJavaScript, 105 bytes
Experimente online!
Devido ao método de atribuir as linhas, isso tenderá a colocar mais na parte inferior, embora exista uma pequena chance de que a parte superior obtenha algumas.
fonte
Ruby, 52 bytes
Cria uma função anônima que recebe dois números inteiros como argumentos e retorna uma matriz de Strings:
fonte
Python 2, 81 bytes
Retorna uma lista de strings.
fonte
Javascript (ES7), 75 bytes
Eu pensei que era inteligente por ter os poderes da ideia 10 apenas para perceber que a maioria das respostas já estava usando isso.
fonte
AWK, 78 bytes
Leva 2 argumentos, primeiro o número de itens, depois o número de caixas. Inicia semeando o gerador de números aleatórios para que cada execução seja diferente. Em seguida, basta criar seqüências de caracteres em uma matriz, Exemplo de uso:
fonte
MATLAB,
10394 bytesCom formatação
Saída de amostra
Existem espaços em branco à direita, pois cada entrada da matriz é exibida com uma guia entre eles, mas isso deve ser aceitável conforme as especificações.
Isso me parece uma implementação muito simplista, por isso tenho certeza de que isso poderia ser melhorado.
Obrigado a @Luis Mendo por sugestões.
fonte
d=@(p)disp(char([1,~(1:p)]+48));for i=1:m-1;p=randi([0,n]);d(p);n=n-p;end;d(n)
a=
. Nesse caso, você não pode fazer isso, em princípio, porque funções anônimas não podem conter loops. Mas você pode usar o truque de colocar tudo em práticaeval('...')
. BTW, que é normalmente considerado uma prática feio e ruim em Matlab, mas aqui nós como abusar idiomas :-)Oitava ,
6254 bytesFunção anônima que recebe dois números e gera uma matriz 2D de caracteres
>
para caixas e*
objetos. Todos os resultados são igualmente prováveis.Experimente online!
fonte
TI-Basic,
6362 bytesEste critério tornou este programa muito mais fácil de escrever.
Exemplo de E / S:
Explicação:
fonte
MATLAB,
736458 bytesAtualização # 3
Eu preciso da classificação, ao que parece, pois, caso contrário, recebo números inteiros negativos. I fez substituir
disp(sprintf(...))
comfprintf(...)
agora, porém, assim que a resposta continua a ser 58 bytes.Atualização # 2:
Percebi que não precisava classificar a matriz e, na verdade, a classificação reduziria a média de números na matriz. Então eu apaguei a
sort(...)
parte. Observe que a saída permanece a mesma, portanto, não estou atualizando a "saída de amostra".Finalmente, fechando a resposta de oitava de Luis! : D
Atualização # 1:
Em vez de converter para string, apenas mostro números diretamente. Eu poderia reduzir para 58 bytes, removendo o
disp(...)
, mas depois recebo o extraans =
com apenas sprintf e não sei se isso é aceitável.Código inicial:
Graças a algumas sugestões de Luis , me livrei do loop na minha resposta anterior . Agora, primeiro crio uma matriz vertical de
m
números aleatórios que somamn
(diff([0;sort(randi(n,m-1,1));n])
), depois os uso como expoentes de 10, os converto em uma string, justificamos à esquerda e os exibimos.Eu poderia tecnicamente me livrar do disp (...) para salvar outros 6 bytes, mas um "ans" é impresso, o que pode violar as especificações. Também pode haver uma maneira de alterá-los para string e justificar à esquerda para obter o formato final desejado, por isso estou aberto a sugestões.
Saída de amostra:
Nota : Alterei minha função para uma função anônima aqui, com base em sugestões. Na saída de amostra, designei isso
a
para demonstrar. Espero que isso não viole as especificações, mas se isso acontecer, por favor me avise e eu vou alterá-lo.fonte
m
números inteiros aleatórios que somamn
, já que fiquei preso nessa parte por um longo tempo .. (Ainda não é possível adicionar mais de 2 links em minhas respostas, incluindo-o em um comentário)Empilhados , 29 bytes
Experimente online!
Comporta-se construindo uma matriz de
M
singletons contendo'|'
e adicionando'#'
a uma matriz escolhida aleatoriamenteN
.fonte
randin
usa o algoritmo Fisher-Yates internamente. (Este é o mesmo algoritmo que a resposta CJam usa FWIW)Python 2 ,
80 95 8988 bytesExperimente online!
fonte
Carvão , 19 bytes
Experimente online! Link é a versão detalhada do código. Explicação:
fonte