Задачка на рекурсию.

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Задачка на рекурсию.

Сообщение Mikle » 30.09.2012 (Вс) 17:00

Дано квадратное поле со стороной = степень двойки, допустим 16, не важно.
Нужно обойти поле, дан такой паттерн (если я правильно применил это слово):
    вправо на 1
    вниз и влево на 1
    вправо на 1
то есть поле 2*2 обходится так:
Код: Выделить всё
0  1
2  3

На поле 4*4 берём за единицу поле 2*2 и обходим по тому же паттерну, каждое поле 2*2 обходим, как указано выше:
Код: Выделить всё
0  1  4  5
2  3  6  7
8  9  12 13
10 11 14 15

Соответственно на поле 8*8 единицей уже будет поле 4*4, смысл, надеюсь, понятен.
Я нашёл простую битовую формулу, которая по координатам клетки сразу вычисляет её порядок прохождения, вот весь проект:
Код: Выделить всё
Option Explicit

Dim Ar(15, 15) As Long

Private Sub Form_Load()
  Dim x As Long, y As Long

  ScaleMode = vbPixels
  Move Left, Top, Width - Screen.TwipsPerPixelX * (ScaleWidth - 512), Height - Screen.TwipsPerPixelY * (ScaleHeight - 512)
  Fill
  For y = 0 To 15
    For x = 0 To 15
      CurrentY = y * 32 + 8
      CurrentX = x * 32 + 6
      Print Format(Ar(x, y), "00#");
    Next x
  Next y
End Sub

Private Sub Fill()
  Dim x As Long, y As Long

  For y = 0 To 15
    For x = 0 To 15
      Ar(x, y) = Calc(x, y)
    Next x
  Next y
End Sub

Private Function Calc(ByVal x As Long, ByVal y As Long) As Long
  Dim d As Long, v As Long

  d = 1
  While d <= 64
    If x And d Then v = v Or d
    d = d + d
    x = x + x
    y = y + y
    If y And d Then v = v Or d
    d = d + d
  Wend
  Calc = v
End Function

Но мне нужно именно ОБОЙТИ клетки в соответствующем порядке, это явно рекурсия, и чую всеми местами, что она должна быть простой, но что-то у меня пока выходит что-то монструозное, жду свежие мысли от вас.
Вариант с обходом по заранее подготовленному\вычисленному массиву индексов не предлагать, это и так понятно.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Думаю, так

Сообщение Qwertiy » 30.09.2012 (Вс) 17:31

Код: Выделить всё
Dim Index As Integer

Private Sub Form_Load()
  ScaleMode = vbPixels
  Move Left, Top, Width - Screen.TwipsPerPixelX * (ScaleWidth - 512), Height - Screen.TwipsPerPixelY * (ScaleHeight - 512)

  Index = -1
  GoRec 0, 0, 16
End Sub

Private Sub DoIt(I As Integer, J As Integer)
  CurrentY = I * 32 + 8
  CurrentX = J * 32 + 6
  Index = Index + 1
  Print Format(Index, "00#");
End Sub

Private Sub GoRec(I As Integer, J As Integer, Size As Integer)
  If Size = 1 Then
    DoIt I, J
  Else
    Dim D As Integer
    D = Size \ 2
    GoRec I, J, D
    GoRec I, J + D, D
    GoRec I + D, J, D
    GoRec I + D, J + D, D
  End If
End Sub

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Задачка на рекурсию.

Сообщение Mikle » 30.09.2012 (Вс) 18:02

Отлично!
Блин, а я всё время наоборот снизу вверх пытался сделать, в смысле от 1 до Size.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 4

    TopList