मेरे शॉपिंग बैग ले जाने में मेरी मदद करें


26

यह एक गर्म गर्मी की शाम थी ...

जब मेरी बेवकूफ कार ने सुपरमार्केट से वापस अपने रास्ते पर सड़क के बीच में टूटने का फैसला किया। मैंने इसे किनारे पर धकेल दिया और घर चलने का फैसला किया। मैंने किराने और बचे हुए सामान को बाहर निकालने के लिए ट्रंक खोला। यह तब था जब मैंने देखा कि आइटम समान रूप से बैग में नहीं थे। कुछ थैलों में अधिक भारी सामान था जबकि कुछ में हल्का सामान था - कुछ में ऐसी वस्तुओं का मिश्रण भी था। मेरे लिए इसे ले जाना आसान बनाने के लिए, मैंने सब कुछ दो बैग में समूहित करने और जितना संभव हो एक दूसरे के करीब उनके वजन करने का फैसला किया।

मैंने नगर की ओर रुख किया

आपका लक्ष्य

मुझे दो शॉपिंग बैग में आइटम को इस तरह से पुनर्व्यवस्थित करने में मदद करना है कि दोनों बैग के बीच अंतर शून्य के करीब हो।
गणितीय:

वजन छोड़ना हाथ - वजन सही AND 0

उदाहरण

अगर मेरे पास केवल 2 आइटम, ब्रेड और पीनट बटर, और ब्रेड का वजन 250 ग्राम और पीनट बटर 150 ग्राम है, तो सबसे अच्छा तरीका है कि आप उन्हें दो हाथों में अलग-अलग ले जाएं।

W LH - W RH = W (BREAD) - W (P.BUTTER)
250 - 150 = 100

अन्य संभावना है:

W (BREAD, P.BUTTER) - W (खाली हाथ) = (250 + 150) - 0 = 400

यह हमारे पहले मामले से बेहतर नहीं है, इसलिए आपको पहले वाले के साथ जाना चाहिए।

आपका कोड चाहिए

  1. शॉपिंग बैग में वस्तुओं के वजन का संकेत देने वाले नंबरों का इनपुट लें। इकाइयां महत्वपूर्ण नहीं हैं, लेकिन उन्हें समान होना चाहिए (आदर्श रूप से किलोग्राम या ग्राम)। इनपुट एक-एक करके या एक ही बार में किया जा सकता है। आप चाहें तो कुल गिनती को अधिकतम 20 आइटम तक सीमित कर सकते हैं।
  2. इनपुट प्रारूप / प्रकार का चयन करने के लिए आप पर निर्भर है, लेकिन वजन के अलावा और कुछ भी मौजूद नहीं होना चाहिए।
  3. किसी भी भाषा की अनुमति है, लेकिन मानक पुस्तकालयों से चिपके रहते हैं।
  4. आउटपुट प्रदर्शित करें। फिर से, आप प्रारूप का चयन करने के लिए स्वतंत्र हैं, लेकिन अपनी पोस्ट में प्रारूप की व्याख्या करें। यानी, हम यह कैसे बता सकते हैं कि कौन से व्यक्ति बाएं हाथ की वस्तु हैं और कौन से दाहिने हाथ की वस्तुएं हैं।

अंक

  1. सबसे छोटा कोड जीतता है।

संकेत

दो संभावित एल्गोरिदम जो मैं सोच सकता था कि वे भेदभाव (तेज) और क्रमपरिवर्तन / संयोजन (धीमे) हैं। आप इन या किसी अन्य एल्गोरिथ्म का उपयोग कर सकते हैं जो काम करता है।


5
मुझे नियम 2 पसंद है, यह लचीला है, लेकिन धोखा देने की अनुमति नहीं देता है
edc65

2
आपने मूल रूप से knapsack समस्या को पुनः प्राप्त किया है। en.wikipedia.org/wiki/Knapsack_problem
स्पर्स

थैंक्यू @Sparr I wicked smaat (सच में नहीं)
Renae Lider

2
यह समस्या इस साइट के लिए बहुत व्यावहारिक और यथार्थवादी है।
मोनिका iamnotmaynard

