Teilen und glücklich bleiben. Wen interessiert der Eroberungsteil?

12

Wenn ich Geschenke für meine beiden Frauen kaufe, möchte ich, dass sie sich für mich gleich wichtig anfühlen, aber es ist schwierig, mit festen Budgets einzukaufen. Stattdessen kaufe ich ein paar Sachen und teile sie in zwei Gruppen mit möglichst gleichem Wert ein. Dann kaufe ich eine Praline, um den Rest zu reparieren.

Aber ich möchte nicht all das harte Heben tun, wenn mein Computer es kann. Und du auch nicht. Lösen Sie dieses Problem, damit Sie wissen, dass es beim nächsten Mal, wenn Sie Geschenke unter Ihren Frauen aufteilen müssen, einfach ist.

Eingang

1 Array von (N * 2) Elementen, wobei N * 2 in der 1. Zeile angegeben ist.
Die Elemente des Arrays in der folgenden Zeile.

Ausgabe

2 Array von jeweils N Elementen, so dass:
Differenz von (Summe der Elemente von Array 1) und (Summe der Elemente von Array 2) so nahe wie möglich bei 0 liegt.

Beispiel

Eingang

4
1 2 3 4 

Ausgabe

1 4
2 3
diff=0

Haftungsausschluss : Ich habe keine zwei Frauen. Aber wenn ich mich schlecht fühle, stelle ich mir vor, zwei Frauen zu haben. Und plötzlich bin ich dankbar und froh, dass ich nur einen habe. : D

rahulroy9202
quelle
3
So wie es aussieht, zwingt "2 Arrays von je N Elementen" die Gruppen, ebenfalls gleich groß zu sein. Ist das beabsichtigt? Zum Beispiel wäre im Moment für die Eingabegruppe 1 1 1 1 1 5die richtige Antwort 1 1 1| 1 1 5, Während 1 1 1 1 1| 5würde mehr Sinn machen.
Shiona
Vermutlich trifft das Problem auch auf Zwillinge und wahrscheinlich auch auf andere Kinderaufstellungen zu. Weihnachten heute ist meistens ein "Er hat mehr als ich" -Ereignis ...
TheConstructor
1
@shiona, ja, die gleiche Größe ist vorgesehen. @ TheConstructor: Teilen unter Kindern ist nicht so lustig wie Teilen unter zwei Frauen. : D
rahulroy9202
Die Tag- Code-Challenge erfordert ein objektives Gewinnkriterium. Es hängt auch eng mit dem Teilmengen-Summenproblem zusammen, das hier zuvor gestellt wurde.
Howard
@Wie gibt es wichtige Unterschiede zur Teilmenge Summe: Sie müssen zwei gleich große Listen erstellen (nicht nur gleich bewertet), Sie müssen alle Elemente verwenden, ...
TheConstructor

Antworten:

4

Java

Der Versuch, dieses Problem in zwei Phasen zu lösen:

  1. Erstellen Sie zwei gleich große Listen, indem Sie die verbleibende größte zur aktuell kleineren und die nächste zur nächsten Liste hinzufügen. Wiederholen.
  2. Identifizieren Sie Elemente aus beiden Listen, die umgeschaltet werden können, um den Wertunterschied zu verringern

Eingabe wie

8
1 2 3 4 5 6 7 8

wird bereits nach phase 1 gelöst wie zb

2 3 5 8
1 4 6 7
diff=0

und Eingabe wie

6
1 4 5 6 7 8

werden beide phasen brauchen damit

1 5 8
4 6 7
diff=3

(nach Phase eins) wird das Ergebnis von

1 6 8
4 5 7
diff=1

Obwohl ich garantieren kann, dass dieser Versuch immer eine Lösung liefert, kann ich nicht beweisen, dass in allen Fällen eine optimale Lösung gefunden wird. Bei der Einschränkung gleich großer Listen erscheint es jedoch durchaus realistisch, dass keine Eckfälle zurückbleiben. Beweise mir das Gegenteil ;-)

Programm auf ideone.com

import java.util.*;

/**
 * Created to solve http://codegolf.stackexchange.com/q/23461/16293 .
 */
