

Task
Produce a graphical or ASCII-art representation of a Hilbert curve of at least order 3.

T Point
   x = 0
   y = 0
 
   F rot(n, rx, ry)
      I !ry
         I rx
            .x = (n - 1) - .x
            .y = (n - 1) - .y
 
         swap(&.x, &.y)
 
   F calcD(n)
      V d = 0
      V s = n >> 1
      L s > 0
         V rx = ((.x [&] s) != 0)
         V ry = ((.y [&] s) != 0)
         d += s * s * ((I rx {3} E 0) (+) (I ry {1} E 0))
         .rot(s, rx, ry)
         s >>= 1
      R d
 
F fromD(n, d)
   V p = Point()
   V t = d
   V s = 1
   L s < n
      V rx = ((t [&] 2) != 0)
      V ry = (((t (+) (I rx {1} E 0)) [&] 1) != 0)
      p.rot(s, rx, ry)
      p.x += (I rx {s} E 0)
      p.y += (I ry {s} E 0)
      t >>= 2
      s <<= 1
   R p
 
F getPointsForCurve(n)
   [Point] points
   L(d) 0 .< n * n
      points [+]= fromD(n, d)
   R points
 
F drawCurve(points, n)
   V canvas = [[‘ ’] * (n * 3 - 2)] * n
 
   L(i) 1 .< points.len
      V lastPoint = points[i - 1]
      V curPoint = points[i]
      V deltaX = curPoint.x - lastPoint.x
      V deltaY = curPoint.y - lastPoint.y
      I deltaX == 0
         assert(deltaY != 0, ‘Duplicate point’)
         V row = max(curPoint.y, lastPoint.y)
         V col = curPoint.x * 3
         canvas[row][col] = ‘|’
      E
         assert(deltaY == 0, ‘Diagonal line’)
         V row = curPoint.y
         V col = min(curPoint.x, lastPoint.x) * 3 + 1
         canvas[row][col] = ‘_’
         canvas[row][col + 1] = ‘_’
 
   [String] lines
   L(row) canvas
      lines [+]= row.join(‘’)
   R lines
 
L(order) 1..5
   V n = 1 << order
   V points = getPointsForCurve(n)
   print(‘Hilbert curve, order=’order)
   V lines = drawCurve(points, n)
   L(line) lines
      print(line)
   print()