2016-06-03 4 views
0

Ich war gestern in der Dusche, und eine Idee traf mich. Es ist ein mathematisches Muster oder eine Reihe von Regeln, um eine Liste von ganzen Zahlen zu finden.Ein praktisch irrelevanter, nur leicht interessanter Algorithmus und wie kann ich die Logik zum Funktionieren bringen?

Die praktische Anwendung dieses Musters oder wie immer man es nennen könnte, liegt an den Super-Mathematikern, ich wollte nur sehen, ob ich ein Programm machen könnte, das es finden könnte.

Im Moment benutze ich VB.net, da ich es jetzt für die Universität benutzen muss, aber ich bin auch offen für C++.

So sind die Regeln dieses Musters sind:

Sie erhalten einen Integer als „Faktor“, und multiplizieren sie mit sich selbst so oft wie Sie möchten. Dadurch wird eine Liste von Zahlen erstellt, die Sie als Namespaces oder als "Container" bezeichnen.

Wenn der Faktor 2 wäre, würde die Liste wie folgt aussehen - 4, 8, 16, 32, 64 usw. (mit Ausnahme des Basisfaktors).

Jetzt unter jedem Punkt der Liste platzieren Sie alle ganzen Zahlen, die darin passen könnten. Wenn die Nummer des Containers beispielsweise 8 ist, würde jede Nummer von 1 bis 7 aufgelistet.

Die Regeln gehen jedoch weiter.

Eine Nummer innerhalb des Containers kann nicht aufgelistet werden, wenn;

  • es = 1 oder 2
  • es = jede Zahl in dem Behälter, bevor
  • = es ist der Faktor vor
  • oder ist durch eine beliebige Anzahl in dem Behälter vor teilbar.

Zum Beispiel

[4]-[8]-[16]-[32] 
3 7 13 31 
    5 12 29 
     11 26 
     9 25 
     6 23 
     4 19 
     3 17 
       14 
       10 
       7 
       5 

Wie Sie die Zahlen sehen Sie bekommen immer unterschiedlich sind. So arbeitete ich an einem Formular in VS 2015, mit dem Sie den Faktor und die Anzahl der Iterationen (wie lange die Liste lief) in die Liste eingeben konnten.

Das Problem ist, wie Sie vielleicht von der Tatsache erraten werden, dass ich das tatsächlich an erster Stelle mache, ist, dass meine Logik nicht so großartig ist. Als Programmierer bin ich ein Anfänger, und als logischer Denker bin ich nicht der Beste.

Siehe unten, was ich bisher ausprobiert habe. Es ist genau das, was zwischen dem Button Unter war:

Dim iteration As Integer = EtrIterationCount.Text 
    Dim factor As Integer = EtrNumericFactor.Text 
    Dim Container()() As Integer = New Integer(iteration)() {} 
    ReDim Container(iteration)(1) 
    Dim Contents() As Integer = New Integer() {} 

    Dim Base As Integer = factor 


    For X = 1 To iteration - 1 

     Container(X)(1) = New Integer() 
     Base = Base * factor 
     Container(X)(0) = Base 

    Next 


    Container(0)(0) = factor 


    For X = 0 To iteration - 1 
     Dim Test As Integer = Container(X)(0) 
     Dim Num = Test 


     For Num = Num To 0 Step -1 

      If X = 0 Then 
       For W = Num To 0 Step -1 
        If Not Test = 1 Then 
         Contents(W) = Test 
        End If 
       Next 
       Array.ConstrainedCopy(Contents, Contents.Length, Container, Container(X)(1), Contents.Length) 

      ElseIf X >= 1 Then 

       For W = Num To 0 Step -1 
        For J = 0 To Contents.Length - 1 

         If Not Contents(J) Mod Container(X - 1)(1) = 0 Then 
          If Not Test = 1 And Test = Container(X)(0) And Contents.Contains(Test) Then 
           Contents(W) = Test 

          End If 

         End If 

        Next 

       Next 

       Array.ConstrainedCopy(Contents, Contents.Length, Container, Container(X)(1), Contents.Length) 

      End If 

      Test = Test - 1 

      MsgBox(Container(X)(1)) 

     Next 

    Next 

Was ich im Grunde versucht zu tun, etwas, das ich habe vorher noch nie gemacht, und eine gezackte/verschachtelte Array erstellen, die erste Anordnung, die als Behälter Angebot alle Iterationen und die erste Zeile mit den faktorierten Zahlen, die zweite Zeile mit dem Array mit der Werteliste.

Es wurde von einem ersten vorgeschlagen, dass ich Vectors oder eine Klasse von Vektoren verwende, um dieses Problem zu lösen, aber ich habe nicht das foggiest, wie man das macht.

Wenn überhaupt, möchte ich, dass dies Praxis ist, wie man mit Arrays umgeht und mir vielleicht eine Logik beibringt, die ich vermisse.

+0

Ihre zweite Regel wird von der vierten Regel abgedeckt; Ersteres wäre nur dann sinnvoll, wenn der Code wesentlich teurer wäre. –

Antwort

0

Es gibt wahrscheinlich mehrere Möglichkeiten, dies zu tun, viele von ihnen besser als das, was ich kam mit, aber ein Dictionary(Of Integer, List(Of Integer)) ausreichen, um die Daten zu halten:

Option Infer On 
Option Strict On 

Module Module1 

    Sub Main() 

     Console.Write("Factor: ") 
     Dim factor = CInt(Console.ReadLine()) 
     Console.Write("Iterations: ") 
     Dim iters = CInt(Console.ReadLine()) 

     Dim result As New Dictionary(Of Integer, List(Of Integer)) 

     Dim thisSection = factor 
     Dim prevSection = 0 

     For i = 2 To iters + 1 
      thisSection = thisSection * factor 
      result.Add(thisSection, New List(Of Integer)) 

      For j = 3 To thisSection - 1 

       Dim isDivisible = False 

       If prevSection > 0 Then 
        If j Mod prevSection = 0 Then 
         isDivisible = True 
        End If 

        If Not isDivisible Then 
         For Each n In result(prevSection) 
          If j Mod n = 0 Then 
           isDivisible = True 
           Exit For 
          End If 
         Next 
        End If 

       End If 

       If Not isDivisible Then 
        result(thisSection).Add(j) 
       End If 

      Next 

      prevSection = thisSection 

     Next 

     For Each de In result 
      Console.WriteLine("[" & de.Key.ToString() & "] " & String.Join(", ", de.Value.OrderByDescending(Function(x) x))) 
     Next 

     Console.ReadLine() 

    End Sub 

End Module 

Beispielausgabe:

Faktor: 2
Iterations: 4
[4] 3
[8] 7, 5
[16] 13, 12, 11, 9, 6, 4, 3
[32] 31, 29, 25, 23, 19, 17, 14, 10, 7, 5

Eine Liste ist ziemlich wie ein Array, aber man kann ohne zu wissen, um die Anzahl der ihm hinzufügen Einträge im Voraus (es erhöht seine Kapazität automatisch).

Die Variablennamen, die ich verwendete, könnten wahrscheinlich beschreibender sein.

Übrigens haben Sie in Ihrem Beispiel 26 in der Spalte [32], aber 13 (= 26/2) ist in der Spalte [16].

+0

Das ist für die Fehlerstelle, das ist, was ich bekomme, nur aufzuwachen und es mit einem Bleistift von Hand zu tun .... Ich dachte an eine Liste, aber wusste nicht, dass es über eine einzige Dimension hinausgehen könnte. Oder wenn es so war, wusste ich nicht, wie ich es strukturieren sollte. –

+0

Ok, es hat funktioniert, fast, aber explodiert für etwas mehr als 10 Iterationen: D Ich glaube, ich brauche einen Supercomputer. –

+0

Es scheint, dass das Verhältnis der Anzahl der erzeugten Zahlen für einen "Faktor" von 2 abwechselnd zu e (2.78128 ...) und 2^0.5 (1.4142 ...) führt ([524288] ergibt 90182 Zahlen, [1048576] 243707, [2097152] 341314). Aber auch die Parallelisierung der Zahlengenerierung wird Sie nicht weit bringen, da die benötigte Zeit mit der Anzahl der Iterationen sehr schnell ansteigt. –

0

Überprüfen Sie auch dies. Es verwendet das Kettenmuster. Es ist einfacher, eine neue Regel hinzuzufügen.

Module Module1 

    Sub Main() 
     Dim results As New Dictionary(Of Integer, List(Of Integer)) 

     Dim initialValue As Integer = 2 
     Dim multiplier As Integer = 4 

     For i As Integer = 2 To multiplier + 1 
      results.Add(Convert.ToInt32(initialValue^i), New List(Of Integer)) 
     Next 

     For dictionaryIndex As Integer = 0 To results.Count - 1 
      Dim currentFactor As Integer = results.Keys(dictionaryIndex) 

      For testValue As Integer = 1 To currentFactor - 1 
       Dim chain As New ChainOfRules() 
       chain.AddRule(New NotInValuesRule(testValue, 1, 2)) 

       If (dictionaryIndex > 0) Then 
        Dim previousFactor As Integer = results.Keys(dictionaryIndex - 1) 
        chain.AddRule(New NotInValuesRule(testValue, results(previousFactor).ToArray)) 
        chain.AddRule(New NotInValuesRule(testValue, previousFactor)) 
        chain.AddRule(New NotDivisibleListRule(testValue, results(previousFactor).ToArray)) 
       End If 

       If (chain.Process) Then 
        results(currentFactor).Add(testValue) 
       End If 
      Next 
     Next 

     For Each pair As KeyValuePair(Of Integer, List(Of Integer)) In results 
      Console.WriteLine() 
      Console.WriteLine("Factor: {0}", pair.Key) 
      Console.WriteLine("-------------------") 
      For Each i As Integer In pair.Value 
       Console.WriteLine("Value: {0}", i) 
      Next 
     Next 

     Console.ReadLine() 
    End Sub 





    ' Rules 

    Public Interface IRule 
     Function Apply() As Boolean 
    End Interface 


    Public Class NotInValuesRule 
     Implements IRule 

     Private Property Value As Integer 
     Private Property ValuesList As List(Of Integer) 

     Public Sub New(value As Integer, ParamArray valuesList As Integer()) 
      Me.Value = value 
      Me.ValuesList = valuesList.ToList() 
     End Sub 

     Public Function Apply() As Boolean Implements IRule.Apply 
      Return Not ValuesList.Contains(Value) 
     End Function 
    End Class 


    Public Class NotDivisibleListRule 
     Implements IRule 

     Private Property Value As Integer 
     Private Property ValuesList As List(Of Integer) 

     Public Sub New(value As Integer, ParamArray valuesList As Integer()) 
      Me.Value = value 
      Me.ValuesList = valuesList.ToList 
     End Sub 

     Public Function Apply() As Boolean Implements IRule.Apply 
      Dim result As Boolean = True 

      For Each previousValue As Integer In ValuesList 
       result = result And (Value Mod previousValue <> 0) 
      Next 

      Return result 
     End Function 
    End Class 


    Public Class ChainOfRules 
     Private Property Rules As New List(Of IRule) 

     Public Sub AddRule(rule As IRule) 
      Rules.Add(rule) 
     End Sub 

     Public Function Process() As Boolean 
      Dim result As Boolean = True 

      For Each Rule As IRule In Rules 
       result = result And Rule.Apply() 
      Next 

      Return result 
     End Function 
    End Class 

End Module 
Verwandte Themen