public class EqualSums {

    public static void main(String[] args) {
        final Scanner s = new Scanner(System.in);
        // Read number of elements to divide
        final int count = s.nextInt();
        if (count % 2 == 1) {
            throw new IllegalStateException(count + " can not be divided by 2. Consider adding a 0 value.");
        }
        // Read the elements to divide
        final SortedList valueStack = new SortedList(count);
        for (int i = 0; i < count; i++) {
            valueStack.add(s.nextLong());
        }

        final SortedList targetOne = new SortedList(count / 2);
        final SortedList targetTwo = new SortedList(count / 2);
        // Divide elements into two groups
        addInPairs(targetOne, targetTwo, valueStack);
        // Try to ensure groups have equal value
        retaliate(targetOne, targetTwo);

        // Output result
        System.out.println(targetOne);
        System.out.println(targetTwo);
        System.out.println("diff=" + Math.abs(targetOne.getSum() - targetTwo.getSum()));
    }

    private static void addInPairs(SortedList targetOne, SortedList targetTwo, SortedList valueStack) {
        SortedList smallerTarget = targetOne;
        SortedList biggerTarget = targetTwo;
        while (!valueStack.isEmpty()) {
            // Add biggest remaining value to small target
            smallerTarget.add(valueStack.removeLast());

            // Add second biggest remaining value to big target
            biggerTarget.add(valueStack.removeLast());

            // Flip targets if roles have changed
            if (smallerTarget.getSum() > biggerTarget.getSum()) {
                final SortedList temp = smallerTarget;
                smallerTarget = biggerTarget;
                biggerTarget = temp;
            }
        }

    }

    private static void retaliate(SortedList targetOne, SortedList targetTwo) {
        long difference;
        boolean changed;
        outer:
        do {
            difference = Math.abs(targetOne.getSum() - targetTwo.getSum());
            if (difference == 0) {
                return;
            }
            changed = false;
            // Try to find two values, that reduce the difference by changing them between targets
            for (Long valueOne : targetOne) {
                for (Long valueTwo : targetTwo) {
                    final Long tempOne = targetOne.getSum() + valueTwo - valueOne;
                    final Long tempTwo = targetTwo.getSum() - valueTwo + valueOne;
                    if (Math.abs(tempOne - tempTwo) < difference) {
                        targetOne.remove(valueOne);
                        targetTwo.add(valueOne);
                        targetTwo.remove(valueTwo);
                        targetOne.add(valueTwo);
                        changed = true;
                        continue outer;
                    }
                }
            }
        } while (changed);
    }

    public static class SortedList extends AbstractList<Long> {

        private final ArrayList<Long> list;
        private long sum = 0;

        public SortedList(int count) {
            list = new ArrayList<>(count);
        }

        // the next functions access list-field directly
        @Override
        public Long get(int index) {
            return list.get(index);
        }

        @Override
        public boolean add(final Long t) {
            final int i = Collections.binarySearch(list, t);
            if (i < 0) {
                // No equal element present
                list.add(-i - 1, t);
            } else {
                list.add(afterLastEqual(i, t), t);
            }
            sum += t;
            return true;
        }

        @Override
        public Long remove(int index) {
            final Long old = list.remove(index);
            sum -= old;
            return old;
        }

        @Override
        public int size() {
            return list.size();
        }

        // the next functions access list-field only through the functions above this point
        // to ensure the sum is well kept

        public long getSum() {
            return sum;
        }

        private int afterLastEqual(final int start, Object o) {
            int found = start;
            while (found < size() && o.equals(get(found))) {
                found++;
            }
            return found;
        }

        private int beforeFirstEqual(final int start, final Object o) {
            int found = start;
            while (found >= 0 && o.equals(get(found))) {
                found--;
            }
            return found;
        }

        @Override
        public int indexOf(Object o) {
            try {
                final int i = Collections.binarySearch(this, (Long) o);
                if (i >= 0) {
                    return beforeFirstEqual(i, o) + 1;
                }
            } catch (ClassCastException e) {
                // Object was not instance of Long
            }
            return -1;
        }