जवाबों:


15

अजगर, 9 बाइट्स

ehc2osNyQ

इनपुट, आउटपुट स्वरूप:

Input:
[1, 2, 3, 4, 5]
Output:
[1, 2, 4]

प्रदर्शन।

ehc2osNyQ
             Q = eval(input())
       yQ    Take all subsets of Q.
    osN      Order those element lists by their sums.
  c2         Cut the list in half.
eh           Take the last element of the first half.

यह काम करता है क्योंकि yसबसेट को इस तरह से लौटाता है कि प्रत्येक उपसमुच्चय और उसके पूरक केंद्र के समतुल्य हैं। चूंकि एक उपसमुच्चय का योग और इसके पूरक का योग हमेशा केंद्र से समान होगा, इसके बाद की सूची में osNyQभी यह संपत्ति होगी। इस प्रकार, केंद्र दो तत्व osNyQहैं जो पूरक हैं, और उनके पास एक इष्टतम विभाजन होना चाहिए। हम उन दो तत्वों में से पहला निकालते हैं और इसे प्रिंट करते हैं।


ओपी द्वारा उत्तर केवल एक हाथ में बैग प्रिंट करता है, इसलिए आपके 9 बाइट समाधान पर बधाई देता है।
डेनिस

आपका लेखन इनपुट के लिए रोक दिया गया है [7 7 Tra for १० ११] ट्रेसबैक (सबसे हालिया कॉल अंतिम): फ़ाइल "pyth.py", लाइन ""२, <मॉड्यूल> फ़ाइल" <string> ", पंक्ति ४, में <मॉड्यूल> फ़ाइल "aapp/macros.py", पंक्ति 865, क्रम में TypeError: अवर्णनीय प्रकार: int () <सूची ()
RosLuP

@RosLuP यह उस समय काम आया, मैंने इस बारे में कुछ बदला sकि इससे काम करना बंद हो गया। लोगों को बदलाव पसंद नहीं आया, और आपकी टिप्पणी अंतिम धक्का थी जिसे मुझे इसे वापस बदलने की आवश्यकता थी।
isaacg

टिप्पणी कोड में यह "क्यू का सबसेट" नहीं होना चाहिए, लेकिन "क्यू का
सबलिस्ट

@RosLuP मैं असहमत हूं - एक सबलिस्ट आमतौर पर सन्निहित है। इस तरह की चीज़ के लिए सबसेट और लेटरनेस दो शब्द हैं।
isaacg

6

अजगर, १६

ho.a-FsMNs./M.pQ

यह इनपुट को STDIN पर पाइथोनिक लिस्ट के रूप में लेता है। आउटपुट 2 सूचियों की एक सूची है जिसमें पहली सूची एक बैग में आइटम है, और दूसरी सूची दूसरे बैग में आइटम का प्रतिनिधित्व करती है। यह ब्रूट सभी संयोजनों को मजबूर करता है, इसलिए यह बड़े इनपुट के लिए बहुत धीरे (या मेमोरी से बाहर चलेगा) चलेगा।

इसे यहाँ ऑनलाइन आज़माएँ

सिर्फ एक इनपुट की हैंडलिंग का समर्थन करने के लिए, यह 17 तक जाता है:

hho.a-FsMNs./M.pQ

यह उन मूल्यों को प्रिंट करेगा जो एक हाथ में जाते हैं।


यह एक बहुत प्रभावशाली समाधान है - यह बिल्कुल भी स्पष्ट नहीं है कि यह गलत जवाब नहीं देगा [[2], [1], [1]], लेकिन मुझे लगता है कि यह काम करता है, ठीक इसी तरह से ./काम करता है।
इसहाक

वास्तव में, मुझे लगता है कि यह उन मामलों पर विफल रहता है जहां सब कुछ एक हाथ में जाता है, जैसे कि जब केवल 1 वस्तु होती है।
इसहाक

@ आईआईएसएसीजी के पास 1 तरह की वस्तु मान्य नहीं थी, क्योंकि आपको स्पष्ट रूप से इसे एक हाथ में पकड़ना था। मैं वास्तव में नहीं जानता कि उसके लिए क्या करना है [[x], []],?
FryAmTheEggman

