Era uma noite quente de verão ...
quando meu carro estúpido decidiu parar no meio da estrada no meu caminho de volta do supermercado. Empurrei-o para a linha lateral e decidi ir para casa. Abri o porta-malas para tirar as compras e as coisas restantes. Foi então que notei que os itens não estavam uniformemente ensacados. Algumas sacolas tinham itens mais pesados, enquanto outras tinham poucas coisas mais leves - algumas até tinham uma mistura desses itens. Para facilitar o transporte, decidi agrupar tudo em duas malas e fazer com que seus pesos fossem o mais próximo possível um do outro.
Seu objetivo
é me ajudar a reorganizar os itens em duas sacolas de compras, de modo que a diferença entre as duas seja o mais próxima possível de zero.
Matematicamente:
PESO MÃO ESQUERDA - PESO MÃO DIREITA ≈ 0
Exemplo
Se eu tivesse apenas 2 itens, Pão e manteiga de amendoim, e o peso do pão for 250 gramas e a manteiga de amendoim for 150 gramas, a melhor maneira é carregá-los separadamente com as duas mãos.
W LH - W RH = W (PÃO) - W (P. MANTEIGA)
250 - 150 = 100
A outra possibilidade é:
W (PÃO, P. MANTEIGA) - W (mão vazia) = (250 + 150) - 0 = 400
Isso não é melhor do que o nosso primeiro caso, então você deve ir com o primeiro.
Seu código deve
- anote números indicando pesos de itens na sacola de compras. As unidades não são importantes, mas devem ser as mesmas (idealmente quilogramas ou gramas). A entrada pode ser feita uma por uma ou todas de uma vez. Você pode restringir a contagem total a 20 itens, no máximo, se desejar.
- Você escolhe o formato / tipo de entrada, mas nada deve estar presente além dos pesos.
- Qualquer idioma é permitido, mas atenha-se às bibliotecas padrão.
- Exibir saída. Novamente, você pode escolher o formato, mas explique o formato na sua postagem. ou seja, como podemos saber quais são os itens à esquerda e quais são os itens à direita.
Pontos
- O menor código vence.
Sugestão
Os dois possíveis algoritmos em que pude pensar são diferenciação (mais rápida) e permutações / combinações (mais lenta). Você pode usar esse ou qualquer outro algoritmo que faça o trabalho.
Respostas:
Pitão, 9 bytes
Formatos de entrada, saída:
Demonstração.
Isso funciona porque
y
retorna os subconjuntos em uma ordem em que cada subconjunto e seu complemento são eqüidistantes do centro. Como a soma de um subconjunto e a soma de seu complemento sempre serão equidistantes do centro, a lista a seguirosNyQ
também terá essa propriedade. Assim, os dois elementos centrais deosNyQ
são complementos e devem ter uma divisão ideal. Extraímos o primeiro desses dois elementos e o imprimimos.fonte
s
que fez parar de funcionar. As pessoas não gostaram da mudança, e seu comentário foi o empurrão final que eu precisava para mudar de volta.Pyth, 16
Isso leva as entradas como uma lista pitônica no STDIN. A saída é uma lista de 2 listas, com a primeira lista sendo os itens em uma bolsa e a segunda lista representando os itens na segunda bolsa. Esse bruto força todas as combinações, por isso será executado muito lentamente (ou ficará sem memória) para entradas grandes.
Experimente online aqui
Para suportar o tratamento de apenas uma entrada, isso aumenta para 17:
Isso imprimirá os valores que aparecem em uma mão.
fonte
[[2], [1], [1]]
, mas acho que funciona, devido exatamente a como./
funciona.[[x], []]
?CJam,
1918 bytesEssa é uma função anônima que exibe uma matriz de números inteiros da pilha e retorna uma matriz de números inteiros separados por um espaço.
Obrigado a @ jimmy23013 por seu
:*
truque engenhoso , que salvou 1 byte.Experimente on-line no intérprete CJam .
Como funciona
Denotar o peso total dos sacos de compra com W . Então, se as malas de uma das mãos pesarem L / 2 - D / 2 , as da outra mão deverão pesar e L - (L / 2 - D / 2) = L / 2 + D / 2 .
Estamos tentando minimizar a diferença D . Mas (W / 2 - D / 2) (W / 2 + D / 2) = W ^ 2/4 - D ^ 2/4 , que se torna maior à medida que D se torna menor.
Assim, o produto máximo corresponde à diferença mínima.
fonte
:*
...W=
deveria funcionar.Python 2.7,
161, 160código
Algoritmo
Verifique se cada combinação está se aproximando da metade do peso total. Repita e encontre o melhor.
entrada
saída
A tupla exibida vai em uma mão, as que não são exibidas vão na outra (não é contra as regras).
fonte
from itertools import*
JavaScript ( ES6 ) 117
Usando uma máscara de bits para tentar todas as divisões possíveis, é limitado a 31 itens (ok com as regras). Como a resposta ref, ela gera apenas uma mão. Nota: eu procuro a diferença mínima> = 0 para evitar Math.abs, pois para cada min <0 existe outro> 0, apenas trocando de mãos.
Para testar: execute o snippet no Firefox, insira uma lista de números separados por vírgula ou espaço.
fonte
Haskell, 73 bytes
Produz uma lista de itens em uma mão. Os elementos ausentes vão para o outro lado.
Uso:
f [7,7,7,10,11]
->[7,7,7]
Para todas as subsequências
s
da lista de entrada,l
calcule o valor absoluto da diferença de peso entres
e os elementos ausentes del
. Encontre o mínimo.fonte
Haskell, 51 bytes
O formato de saída é que os pesos da esquerda são positivos e os da direita são negativos.
Para gerar todas as divisões possíveis, usamos
mapM(\x->[x,-x])l
para negar todos os subconjuntos possíveis de elementos. Em seguida,((,)=<<abs.sum)
rotule cada um com sua soma absoluta esnd$minimum$((,)=<<abs.sum)
use o menor elemento rotulado.Não consegui obtê-lo sem pontos por causa de problemas de verificação de tipo.
fonte
snd.minimum.map((,)=<<abs.sum).mapM(\x->[x,-x])
. São 47 bytes. (embora eu tenha uma versão mais antiga instalada ...)R (234)
uma solução mais longa e mais lenta com R.
Função:
Entrada esperada - vetor com os pesos.
Saída prevista - vetor com os pesos de uma mão.
Exemplo
Versão do código legível por humanos:
fonte
Axioma, 292 bytes
Uma aplicação de força bruta. Isso minimizaria o conjunto
porque se é mínimo
também seria mínimo
onde (reduzir (+, a) -reduzir (+, r)) e reduzir (+, r) são o peso 2 de dois sacos. (Mas essa última fórmula não me parece mínima, na aplicação). Ungolf e resultados
fonte