Sun, 20 Jul 2014 20:29:34 +0100
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;

namespace TurnDownForNotch
{
	class Program
	{
		static void Main(string[] args)
		{
			Bitmap bmp = new Bitmap("source.png");
			List<byte> data = new List<byte>();
			Point lastPos = new Point(-1, -1);
			Point pos = new Point(251, 128);

			bool hasNext = true;
			while (hasNext)
			{
				byte value = getValueAtPoint(bmp, pos);
				data.Add(value);

				byte[] others = new byte[8];
				for (int i = 0; i < others.Length; i++)
				{
					others[i] = getValueAtPoint(bmp, getNextPos(pos, i));
				}

				hasNext = false;
				for (int i = 0; i < others.Length; i++)
				{
					if (others[i] != 0)
					{
						Point nextPos = getNextPos(pos, i);
						if (nextPos.X != lastPos.X || nextPos.Y != lastPos.Y)
						{
							lastPos = pos;
							pos = nextPos;
							hasNext = true;
							break;
						}
					}
				}
			}
			using (BinaryWriter bw = new BinaryWriter(File.OpenWrite("out-in.bin")))
			{
				for (int i = 0; i < data.Count; i++) { bw.Write(data[i]); }
			}
			using (BinaryWriter bw = new BinaryWriter(File.OpenWrite("in-out.bin")))
			{
				for (int i = data.Count; i-- > 0; ) { bw.Write(data[i]); }
			}
		}

		private static Point getNextPos(Point pos, int direction)
		{
			switch (direction)
			{
				case 0: return new Point(pos.X,     pos.Y - 1);
				case 1: return new Point(pos.X + 1, pos.Y - 1);
				case 2: return new Point(pos.X + 1, pos.Y    );
				case 3: return new Point(pos.X + 1, pos.Y + 1);
				case 4: return new Point(pos.X,     pos.Y + 1);
				case 5: return new Point(pos.X - 1, pos.Y + 1);
				case 6: return new Point(pos.X - 1, pos.Y    );
				case 7: return new Point(pos.X - 1, pos.Y - 1);
			}
			throw new Exception();
		}

		private static byte getValueAtPoint(Bitmap bmp, Point pos)
		{
			Color c = bmp.GetPixel(pos.X, pos.Y);
			Debug.Assert(c.R == c.G && c.G == c.B);
			return c.R;
		}
	}
}
View Raw