मुझे ऐसा लगता है - यह शायद ठीक है जब तक कि ओपी अन्यथा नहीं कहता।
इसहाक

@isaacg मैंने नीचे एक उत्तर पोस्ट किया है। यह 1 तत्व के लिए सही उत्तर देता है (मुझे कोड में एक और बाइट जोड़ना था)
Renae Lider

6

CJam, 19 18 बाइट्स

{S+m!{S/1fb:*}$W=}

यह एक अनाम फ़ंक्शन है जो स्टैक से पूर्णांक के एक सरणी को पॉप करता है और एक स्थान द्वारा अलग किए गए पूर्णांकों की एक सरणी देता है।

अपनी सहज :*चाल के लिए @ jimmy23013 को धन्यवाद , जिसने 1 बाइट बचाई।

CJam दुभाषिया में इसे ऑनलाइन आज़माएं ।

यह काम किस प्रकार करता है

S+    e# Append a space to the array of integers.
m!    e# Push the array of all possible permutations.
{     e# Sort the array by the following:
  S/  e#   Split the array at the space.
  1fb e#   Add the integers in each chunk (using base 1 conversion).
  :*  e#   Push the product of both sums.
}$    e# Permutations with a higher product will come last.
W=    e# Select the last permutation.

डब्ल्यू के साथ शॉपिंग बैग के कुल वजन को नकारें । फिर, यदि किसी एक हाथ में बैग का वजन डब्ल्यू / 2 - डी / 2 है , तो दूसरे हाथ में वजन और डब्ल्यू - (डब्ल्यू / 2 - डी / 2) = डब्ल्यू / 2 + डी / 2 है

हम अंतर डी को कम करने की कोशिश कर रहे हैं । लेकिन (W / 2 - D / 2) (W / 2 + D / 2) = W ^ 2/4 - D ^ 2/4 , जो D जितना छोटा होता जाता है उतना बड़ा होता जाता है ।

इस प्रकार, अधिकतम उत्पाद न्यूनतम अंतर से मेल खाता है।


मुझे लगता है :*... W=काम करना चाहिए।
jimmy23013

@ jimmy23013: धन्यवाद! इसने मेरे उत्तर को बहुत अधिक रोचक बना दिया।
डेनिस

5

पायथन 2.7, 161 , 160

कोड

from itertools import*
m=input();h=sum(m)/2.;d=h
for r in(c for o in range(len(m)+1) for c in combinations(m,o)):
 t=abs(h-sum(r))
 if t<=d:d=t;a=r
print a

कलन विधि

2 एक्स डब्ल्यू एक हाथ = कुल वजन
डब्ल्यू एक हाथ ~ कुल वजन / 2

जांचें कि क्या प्रत्येक संयोजन कुल वजन के आधे के करीब हो रहा है। Iterate और सबसे अच्छा लगता है।

इनपुट

>>>[1,2,3,4]

उत्पादन

(2, 3)

प्रदर्शित टपल एक हाथ में जाता है, जो प्रदर्शित नहीं होता है वह दूसरे में जाता है (यह नियमों के विरुद्ध नहीं है)।


आप ऐसा करके एक बाइट को बचा सकता हैfrom itertools import*
DJMcMayhem

4

जावास्क्रिप्ट ( ईएस 6 ) 117

हर संभव विभाजन की कोशिश करने के लिए एक बिट मास्क का उपयोग करना, इसलिए यह 31 आइटम (नियमों के साथ ठीक) तक सीमित है। रेफरी उत्तर की तरह यह सिर्फ एक हाथ से आउटपुट करता है। ध्यान दें: मैं Math.abs से बचने के लिए न्यूनतम अंतर> = 0 को देखता हूं, जैसा कि प्रत्येक मिनट के लिए <0 एक और> 0 है, बस हाथों को ठोकर मारना है।

परीक्षण करने के लिए: फ़ायरफ़ॉक्स में स्निपेट को चलाएं, संख्याओं की एक सूची इनपुट करें अल्पविराम या अंतरिक्ष अलग।

