Ce fut une chaude soirée d'été ...
quand ma stupide voiture a décidé de tomber en panne au milieu de la route sur le chemin du retour du supermarché. Je l'ai poussé à l'écart et j'ai décidé de rentrer à pied. J'ai ouvert le coffre pour sortir l'épicerie et le reste. C'est alors que j'ai remarqué que les articles n'étaient pas uniformément emballés. Certains sacs avaient des articles plus lourds tandis que d'autres avaient peu de choses plus légères - certains avaient même un mélange de ces articles. Pour me faciliter le transport, j'ai décidé de tout regrouper dans deux sacs et de faire leurs poids le plus près possible les uns des autres.
Ton but
est de m'aider à réorganiser les articles dans deux sacs de manière à ce que la différence entre les deux sacs soit aussi proche que possible de zéro.
Mathématiquement:
POIDS MAIN GAUCHE - POIDS MAIN DROITE ≈ 0
Exemple
Si je n'avais que 2 articles, du pain et du beurre d'arachide, et que le poids du pain est de 250 grammes et que le beurre d'arachide est de 150 grammes, la meilleure façon est de les transporter séparément à deux mains.
W LH - W RH = W (PAIN) - W (P.BUTTER) 250-150
= 100
L'autre possibilité est:
W (PAIN, BEURRE) - W (main vide) = (250 + 150) - 0 = 400
Ce n'est pas mieux que notre premier cas, vous devriez donc opter pour le premier.
Votre code devrait
- prendre des entrées de nombres indiquant le poids des articles dans le panier. Les unités ne sont pas importantes, mais elles devraient être les mêmes (idéalement des kilogrammes ou des grammes). L'entrée peut être effectuée une par une ou toutes en même temps. Vous pouvez limiter le nombre total à 20 articles maximum, si vous le souhaitez.
- Le format / type d'entrée est à vous de choisir, mais rien d'autre ne doit être présent autre que les poids.
- N'importe quelle langue est autorisée, mais respectez les bibliothèques standard.
- Afficher la sortie. Encore une fois, vous êtes libre de choisir le format, mais expliquez le format dans votre message. c'est-à-dire, comment pouvons-nous savoir lesquels sont des éléments de gauche et lesquels sont des éléments de droite.
Points
- Le code le plus court gagne.
Allusion
Les deux algorithmes possibles auxquels je pourrais penser sont la différenciation (plus rapide) et les permutations / combinaisons (plus lent). Vous pouvez utiliser ces algorithmes ou tout autre algorithme qui fait le travail.
Réponses:
Pyth, 9 octets
Formats d'entrée et de sortie:
Manifestation.
Cela fonctionne car
y
renvoie les sous-ensembles dans un ordre tel que chaque sous-ensemble et son complément sont équidistants du centre. Puisque la somme d'un sous-ensemble et la somme de son complément seront toujours équidistantes du centre, la liste suivanteosNyQ
aura également cette propriété. Ainsi, les deux éléments centraux deosNyQ
sont complémentaires et doivent avoir une répartition optimale. Nous extrayons le premier de ces deux éléments et l'imprimons.la source
s
qui l'a empêché de fonctionner. Les gens n'ont pas aimé le changement, et votre commentaire a été le dernier coup de pouce dont j'avais besoin pour le modifier.Pyth, 16
Cela prend les entrées comme une liste pythonique sur STDIN. Le résultat est une liste de 2 listes avec la première liste étant les articles dans un sac, et la deuxième liste représentant les articles dans le deuxième sac. Cette brute force toutes les combinaisons, elle s'exécutera donc très lentement (ou manquera de mémoire) pour les entrées volumineuses.
Essayez-le en ligne ici
Pour prendre en charge la gestion d'une seule entrée, cela va jusqu'à 17:
Cela imprimera les valeurs qui vont dans une main.
la source
[[2], [1], [1]]
, mais je pense que cela fonctionne, en raison de la façon exacte dont./
fonctionne.[[x], []]
,?CJam,
1918 octetsIl s'agit d'une fonction anonyme qui extrait un tableau d'entiers de la pile et renvoie un tableau d'entiers séparés par un espace.
Merci à @ jimmy23013 pour son astucieux
:*
tour qui a sauvé 1 octet.Essayez-le en ligne dans l' interpréteur CJam .
Comment ça marche
On note le poids total des sacs à provisions avec W . Ensuite, si les sacs d'une des mains pèsent W / 2 - D / 2 , ceux de l'autre main doivent peser et W - (W / 2 - D / 2) = W / 2 + D / 2 .
Nous essayons de minimiser la différence D . Mais (W / 2 - D / 2) (W / 2 + D / 2) = W ^ 2/4 - D ^ 2/4 , qui devient plus grand lorsque D devient plus petit.
Ainsi, le produit maximal correspond à la différence minimale.
la source
:*
...W=
devrait fonctionner.Python 2.7,
161, 160code
Algorithme
Vérifiez si chaque combinaison se rapproche de la moitié du poids total. Itérer et trouver le meilleur.
contribution
sortie
Le tuple affiché va dans une main, ceux qui ne sont pas affichés vont dans l'autre (ce n'est pas contraire aux règles).
la source
from itertools import*
JavaScript ( ES6 ) 117
Utiliser un masque de bits pour essayer toutes les divisions possibles, il est donc limité à 31 éléments (ok avec les règles). Comme la réponse ref, elle ne produit qu'une seule main. Remarque: je cherche la différence minimale> = 0 pour éviter Math.abs, car pour chaque min <0, il y a un autre> 0, juste en échangeant des mains.
Pour tester: exécutez l'extrait dans Firefox, entrez une liste de nombres séparés par des virgules ou des espaces.
la source
Haskell, 73 octets
Affiche une liste d'éléments dans une main. Les éléments manquants vont en revanche.
Utilisation:
f [7,7,7,10,11]
->[7,7,7]
Pour toutes les sous-séquences
s
de la liste d'entrée,l
calculez la valeur absolue de la différence de poids entres
et les éléments manquants del
. Trouvez le minimum.la source
Haskell, 51 octets
Le format de sortie est que les poids à gauche sont positifs et les poids à droite sont négatifs.
Pour générer chaque fractionnement possible, nous utilisons
mapM(\x->[x,-x])l
pour annuler tous les sous-ensembles d'éléments possibles. Ensuite,((,)=<<abs.sum)
étiquetez chacun avec sa somme absolue etsnd$minimum$((,)=<<abs.sum)
prenez le plus petit élément étiqueté.Je n'ai pas pu l'obtenir sans point en raison de problèmes de vérification de type.
la source
snd.minimum.map((,)=<<abs.sum).mapM(\x->[x,-x])
. C'est 47 octets. (même si j'ai une ancienne version installée ...)R (234)
une solution plus longue et plus lente avec R.
Une fonction:
Entrée attendue - vecteur avec les poids.
Sortie attendue - vecteur avec les poids pour une main.
Exemple
Version de code lisible par l'homme:
la source
Axiome, 292 octets
Une application de force brute. Cela minimiserait l'ensemble
parce que si c'est minimum
ce serait aussi un minimum
où (réduire (+, a) -réduire (+, r)) et réduire (+, r) sont les 2 poids de deux sacs (mais cette dernière formule ne me trouve pas le minimum, dans l'application). Ungolf et résultats
la source