Recentemente, fiz um teste do HackerRank para uma posição de Ciência de Dados e entendi errado essa pergunta. Eu vim para 1/200
. Aqui está como:
Existem 50 combinações que tornarão isso verdade. (ou seja, {1,2}, {2,4}, {3,6} ... {50,100}). A probabilidade de um número específico ser escolhido é 1/100
. A probabilidade de que o conjunto específico seja escolhido é (1/100 * 1/100)
.
Uma vez que existem 50 conjuntos,
P=50*(1/100)*(1/100)=1/200
Obviamente, estou assumindo que 1 e 100 estão incluídos. Mas esta foi a resposta errada. Alguém pode me ajudar a entender meu erro?
probability
combinatorics
Jo Bennet
fonte
fonte
Respostas:
Seu primeiro erro é que existem 50 resultados, na verdade existem 100 (editar: veja o comentário abaixo para esclarecimentos). Isso ocorre porque obter (1,2) e (2,1) é o resultado de dois resultados separados, mas em cada caso o número maior é exatamente o dobro do número menor.
Portanto, o total de maneiras possíveis de obter isso é realmente fornecido pelo conjunto:
{(1,2), (2,1), (2,4), (4,2), ..., (50.100), (100,50)}
Que é uma lista de 100 resultados possíveis.
O número total de resultados possíveis é100×99
Como existem 100 números possíveis para escolher na primeira vez e, em seguida, 99 na segunda, pois eles devem ser distintos.
Portanto, a resposta é dada por:
Usando o mesmo argumento, é fácil provar que a probabilidade para o caso mais geral de escolher números de onde é algum número par positivo, é dada por:n1,2,...,n n
fonte
O "Hacker" no nome do teste sugere que tentemos encontrar uma solução orientada à computação.
Vamos, portanto, começar com um programa para enumeração de força bruta de (a) casos "favoráveis" em que um número inteiro é duas vezes o outro e (b) todos os casos possíveis. A resposta seria então a proporção deles. Eu codifiquei uma solução geral. Sua entrada é um número inteiro positivo
n
e sua saída é a probabilidade.(A prova de correção baseia-se no fato de que para qualquer número positivo .)i≠2i i
Este programa requer testes e até incrementos para cada iteração do loop interno. Portanto, ele precisa entre cálculos de e cada vez que o loop interno é executado, ou a geral. Esse é desempenho de : OK para pequeno como , mas terrível uma vez que excede ou mais.3 3 3n 6n 3n2 6n2 O(n2) n n=100 n 10000
Como hacker, uma das primeiras coisas que você deseja fazer é eliminar o desempenho quadrático, simplificando o loop interno (se possível). Para isso, passe sistematicamente pelas linhas do loop interno (conforme numerado) e observe o seguinte:
A linha 1 é executada quase uma vez para cada valor den−1
i
e, portanto,all
é incrementada vezes. Consequentemente, para o cálculo de , o loop over pode ser substituído pelo incremento de .all
j
all
n-1
A linha 2 é executada exatamente uma vez quando e, caso contrário, não é. Portanto, ele pode ser substituído pelo incremento de sempre que .2i≤n 1 2i≤n
all
A linha 3 é executada uma vez que
i
seja uniforme.Aqui está o programa transformado.
Podemos ir além e eliminar seu loop?
A linha 1 'é executada vezes. Portanto, é incrementado por .n
all
n*(n-1)
A linha 2 'é executada apenas quando . Uma maneira de contar isso é (o maior número inteiro menor ou igual a ).⌊ n / 2 ⌋ n / 22i≤n ⌊n/2⌋ n/2
A linha 3 'é executada apenas para valores pares de . Novamente, isso acontece vezes.⌊ n / 2 ⌋i ⌊n/2⌋
A segunda transformação do programa é:
Isso já é uma tremenda conquista: um algoritmo foi reduzido a um algoritmo (que pode ser considerado uma "fórmula fechada" para a resposta).O ( 1 )O(n2) O(1)
Finalmente, existem algumas transformações algébricas simples que podemos fazer rolando a inicialização (linha 0) para o primeiro uso de cada variável e combinando as linhas 2 '' e 3 '':
Nesse ponto, um humano poderia executar o programa. Vamos fazer isso com :n=100
A saída, portanto, é .1/99
Para resumir, um algoritmo de força bruta pode ser transformado sistematicamente usando regras simples de reescrita de programa em um programa elegante e elegante .O(1)
fonte
Primeiro de tudo, você está amostrando sem substituição. Assim, existem 100 * 99 resultados diferentes, por exemplo, (1,1) não é um resultado válido.
Em segundo lugar, a ordem não importa. O maior deve ser exatamente duas vezes, não o segundo. Portanto, remova os pares simétricos.
Assim, 50 de (100) * 99/2 são positivos ou 1/99
fonte