        @Override
        public int lastIndexOf(Object o) {
            try {
                final int i = Collections.binarySearch(this, (Long) o);
                if (i >= 0) {
                    return afterLastEqual(i, o) - 1;
                }
            } catch (ClassCastException e) {
                // Object was not instance of Long
            }
            return -1;
        }

        @Override
        public boolean remove(Object o) {
            if (o == null) {
                return false;
            }
            final int i = indexOf(o);
            if (i >= 0) {
                remove(i);
                return true;
            }
            return false;
        }

        public Long removeLast() {
            return remove(size() - 1);
        }

        public Long removeFirst() {
            return remove(0);
        }

        @Override
        public String toString() {
            Iterator<Long> it = iterator();
            if (!it.hasNext()) {
                return "";
            }

            StringBuilder sb = new StringBuilder();
            for (; ; ) {
                Long e = it.next();
                sb.append(e);
                if (!it.hasNext()) {
                    return sb.toString();
                }
                sb.append(' ');
            }
        }
    }
}
DerKonstruktor
quelle
3

Brachylog 2

pᶠḍᵐ{+ᵐo-}ᵒh

Probieren Sie es online!

Dies ist ein Beliebtheitswettbewerb, aber das bedeutet nicht unbedingt, dass Golfsprachen schlecht passen. (Eigentlich hätte ich in Jelly antworten sollen, weil Jelly-Antworten aus irgendeinem Grund eine unverhältnismäßig hohe Anzahl von Stimmen erhalten, unabhängig davon, wer sie abgibt oder wie gut sie golfen, aber Brachylog ist besser lesbar.)

Wir beginnen damit, die Liste aller Permutationen der Eingabe ( pᶠ) zu nehmen und jede ( ) in zwei gleiche Teile aufzuteilen ( wir könnten ihr einen Index geben, wenn Sie aus irgendeinem Grund mehr als zwei Frauen hätten). Dann ordnen wir die aufgeteilten Permutationen ( {…}ᵒ), indem wir die Summe (+ ) jeder ( ) Hälfte nehmen, die absolute Differenz (dh die o-"geordnete Differenz") nehmen und diese Differenzen verwenden, um die Sortierreihenfolge zu definieren. Das beste Ergebnis ist das erste, also nehmen wir den Kopf der Liste mit h, um das Ergebnis zu erhalten.


quelle
2

Mathematica

Eingabeformulare

Die Eingabezeichenfolge muss über STDIN erfolgen. assetsbezieht sich auf die unter den Ehefrauen (oder Zwillingen) zu verteilenden Beträge. lengthist die Anzahl der Vermögenswerte.

assets=ToExpression[Rest[s=StringSplit[input]]]
length=ToExpression[First[s]]

Für die vorliegenden Zwecke gehen wir davon aus, dass das Vermögen aus den ganzen Zahlen von 1 bis 20 besteht.

assets=Range[20];
length=Length[Range[20]]

wird bearbeitet

(* find all possible distributions to one wife; the other presumably gets the remaining assets *)
r=Subsets[assets,{length/2}];

(*order them according to the difference with respect to the total of half of the assets. 
Remove the first set of assets.  One wife will get these.*)
s=SortBy[r/.{{a__Integer}:> {{a},Abs[Tr[Range[20]/2]-Tr[{a}]]}},Last][[1]];