f=(l,n)=>{ // the unused parameter n is inited to 'undefined'
  for(i=0;++i<1<<l.length;t<0|t>=n||(r=a,n=t))
    l.map(v=>(t+=i&m?(a.push(v),v):-v,m+=m),m=1,t=0,a=[]);
  alert(r)
}

// Test

// Redefine alert to avoid that annoying popup when testing
alert=x=>O.innerHTML+=x+'\n';

go=_=>{
  var list=I.value.match(/\d+/g).map(x=>+x); // get input and convert to numbers
  O.innerHTML += list+' -> ';
  f(list);
}
#I { width: 300px }
<input id=I value='7 7 7 10 11'><button onclick='go()'>-></button>

<pre id=O></pre>


2

हास्केल, 73 बाइट्स

import Data.List
f l=snd$minimum[(abs$sum l-2*sum s,s)|s<-subsequences l]

एक हाथ में वस्तुओं की एक सूची आउटपुट करता है। लापता तत्व दूसरी ओर जाते हैं।

उपयोग: f [7,7,7,10,11]->[7,7,7]

sइनपुट सूची के सभी बाद के लिए और के लापता तत्वों के lबीच वजन अंतर के निरपेक्ष मूल्य की गणना करें । न्यूनतम खोजें।sl


1

हास्केल, 51 बाइट्स

f l=snd$minimum$((,)=<<abs.sum)<$>mapM(\x->[x,-x])l

आउटपुट स्वरूप यह है कि बाएं हाथ का वजन सकारात्मक है और दाएं हाथ का वजन नकारात्मक है।

>> f [2,1,5,4,7]
[-2,-1,5,4,-7]

हर संभव विभाजन उत्पन्न करने के लिए, हम mapM(\x->[x,-x])lतत्वों के हर संभव सबसेट को नकारने के लिए उपयोग करते हैं। फिर, ((,)=<<abs.sum)प्रत्येक को अपनी पूर्ण राशि के साथ लेबल करें और snd$minimum$((,)=<<abs.sum)सबसे छोटे-लेबल वाले तत्व को लें।

टाइप-चेकिंग की समस्या के कारण मैं इसे पॉइंट-फ्री नहीं कर पाया।


@WillNess वर्तमान संस्करण में वे सभी प्रस्तावना में हैं।
18

BTW निम्नलिखित बिंदु-मुक्त कोड GHCi प्रॉम्प्ट पर काम करता है snd.minimum.map((,)=<<abs.sum).mapM(\x->[x,-x]):। यह 47 बाइट्स है। (हालांकि मेरे पास एक पुराना संस्करण स्थापित है ...)
विल नेस

0

आर (234)

आर के साथ एक लंबा और धीमा समाधान।

समारोह:

function(p){m=sum(p)/2;n=100;L=length(p);a=matrix(0,n,L+2);for(i in 1:n){idx=sample(1:L,L);a[i,1:L]=idx;j=1;while(sum(p[idx[1:j]])<=m){a[i,L+1]=abs(sum(p[idx[1:j]])-m);a[i,L+2]=j;j=j+1}};b=which.min(a[,L+1]);print(p[a[b,1:a[b,L+2]]])}


अपेक्षित इनपुट - वजन के साथ वेक्टर।
अपेक्षित आउटपुट - एक हाथ के लिए वजन के साथ वेक्टर।


उदाहरण

> Weight(c(1,2,3,4))
[1] 3 2
> Weight(c(10,1,2,3,4))
[1] 10
> Weight(c(40,20,80,50,100,33,2))
[1] 100  40  20  2
> Weight(c(7,7,7,10,11))
[1] 7 7 7

मानव पठनीय कोड संस्करण:

