想像で書いてみたモノ。
東方算程譚:dragon-curve (2)を拝見しながら昨日からゴソゴソしています。で、リンク先の「空間計算量をケチった版」をそれっぽく書いてみました。
以下、コードですが、想像で書いていますのでかなりさっぱりです。保証できません。
Imports System
Imports System.Collections.Generic
Public Class Vector(Of T)
Private _list As List(Of T)
Public ReadOnly Property Size() As Integer
Get
Return Me._list.Count
End Get
End Property
Public Sub New()
Me._list = New List(Of T)
End Sub
Public Overloads Sub Assin(ByVal n As Integer, ByVal t As T)
Me._list.Clear()
For i As Integer = 0 To n - 1
Me._list.Add(t)
Next
End Sub
Public Overloads Sub Assin(ByVal first As Iterator, ByVal [end] As Iterator)
Me._list.Clear()
If first Is Nothing Then
Exit Sub
End If
While True
Me._list.Add(first.Current)
If first.Current.Equals([end].Current) Then
Exit While
End If
If first.MoveNext() = False Then
Exit While
End If
End While
End Sub
Public Function Begin() As Iterator
If Me._list.Count = 0 Then
Return Nothing
End If
Dim result As New Iterator(Vector(Of T).Iterator.Mode.Normal, Me._list)
result.MoveNext()
Return result
End Function
Public Function [End]() As Iterator
If Me._list.Count = 0 Then
Return Nothing
End If
Dim result As New Iterator(Vector(Of T).Iterator.Mode.Normal, Me._list)
If Me._list.Count = 1 Then
result.MoveNext()
ElseIf Me._list.Count > 1 Then
For i As Integer = 0 To Me._list.Count - 2
result.MoveNext()
Next
End If
Return result
End Function
Public Overloads Sub Resize(ByVal n As Integer)
Me.Resize(n, Nothing)
End Sub
Public Overloads Sub Resize(ByVal n As Integer, ByVal t As T)
If Me._list.Count >= n Then
Exit Sub
End If
For i As Integer = 0 To (n - Me._list.Count) - 1
Me._list.Add(t)
Next
End Sub
Public Function RBegin() As Iterator
If Me._list.Count = 0 Then
Return Nothing
End If
Dim result As New Iterator(Vector(Of T).Iterator.Mode.Reverse, Me._list)
If Me._list.Count = 1 Then
result.MoveNext()
ElseIf Me._list.Count > 1 Then
For i As Integer = 0 To Me._list.Count - 2
result.MoveNext()
Next
End If
Return result
End Function
Public Function REnd() As Iterator
If Me._list.Count = 0 Then
Return Nothing
End If
Dim result As New Iterator(Vector(Of T).Iterator.Mode.Reverse, Me._list)
result.MoveNext()
Return result
End Function
Public Class Iterator
Enum Mode As Integer
Normal = 1
Reverse = -1End Enum
Private _mode As Mode
Private _list As List(Of T)
Private _index As IntegerPublic Sub New(ByVal mode As Mode, ByVal list As List(Of T))
Me._mode = mode
Me._list = list
Reset()
End Sub
Public Sub Reset()
If Me._mode = Vector(Of T).Iterator.Mode.Normal Then
Me._index = -1
Else
Me._index = Me._list.Count
End If
End Sub
Public Property Current() As T
Get
Return Me._list.Item(Me._index)
End Get
Set(ByVal value As T)
Me._list.Item(Me._index) = value
End Set
End Property
Public Function MoveNext() As Boolean
If Me._mode = Vector(Of T).Iterator.Mode.Normal Then
If Me._index = Me._list.Count - 1 Then
Return False
End If
Else
If Me._index = 0 Then
Return False
End If
End If
Me._index += Me._mode
Return True
End Function
End Class
End Class
Module STD
Sub Advance(Of T)(ByVal iterator As Vector(Of T).Iterator, ByVal n As Integer)
For i As Integer = 0 To n - 1
iterator.MoveNext()
Next
End Sub
Sub Transform(Of T)(ByVal first As Vector(Of T).Iterator, ByVal [end] As Vector(Of T).Iterator, ByVal target As Vector(Of T).Iterator, ByVal [delegate] As [Delegate])
If first Is Nothing Then
Exit Sub
End If
If target Is Nothing Then
Exit Sub
End If
While True
Dim value As T
If [delegate] IsNot Nothing Then
' ダイナミック、かつ大胆に!
value = DirectCast([delegate].DynamicInvoke(first.Current), T)Else
value = first.Current
End If
target.Current = value
If first.Current.Equals([end].Current) Then
Exit While
End If
If first.MoveNext() = False OrElse target.MoveNext() = False Then
Exit While
End If
End While
End Sub
End Module
Module Utility
Sub Swap(Of T)(ByRef a As T, ByRef b As T)
Dim temp As T
temp = a
a = b
b = tempEnd Sub
End Module
Public Class Dragon
Public Sub NextDragon(Of T)(ByVal currentDragon As Vector(Of T), ByVal result As Vector(Of T))
result.Assin(currentDragon.Begin, currentDragon.End)
result.Resize(currentDragon.Size * 2 + 1)Dim iter As Vector(Of T).Iterator = result.Begin
STD.Advance(iter, currentDragon.Size)STD.Transform(currentDragon.RBegin, currentDragon.REnd, iter, Nothing)
End Sub
End Class
Public Class Program
Public Shared Sub Main()
Dim input As New Vector(Of Boolean)
Dim output As New Vector(Of Boolean)Dim dragon As New Dragon
For i As Integer = 1 To 50
dragon.NextDragon(input, output)
Console.WriteLine("n={0}:折り目の数 {1}", i.ToString.PadRight(2), output.Size.ToString)
Swap(input, output)
Next
End Sub
End Class