Esse problema é bastante fácil de fazer com força bruta. De fato, será razoavelmente rápido também a força bruta. Mas onde está a graça nisso?
O problema
Produza uma lista de todos os pares de números exclusivos de 5 dígitos que somam 121212
. No entanto, cada dígito decimal deve aparecer exatamente uma vez em qualquer número. Então, um par válido seria (98167, 23045)
. Mas um par inválido seria (23456, 97756)
porque 7, 5, 6
é repetido mais de uma vez e 1, 8, 0
não é usado. Existem exatamente 192 pares únicos.
Regras
Eficiência: Você pode fazer isso com força bruta. Mas isso é trivial de se fazer. Portanto, o verdadeiro desafio aqui é encontrar uma maneira de produzir com eficiência a lista de números.
Requisitos do código-fonte: Ele não pode armazenar a lista de números (ou qualquer parte dela). A sequência numérica deve ser gerada em tempo real.
Diverta-se!
fonte
Respostas:
Javascript
Hospedado em: http://ebusiness.hopto.org/findpairs.htm
Realização matemática: se você tem um par, outros 15 podem ser gerados trivialmente trocando dígitos entre os dois números, portanto, só procuro números em que os dígitos do primeiro são todos maiores que os dígitos do segundo e, em seguida, simplesmente produzo todas as permutações.
Começo com os dígitos menos significativos e gero a sequência como uma travessia em árvore, para cada etapa que afirma que o resultado intermediário está correto e que nenhum dígito é gasto duas vezes. Com esses métodos, a função precisa ser chamada apenas 50 vezes no total. Na minha máquina, o Chrome gera resultados de tempo de execução de tipicamente 2 ms.
fonte
C ++
http://www.ideone.com/Lr84g
fonte
10!/2
) e, em seguida, verificando se é compatível com 121212. Nada ruim para a primeira execução. Mas eu ainda estou curioso para saber se podemos obter mais eficiente ...(51430, 69872)
par válido. Você pode pré-armazenar a lista de dígitos (0123456789
) e a soma (121212
).Python 2.
É bastante eficiente porque constrói os números (o loop mais interno é executado 4570 vezes no total) e muito curto porque joguei um pouco (201 caracteres), mas não tenho muita certeza se quero explicar isso :)
Os valores retornados são bastante peculiares: ligue
w
com uma tupla vazia e você obterá um iterador de 10 tuplas. Estas 10 tuplas são os dígitos dos dois números, infelizmente para trás e alternando , ou seja, a tuplarepresenta os números 51430 e 69782.
Teste:
Aqui está a versão não destruída:
fonte
C
Isso percorre todos os pares de números de 5 dígitos que somam 121212 (significando 39393 iterações, ou ~ 1/46 das iterações usadas pela resposta de fR0DDY ). Para cada par, ele forma uma máscara de bits dos dígitos em cada número e depois vê se OR para 0b1111111111.
fonte
Javascript (481)
http://jsfiddle.net/XAYr3/4/
Ideia básica: gere combinações de dígitos válidos que possam ser usados na coluna mais à direita. Por exemplo, (0,2), (3,9), (4,8), (5,7). Para cada combinação, encontre recursivamente pares que funcionam para o dígito da direita, sem duplicar os dígitos no primeiro par. Faça o recursão até que um par de números de 5 dígitos tenha sido gerado. Combine todos esses resultados em uma única matriz, e a lista é de 192 elementos. Acredito que isso deva exigir o menor número possível de iterações, mas toda a alocação / desalocação de array o torna praticamente ineficiente.
Meus testes de contagem mostram que a função
f
é chamada 310 vezes, o loop internoi
é executado 501 vezes no total (em todas as chamadas paraf
) e o loop interno e internoj
é executado 768 vezes no total (em tudo).fonte
Python, 171 caracteres
O código mantém a invariante que
x
,y
temc
dígitos e que todos os dígitos não utilizados estão no conjuntod
.A rotina
R
é chamada um total de 841 vezes, o que é bastante eficiente.fonte
C ++
http://www.ideone.com/Lr84g
fonte