Program.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Linq;
  6. namespace D6.Bonus
  7. {
  8. class Program
  9. {
  10. static void Main(string[] args)
  11. {
  12. if (args.Length < 2) return;
  13. if (File.Exists(args[0]) == false) return;
  14. if (int.TryParse(args[1], out int ceil) == false) return;
  15. var coordinates = new List<((uint x, uint y) coord, bool isInfinite)>();
  16. var file = File.OpenText(args[0]);
  17. uint minXY = int.MaxValue;
  18. uint maxXY = 0;
  19. do
  20. {
  21. var line = file.ReadLine();
  22. if (line == null) break;
  23. var cl = line.Split(", ");
  24. (uint x, uint y) xy = (uint.Parse(cl[0]), uint.Parse(cl[1]));
  25. if (xy.x < minXY) minXY = xy.x;
  26. if (xy.y < minXY) minXY = xy.y;
  27. if (xy.x > maxXY) maxXY = xy.x;
  28. if (xy.y > maxXY) maxXY = xy.y;
  29. coordinates.Add((xy, false));
  30. } while (true);
  31. uint size = minXY + maxXY;
  32. var area = new (int closest, int total)[size, size];
  33. FillMapArea(size, coordinates, area);
  34. FlagPointOnEdges(size, coordinates);
  35. GenerateBitMap(ceil, coordinates, size, area);
  36. }
  37. private static void GenerateBitMap(int ceil, List<((uint x, uint y) coord, bool isInfinite)> coordinates, uint size, (int closest, int total)[,] area)
  38. {
  39. var bmp = new Bitmap((int)size, (int)size);
  40. Random r = new Random();
  41. Dictionary<int, Color> Colors = new Dictionary<int, Color>();
  42. for (var x = 0; x < size; x++)
  43. {
  44. for (var y = 0; y < size; y++)
  45. {
  46. var id = area[x, y].closest;
  47. var total = area[x, y].total;
  48. if (Colors.ContainsKey(id) == false)
  49. Colors.Add(id, Color.FromArgb(coordinates.ElementAt(id).isInfinite ? 20 : 255, r.Next(0, 256), r.Next(0, 256), r.Next(0, 256)));
  50. if (coordinates.ElementAt(id).isInfinite && (x + y % 3) % 3 > 0) continue;
  51. bmp.SetPixel(x, y, Colors[id]);
  52. var c = bmp.GetPixel(x, y);
  53. 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)));
  54. }
  55. }
  56. foreach (var coord in coordinates)
  57. {
  58. int x = (int)coord.coord.x;
  59. int y = (int)coord.coord.y;
  60. bmp.SetPixel(x, y, Color.Red);
  61. bmp.SetPixel(x - 1, y, Color.Red);
  62. bmp.SetPixel(x + 1, y, Color.Red);
  63. bmp.SetPixel(x, y - 1, Color.Red);
  64. bmp.SetPixel(x, y + 1, Color.Red);
  65. bmp.SetPixel(x - 1, y - 1, Color.DarkRed);
  66. bmp.SetPixel(x + 1, y - 1, Color.DarkRed);
  67. bmp.SetPixel(x - 1, y + 1, Color.DarkRed);
  68. bmp.SetPixel(x + 1, y + 1, Color.DarkRed);
  69. }
  70. bmp = new Bitmap(bmp, new Size((int)(size * 2), (int)(size * 2)));
  71. bmp.Save("result.bmp");
  72. }
  73. private static void FlagPointOnEdges(uint size, List<((uint x, uint y) coord, bool isInfinite)> coordinates)
  74. {
  75. for (uint i = 0; i < size; ++i)
  76. {
  77. #pragma warning disable IDE0042 // Deconstruct variable declaration
  78. var x0yi = GetClosest(coordinates, (0, i));
  79. MarkInfinite(coordinates, x0yi.closest);
  80. var xiy0 = GetClosest(coordinates, (i, 0));
  81. MarkInfinite(coordinates, xiy0.closest);
  82. var xsizeyi = GetClosest(coordinates, (size, i));
  83. MarkInfinite(coordinates, xsizeyi.closest);
  84. var xiysize = GetClosest(coordinates, (i, size));
  85. MarkInfinite(coordinates, xiysize.closest);
  86. #pragma warning restore IDE0042 // Deconstruct variable declaration
  87. }
  88. }
  89. private static void FillMapArea(uint size, List<((uint x, uint y) coord, bool isInfinite)> coordinates, (int closest, int total)[,] area)
  90. {
  91. for (uint x = 0; x < size; x++)
  92. {
  93. for (uint y = 0; y < size; y++)
  94. {
  95. var closest = GetClosest(coordinates, (x, y));
  96. area[x,y] = closest;
  97. }
  98. }
  99. }
  100. private static (int closest, int total) GetClosest(List<((uint x, uint y) coord, bool isInfinite)> coordinates, (uint x, uint y) point)
  101. {
  102. int total = 0;
  103. int lowest = int.MaxValue;
  104. int lowestId = 0;
  105. for (int i = 0; i < coordinates.Count; i++)
  106. {
  107. var (x, y) = coordinates[i].coord;
  108. var manhattan = Math.Abs((int)point.x - (int)x) + Math.Abs((int)point.y - (int)y);
  109. if (manhattan < lowest)
  110. {
  111. lowest = manhattan;
  112. lowestId = i;
  113. }
  114. total += manhattan;
  115. }
  116. return (lowestId, total);
  117. }
  118. private static void MarkInfinite(List<((uint x, uint y) coord, bool isInfinite)> coordinates, int id)
  119. {
  120. var coord = coordinates[id];
  121. coord.isInfinite = true;
  122. coordinates[id] = coord;
  123. }
  124. }
  125. }