Você tem n
moedas cujo peso é -1 ou 1. Cada uma é rotulada de 0
a n-1
para que você possa diferenciá-las. Você também tem um dispositivo de pesagem (mágico). No primeiro turno, você pode colocar quantas moedas quiser no dispositivo de pesagem, capaz de medir tanto pesos negativos quanto positivos, e ele informará exatamente quanto pesam.
No entanto, há algo realmente estranho no dispositivo de pesagem. Se você colocar moedas x_1, x_2, ..., x_j
no dispositivo pela primeira vez, na próxima vez em que tiver que colocar moedas (x_1+1), (x_2+1) , ..., (x_j+1)
na balança, com a exceção de que você obviamente não poderá colocar uma moeda com número maior que n-1
. Não é só isso: para cada nova pesagem você escolhe se também deseja colocar moedas 0
na balança.
Sob essa regra, qual é o menor número de pesagens que sempre informará exatamente quais moedas pesam 1 e quais pesam -1?
Claramente, você poderia simplesmente colocar moedas 0
no dispositivo na primeira curva e depois seriam necessárias n
pesagens exatas para resolver o problema.
Línguas e bibliotecas
Você pode usar qualquer idioma ou biblioteca que desejar (que não foi projetada para este desafio). No entanto, eu gostaria de poder testar seu código, se possível, para que você possa fornecer instruções claras sobre como executá-lo no Ubuntu que seriam muito apreciadas.
Ponto
Para um dado, n
sua pontuação é n
dividida pelo número de pesagens necessárias no pior caso. Pontuações mais altas são, portanto, melhores. Não há entrada para esse quebra-cabeça, mas seu objetivo é encontrar um n
para o qual você possa obter a maior pontuação.
Se houver um empate, a primeira resposta vence. Na situação extremamente improvável em que alguém encontra uma maneira de obter uma pontuação infinita, essa pessoa vence imediatamente.
Tarefa
Sua tarefa é simplesmente escrever um código que obtenha a maior pontuação. Seu código terá que escolher an inteligente e também otimizar o número de pesagens para isso n
.
Entradas principais
4/37/5 em Python por Sarge Borsch- 26/14 em Java por Peter Taylor
fonte
x_i
: podemos ter, por exemplo, uma primeira pesagem de (x_1, x_2, x_3) = (3, 2, 7) e a segunda pesagem (4, 3, 8) ou ( 0, 4, 3, 8). Os rótulos das moedas não precisam ser consecutivos e o índicei
inx_i
não se refere ao rótulo da moeda.Respostas:
C ++, pontuação
23/1225/1327/1428/14 = 231/15As soluções da propriedade Matrix X revisitadas (ou a Alegria de X) são diretamente utilizáveis como soluções para esse problema. Por exemplo, a solução de 31 linhas e 15 colunas:
a linha N representa quais moedas você coloca na balança para a medição N. Quaisquer que sejam os resultados da ponderação obtida, obviamente existe um conjunto de valores de moedas que dão esse peso. Se houver outra combinação também (a solução não é única), considere como elas diferem. Você deve substituir um conjunto de ponderação
1
de moedas por ponderação de moedas-1
. Isso fornece um conjunto de colunas que correspondem a esse flip. Também há um conjunto de moedas-1
que você substitui1
. Esse é outro conjunto de colunas. Como as medições não mudam entre as duas soluções, isso significa que a soma das colunas dos dois conjuntos deve ser a mesma. Mas as soluções para a propriedade Matrix X revisitadas (ou a Alegria de X) são exatamente essas matrizes em que esses conjuntos de colunas não existem; portanto, não há duplicatas e cada solução é única.Cada conjunto real de medições pode ser descrito por alguma
0/1
matriz. Porém, mesmo que alguns conjuntos de colunas somam os mesmos vetores, pode ser que os sinais dos valores das moedas da solução candidata não correspondam exatamente a esse conjunto. Portanto, não sei se matrizes como a acima são ótimas. Mas pelo menos eles fornecem um limite inferior. Portanto, a possibilidade de 31 moedas poderem ser feitas em menos de 15 medições ainda está aberta.Observe que isso só é verdade para uma estratégia não fixa em que sua decisão de colocar moedas
0
na balança depende do resultado das ponderações anteriores. Caso contrário, você terá soluções em que os sinais das moedas correspondem aos conjuntos que possuem a mesma soma da coluna.fonte
Python 2, pontuação = 1,0
Essa é a pontuação mais fácil, caso ninguém encontre uma pontuação melhor (duvidosa).
n
pesagens para cada umn
.Eu importei
antigravity
para que o programa possa trabalhar com pesos negativos.fonte
antigravity
é basicamente um no-op, certo?Pontuação = 26/14 ~ = 1.857
Salvar como
LembikWeighingOptimisation.java
, compilar comojavac LembikWeighingOptimisation.java
, executar comojava LembikWeighingOptimisation
.Muito obrigado a Mitch Schwartz por apontar um bug na primeira versão do quick-rejeitar.
Isso usa algumas técnicas bastante básicas que não posso justificar rigorosamente. Forças brutas, mas apenas para iniciar operações de pesagem que usam no máximo metade das moedas: seqüências que usam mais da metade das moedas não são diretamente transferíveis para as pesagens complementares (porque não sabemos o peso total), mas em um nível ondulado, deve haver aproximadamente a mesma quantidade de informação. Ele também itera através do início das pesagens na ordem do número de moedas envolvidas, com base nessa maneira que cobre as pesagens dispersas (que esperamos fornecer informações sobre a extremidade superior relativamente cedo) sem primeiro rastejar por um cacho que começa com um subconjunto denso em a extremidade inferior.
A
MaskRange
classe é uma grande melhoria na versão anterior em termos de uso de memória e evita que o GC seja um gargalo.fonte
Python 3,
pontuação = 4/3 = 1,33… (N = 4)pontuação = 1,4 (N = 7)Atualização: implementou a pesquisa de força bruta no conjunto de solucionadores "estáticos" e obteve um novo resultado
Eu acho que pode ser melhorado ainda mais, procurando solucionadores dinâmicos, que podem usar os resultados de ponderação para outras decisões.
Aqui está um código Python que pesquisa todos os solucionadores estáticos em busca de valores pequenos
n
(esses sempre pesam os mesmos conjuntos de moedas, portanto, o nome "estático") e determina o número de etapas do pior caso, simplesmente verificando se seus resultados de medição permitem apenas uma moeda correspondente definido em todos os casos. Além disso, ele registra a melhor pontuação encontrada até o momento e solucionadores de ameixas precoces, que mostraram que são definitivamente piores do que os encontrados anteriormente. Essa foi uma otimização importante, caso contrário, eu não poderia esperar por esse resultado comn
= 7. (Mas claramente ainda não está muito otimizado)Sinta-se à vontade para fazer perguntas se não estiver claro como isso funciona…
A saída:
Esta linha
(StaticSolver({0,2}, {0,1,3}, {0,1,2,4}, {1,2,3,5}, {0,2,3,4,6}), 5), score = 7/5 = 1.4
descobre o melhor solucionador encontrado. Os números entre{}
chaves são os índices de moedas para colocar no dispositivo de ponderação a cada passo.fonte