(*The other wife's assets will be the complement.  The difference is carried over from the sorting routine. *)
Grid[{{Grid[{s[[1]],Complement[assets,s[[1]]]}]},{"difference = "<>ToString[s[[2]]]}}]

r20


Ist die Verteilung ungerecht? Wählen Sie also eine andere.

@ The Constructor merkt an, dass Frau 2 die Tatsache bestreiten kann, dass Frau 1 das beste Vermögen hat. Das Folgende ergibt also alle "fairen" (Differenz = niedrigste Differenz) Anteile für Frau 1; Frau 2 bekommt das restliche Vermögen; Die Null bezieht sich auf die Vermögensdifferenz der Ehefrauen. Es gibt 5448 Möglichkeiten, Vermögenswerte mit den Gewichten 1 bis 20 zu verteilen. Es werden nur wenige Zeilen angezeigt.

Das Format ist

s=SortBy[r/.{{a__Integer}:> {{a},Abs[Tr[Range[20]/2]-Tr[{a}]]}},Last];
z=Cases[s,{_List,x_}/;x==s[[1,2]]];
Short[z,10]
Length[z]

{{{1,2,3,4,5,16,17,18,19,20}, 0}, {{1,2,3,4,6,15,18,19,20}, 0}, {{1,2,3,4,7,14,17,18,19,20}, 0}, {{1,2,3,4,7,15,16,18,19,20 }, 0}, {{1,2,3,4,8,13,17,18,19,20}, 0}, {{1,2,3,4,8,14,16,18,19 , 20}, 0}, {{1,2,3,4,8,15,16,17,19,20}, 0}, {{1,2,3,4,9,12,17,18 , 19,20}, 0}, {{1,2,3,4,9,13,16,18,19,20}, 0}, {{1,2,3,4,9,14,15} , 18,19,20}, 0}, {{1,2,3,4,9,14,16,17,19,20}, 0}, {{1,2,3,4,9,15} , 16,17,18,20}, 0}, {{1,2,3,4,10,11,17,18,19,20}, 0}, {{1,2,3,4,10 , 12,16,18,19,20}, 0}, << 5420 >>, {{5,6,7,8,9,11,13,14,15,17}, 0}, {{5 , 6,7,8,9,12,13,14,15,16}, 0}, {{5,6,7,8,10,11,13,14,19}, 0}, { {5,6,7,8,10,11,12,13,15,18}, 0}, {{5,6,7,8,10,11,13,16,17}, 0} {{5,6,7,8,10,11,12,14,15,17}, 0}, {{5,6,7,8,10,13,14,15,16}, 0}, {{5,6,7,9,10,11,12,13,14,18}, 0}, {{5,6,7,9,10,11,12,13,15,17 }, 0}, {{5,6,7,9,10,11,12,14,15,16}, 0}, {{5,6,8,9,10,11,12,13,14 , 17}, 0}, {{5,6,8,9,10,11,12,13,15,16}, 0}, {{5,7,8,9,10,11,12,13,14,16}, 0}, {{6,7,8,9,10,11,12,13,14,15}, 0}}

5448


Die vorherige Einreichung finden Sie unter den Bearbeitungen. Es ist weitaus ineffizienter, wenn man sich darauf verlässt Permutations.

DavidC
quelle
Mathematica scheint für eine solche Aufgabe schön zu sein. Eine letzte Sache ist, dass echte Frauen wahrscheinlich streiten würden, da die 5 wertvollsten Gegenstände alle auf einem Stapel liegen. (Ja, mit 1 bis 20 gibt es keine Lösung ohne Raum für Argumente)
TheConstructor
Tatsächlich gibt es einige Möglichkeiten, die Assets zu verteilen. Ich habe einige der Möglichkeiten in einem Nachtrag aufgeführt. Hinweis: Es wird nur das Vermögen einer Frau aufgeführt. der andere bekommt die Ergänzung.
DavidC
Das ist einer der Gründe, warum ich meine Anfangsstapel so baue, wie ich es tue: Normalerweise befinden sich die beiden wertvollsten Dinge nicht auf demselben Stapel. Ihre ursprüngliche Lösung beweist, dass es 10 Zahlenpaare mit einer Summe von 21 gibt. Sie wählen implizit aufeinanderfolgende Paare.
TheConstructor
Ja, ich schätze die Logik Ihres Ansatzes.
DavidC
2

J

Es gibt einen Spickzettel mit allen J-Primitiven unter diesem Link , falls Sie zu Hause mitmachen möchten. Denken Sie daran: J wird im Allgemeinen von rechts nach links gelesen, das 3*2+1heißt 7, nicht 9. Jedes Verb (J für Funktion) ist entweder monadisch, also vorne wie f y, oder dyadisch, also dazwischen wie x f y.