weight <- function(input) {
  mid <- sum(input)/2
  n <- 100
  input_Length <- length(input)
  answers <- matrix(0, n, input_Length+2)
  for(i in 1:n){
    idx <- sample(1:input_Length, input_Length)
    answers[i, 1:input_Length ] <- idx
    j <- 1
    while(sum(input[idx[1:j]]) <= mid){
        answers[i, input_Length+1] <- abs(sum(input[idx[1:j]]) - mid)
        answers[i, input_Length+2] <- j
        j <- j + 1
    }
  }
  best_line <- which.min(answers[, input_Length+1])
  print(paste("weight diference: ", answers[best_line, input_Length+1]))
  print(input[answers[best_line, 1:answers[best_line, input_Length+2]]])
}

0

Axiom, 292 बाइट्स

R==>reduce;F(b,c)==>for i in 1..#b repeat c;p(a)==(#a=0=>[a];w:=a.1;s:=p delete(a,1);v:=copy s;F(s,s.i:=concat([w],s.i));concat(v,s));m(a)==(#a=0=>[[0],a];#a=1=>[a,a];b:=p(a);r:=[a.1];v:=R(+,a)quo 2;m:=abs(v-a.1);F(b,(b.i=[]=>1;d:=abs(v-R(+,b.i));d<m=>(m:=d;r:=copy b.i);m=0=>break));[[m],r])

एक जानवर बल अनुप्रयोग। इससे सेट कम से कम होगा

A={abs(reduce(+,a)quo 2-reduce(+,x))|x in powerSet(a)}

क्योंकि अगर न्यूनतम है

y=min(A)=abs(reduce(+,a)quo 2-reduce(+,r))

यह न्यूनतम भी होगा

2*y=abs(reduce(+,a)-2*reduce(+,r))=abs((reduce(+,a)-reduce(+,r))-reduce(+,r)) 

जहाँ (कम (+, a) -reduce (+, r)) और कम (+, r) दो दो बैग में से दो हैं। (लेकिन वह अंतिम सूत्र मुझे आवेदन में न्यूनतम नहीं मिला)। Ungolf और परिणाम

-- Return the PowerSet or the Powerlist of a
powerSet(a)==
    #a=0=>[a]
    p:=a.1;s:=powerSet delete(a,1);v:=copy s
    for i in 1..#s repeat s.i:=concat([p],s.i)
    concat(v,s)

-- Return one [[m], r] where
-- r is one set or list with reduce(+,r)=min{abs(reduce(+,a)quo 2-reudece(+,x))|x in powerSet(a)}
-- and m=abs(reduce(+,a) quo 2-reduce(+,r))
-- because each of two part, has to have the same weight
MinDiff(a)==
    #a=0=>[[0],a]
    #a=1=>[ a ,a]
    b:=powerSet(a)
    r:=[a.1];v:=reduce(+,a) quo 2;m:=abs(v-a.1)
    for i in 1..#b repeat
        b.i=[]=>1
        k:=reduce(+,b.i)
        d:=abs(v-k)
        d<m=>(m:=d;r:=copy b.i)
        m=0=>break
    [[m],r]

--Lista random di n elmenti, casuali compresi tra "a" e "b"
randList(n:PI,a:INT,b:INT):List INT==
    r:List INT:=[]
    a>b =>r
    d:=1+b-a
    for i in 1..n repeat
          r:=concat(r,a+random(d)$INT)
    r

(5) -> a:=randList(12,1,10000)
   (5)  [8723,1014,2085,5498,2855,1121,9834,326,7416,6025,4852,7905]
                                                       Type: List Integer
(6) -> m(a)
   (6)  [[1],[1014,2085,5498,1121,326,6025,4852,7905]]
                                                  Type: List List Integer
(7) -> x:=reduce(+,m(a).2);[x,reduce(+,a)-x]
   (7)  [28826,28828]
                                               Type: List PositiveInteger
(8) -> m([1,2,3,4])
   (8)  [[0],[2,3]]
                                                  Type: List List Integer
(9) -> m([10,1,2,3,4])
   (9)  [[0],[10]]
                                                  Type: List List Integer
(10) -> m([40,20,80,50,100,33,2])
   (10)  [[0],[40,20,100,2]]
                                                  Type: List List Integer
(11) -> m([7,7,7,10,11])
   (11)  [[0],[10,11]]
                                                  Type: List List Integer
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.