Task: Hilbert curve



C#: using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace HilbertCurve {
    class Program {
        static void Swap<T>(ref T a, ref T b) {
            var c = a;
            a = b;
            b = c;
        }

        struct Point {
            public int x, y;

            public Point(int x, int y) {
                this.x = x;
                this.y = y;
            }

            
            public void Rot(int n, bool rx, bool ry) {
                if (!ry) {
                    if (rx) {
                        x = (n - 1) - x;
                        y = (n - 1) - y;
                    }
                    Swap(ref x, ref y);
                }
            }

            public override string ToString() {
                return string.Format("({0}, {1})", x, y);
            }
        }

        static Point FromD(int n, int d) {
            var p = new Point(0, 0);
            int t = d;

            for (int s = 1; s < n; s <<= 1) {
                var rx = (t & 2) != 0;
                var ry = ((t ^ (rx ? 1 : 0)) & 1) != 0;
                p.Rot(s, rx, ry);
                p.x += rx ? s : 0;
                p.y += ry ? s : 0;
                t >>= 2;
            }

            return p;
        }

        static List<Point> GetPointsForCurve(int n) {
            var points = new List<Point>();
            int d = 0;
            while (d < n * n) {
                points.Add(FromD(n, d));
                d += 1;
            }
            return points;
        }

        static List<string> DrawCurve(List<Point> points, int n) {
            var canvas = new char[n, n * 3 - 2];
            for (int i = 0; i < canvas.GetLength(0); i++) {
                for (int j = 0; j < canvas.GetLength(1); j++) {
                    canvas[i, j] = ' ';
                }
            }

            for (int i = 1; i < points.Count; i++) {
                var lastPoint = points[i - 1];
                var curPoint = points[i];
                var deltaX = curPoint.x - lastPoint.x;
                var deltaY = curPoint.y - lastPoint.y;
                if (deltaX == 0) {
                    Debug.Assert(deltaY != 0, "Duplicate point");
                    
                    int row = Math.Max(curPoint.y, lastPoint.y);
                    int col = curPoint.x * 3;
                    canvas[row, col] = '|';
                } else {
                    Debug.Assert(deltaY == 0, "Duplicate point");
                    
                    var row = curPoint.y;
                    var col = Math.Min(curPoint.x, lastPoint.x) * 3 + 1;
                    canvas[row, col] = '_';
                    canvas[row, col + 1] = '_';
                }
            }

            var lines = new List<string>();
            for (int i = 0; i < canvas.GetLength(0); i++) {
                var sb = new StringBuilder();
                for (int j = 0; j < canvas.GetLength(1); j++) {
                    sb.Append(canvas[i, j]);
                }
                lines.Add(sb.ToString());
            }
            return lines;
        }

        static void Main() {
            for (int order = 1; order <= 5; order++) {
                var n = 1 << order;
                var points = GetPointsForCurve(n);
                Console.WriteLine("Hilbert curve, order={0}", order);
                var lines = DrawCurve(points, n);
                foreach (var line in lines) {
                    Console.WriteLine(line);
                }
                Console.WriteLine();
            }
        }
    }
}






VB: option explicit


const pi180= 0.01745329251994329576923690768489 
const pi=3.1415926535897932384626433832795 
class turtle
   
   dim fso
   dim fn
   dim svg
   
   dim iang  
   dim ori   
   dim incr
   dim pdown
   dim clr
   dim x
   dim y

   public property let orient(n):ori = n*pi180 :end property
   public property let iangle(n):iang= n*pi180 :end property
   public sub pd() : pdown=true: end sub 
   public sub pu()  :pdown=FALSE :end sub 
   
   public sub rt(i)  
     ori=ori - i*iang:
     if ori<0 then ori = ori+pi*2
   end sub 
   public sub lt(i):  
     ori=(ori + i*iang) 
     if ori>(pi*2) then ori=ori-pi*2
   end sub
   
   public sub bw(l)
      x= x+ cos(ori+pi)*l*incr
      y= y+ sin(ori+pi)*l*incr
   end sub 
   
   public sub fw(l)
      dim x1,y1 
      x1=x + cos(ori)*l*incr
      y1=y + sin(ori)*l*incr
      if pdown then line x,y,x1,y1
      x=x1:y=y1
   end sub
   
   Private Sub Class_Initialize() 
      setlocale "us"    
      initsvg
      pdown=true
   end sub
   
   Private Sub Class_Terminate()   
      disply
   end sub
   
   private sub line (x,y,x1,y1)
      svg.WriteLine "<line x1=""" & x & """ y1= """& y & """ x2=""" & x1& """ y2=""" & y1 & """/>"
   end sub 

   private sub disply()
       dim shell
       svg.WriteLine "</svg></body></html>"
       svg.close
       Set shell = CreateObject("Shell.Application") 
       shell.ShellExecute fn,1,False
   end sub 

   private sub initsvg()
     dim scriptpath
     Set fso = CreateObject ("Scripting.Filesystemobject")
     ScriptPath= Left(WScript.ScriptFullName, InStrRev(WScript.ScriptFullName, "\"))
     fn=Scriptpath & "SIERP.HTML"
     Set svg = fso.CreateTextFile(fn,True)
     if SVG IS nothing then wscript.echo "Can
     svg.WriteLine "<!DOCTYPE html>" &vbcrlf & "<html>" &vbcrlf & "<head>"
     svg.writeline "<style>" & vbcrlf & "line {stroke:rgb(255,0,0);stroke-width:.5}" &vbcrlf &"</style>"
     svg.writeline "</head>"&vbcrlf & "<body>"
     svg.WriteLine "<svg xmlns=""http://www.w3.org/2000/svg"" width=""800"" height=""800"" viewBox=""0 0 800 800"">" 
   end sub 
end class

sub hilb (n,a)
if n=0 then exit sub
x.rt a
hilb n-1,-a: x.fw 1:x.lt a: Hilb n - 1,a 
x.fw 1
hilb n-1,a : x.lt a: x.fw 1: Hilb n - 1,-a 
x.rt a
end sub

 
dim x
set x=new turtle
x.iangle=90
x.orient=0
x.incr=5
x.x=100:x.y=700

hilb 7,1
set x=nothing