N =: (". 1!:1 ] 1) % 2          NB. number of items per wife
S =: ". 1!:1 ] 1                NB. list of items to distribute

bins =: #: i. 2 ^ 2*N           NB. all binary strings of length 2n
even =: bins #~ N = +/"1 bins   NB. select those with row-sum 1

NB. all distributions of equal numbers of items to each wife
NB. resultant shape: a list of 2xN matrices
NB. this /. adverb is where all the magic happens, see below
dist =: even ]/."1 S

diff =: | -/"1 +/"1 dist        NB. difference in wives' values
idx  =: (i. <./) diff           NB. index of the lowest difference

1!:2&2 idx { dist               NB. print the winning distribution of items
1!:2&2 'diff=', idx { diff      NB. and the difference of that distribution

Anmerkungen und Erläuterungen:

  • u/bedeutet "umklappen u", führen Sie also die Binäroperation für jedes Element in der Liste aus. Also zum Beispiel: +/bedeutet Fold Plus oder Summe ; <.ist weniger von , <./bedeutet also weniger falten oder Minimum .

  • u"1bedeutet " uauf eindimensionalen Zellen ausführen ", dh über jede Zeile. Normalerweise sind die Verben in J entweder atomar oder gelten für das gesamte Argument. Dies gilt für beide Argumente, wenn das Verb dyadisch verwendet wird (mit zwei Argumenten). Folgendes berücksichtigen:

       i. 2 3        NB. just a 2x3 matrix of numbers
    0 1 2
    3 4 5
       +/   i. 2 3   NB. Sum the items
    3 5 7
       +/"1 i. 2 3   NB. Sum the items of each row
    3 12
    
  • #:ist ein Verb, das eine Zahl in ihre binäre Darstellung erweitert. Wenn Sie es in einer Liste mit mehr als einem Element verwenden, werden auch alle Zahlen korrekt ausgerichtet, sodass #:i.2^nSie jede binäre Zeichenfolge mit einer Länge erhalten n.

  • /.wird dyadisch als Key bezeichnet . Dabei werden die Elemente der Liste auf der linken Seite als Schlüssel und die auf der rechten Seite als Werte verwendet. Es gruppiert jeden Satz von Werten, die einen Schlüssel gemeinsam haben, und führt dann eine Operation an ihnen aus.

    Im Fall von ]/.ist die Operation nur das Identitätsverb, daher passiert dort überhaupt nichts Besonderes, aber die Tatsache, dass /.die Liste für uns aufgeteilt wird, ist das Wichtige. Aus diesem Grund erstellen "1wir die Binärlisten : Damit wir für jede Liste ( ) die Geschenke für die Frauen auf alle möglichen Arten aufteilen können.

  • 1!:1]1und 1!:2&2sind die Einlese- bzw. Ausleseoperationen. Der 1!:nTeil ist das Verb und die andere Zahl ist das Dateihandle. 1ist console in, 2ist console out und 3 4 5sind stdin, stdout und stderr. Wir verwenden dies auch ".beim Lesen, um die Eingabezeichenfolgen in Zahlen umzuwandeln.

algorithmshark
quelle
1
+1 für die Übermittlung einer Antwort in J und mindestens versuchen, es verständlich zu machen.
Level River St
1

Clojure

(defn divide [n]
 (loop [lv [] rv [] d (reverse (sort n))]
  (if (empty? d)
   [lv rv]
   (if (> (reduce + lv) (reduce + rv))
     (if (>= (count lv ) (count rv))
       (recur lv (conj rv (first d)) (into [] (rest d)))
       (recur (conj lv (last d)) rv (pop d))) 
     (if (<= (count lv ) (count rv))
       (recur (conj lv (first d)) rv (into [] (rest d)) )
       (recur lv (conj rv (last d)) (pop d)))))))


 (defn display [[f s]]
   (println f)
   (println s)
   (println (str "Diff " (- (reduce + f) (reduce + s)))))

Prüfung

 (->> 
 [5 1 89 36 2 -4 20 7]
 divide 
 display)


 =: [89 -4 1 2]
    [36 20 7 5]
    Diff 20
