Alle Zahlen mit gleicher Quersumme auflisten
-
Hallo Forum,
wie würde man alle Zahlen mit gleicher Quersumme in einem beliebigen Zahlensystem auflisten. Ich benötigen den Algo um n Dinge auf m Behälter zu verteilen. n und m sind variabel. Meistens gibt es 20 Dinge und 10 Behälter.
Kleines Beispiel: Es sollen 7 Dinge auf 4 Behälter verteilt werden.
Das Ergebnis soll so aussehen:
0007
0016
0025
...
0070
0106
0115
...
7000
Jede Stelle steht für einen Behälter, die Ziffer für die Befüllung.- Die Quersumme ist immer die Anzahl der Dinge.
- Das Zahlensystem ist #Dinge+1.
- Wenn auf eine Ziffer ein 1 drauf kommt wird (#Dinge+1)^(Stelle-1) gerechnet. Im Gegenzug wird nach dem gleichen Muster woanders ein 1 abgezogen. Allerdings kann es vorkommen das mehrere 1 verschoben werden. Siehe diesen Übergang:
0610
1006Ich habe mal ein Excel Makro geschrieben um ein Muster zu erkennen:
Public Sub start() Call LoopArray(7, 4) End Sub Private Sub LoopArray(items As Long, container As Long) Dim CurrentDistribution() As Long Dim rest As Long, i As Long, QSum As Long, lActualRow As Long Dim counter As Currency ReDim CurrentDistribution(1 To container) ' Hier speichern wir die momentane Zerlegung ab: ' Es werden alle Zerlegungen durchgegangen. Auch die ohne passende Quersumme: For counter = 0 To (items + 1) ^ (container + 1) ' Jetzt zerlegen wir den Counter im momentanen Zahlensystem: rest = counter: QSum = 0 For i = 1 To container CurrentDistribution(i) = rest Mod (items + 1) QSum = QSum + CurrentDistribution(i) rest = rest \ (items + 1) Next i ' Hat die momentane Zerlegung die richtige Quersumme? Wenn ja rausschreiben. If QSum = items Then lActualRow = lActualRow + 1 For i = 1 To container Tabelle1.Cells(lActualRow, container + 1 - i) = CurrentDistribution(i) Next i End If Next counter End Sub
Ich finde aber keine Lösung.
In diesem Minibeispiel kann die Lücke zwischen zwei Zahlen mit der richtigen Quersumme schon 3584 betragen. Es wird also unsinnigerweise 3583 mal die Schleife durchgegangen und die Quersumme errechnet. Ein Aufruf wie "LoopArray(20, 10)" sprengt aber schon meine Lebenserwartung.
Wie kann ich die Sache beschleunigen? Ich könnte jetzt stattdessen mit einer extra Funktion die Einsen von links nach rechts verschieben. (Das kann ich selber machen) Aber vielleicht gibt es dafür irgendeine mathematische Formel?
Vielen Dank
-
Argh: Schon der erste Fehler.
- Wenn auf eine Ziffer ein 1 drauf kommt wird (#Dinge+1)^(Stelle-1) gerechnet. Im Gegenzug wird nach dem gleichen Muster woanders ein 1 abgezogen. Allerdings kann es vorkommen das mehrere 1 verschoben werden. Siehe diesen Übergang:
0610
1006Der Übergang ist natürlich:
0700
1006
-
Der Fehler liegt schon darin, dass du "n Dinge in m Behältern" als Zahl mit m Stellen in einem Ziffernsystem zur Basis n darstellen willst. Ansonsten ist die richtige Lösung nicht, alle Kombinationen durchgehen und die gewünschten zu behalten, sondern gleich nur die gewünschten zu generieren. So nach dem Motto: Pack 1 Teil in den ersten Behälter. Wieviel hab ich noch? Ermittle alle Möglichkeiten, sie auf den Rest zu verteilen. Dann pack 2 Teile in den ersten Behälter, mach das gleiche usw.
-
Du könntest rekursiv die Gesamtzahl in alle möglichen Summen zerlegen:
void zerlege(zahl,länge) { static vector<int> summanden; if(summanden.size())==länge) { ausgabe(); return; } for(i=0;i<=zahl;++i) { summanden.push_back(i); zerlege(zahl-i,länge); summanden.pop_back(); } }
@edit @Bashar: Und da haben wir schon den Ausgleich
-
Wenn ich es richtig sehe hattet Ihr beide die richtige Idee. Jetzt muß ich nicht in irgendwelchen Arrays rumprokeln.... vielen vielen Dank Bashar und CStoll
-
Sry, auch wenn Off Topic und ich Mathe-Noob: Hat man es eigentlich dem Zehnersystem zu verdanken, dass durch die Quersumme bestimmen kann, dass Zahlen durch 3 teilbar sind? würde das z.b. im hexadezimalen ähnlich gehen?
Könnte man nicht auf ähnliche weise prüfen, ob Zahlen durch andere Zahlen ohne Rest teilbar sind, wenn man sie im richtigen Zahlensystem hätte? (mist, ich glaube da hab ich mir gerade selbst die antwort gegeben, aber wenn jemand was dazu sagen will, bitte ^^ ).