Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1076to1080
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Für VBA und Knobelfreunde

Für VBA und Knobelfreunde
04.06.2009 07:48:59
alifa
Heute ein Neues. Ich kriege das nicht hin (wegen der großen Zahlen?) Gesucht eine 10-stellige Zahl, teilbar durch sieben. Alle Ziffern von 0 bis 9 sind je ein Mal darin enthalten. Diese Zahl soll enthalten: Eine einstellige, eine zweistellige, eine dreistellige.............neunstellige Zahl, die alle durch 7 teilbar sind. Z.B.
1357902468 ist durch 7 teilbar. 7 , 35, 357 auch. Leider gibt es keine 4-stellige, die durch 7 teilbar wäre. Vielleicht etwas für VBA Freunde. Bis jetzt kriegte ich das Makro nicht hin.
Gruß, Erhard

12
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Für VBA und Knobelfreunde
04.06.2009 08:55:07
Andi
Hi,
ich kann Dir leider gerade keinen Algorithmus dafür sagen, bin aber durch rumprobieren auf die Zahl 4956213087 gekommen:
1 x 7 = 7
3 x 7 = 21
44 x 7 = 308
708 x 7 = 4956
3044 x 7 = 21308
30441 x 7 = 213087
803044 x 7 = 5621308
8030441 x 7 56213087
70803044 x 7 = 495621308
708030441 x 7 = 4956213087
Schönen Gruß,
Andi
AW: Für VBA und Knobelfreunde
04.06.2009 09:43:51
alifa
Hallo Erich,
bis jetzt habe ich alle deine Fragen beantworten können und das auch getan. Siehe meine Makros. das Bild mit Divisionsskelett, die Sinnfrage und alle anderen auch. Mein letztes Makro hast du verbessert. Anerkennung! Mit deinem heutigen Beitrag liegst du leider völlig daneben. In Zeile 5 bleiben 2 Ziffern (10-8) und die können sehr wohl auch durch 7 teilbar sein. Ich habe stundenlang versucht, für dieses Problem selbst ein Makro zu schreiben. Nicht das ich vergesse: Diese Aufgabe habe ich im Internet gefunden, nähere Angaben möchte ich nicht machen. Mir ist das Makro viel wichtiger, als die Lösung und ich meine, die Aufgabe ist allemal ein Makro wert, weil sie weder sinnlos, noch unlösbar ist. So, das war die Antwort an Erich jetzt zu dir Andi: Manchmal geht probieren über studieren!
Gruß aus dem Oberbergischen, Erhard
Anzeige
VBA und Knobelfreunde
05.06.2009 02:27:24
Erich
Hi Erhard,
zunächst eine Info: Dieser Thread ist eine Fortsetzung von
https://www.herber.de/forum/archiv/1076to1080/t1077845.htm
und
https://www.herber.de/forum/archiv/1076to1080/t1078798.htm
(aktuell: https://www.herber.de/forum/messages/1078798.html )
Ja, da lag ich daneben - für die Aufgabe habe ich 9264 Lösungen gefunden.
Auch Andis Lösung kommt darin vor. Hier das Makro:

Sub Teiler7()    ' 3628800 Permutationen, davon sind 9264 Lösungen
Dim zz As Long, arrE(1 To 3628800) As String, ii As Integer, pp As Integer
Dim arrV(1 To 10) As Integer, nn As Long, arrW(1 To 8) As String, dblT As Double
Const tt As String = "0123456789"
Application.StatusBar = False
Perm tt, "", zz, arrE()
For zz = 1 To 3628800
For ii = 10 To 2 Step -1
For pp = 1 To 11 - ii
dblT = CDbl(Mid(arrE(zz), pp, ii))
If dblT = 7 * Fix(dblT / 7) Then
arrV(ii) = 1
If 1 = 9 Then
nn = nn + 1
Cells(nn, 1) = arrE(zz)
Cells(nn, 2).Resize(, 8) = arrW
For ii = 1 To 8
Cells(nn, ii + 10) = CDbl(arrW(ii)) / 7
Next ii
Cells(nn, ii + 10) = arrE(zz) / 7
End If
Erase arrV, arrW
Application.StatusBar = zz & " / " & arrE(zz)
DoEvents
Next zz
Application.StatusBar = False
End Sub
Sub Perm(aa As String, bb As String, Ze As Long, arrX() As String)
Dim ii As Long, jj As Long
jj = Len(aa)
If jj > 1 Then
For ii = 1 To jj
Perm Left(aa, ii - 1) + Right(aa, jj - ii), bb + Mid(aa, ii, 1), Ze, arrX()
Next ii
Else
Ze = Ze + 1
arrX(Ze) = bb & aa
End If
End Sub

Auf die Ausgabe der einstelligen durch 7 teilbaren Zahl wird hier verzichtet, die ist ohnehin immer 0 oder 7.
Rückmeldung wäre nett! - Grüße von Erich aus Kamp-Lintfort

Anzeige
AW: VBA und Knobelfreunde
05.06.2009 09:32:18
alifa
Hallo Erich,
zunächst vielen Dank für das Makro. Nett, dass es doch noch geklappt hat!. Die ersten 2636 Zeilen enthalten nur 9 Ziffern. Da steht anscheinend die 0 vor. Diese Ergebnisse müssten durch ein "If" im Makro ausgeschlossen werden. Z.B. die erste Zahl, 123956784 enthält keine entsprechende achtstellige, durch 7 teilbare Zahl. Ich muss gestehen, dass ich das Makro nur in groben Zügen verstehe. Du hast mehrere Datenfelder eingesetzt. Es wäre nett, wenn du Erklärungen zufügen könntest.
Gruß, Erhard
AW: Prozedur mit Kommentaren
05.06.2009 10:24:03
Erich
Hi Erhard,
die Lösungen mit "0" am Anfang auszuschließen halte ich für nicht logisch.
Müsstest du dann nicht auch z. B. die Lösung
1269543807 07 126 2695 95438 954380 9543807 12695438 126954380
ausschließen, weil die zweistellige 07 eigentlich nur eine einstellige Zahl 7 ist?
Für mich geht es hier um Permutationen der Menge {0,1,2,3,4,5,6,7,8,9},
in der die "0" eine Ziffer wie jede andere ist.
Richtiger fände ich es, einfach die Zeile
Columns(1).NumberFormat = "@"
zu ergänzen, dann sieht man die Null auch in der ersten Spalte.
Die Ermittlung der Permutationen werde ich jetzt hier nicht erläutern, da kannst du sicher
Einiges per Google oder so finden. Hier noch mal die Hauptroutine mit ein paar
Kommentaren:

Sub Teiler7()    ' 3628800 Permutationen, davon sind 9264 Lösungen
Dim zz As Long, arrE(1 To 3628800) As String, ii As Integer, pp As Integer
Dim arrV(1 To 10) As Integer, nn As Long, arrW(1 To 8) As String, dblT As Double
Const tt As String = "0123456789"
Application.StatusBar = False
Perm tt, "", zz, arrE()        ' 3628800 Permutationen werden in arrE abgelegt
Columns(1).NumberFormat = "@"
For zz = 1 To 3628800          ' Schleife über die 3628800 Permutationen
For ii = 10 To 2 Step -1    ' ii steht für die Länge (10 bis 2) der Teilzahlen
For pp = 1 To 11 - ii    ' pp steht für die Position der Teilzahl
dblT = CDbl(Mid(arrE(zz), pp, ii))  ' Teilzahl als Double
If dblT = 7 * Fix(dblT / 7) Then    ' Ist die Teilzahl teilbar durch 7?
arrV(ii) = 1                     '  Länge ii erledigt
' arrW(ii-1) ist die gefundene Teilzahl als Text
If 1 = 9 Then ' Wurden alle 9 Längen (10 bis 2) erledigt?
nn = nn + 1                     ' Wenn ja, neue Zeilennr.
Cells(nn, 1) = arrE(zz)           ' Eintragen der Lösung arrE(zz)
Cells(nn, 2).Resize(, 8) = arrW   ' Teilzahlen der Lösung in Spalten 2-9 (B:I)
For ii = 1 To 8
Cells(nn, ii + 10) = CDbl(arrW(ii)) / 7 ' Quotienten in Spalten 11-18 (K:R)
Next ii
Cells(nn, ii + 10) = arrE(zz) / 7   ' Lösung / 7 in Spalte 19 (S)
End If
Erase arrV, arrW
Application.StatusBar = zz & " / " & arrE(zz)
DoEvents
Next zz
Application.StatusBar = False
End Sub

Rückmeldung wäre nett! - Grüße von Erich aus Kamp-Lintfort

Anzeige
AW: Prozedur mit Kommentaren
05.06.2009 17:19:23
alifa
Hallo Erich,
habe dein Makro ergänzt und jetzt gibt es nur noch 6628 Lösungen. Diese enthalten keine Null als erste Ziffer und stimmen perfekt. Alle sind 10-stellig und beinhalten die gesuchten Zahlen. Hier die Ergänzung:
Erase arrV, arrW
Application.StatusBar = zz & " / " & arrE(zz)
DoEvents
Next zz
Call Loesch
Application.StatusBar = False
End Sub



Sub Loesch()
Dim Zeile As Long, Spalte As Long, t!
Application.EnableEvents = False
Application.ScreenUpdating = False
For Spalte = 1 To 20
For Zeile = 9300 To 1 Step -1
If (Mid(ActiveCell.Value, 1, 1)) = "0" Then
Selection.EntireRow.Delete
End If
Next
Next
Application.EnableEvents = True
MsgBox "Fertig nach " & Round(Timer - t, 2) & " Sekunden"
End Sub


Gruß, Erhard

Anzeige
Löschen ist falsch, bringt aber eh nichts
06.06.2009 19:49:55
Erich
Hi Erhard,
in deiner Losch-Routine haben Zeile und Spalte (das könnten auch ganz andere Variablennamen sein)
nichts zu tun damit, welche Zelle gepfrüft oder welche Zeile gelöscht wird.
Geprüft wird immer die (zufällig gerade) aktive Zelle.
Die beiden Schleifen über Zeile und Spalte führen nur dazu, dass der Schleifenkörper

If (Mid(ActiveCell.Value, 1, 1)) = "0" Then
Selection.EntireRow.Delete
End If

20 * 9300 = 186000 mal ausgeführt wird.
Ab der ersten aktiven Zelle, an deren 1. Stelle keine "0" steht, ändert sich nichts mehr.
Wenn der Cursor vor dem Makroaufruf in A1 steht, werden die ersten 2636 Zeilen gelöscht,
in denen in Spalte A die Lösungen In anderen Spalten prüft dein Makro nicht!
Stünde der Cursor vor dem Makroaufruf in B1, würde sich überhaupt nichts verändern an der Tabelle.
Damit würdest du das Gleiche (nur schneller) erreichen:


Sub Loesch0()
Dim ii As Long, t As Single
Application.EnableEvents = False
Application.ScreenUpdating = False
For ii = 1 To 2700
If (Mid(ActiveCell.Value, 1, 1)) = "0" Then
Selection.EntireRow.Delete
End If
Next
Application.EnableEvents = True
MsgBox "Fertig nach " & Round(Timer - t, 2) & " Sekunden"
End Sub


Hier eine Routine, die in allen relevanten Zeilen und Spalten sucht:


Option Explicit
Sub Loesch()
Dim Zeile As Long, Spalte As Long, t As Single
Application.EnableEvents = False
Application.ScreenUpdating = False
t = Timer
For Zeile = Cells(Rows.Count, 3).End(xlUp).Row To 1 Step -1
For Spalte = 1 To 8
If Left(Cells(Zeile, Spalte).Value, 1) = "0" Then
Rows(Zeile).Delete
Exit For
End If
Next Spalte
Next Zeile
Application.EnableEvents = True
Application.ScreenUpdating = True
MsgBox "Fertig nach " & Round(Timer - t, 2) & " Sekunden"
End Sub

Diese Routine löscht 4620 von den 9264 Lösungen, 4644 Lösungen bleiben erhalten.
Aber: Dabei werden auch Lösungen gelöscht, die nach der engeren Definition zulässig sind!
Beispiel:
In der Liste mit den 9264 Lösungen (mit den Nullen) gibt es die Lösung
1420385967 14 420 0385 14203 420385 2038596 20385967 142038596
Sie wird wegen der 0 am Anfang von 0385 gelöscht.
Lässt man gleich nach Lösungen suchen, bei denen keine führenden Nullen vorkommen,
wird die Lösung
1420385967 14 420 8596 14203 420385 2038596 20385967 142038596
gefunden.
Sie ist sicher zulässig - 8596 ist eben eine weitere 4stellige durch 7 teilbare Teilzahl.
Man darf also nicht einfach löschen, sondern müsste auch prüfen,
ob anstelle einer nicht zulässigen Teilzahl eine andere zulässig ist,
sonst löscht man zu viele Lösungen.
So findet man direkt die 4840 Lösungen ohne führende Nullen:


Option Explicit
Sub Teiler7()    ' 3628800 Permutationen, davon sind 9264 Lösungen
Dim zz As Long, arrE(1 To 3628800) As String, ii As Integer, pp As Integer
Dim arrV(1 To 10) As Integer, nn As Long, arrW(1 To 8) As String, dblT As Double
Const tt As String = "0123456789"
Application.StatusBar = False
Perm tt, "", zz, arrE()        ' 3628800 Permutationen werden in arrE abgelegt
Columns(1).NumberFormat = "@"
For zz = 1 To 3628800          ' Schleife über die 3628800 Permutationen
For ii = 10 To 2 Step -1    ' ii steht für die Länge (10 bis 2) der Teilzahlen
For pp = 1 To 11 - ii    ' pp steht für die Position der Teilzahl
If Mid(arrE(zz), pp, 1) > "0" Then
dblT = CDbl(Mid(arrE(zz), pp, ii))  ' Teilzahl als Double
If dblT = 7 * Fix(dblT / 7) Then    ' Ist Teilzahl teilbar durch 7?
arrV(ii) = 1                     '  Länge ii erledigt
' arrW(ii-1): gefundene Teilzahl als Text
If 1 = 9 Then ' Wurden alle 9 Längen (10 bis 2) erledigt?
nn = nn + 1                     ' Wenn ja, neue Zeilennr.
Cells(nn, 1) = arrE(zz)           ' Eintragen der Lösung arrE(zz)
Cells(nn, 2).Resize(, 8) = arrW   ' Teilzahlen der Lösung in Spalten 2-9 (B:I)
For ii = 1 To 8
Cells(nn, ii + 10) = CDbl(arrW(ii)) / 7 ' Quotienten in Spalten 11-18 (K:R)
Next ii
Cells(nn, ii + 10) = arrE(zz) / 7   ' Lösung / 7 in Spalte 19 (S)
End If
Erase arrV, arrW
Application.StatusBar = zz & " / " & arrE(zz)
DoEvents
Next zz
Application.StatusBar = False
End Sub
Sub Perm(aa As String, bb As String, Ze As Long, arrX() As String)
Dim ii As Long, jj As Long
jj = Len(aa)
If jj > 1 Then
For ii = 1 To jj
Perm Left(aa, ii - 1) + Right(aa, jj - ii), bb + Mid(aa, ii, 1), Ze, arrX()
Next ii
Else
Ze = Ze + 1
arrX(Ze) = bb & aa
End If
End Sub

Rückmeldung wäre nett! - Grüße von Erich aus Kamp-Lintfort

Anzeige
AW: Löschen ist falsch, bringt aber eh nichts
07.06.2009 09:55:15
alifa
Hallo Erich,
was ist richtig Gier oder Grüner?!?
Zunächst vielen Dank, mit einem tränenden und einem lachenden Auge!
Du hast Recht, mit dem Löschen. Hatte mein Makro verbessert und kam auch auf die 4644 Lösungen, was falsch war. Ich finde deine Lösung beachtenswert und staune noch. Die Schlüsselwörter(z.B. Application.StatusBar u.a.) werde ich im Web suchen, um der Sache richtig auf den Grund zu gehen.
Ich wünsche dir einen schönen Sonntag. Aus dem Oberbergischen, Erhard
Grüner oder Gier?
07.06.2009 11:51:46
Erich
Hi Erhard,
"was ist richtig Gier oder Grüner?!?"? Schau doch mal in Forums-Seiten - Profile - Profilliste ...
Noch einen schönen Sonntag! Grüße von Erich aus Kamp-Lintfort
P.S. Wer ist E. Grüner?
Anzeige
AW: Grüner oder Gier?
09.06.2009 11:59:08
alifa
Hallo Erich,
Wie kann ich das Makro mit der 7 so ändern, dass JEDE UNTERZAHL nur EINMAL vorkommt. Also bei Andi's Zahl 4956213087 sind drei 4-stellige "Unterzahlen", die durch 7 teilbar sind. 4956, 9562,5621. Es sollen aber von allen NUR eine sein.
Gruß, Erhard
Teilzahl einmalig
09.06.2009 15:43:52
Erich
Hi Erhard,
sinnvoll ist das wohl nur, wenn auch gefordert wird, dass keine Teilzahl mit 0 beginnt,
sonst wären 0 und 7 als einstellige Teilzahlen immer da.
Damit bekomme ich 36 Lösungen:

Sub Teiler7E()    ' 3628800 Permutationen, davon sind 9264 Lösungen
Dim zz As Long, arrE(1 To 3628800) As String, ii As Integer, pp As Integer
Dim arrV(1 To 10) As Integer, nn As Long, arrW(1 To 8) As String, dblT As Double
Const tt As String = "0123456789"
Application.StatusBar = False
Perm tt, "", zz, arrE()        ' 3628800 Permutationen werden in arrE abgelegt
Columns(1).NumberFormat = "@"
For zz = 1 To 3628800          ' Schleife über die 3628800 Permutationen
For ii = 10 To 2 Step -1    ' ii steht für die Länge (10 bis 2) der Teilzahlen
For pp = 1 To 11 - ii    ' pp steht für die Position der Teilzahl
If Mid(arrE(zz), pp, 1) > "0" Then
dblT = CDbl(Mid(arrE(zz), pp, ii))  ' Teilzahl als Double
If dblT = 7 * Fix(dblT / 7) Then    ' Ist Teilzahl teilbar durch 7?
If arrV(ii) > 0 Then
arrV(ii) = -1                 '  Länge ii ist doppelt, raus
Exit For
Else
arrV(ii) = 1                  '  Länge ii gefunden
' arrW(ii-1): gefundene Teilzahl als Text
If 1 = 9 Then ' Wurden alle 9 Längen (10 bis 2) erledigt?
nn = nn + 1                     ' Wenn ja, neue Zeilennr.
Cells(nn, 1) = arrE(zz)           ' Eintragen der Lösung arrE(zz)
Cells(nn, 2).Resize(, 8) = arrW   ' Teilzahlen der Lösung in Spalten 2-9 (B:I)
'         For ii = 1 To 8
'            Cells(nn, ii + 10) = CDbl(arrW(ii)) / 7 ' Quotienten in Spalten 11-18 (K:R)
'         Next ii
'         Cells(nn, ii + 10) = arrE(zz) / 7   ' Lösung / 7 in Spalte 19 (S)
End If
Erase arrV, arrW
Application.StatusBar = zz & " / " & arrE(zz) & " / " & nn
DoEvents
Next zz
Application.StatusBar = False
End Sub

Rückmeldung wäre nett! - Grüße von Erich aus Kamp-Lintfort

Anzeige
AW: Teilzahl einmalig
09.06.2009 17:29:22
alifa
Hallo Erich,
kleine Änderung, große Wirkung! Ich befinde mich in deiner Schuld. Was kann ich für dich tun?
Gruß, Erhard

299 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige