2016-06-03 6 views
0

어제 샤워를하고 있었는데 아이디어가 저를 때렸습니다. 정수리스트를 찾는 수학적 패턴 또는 규칙 세트입니다.사실상 무의미한 약간의 흥미로운 알고리즘과 어떻게 로직을 작동시킬 수 있습니까?

이 패턴의 실용적인 응용 또는 당신이 그것을 불러 낼 수있는 것은 초 수학자 뿐이며, 나는 그것을 찾을 수있는 프로그램을 만들 수 있는지보고 싶었습니다.

지금은 VB.net을 사용하고 있습니다. 지금은 대학에서 사용해야하지만 C++에서도 사용할 수 있습니다.

그래서,이 패턴의 규칙은 다음과 같습니다

당신은 당신의 "요소"로 정수를 얻는다면, 당신이 원하는만큼 여러 번 자체를 곱합니다. 이것은 네임 스페이스 또는 내가 "컨테이너"라고 부르는 것의 번호 목록을 만듭니다.

인자가 2라면,리스트는 4, 8, 16, 32, 64 등 (기본 인자 제외)처럼 보일 것입니다.

이제 목록의 각 항목 아래에 내부에 들어갈 수있는 모든 정수를 배치합니다. 예를 들어 컨테이너 번호가 8 인 경우 1에서 7까지의 모든 숫자가 나열됩니다.

그러나 규칙은 그 이상입니다.

다음과 같은 경우 컨테이너 내부의 번호를 나열 할 수 없습니다.

  • 는 1 또는 2
  • 그건 =
  • 전에
  • 그건 = 인자 전에 용기 내의 임의의 수 또는 이전에 컨테이너의 개수로 나누어이다. 당신이 숫자를 볼 수있는 예를

    [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 
    

    를 들어

당신은 얻을 항상 다르다. 그래서 저는 VS 2015의 양식을 작성하여 목록에있는 요인과 반복 횟수 (목록이 얼마나 오래되었는지)를 입력 할 수있었습니다.

내가 처음에 이것을 실제로하고 있다는 사실로 짐작할 수 있듯이 문제는 내 논리가 그다지 위대한 것은 아니라는 것입니다. 프로그래머로서 나는 초보자이며 논리적 인 사상가로서 나는 최선이 아니다.

지금까지 시도한 내용을 확인하십시오. 그것은 버튼 부 사이에 무슨 그냥 :

기본적으로 내가 할 노력했다 무엇
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 

, 뭔가 내가 전에 완료하고, 들쭉날쭉/중첩 된 배열을 만들 것입니다, 첫 번째 배열은 컨테이너 목록의 역할 모든 반복 및 인수가 포함 된 첫 번째 행, 두 번째 행은 값 목록이있는 배열을 포함합니다.

먼저이 문제를 해결하기 위해 벡터 또는 벡터 클래스를 사용하는 것이 좋습니다.하지만 그 일을 가장 안 좋은 방법으로 생각하지는 못했습니다.

만약 내가 이것을 연습하고 배열을 다루는 방법을 알고 싶다면 어쩌면 내가 놓친 일부 논리를 가르쳐 주겠다.

+0

두 번째 규칙은 네 번째 규칙에 적용됩니다. 후자가 확인하는 것이 훨씬 더 비싼 경우에만 코드에서 구현할 가치가 있습니다. –

답변

0

내가 생각 해낸 것보다 그들 중 많은 더 나은이 작업을 수행하는 아마 여러 가지 방법이 있습니다,하지만 Dictionary(Of Integer, List(Of Integer)) 데이터 보유 충분합니다 :

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 

샘플 출력 :

을 팩터 : 2
반복 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

목록이 거의 배열처럼이지만 수를 알지 않고 추가 할 항목을 미리 (자동으로 용량을 늘립니다).

내가 사용한 변수 이름은 아마도 더 이해하기 쉽습니다.

덧붙여서, 예제에서 [32] 열에는 26이 있지만 [16] 열에는 13 (= 26/2)이 있습니다.

+0

그게 바로 오류 발생 지점을위한거야, 그게 내가 깨어나서 손으로 연필로하고 있는거야. ... 나는 목록을 생각하고 있었지만 그것이 하나의 차원을 넘어 설 수 있다는 것을 몰랐다. 아니면 그랬다면 구조화 방법을 몰랐습니다. –

+0

괜찮 았는지, 잘 돌아가지만 10 가지 이상의 반복에 대해서는 폭발 할 수 있습니다. D : 저는 슈퍼 컴퓨터가 필요하다고 생각합니다. –

+0

"factor"2에 대해 생성 된 숫자의 비율은 e (2.78128 ...)와 2^0.5 (1.4142 ...)로 번갈아 나타나는 경향이 있습니다 ([524288]은 90182 개의 숫자를 제공하고 [1048576] 243707, [2097152] 341314). 그러나 숫자 생성을 병렬 처리한다고해서 반복되는 숫자가 매우 빠른 속도로 증가하므로 시간이 많이 걸릴 수도 있습니다. –

0

또한 확인해보십시오. 체인 패턴을 사용합니다. 새로운 규칙을 더 쉽게 추가 할 수 있습니다.

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