Mamun
quelle
Ergebnismengen sollten gleich groß sein und die Differenz zwischen den Werten in jeder Menge sollte gedruckt werden. Nach den Ergebnissen eines Schnelltests auf ideone zu urteilen, haben Sie möglicherweise beide Punkte verfehlt
TheConstructor
Hinzufügen einer Anzeigemethode zum Drucken des Ergebnisses.
Mamun
Ergebnismenge jetzt gleich groß
Mamun
Für [1 4 5 6 7 8]Ihr Programm berechnet, [8 5 4] [7 6 1] Diff 3wo eindeutig Lösungen mit einer Differenz von 1 existieren.
TheConstructor
1

MATLAB

Hier ist meine Lösung:

%input array
presents=zeros(2,8);
presents(1,1)=8; %number of presents
presents(2,:)=[1 2 7 4 5 3 2 8]; %list of presents

%calculate the cumulative sum of all permutations
%its all about the gift values
how_many=presents(1,1);
options=perms(presents(2,:);
subtotals=cumsum(options,2);

%find the first index where the difference between the two parts is minimal
%makes both wives happy!!
[~, double_happiness] = min(abs(sum(presents(2,:))/2-subtotals(:,how_many/2)));

%create the present lists for Jennifer and Kate :)
for_jennifer=options(double_happiness,1:how_many/2)
for_kate=options(double_happiness,how_many/2+1:end)

Zum Beispiel führt die aktuelle Liste in meinem Quellcode zu:

for_jennifer =

     8     2     5     1


for_kate =

     4     7     2     3

das ist beide 16.

Wenn ich meinen Code spiele, was weniger Spaß macht, bekomme ich sehr unoptimierte 132 Zeichen. Schlag das ;)

function f(p);o=perms(p(:,2));s=cumsum(o,2);[~,d]=min(abs(sum(p(:,2))/2-s(:,p(1,1)/2)));a={o(d,1:p(1,1)/2);o(d,p(1,1)/2+1:end)};a{:}
mmumboss
quelle
Das Eingabearray muss quadratisch sein.
DavidC
Nein, nicht quadratisch? Aber jetzt sehe ich, dass die Anzahl der Artikel in der ersten Reihe sein sollte. Ich werde es ändern.
mmumboss
0

PHP

Warnung: Sehr schmutziger Code
Er versucht jede mögliche Permutation des Eingabearrays.

Ideone-Beispiel für 4/1 2 3 4: http://ideone.com/gIi174

<?php
// Discard the first input line! It's useless :)
fgets(STDIN);
$numbers = explode(' ', rtrim(fgets(STDIN)));
$valuePerWife = array_sum($numbers) / 2;

// Taken from here: http://stackoverflow.com/a/13194803/603003
// Credits to dAngelov: http://stackoverflow.com/users/955185/dangelov
function pc_permute($items, $perms = array( )) {
    if (empty($items)) {
        $return = array($perms);
    }  else {
        $return = array();
        for ($i = count($items) - 1; $i >= 0; --$i) {
             $newitems = $items;
             $newperms = $perms;
         list($foo) = array_splice($newitems, $i, 1);
             array_unshift($newperms, $foo);
             $return = array_merge($return, pc_permute($newitems, $newperms));
         }
    }
    return $return;
}


foreach (pc_permute($numbers) as $permutation) {
    $sum = 0;
    $rest = [];

    for ($i=0; $i<count($permutation); $i++) {
        $sum += $permutation[$i];
        if ($sum == $valuePerWife) {
            $rest = array_slice($permutation, $i + 1);
            break;
        }
    }

    if (array_sum($rest) == $valuePerWife) {
        echo implode(' ', array_slice($permutation, 0, $i + 1)), "\n";
        echo implode(' ', array_slice($permutation, $i + 1)), "\n";
        echo 'diff=0';
        exit;
    }
}
exit('DIDNT FOUND ANY COMBINATION!');
ComFreek
quelle
0

Python:

import itertools as t
raw_input()
a=[int(i) for i in raw_input().split()]
a=list(t.permutations(a))
b=len(a[0])/2
c=[(d[b:],d[:b]) for d in a]
d=[abs(sum(d[b:])-sum(d[:b])) for d in a]
e=zip(d,c)
e.sort()
print " ".join([str(i) for i in e[0][1][0]])
print " ".join([str(i) for i in e[0][1][1]])
print "diff",e[0][0]

