Testen ob ein Integer die Zahlen 1-9 enthält

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Testen ob ein Integer die Zahlen 1-9 enthält

    Hallo liebes Forum.
    Ich bin aus meiner Winterstarre wieder zurückgekehrt und stehe gerade extrem auf dem Schlauch.

    Ich bin gerade dabei diese Aufgabe als VB Programm umzusetzen.


    Prinzipiell läuft auch schon alles, jedoch habe ich am Ende noch extrem schmutzigen Code

    VB.NET-Quellcode

    1. For Each x As Integer In Array9
    2. If x.ToString.Contains("1") AndAlso x.ToString.Contains("2") AndAlso x.ToString.Contains("3") AndAlso x.ToString.Contains("4") AndAlso x.ToString.Contains("5") AndAlso x.ToString.Contains("6") AndAlso x.ToString.Contains("7") AndAlso x.ToString.Contains("8") AndAlso x.ToString.Contains("9") Then
    3. Console.WriteLine("Lösung:" & x)
    4. End If
    5. Next


    Am Ende will ich ich den Array mit allen Lösungen durchgehen und schauen, in welchen jede Zahl vorkommt (da wenn jede vorkommt, keine mehr doppelt sein kann)

    Jedoch ist die Methode den Integer als String jedesmal nach einer Zahl durchzuschauen nicht gerade die schöne Art.
    Fällt euch dort zufällig was auf Anhieb ein ?

    Freue mich über Vorschläge

    Mit freundlichen Grüßen
    Neo127
    Wenn du mit Ziffern arbeiten willst, ist der Umweg über einen String gar nicht so verkehrt.

    VB.NET-Quellcode

    1. For Each x As Integer In Array9
    2. Dim s = x.ToString
    3. If s.Contains("1") AndAlso s.Contains("2") AndAlso s.Contains("3") AndAlso s.Contains("4") AndAlso s.Contains("5") AndAlso s.Contains("6") AndAlso s.Contains("7") AndAlso s.Contains("8") AndAlso s.Contains("9") Then
    4. Console.WriteLine("Lösung:" & x)
    5. End If
    6. Next

    Oder du schreibst eine Funktion ContainsAllNumbers, die du aus der Schleife aufrufst

    VB.NET-Quellcode

    1. Function ContainsAllNumbers(s As String) As Boolean
    2. Dim Digits = "123456789".ToCharArray
    3. For Each d In Digits
    4. If Not s.Contains(d) Then Return False
    5. Next
    6. Return True
    7. End Function

    Alternativ:

    VB.NET-Quellcode

    1. Function ContainsAllNumbers(n As Integer) As Boolean
    2. Dim s = n.ToString
    3. Dim Digits = "123456789".ToCharArray
    4. For Each d In Digits
    5. If Not s.Contains(d) Then Return False
    6. Next
    7. Return True
    8. End Function
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „petaod“ ()

    Danke für deine Antwort und den ganzen Code.

    Hatte erst gedacht es wäre irgendwie möglich entweder mehrere Zeichen gleichzeitig in Contain abzufragen, oder es gar eine Contain Alternative für Integer gibt.
    Werde mich wahrscheinlich auf die erste simple Version mit s = x.ToString entscheiden, da diese Abfrage nur einmal vorkommt.

    Nochmal vielen Dank und dir ein tollen restlichen Abend
    Interessante Aufgabe. Nur die 3. Anforderung versteh ich nicht ganz.

    Was ich auch nicht verstehe, warum das geprüft werden muss, ob jede Zahl von 1 - 9 in der 9-Stelligen Zahl vorhanden sein soll. Nimm doch gleich von Anfang weg "123456789" und lass die ordentlich "Shuffeln". Es werden in diesem String immer die Zahlen 1 - 9 vorhanden sein, einfach nur nie an der gleichen Stelle.

    Freundliche Grüsse

    exc-jdbi
    @Neo127 Vielleicht so was:
    Value to Strinng to CharArray, sortieren, per LINQ Dubletten rauswerfen, Anzahl der restlichen Werte ermitteln.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @3daycliff Korrekt.
    Man baue eine Zahl, die die betreffenden Eigenschaften hat.
    Also:
    Wie bestimmt man, ob eine Zahl durch n teilbar ist?
    n=7 ist etwas problematisch.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Wie bestimmt man, ob eine Zahl durch n teilbar ist?
    n=7 ist etwas problematisch.

    Visual Basic-Quellcode

    1. if x/7 = int(x/7) then ...


    Die Aufgabe ist schon älter. Mit heutigen Rechnern kann man alle Möglichkeiten, in zumutbarer Zeit, durchprobieren.
    Mit ein paar Vorüberlegungen lässt sich aber die Datenmenge reduzieren. Eine Zahl ist durch 2 teilbar, wenn ihre letzte
    Stelle eine gerade Zahl ist, daher kommen für die geraden Stellenzahlen nur gerade Zahlen in Frage. Dann bleiben für
    die ungeraden Stellenzahlen nur die ungeraden Zahlen übrig. Eine Zahl ist durch 5 teilbar, wenn ihre letzte Stelle eine
    0 oder eine 5 ist. Da 0 hier nicht erlaubt ist, bleibt nur die 5 übrig. Die fällt dann für die anderen Positionen weg.
    Das Problem lässt sich so mit 8 verschachtelten Schleifen in kurzer Zeit lösen.

    Gruss,

    Neptun

    Neptun schrieb:

    Dann bleiben für die ungeraden Stellenzahlen nur die ungeraden Zahlen übrig
    Falsch.
    Eine Zahl ist durch 3 teilbar, wennn ...
    12, 18 enden gerade.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hätte nicht gedacht das sich so viele Leute daran interessieren.

    Packe einfach mal mein ganzen (grauenhaften) Code, welchen ich in ein paar Minuten zusammengeklatscht habe hier rein.

    Habe mal ein paar Kommentare dazugepackt, das es einfach zu lesen ist

    VB.NET-Quellcode

    1. Module Module1
    2. Dim arraycounter As Integer = 1 'Wert zum Tracken der Größe des Arays (Wird in an Stelle 0 in jedem Array gespeichert)
    3. Dim Array1(), Array2(), Array3(), Array4(), Array5(), Array6(), Array7(), Array8(), Array9() As Integer 'Arrays für jede Stelle der Zahl wird erstellt, um die Ergebnisse für jede Zahl abzuspeichern
    4. Sub Main()
    5. Array1 = New Integer(9) {} : Array2 = New Integer(81) {} : Array3 = New Integer(600) {} : Array4 = New Integer(600) {} : Array5 = New Integer(600) {} : Array6 = New Integer(600) {} : Array7 = New Integer(600) {} : Array8 = New Integer(600) {} : Array9 = New Integer(600) {}
    6. For item As Integer = 1 To 9 'Geht die Stellen der Zahl durch
    7. arraycounter = 1
    8. For counter As Integer = 1 To 9 'Geht die Ziffern 1-9 durch
    9. Select Case item
    10. Case 1
    11. If isDivisible(counter, item) = True Then
    12. Console.WriteLine(counter & " durch " & item & " teilbar " & counter / item)
    13. Array1(arraycounter) = counter
    14. arraycounter += 1
    15. End If
    16. If counter = 9 Then
    17. Array1(0) = arraycounter - 1
    18. End If
    19. Case 2
    20. Array2 = CalcDiv(Array1, Array2, counter, item)
    21. Case 3
    22. Array3 = CalcDiv(Array2, Array3, counter, item)
    23. Case 4
    24. Array4 = CalcDiv(Array3, Array4, counter, item)
    25. Case 5
    26. Array5 = CalcDiv(Array4, Array5, counter, item)
    27. Case 6
    28. Array6 = CalcDiv(Array5, Array6, counter, item)
    29. Case 7
    30. Array7 = CalcDiv(Array6, Array7, counter, item)
    31. Case 8
    32. Array8 = CalcDiv(Array7, Array8, counter, item)
    33. Case 9
    34. Array9 = CalcDiv(Array8, Array9, counter, item)
    35. End Select
    36. Next
    37. Next
    38. For Each x As Integer In Array9 'Geht jede Zahl durch und schaut ob alle Zahlen von 1-9 entahlten sind
    39. Dim s = x.ToString
    40. If s.Contains("1") AndAlso s.Contains("2") AndAlso s.Contains("3") AndAlso s.Contains("4") AndAlso s.Contains("5") AndAlso s.Contains("6") AndAlso s.Contains("7") AndAlso s.Contains("8") AndAlso s.Contains("9") Then
    41. Console.WriteLine("Lösung:" & s)
    42. End If
    43. Next
    44. Console.ReadKey() 'Pausiert die Konsole, bis Input vom User gegeben wird (Damit der User sich die Antwort ansehen kann)
    45. End Sub
    46. Function isDivisible(x As Integer, d As Integer) As Boolean 'Funktion um zu schauen, ob etwas ohne Rest teilbar ist
    47. Return (x Mod d) = 0
    48. End Function
    49. Function CalcDiv(pastArray As Integer(), currentArray As Integer(), counterfunc As Integer, itemfunc As Integer) As Integer() 'Funktion zum errechnen aller teilbaren Lösungen
    50. For NumbCounter As Integer = 1 To pastArray(0) 'Geht alle Errechneten Zahlen des Vorherigen Arrays/der vorherigen Stelle durch
    51. If isDivisible(pastArray(NumbCounter) * 10 + counterfunc, itemfunc) = True Then 'Checkt ob die Vorherige Zahl mit einer neuen Zahl angehängt wieder teilbar ist (Neue Zahl = counter [siehe Zeile 12])
    52. Console.WriteLine(pastArray(NumbCounter) * 10 + counterfunc & " durch " & itemfunc & " teilbar = " & ((pastArray(NumbCounter) * 10 + counterfunc) / itemfunc))
    53. currentArray(arraycounter) = (pastArray(NumbCounter) * 10 + counterfunc) 'Speichert Zahl im Array im
    54. arraycounter += 1 'Setz den Counter um 1 hoch, damit die nächste Zahl im nächsten Datensatz gespeichert wird
    55. End If
    56. Next
    57. If counterfunc = 9 Then 'Wenn die Zahl 9 durch ist, schreibt er er die Anzahl an Datensätzen an die Stelle 0 im Array
    58. currentArray(0) = arraycounter - 1
    59. End If
    60. Return currentArray
    61. End Function
    62. End Module





    Edit:

    @Neptun

    Hatte vor es so zu lösen, das ich dem Programm in dem Sinne keine vorgaben gebe, welche es erleichtern könnte.
    Es soll ohne persönliche vorgaben bzw ohne jeglichen eigenen Hirnschmalz die Aufgabe lösen können

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Neo127“ ()

    @Neptun Dein Ansatz gefällt mir
    Ich habe mir gesagt ich lass den einfach Shuffeln und die Zahl 5 sofern nicht an der richtigen Stelle Swapen.
    Laufzeit 169 ms.

    @Neo127
    Mein Vorgehen.

    VB.NET-Quellcode

    1. 'Ablauf
    2. '******
    3. 'Nimm eine While-Schleife und schreib die
    4. 'while-condition als True also "While True"
    5. 'Ich persönlich nehme gerne eine Int32-Array
    6. 'mit den Zahlen 1 - 9 und lass die komplett
    7. 'Shuffeln ".OrderBy"
    8. 'Jetzt eine For-Schleife die durch die soeben
    9. 'geShuffelte Array durch iteriert.
    10. 'Eine Funktion machen die die Array bis an der n-te
    11. 'Stelle verkettet. "String.Join", "Take", "CInt"
    12. 'Eine weitere Funktion die die oben verkettete
    13. 'Nummer prüft ob der Wert mit n teilbar ist.
    14. 'Schau dazu "mod" an. Return numeric Mod n = 0
    15. 'Und nun lässt du den Algo rennen.



    Freundliche Grüsse

    exc-jdbi

    exc-jdbi schrieb:

    Interessante Aufgabe. Nur die 3. Anforderung versteh ich nicht ganz.

    Was ich auch nicht verstehe, warum das geprüft werden muss, ob jede Zahl von 1 - 9 in der 9-Stelligen Zahl vorhanden sein soll. Nimm doch gleich von Anfang weg "123456789" und lass die ordentlich "Shuffeln". Es werden in diesem String immer die Zahlen 1 - 9 vorhanden sein, einfach nur nie an der gleichen Stelle.

    Freundliche Grüsse

    exc-jdbi


    Vollzitat des Vorposts an dieser Stelle entfernt ~VaporiZed


    Die Aufgabe ist für meinen potentiellen neuen Ausbildungsbetrieb.
    Ich hab in meinem aktuellen Betrieb große Probleme die letzten 2 Jahre gehabt (angeschrienen, beleidigt, gelästert, falsche Abmahnungen) das ich den Betrieb jetzt im 3. Ausbildungsjahr verlasse, da mein Leben und meine Schulnoten darunter leiden. Daher wollte ich in einen neuen Betrieb wechseln.
    Dort sollte ich nach dem Gespräch mit meinen potentiellen neuen Ausbildungsbetrieb diese Aufgabe lösen.
    Aus diesen Grund habe ich auch nur nach Vorschläge bezüglich dieser einen Sache nachgefragt, da ich meine Leistung und nicht die von anderen Leuten zeigen will.
    Die einzige Bedingung war es, nicht mithilfe von random raten die Zahl auszubekommen, was Shuffle ja wäre.
    Daher habe ich nicht den Weg genommen, sondern den Weg, das dass Programm alles selber macht.

    Wünsche euch noch einen schönen Abend ^^

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    also ich würd die Aufgabe so lösen, wie sie da steht.
    Also eine List(Of Integer) machen, wo die zulässigen zahlen/ziffern drinne sind
    Und dann die Lösung schrittweise aufbauen.
    Erst die erste ziffer, dann die 2. Ziffer - und da muss man dann rumprobieren, welche der verbliebenen Ziffern die Bedingung noch erfüllen.
    Dann die 3. ziffer usw. bis 9.
    die verwendeten ziffern tatsächlich jeweils aus der List(Of Integer) entfernen - sie dürfen ja nicht mehrfach auftreten.

    Das ziffer zufügen ist eine eigene Methode, da muss die gesamtzahl mit 10 multipliziert werden, bevor du die ziffer zufügst.

    Und wenn sich zwischenzeitlich zeigt, dass es nicht aufgehen wird, muss man Schritte zurückgehen, bis zum Punkt, wo man die falsche Ziffer gewählt hat.
    Eine rekursive Lösung mit Backtracking zeichnet sich ab...

    Wieviel Zeit hast du für die Aufgabe?

    Andererseits würde ich dir den neuen Betrieb wirklich wirklich empfehlen. Da scheinen Leute zu sitzen, die's echt drauf haben, und von denen du schwer was lernen kannst.
    Allein die Idee, dir eine ProgrammierAufgabe zu stellen, zeugt von Qualität der IT-Abteilung.

    Dein Code versteh ich leider garnet. Was sollen diese vielen Arrays, und wieso Array(600)?

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Hallo @ErfinderDesRades
    Hatte nur den Tag Zeit, um zu schauen was ich in der Zeit hin bekomme.
    das waren anfangs festgelegte Arraygrößen, bei denen ich mir sicher war, das dort die Lösung reinpassten.
    Mitlerweile habe ich eine größe von 1 festgelegt, welche immer wieder erhöht wird, wenn neue Datensätze hinzugefügt werden.
    Die ganzen Arrays sind unnütz, ich weiß unrsprünglich sollte auch nur die letzte Zahl in einem Array abgespeichert werden, jedoch ist mir dann aufgefallen, das es einfacher und logischer wäre die komplette Zahl immer abzuspeichern.
    Habe es heute morgen abgeschickt.

    VB.NET-Quellcode

    1. [/sub]Module Module1
    2. Dim arraycounter As Integer = 1 'Wert zum Tracken der Größe des Arays (Wird in an Stelle 0 in jedem Array gespeichert)
    3. Dim Array1(), Array2(), Array3(), Array4(), Array5(), Array6(), Array7(), Array8(), Array9() As Integer 'Arrays für jede Stelle der Zahl wird erstellt, um die Ergebnisse für jede Zahl abzuspeichern
    4. Sub Main()
    5. Array1 = New Integer(8) {} : Array2 = New Integer(1) {} : Array3 = New Integer(1) {} : Array4 = New Integer(1) {} : Array5 = New Integer(1) {} : Array6 = New Integer(1) {} : Array7 = New Integer(1) {} : Array8 = New Integer(1) {} : Array9 = New Integer(1) {}
    6. For item As Integer = 1 To 9 'Geht die Stellen der Zahl durch
    7. arraycounter = 0
    8. For counter As Integer = 1 To 9 'Geht die Ziffern 1-9 durch
    9. Select Case item
    10. Case 1
    11. If isDivisible(counter, item) = True Then
    12. Console.WriteLine(counter & " durch " & item & " teilbar " & counter / item)
    13. Array1(arraycounter) = counter
    14. arraycounter += 1
    15. End If
    16. Case 2
    17. Array2 = CalcDiv(Array1, Array2, counter, item)
    18. Case 3
    19. Array3 = CalcDiv(Array2, Array3, counter, item)
    20. Case 4
    21. Array4 = CalcDiv(Array3, Array4, counter, item)
    22. Case 5
    23. Array5 = CalcDiv(Array4, Array5, counter, item)
    24. Case 6
    25. Array6 = CalcDiv(Array5, Array6, counter, item)
    26. Case 7
    27. Array7 = CalcDiv(Array6, Array7, counter, item)
    28. Case 8
    29. Array8 = CalcDiv(Array7, Array8, counter, item)
    30. Case 9
    31. Array9 = CalcDiv(Array8, Array9, counter, item)
    32. End Select
    33. Next
    34. Next
    35. For Each x As Integer In Array9 'Geht jede Zahl durch und schaut ob alle Zahlen von 1-9 entahlten sind
    36. Dim s = x.ToString
    37. If s.Contains("1") AndAlso s.Contains("2") AndAlso s.Contains("3") AndAlso s.Contains("4") AndAlso s.Contains("5") AndAlso s.Contains("6") AndAlso s.Contains("7") AndAlso s.Contains("8") AndAlso s.Contains("9") Then
    38. Console.WriteLine("Lösung:" & s)
    39. End If
    40. Next
    41. Console.ReadKey() 'Pausiert die Konsole, bis Input vom User gegeben wird (Damit der User sich die Antwort ansehen kann)
    42. End Sub
    43. Function isDivisible(x As Integer, d As Integer) As Boolean 'Funktion um zu schauen, ob etwas ohne Rest teilbar ist
    44. Return (x Mod d) = 0
    45. End Function
    46. Function CalcDiv(pastArray As Integer(), currentArray As Integer(), counterfunc As Integer, itemfunc As Integer) As Integer() 'Funktion zum errechnen aller teilbaren Lösungen
    47. ReDim Preserve currentArray(currentArray.Length + pastArray.Length) 'Setzt Arraygröße auf maximal Mögliche Ergebnisse, da die Anzahl an Berechnungen auf den Array hinzugefügt werden
    48. For NumbCounter As Integer = 1 To pastArray.Length - 1 'Geht alle Errechneten Zahlen des Vorherigen Arrays/der vorherigen Stelle durch
    49. If isDivisible(pastArray(NumbCounter) * 10 + counterfunc, itemfunc) = True Then 'Checkt ob die Vorherige Zahl mit einer neuen Zahl angehängt wieder teilbar ist (Neue Zahl = counter [siehe Zeile 12])
    50. Console.WriteLine(pastArray(NumbCounter) * 10 + counterfunc & " durch " & itemfunc & " teilbar = " & ((pastArray(NumbCounter) * 10 + counterfunc) / itemfunc))
    51. currentArray(arraycounter) = (pastArray(NumbCounter) * 10 + counterfunc) 'Speichert Zahl im Array
    52. arraycounter += 1 'Setz den Counter um 1 hoch, damit die nächste Zahl im nächsten Datensatz gespeichert wird
    53. End If
    54. Next
    55. If counterfunc = 9 Then 'Wenn die Zahl 9 durch ist, schreibt er er die Anzahl an Datensätzen an die Stelle 0 im Array
    56. ReDim Preserve currentArray(arraycounter - 1) 'Setzt Arraygröße auf benutze Menge
    57. End If
    58. Return currentArray
    59. End Function
    60. End Module[sub]


    Vollzitat entfernt ~EaranMaleasi

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „EaranMaleasi“ ()

    Rein mathematisch betrachtet muss die Differenz zwischen zwei dieser Zahlen durch 9 teilbar sein. Du kannst also mit der ersten Zahl 123456789 beginnen und immer mit 9 addieren und dann prüfen. Dann sparst du dir 90% der Abgleiche.

    Beispiel:
    123456798 - 123456789 = 9 (9 * 1)
    123456879 - 123456798 = 81 (9 * 9)
    123456897 - 123456879 = 18 (9 * 2)
    123456978 - 123456897 = 81 (9 * 9)
    123456987 - 123456978 = 9 (9 * 1)
    123457689 - 123456987 = 702 (9 * 78)
    123457869 - 123457689 = 180 (9 * 20)
    123457896 - 123457869 = 27 (9 * 3)
    123465789 - 123457896 = 7893 (9 * 877)
    123467589 - 123465789 = 1800 (9 * 200)
    123467859 - 123467589 = 270 (9 * 30)
    etc.

    VB.NET-Quellcode

    1. Private Function SucheZahlen() As List(Of Integer)
    2. Dim x As Integer = 123456789
    3. Dim Zahlenliste As New List(Of Integer)
    4. Dim isValid As Boolean = True
    5. For i = 123456789 To 1000000008 Step 9
    6. Dim SuchZahl As String = i.ToString
    7. isValid = True
    8. For j = 1 To 9
    9. Dim Zeichen = j.ToString
    10. If Not SuchZahl.Contains(Zeichen) Then
    11. isValid = False
    12. Exit For
    13. End If
    14. Next
    15. If isValid Then
    16. Zahlenliste.Add(i)
    17. End If
    18. Next
    19. Return Zahlenliste
    20. End Function



    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Yanbel“ ()

    Neo127 schrieb:

    Prinzipiell läuft auch schon alles, jedoch habe ich am Ende noch

    Wenn ich die obigen Angaben richtig verstanden habe, kommen bereits ein paar Zeilen Code zum Ergebnis:

    VB.NET-Quellcode

    1. Private Function GetResultFromTask() As List(Of Integer)
    2. Dim numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9}
    3. Return (From a In numbers
    4. From b In numbers.Except({a})
    5. From c In numbers.Except({a, b})
    6. From d In numbers.Except({a, b, c})
    7. From e In numbers.Except({a, b, c, d})
    8. From f In numbers.Except({a, b, c, d, e})
    9. From g In numbers.Except({a, b, c, d, e, f})
    10. From h In numbers.Except({a, b, c, d, e, f, g})
    11. From i In numbers.Except({a, b, c, d, e, f, g, h})
    12. Where numbers.All(Function(n) (CInt(String.Join("", New Integer() {a, b, c, d, e, f, g, h, i})) \ CInt(10 ^ (9 - n))) Mod n = 0)
    13. Select CInt(String.Join("", New Integer() {a, b, c, d, e, f, g, h, i}))).ToList
    14. End Function
    Ich denke dann setze ich meine zwei Lösungen auch noch rein.

    1. Mit Shuffel-Random
    2. Mit Permutation (ohne Random)

    Freundliche Grüsse

    exc-jdbi

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. '2 Lösungen
    4. '**********
    5. '1. Mit einer Shuffel-Random
    6. '2. Mit einer Permutation (ohne Random)
    7. 'In beiden Varianten wird eine Basis-Array
    8. '{1, 2, 3, 4, 5, 6, 7, 8, 9} verwendet
    9. 'D.h. nur die Plätze der jeweiligen Zahlen
    10. 'werden vertauscht.
    11. Public Module MaskSolver
    12. Public MaskEndings()() As Int32 =
    13. {
    14. ({0}),' 0 ist nicht vorhanden
    15. ({1, 2, 3, 4, 6, 7, 8, 9}),' Jede Zahl ist durch 1 teilbar
    16. ({2, 4, 6, 8}),' Nur gerade Zahlen
    17. ({1, 2, 3, 4, 6, 7, 8, 9}),' Jede Endung ist möglich
    18. ({2, 4, 6, 8}),' Nur gerade Zahlen
    19. ({5}),' Nur 5 da 0 wegfällt
    20. ({2, 4, 6, 8}),' Nur gerade Zahlen
    21. ({1, 2, 3, 4, 6, 7, 8, 9}),' Jede Endung ist möglich
    22. ({2, 4, 6, 8}),' Nur gerade Zahlen
    23. ({1, 2, 3, 4, 6, 7, 8, 9})' Jede Endung ist möglich
    24. }
    25. End Module
    26. Module NumericSolver
    27. Public Rand As New Random
    28. Public Sub Main()
    29. 'Result = 381654729
    30. Beispiel1()
    31. Beispiel2()
    32. End Sub
    33. ' ********* ********* ********* ********* ********* *********
    34. ' ********* ********* ********* ********* ********* *********
    35. Private Sub Beispiel1()
    36. Dim iter As Int32
    37. Dim numeric As Int32
    38. Dim sw = New Stopwatch
    39. Dim digits() As Int32 = Nothing
    40. sw.Restart()
    41. While True
    42. iter = 0
    43. digits = GetRngDigits()
    44. Swab5(digits)
    45. For i As Int32 = 0 To digits.Length - 1
    46. numeric = ConcatenateNumeric(digits, i)
    47. 'Sofern Anzahl Stellen
    48. If Not CheckNumeric(numeric, i + 1) Then Exit For
    49. iter += 1
    50. If iter = 9 Then Exit While
    51. Next
    52. End While
    53. sw.Stop()
    54. 'PrintOut
    55. Console.WriteLine("Random-Variante")
    56. Array.ForEach(digits, Sub(x) Console.Write(x))
    57. Console.WriteLine()
    58. Console.WriteLine(sw.ElapsedMilliseconds)
    59. Console.ReadLine()
    60. 'Resultat: 381654729
    61. 'ca. 160 - 250 ms
    62. End Sub
    63. Private Sub Swab5(digits() As Int32)
    64. Dim idx = Array.FindIndex(digits, Function(x) x = 5)
    65. If idx = 4 Then Return
    66. digits(idx) = digits(4)
    67. digits(4) = 5
    68. End Sub
    69. Private Function GetRngDigits() As Int32()
    70. Return {1, 2, 3, 4, 5, 6, 7, 8, 9}.
    71. OrderBy(Function(x) Rand.Next).ToArray
    72. End Function
    73. Private Function ConcatenateNumeric(digits() As Int32, n As Int32) As Int32
    74. Return Convert.ToInt32(String.Join(String.Empty, digits.Take(n + 1)))
    75. End Function
    76. Private Function CheckNumeric(numeric As Int32, n As Int32) As Boolean
    77. Return numeric Mod n = 0
    78. End Function
    79. ' ********* ********* ********* ********* ********* *********
    80. ' ********* ********* ********* ********* ********* *********
    81. Private Sub Beispiel2()
    82. Dim sw As New Stopwatch
    83. Dim digits = {1, 2, 3, 4, 5, 6, 7, 8, 9}
    84. Dim cadidate = New List(Of Int32())
    85. sw.Restart()
    86. Permutated(digits, digits.Length, cadidate)
    87. sw.Stop()
    88. 'PrintOut
    89. Console.WriteLine("Permutation-Variante")
    90. For Each item In cadidate
    91. Array.ForEach(item, Sub(x) Console.Write(x))
    92. Console.WriteLine()
    93. Next
    94. Console.WriteLine(sw.ElapsedMilliseconds)
    95. Console.ReadLine()
    96. 'Resultat: 381654729
    97. 'ca. 400 ms
    98. End Sub
    99. Private Sub Permutated(ByRef digits() As Int32,
    100. ByVal length As Int32,
    101. ByRef candidate As List(Of Int32()))
    102. If length <= 1 Then
    103. If CheckDigits(digits) Then
    104. If CheckConcatenateNumeric(digits) Then
    105. candidate.Add(digits.ToArray)
    106. End If
    107. End If
    108. Else
    109. For i As Integer = 0 To length - 1
    110. Swap(digits(i), digits(length - 1))
    111. Permutated(digits, length - 1, candidate)
    112. Swap(digits(i), digits(length - 1))
    113. Next
    114. End If
    115. End Sub
    116. Private Function CheckDigits(digits() As Int32) As Boolean
    117. Return Enumerable.Range(0, digits.Length).
    118. Where(Function(x) MaskEndings(x + 1).Contains(digits(x))).
    119. Count = digits.Length
    120. End Function
    121. Private Function CheckConcatenateNumeric(digits() As Int32) As Boolean
    122. Return Enumerable.Range(0, digits.Length).
    123. Where(Function(x) CheckNumerics(ConcatenateNumerics(digits, x), x + 1)).
    124. Count = digits.Length
    125. End Function
    126. Private Function ConcatenateNumerics(digits() As Int32, n As Int32) As Int32
    127. Dim result = 0I
    128. Dim _digits = digits.Take(n + 1).ToArray
    129. Array.ForEach(_digits, Sub(x) result = result * 10 + x)
    130. Return result
    131. End Function
    132. Private Function CheckNumerics(numeric As Int32, n As Int32) As Boolean
    133. Return numeric Mod n = 0
    134. End Function
    135. Private Sub Swap(Of T)(ByRef t1 As T, ByRef t2 As T)
    136. Dim tmp As T = t1
    137. t1 = t2 : t2 = tmp
    138. End Sub
    139. ' ********* ********* ********* ********* ********* *********
    140. ' ********* ********* ********* ********* ********* *********
    141. End Module