Vous avez des n
pièces qui pèsent chacune -1 ou 1. Chacune est étiquetée de 0
à n-1
afin que vous puissiez distinguer les pièces. Vous avez également un appareil de pesée (magique). Au premier tour, vous pouvez mettre autant de pièces que vous le souhaitez sur l'appareil de pesage qui est capable de mesurer les poids négatifs et positifs et il vous dira exactement combien ils pèsent.
Cependant, le dispositif de pesage a quelque chose de vraiment étrange. Si vous mettez des pièces x_1, x_2, ..., x_j
sur l'appareil la première fois, la prochaine fois, vous devrez placer des pièces (x_1+1), (x_2+1) , ..., (x_j+1)
sur la balance, à l'exception que vous ne pouvez bien sûr pas mettre une pièce numérotée plus haut que n-1
. Non seulement cela, pour chaque nouvelle pesée, vous pouvez choisir si vous souhaitez également mettre des pièces 0
sur la balance.
Selon cette règle, quel est le plus petit nombre de pesées qui vous dira toujours exactement quelles pièces pèsent 1 et lesquelles pèsent -1?
De toute évidence, vous pourriez simplement mettre de la monnaie 0
sur l'appareil au premier tour, puis il faudrait exactement des n
pesées pour résoudre le problème.
Langues et bibliothèques
Vous pouvez utiliser n'importe quelle langue ou bibliothèque que vous aimez (qui n'a pas été conçue pour ce défi). Cependant, j'aimerais pouvoir tester votre code si possible, donc si vous pouvez fournir des instructions claires sur la façon de l'exécuter dans Ubuntu, ce serait très apprécié.
But
Pour une donnée, n
votre score est n
divisé par le nombre de pesées dont vous avez besoin dans le pire des cas. Des scores plus élevés sont donc meilleurs. Il n'y a aucune entrée dans ce puzzle, mais votre objectif est de trouver celui n
pour lequel vous pouvez obtenir le meilleur score.
S'il y a égalité, la première réponse l'emporte. Dans la situation extrêmement improbable où quelqu'un trouve un moyen d'obtenir un score infini, cette personne gagne immédiatement.
Tâche
Votre tâche consiste simplement à écrire du code qui obtient le meilleur score. Votre code devra à la fois choisir astucieusement un n puis optimiser également le nombre de pesées pour cela n
.
Entrées principales
4/37/5 en Python par Sarge Borsch- 26/14 à Java par Peter Taylor
la source
x_i
: On peut avoir par exemple une première pesée de (x_1, x_2, x_3) = (3, 2, 7), puis la deuxième pesée peut être soit (4, 3, 8) ou ( 0, 4, 3, 8). Les étiquettes de pièces ne doivent pas être consécutives, et l'indicei
enx_i
ne se réfère pas à l'étiquette de la pièce.Réponses:
C ++, Score
23/1225/1327/1428/14 = 231/15Les solutions de la propriété Matrix X revisitées (ou la joie de X) sont directement utilisables comme solutions à ce problème. Par exemple, la solution de 31 lignes 15 colonnes:
la ligne N représente les pièces que vous mettez sur l'échelle pour la mesure N. Quels que soient les résultats de la pondération que vous obtenez, il existe évidemment un ensemble de valeurs de pièces qui donne ce poids. S'il existe également une autre combinaison (la solution n'est pas unique), considérez en quoi elles diffèrent. Vous devez remplacer un ensemble de pondération des pièces
1
par une pondération des pièces-1
. Cela donne un ensemble de colonnes qui correspondent à ce flip. Il existe également un ensemble de pondération des pièces-1
que vous remplacez1
. C'est un autre ensemble de colonnes. Parce que les mesures ne changent pas entre les deux solutions, cela signifie que les sommes des colonnes des deux ensembles doivent être les mêmes. Mais les solutions à la propriété Matrix X revisitées (ou la joie de X) sont exactement ces matrices où de tels ensembles de colonnes n'existent pas, il n'y a donc pas de doublons et chaque solution est unique.Chaque ensemble réel de mesures peut être décrit par une
0/1
matrice. Mais même si certains ensembles de colonnes totalisent les mêmes vecteurs, il se pourrait que les signes des valeurs des pièces de la solution candidate ne correspondent pas exactement à un tel ensemble. Je ne sais donc pas si des matrices telles que celle ci-dessus sont optimales. Mais au moins, ils fournissent une limite inférieure. Ainsi, la possibilité de faire 31 pièces en moins de 15 mesures est toujours ouverte.Notez que cela n'est vrai que pour une stratégie non fixe où votre décision de placer des pièces
0
sur la balance dépend du résultat des pondérations précédentes. Sinon, vous aurez des solutions où les signes des pièces correspondent aux ensembles qui ont la même somme de colonne.la source
Python 2, score = 1,0
C'est le score facile, au cas où personne ne trouverait un meilleur score (douteux).
n
pesées pour chacunn
.J'ai importé
antigravity
pour que le programme fonctionne avec des poids négatifs.la source
antigravity
est fondamentalement un no-op, non?Score = 26/14 ~ = 1,857
Enregistrer sous
LembikWeighingOptimisation.java
, compiler sousjavac LembikWeighingOptimisation.java
, exécuter sousjava LembikWeighingOptimisation
.Un grand merci à Mitch Schwartz pour avoir signalé un bogue dans la première version du rejet rapide.
Cela utilise des techniques assez basiques que je ne peux pas justifier rigoureusement. Il force brutalement, mais uniquement pour démarrer des opérations de pesage qui utilisent au plus la moitié des pièces: les séquences qui utilisent plus de la moitié des pièces ne sont pas directement transférables aux pesées complémentaires (car on ne connaît pas le poids total), mais à un niveau ondulé, il devrait y avoir à peu près la même quantité d'informations. Il réitère également les pesées de départ en fonction du nombre de pièces impliquées, en partant du principe qu'il couvre les pesées dispersées (qui, espérons-le, donnent des informations sur l'extrémité supérieure relativement tôt) sans d'abord parcourir un groupe qui commence par un sous-ensemble dense à l'extrémité inférieure.
La
MaskRange
classe est une amélioration massive par rapport à la version précédente en termes d'utilisation de la mémoire, et supprime le GC d'être un goulot d'étranglement.la source
Python 3,
score = 4/3 = 1,33… (N = 4)score = 1,4 (N = 7)Mise à jour: implémentation de la recherche par force brute dans un ensemble de solveurs "statiques" et obtention d'un nouveau résultat
Je pense qu'il peut être encore amélioré en recherchant des solveurs dynamiques, qui peuvent utiliser les résultats de pondération pour d'autres décisions.
Voici un code Python qui recherche dans tous les solveurs statiques de petites
n
valeurs (ces solveurs pèsent toujours les mêmes ensembles de pièces, d'où le nom "statique") et détermine leur pire nombre d'étapes en vérifiant simplement que leurs résultats de mesure n'autorisent qu'une seule pièce correspondante fixé dans tous les cas. En outre, il garde la trace du meilleur score trouvé jusqu'à présent et des premiers solveurs de pruneaux qui avaient montré qu'ils étaient nettement pires que ceux qui avaient été trouvés auparavant. Ce fut une optimisation importante, sinon je ne pouvais pas attendre ce résultat avecn
= 7. (Mais il est clair qu'il n'est toujours pas très bien optimisé)N'hésitez pas à poser des questions si vous ne savez pas comment cela fonctionne…
Le résultat:
Cette ligne
(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
découvre le meilleur solveur trouvé. Les chiffres entre{}
accolades sont les indices des pièces à mettre sur le dispositif de pondération à chaque étape.la source