oder ein bisschen golfen:

import itertools as t
b=int(raw_input())/2
e=[(abs(sum(d[b:])-sum(d[:b])),(d[b:],d[:b])) for d in t.permutations([int(i) for i in raw_input().split()])]
e.sort()
f=e[0]
g=f[1]
print " ".join([str(i) for i in g[0]]),"\n"," ".join([str(i) for i in g[1]]),"\n","diff=",f[0]

Oder noch weiter golfen, da die Hälfte der Linien nur Make-up ist. (Angenommen, ich kann nur das rohe interne Array ausgeben, da dies nicht in der Operation angegeben ist.) Sie können das printin (zum Beispiel) der interaktiven Shell weglassen und ein [::-1](ganz am Ende, nach [0]) hinzufügen , wenn Sie wirklich wollen der Unterschied zuletzt.

import itertools as t
b=int(raw_input())/2
print sorted([(abs(sum(d[b:])-sum(d[:b])),(d[b:],d[:b])) for d in t.permutations([int(i) for i in raw_input().split()])])[0]

(Ergebnisse in (0, ((1, 2, 7, 8), (3, 4, 5, 6))))

Dies ist jedoch nur brachial für alle möglichen Kombinationen und sollte nicht als entfernt effizient angesehen werden. Wenn es jedoch nicht darauf ankommt, dass die Liste gleich lang ist, funktioniert dies auch (bei großen Arrays):

raw_input()
a,b=[],[]
for i in sorted([int(i) for i in raw_input().split()])[::-1]:
    b.append(i)
    if sum(b)>sum(a): b,a=a,b
print a,b,abs(sum(b)-sum(a))

Mit dem Code darunter läuft es zum Beispiel kaum anders: 500k auf 10 ^ 10 Maximalwerten sind sozusagen nicht viel. Dies ist auch viel schneller: Wo der andere Code wahrscheinlich nicht in weniger als einem Jahr fertig ist (und das ist sehr optimistisch), dauert dies ungefähr eine halbe Sekunde, obwohl Ihre Laufleistung variieren kann.

def raw_input():
    import random
    return " ".join([str(random.randint(1,10**10)) for _ in range(10000)])

raw_input()
a,b=[],[]
for i in sorted([int(i) for i in raw_input().split()])[::-1]:
    b.append(i)
    if sum(b)>sum(a): b,a=a,b
print a,b,abs(sum(b)-sum(a))
Synthetica
quelle
Frage: Warum ist das ein CW-Beitrag?
HyperNeutrino
0

Literate Haskell

> import Data.List
> import Data.Function

Ich benutzte die Listenmonade, um sie aufzuteilen.

> divide []=return ([], [])
> divide (x:xs)=do
>   (w1, w2) <- divide xs
>   [(x:w1, w2), (w1, x:w2)]

Dann machen wir einen Rater.

> rating (w1, w2)=abs $ (sum w1) - (sum w2)

Und dann eine Funktion, die den Unterschied minimiert.

> best = minimumBy (compare `on` rating) . filter (\(x,y)->length x == length y)

Und etwas, das sie alle vereint.

> bestDivison=best . divide

Weiter ein Parser.

> parse::String->[Int]
> parse=fmap read . words

Und ein Ausgabeformatierer.

> output (w1,w2)=unlines [unwords (map show w1)
>                        , unwords ( map show w2)
>                        , "diff="++(show $ abs $ (sum w1) - (sum w2))]

Und jetzt das Programm

> main = do
>   getLine --Ignored, I don't need the arrays length
>   input <- fmap parse getLine
>   putStrLn "" --For readability
>   putStrLn $ output $ bestDivison input

Beispiel:

λ <*Main>: main
8
5 1 89 36 2 -4 20 7

5 36 20 7
1 89 2 -4
diff=20
PyRulez
quelle
Ergebnismengen sollten gleich groß sein
TheConstructor