Big Fat Lazy Spiral
Big Fat Lazy Spiral
I failed to get the transformation perfect, fortunately it was readable.
-
- Posts: 58
- Joined: Thu Nov 29, 2012 7:45 pm
- Location: Germany
That's all of the discussion about this one?
I didn't even try to detect the circles. Instead I detected regions and counted the pixels used (43.5 per circle is a good value). If the number of pixels in the group is somewhere between, I simply tried both - but that only happened in the previous spiral.
Here is my C# code, runs within a few seconds:
I didn't even try to detect the circles. Instead I detected regions and counted the pixels used (43.5 per circle is a good value). If the number of pixels in the group is somewhere between, I simply tried both - but that only happened in the previous spiral.
Here is my C# code, runs within a few seconds:
Code: Select all
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;
using System.Drawing;
namespace lazySpiral
{
class MainClass
{
static bool FillRegion(Bitmap bmp, int x, int y, List<List<bool>> bits, bool white, out int xtmp, out int ytmp) {
xtmp = 0; ytmp = 0;
HashSet<Point> current = new HashSet<Point> { new Point(x,y) };
int hits = 0;
int[,] offset = new int[,] { {-1,0}, {1,0}, {0,-1}, {0,1} };
while (current.Count > 0) {
Point tmp = current.First ();
current.Remove (tmp);
hits++;
bmp.SetPixel (tmp.X, tmp.Y, Color.Black);
for (int dir = 0; dir < 4; dir++) {
Color cl = bmp.GetPixel (tmp.X + offset [dir, 0], tmp.Y + offset [dir, 1]);
Point neighbor = new Point (tmp.X + offset [dir, 0], tmp.Y + offset [dir, 1]);
if (cl.B < 100)
continue;
if (white) {
if (cl.B == cl.G) { //is white
current.Add (neighbor);
} else if (cl.B > cl.G) { //is purple
if (Enumerable.Range (0, 4).Any (p =>
bmp.GetPixel (neighbor.X + offset [p, 0], neighbor.Y + offset [p, 1]).B >
bmp.GetPixel (neighbor.X + offset [p, 0], neighbor.Y + offset [p, 1]).G &&
bmp.GetPixel (neighbor.X + offset [p, 0], neighbor.Y + offset [p, 1]).B >= 100)) {
xtmp = tmp.X + offset [dir, 0];
ytmp = tmp.Y + offset [dir, 1];
}
}
} else {
if (cl.B > cl.G) { //is purple
current.Add (neighbor);
} else if (cl.B == cl.G) { //is white
if (Enumerable.Range (0, 4).Any (p =>
bmp.GetPixel (neighbor.X + offset [p, 0], neighbor.Y + offset [p, 1]).B ==
bmp.GetPixel (neighbor.X + offset [p, 0], neighbor.Y + offset [p, 1]).G &&
bmp.GetPixel (neighbor.X + offset [p, 0], neighbor.Y + offset [p, 1]).B >= 100)) {
xtmp = tmp.X + offset [dir, 0];
ytmp = tmp.Y + offset [dir, 1];
}
}
}
}
}
float pixelPerDot = 43.5f;
foreach (List<bool> l in bits) {
for (int i = 0; i < Math.Round(hits/pixelPerDot); i++) {
l.Add (white);
}
}
Console.WriteLine (x + "/" + y + ": " + hits);
//error correction
float remainder = hits % pixelPerDot;
if (remainder > pixelPerDot / 2)
remainder = pixelPerDot - remainder;
if (remainder > 15) {
Console.WriteLine (x + "/" + y + ": " + hits + " remainder: " + remainder);
for (int i = bits.Count - 1; i >= 0; i--) {
bits.Add (new List<bool> (bits [i]));
if (hits % pixelPerDot < pixelPerDot / 2) {
bits [i].Add (white);
} else {
bits [i].RemoveAt (bits [i].Count - 1);
}
}
}
return hits != 1;
}
static void Main(string[] args)
{
Bitmap bmp = new Bitmap ("/home/eulerschezahl/Downloads/spiral3.png"); //image is edited for previous spiral
int x = 2050;
int y = 2050;
int xtmp, ytmp;
List<List<bool>> bits = new List<List<bool>> { new List<bool>() };
bool white = true;
int c = 0;
do {
FillRegion (bmp, x, y, bits, white, out xtmp, out ytmp);
white = !white;
x = xtmp;
y = ytmp;
//bmp.Save ("/home/eulerschezahl/Downloads/spiral2_post" + (c++).ToString("D4") + ".png");
} while(x != 0 || y != 0);
bmp.Save ("/home/eulerschezahl/Downloads/spiral3_post.png");
foreach (List<bool> l in bits) {
if (l.Count % 8 != 0)
continue;
List<byte> bytes = new List<byte> ();
for (int i = 0; i < l.Count; i+=8) {
byte b = 0;
for (int j = 0; j < 8; j++) {
b *= 2;
if (l [i + j])
b++;
}
bytes.Add (b);
}
File.WriteAllBytes ("/home/eulerschezahl/Downloads/solution" + (c++) + ".png", bytes.ToArray ());
}
}
}
}