using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; namespace D6.Bonus { class Program { static void Main(string[] args) { if (args.Length < 2) return; if (File.Exists(args[0]) == false) return; if (int.TryParse(args[1], out int ceil) == false) return; var coordinates = new List<((uint x, uint y) coord, bool isInfinite)>(); var file = File.OpenText(args[0]); uint minXY = int.MaxValue; uint maxXY = 0; do { var line = file.ReadLine(); if (line == null) break; var cl = line.Split(", "); (uint x, uint y) xy = (uint.Parse(cl[0]), uint.Parse(cl[1])); if (xy.x < minXY) minXY = xy.x; if (xy.y < minXY) minXY = xy.y; if (xy.x > maxXY) maxXY = xy.x; if (xy.y > maxXY) maxXY = xy.y; coordinates.Add((xy, false)); } while (true); uint size = minXY + maxXY; var area = new (int closest, int total)[size, size]; fillMapArea(size, coordinates, area); flagPointOnEdges(size, coordinates); GenerateBitMap(ceil, coordinates, size, area); } private static void GenerateBitMap(int ceil, List<((uint x, uint y) coord, bool isInfinite)> coordinates, uint size, (int closest, int total)[,] area) { var bmp = new Bitmap((int)size, (int)size); Random r = new Random(); Dictionary Colors = new Dictionary(); for (var x = 0; x < size; x++) { for (var y = 0; y < size; y++) { var id = area[x, y].closest; var total = area[x, y].total; if (Colors.ContainsKey(id) == false) Colors.Add(id, Color.FromArgb(coordinates.ElementAt(id).isInfinite ? 20 : 255, r.Next(0, 256), r.Next(0, 256), r.Next(0, 256))); if (coordinates.ElementAt(id).isInfinite && (x + y % 2) % 3 == 0) continue; bmp.SetPixel(x, y, Colors[id]); var c = bmp.GetPixel(x, y); if (total < ceil) bmp.SetPixel(x, y, Color.FromArgb((int)((c.R + 127) / 1.5), (int)((c.G + 127) / 1.5), (int)((c.B + 127) / 1.5))); } } foreach (var coord in coordinates) { int x = (int)coord.coord.x; int y = (int)coord.coord.y; bmp.SetPixel(x, y, Color.Red); bmp.SetPixel(x - 1, y, Color.Red); bmp.SetPixel(x + 1, y, Color.Red); bmp.SetPixel(x, y - 1, Color.Red); bmp.SetPixel(x, y + 1, Color.Red); bmp.SetPixel(x - 1, y - 1, Color.DarkRed); bmp.SetPixel(x + 1, y - 1, Color.DarkRed); bmp.SetPixel(x - 1, y + 1, Color.DarkRed); bmp.SetPixel(x + 1, y + 1, Color.DarkRed); } bmp = new Bitmap(bmp, new Size((int)(size * 2), (int)(size * 2))); bmp.Save("result.bmp"); } private static int findMaxCoveredArea(List<((uint x, uint y) coord, bool isInfinite)> coordinates, int[] area) { int maxArea = 0; for (int i = 0; i < area.Length; ++i) { if (coordinates.ElementAt(i).isInfinite) continue; if (area[i] > maxArea) maxArea = area[i]; } return maxArea; } private static void flagPointOnEdges(uint size, List<((uint x, uint y) coord, bool isInfinite)> coordinates) { for (uint i = 0; i < size; ++i) { var x0yi = GetClosest(coordinates, (0, i)); MarkInfinite(coordinates, x0yi.closest); var xiy0 = GetClosest(coordinates, (i, 0)); MarkInfinite(coordinates, xiy0.closest); var xsizeyi = GetClosest(coordinates, (size, i)); MarkInfinite(coordinates, xsizeyi.closest); var xiysize = GetClosest(coordinates, (i, size)); MarkInfinite(coordinates, xiysize.closest); } } private static void fillMapArea(uint size, List<((uint x, uint y) coord, bool isInfinite)> coordinates, (int closest, int total)[,] area) { for (uint x = 0; x < size; x++) { for (uint y = 0; y < size; y++) { var closest = GetClosest(coordinates, (x, y)); area[x,y] = closest; } } } private static (int closest, int total) GetClosest(List<((uint x, uint y) coord, bool isInfinite)> coordinates, (uint x, uint y) point) { int total = 0; int lowest = int.MaxValue; int lowestId = 0; for (int i = 0; i < coordinates.Count; i++) { var (x, y) = coordinates[i].coord; var manhattan = Math.Abs((int)point.x - (int)x) + Math.Abs((int)point.y - (int)y); if (manhattan < lowest) { lowest = manhattan; lowestId = i; } total += manhattan; } return (lowestId, total); } private static void MarkInfinite(List<((uint x, uint y) coord, bool isInfinite)> coordinates, int id) { var coord = coordinates[id]; coord.isInfinite = true; coordinates[id] = coord; } } }