3_1.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { LoadInput } from "../common.ts";
  2. import * as util from "util";
  3. const tests = [
  4. "467..114..",
  5. "...*......",
  6. "..35..633.",
  7. "......#...",
  8. "617*......",
  9. ".....+.58.",
  10. "..592.....",
  11. "......755.",
  12. "...$.*....",
  13. ".664.598..",
  14. ];
  15. const testMap = BuildSchematicsMap(tests);
  16. let testParts = ParseSchematics(testMap);
  17. testParts = ValidateEngineParts(testParts);
  18. console.log(util.inspect(testParts, { breakLength: Infinity, depth: 256, colors: true }));
  19. /**
  20. * Parse the schematics to find all possible Engine Parts
  21. * @param {string[][]} schematicsMap A 2D grid of characters making up a schematic
  22. * @returns {EnginePart[]} An array of potential Engine Parts
  23. */
  24. function ParseSchematics(schematicsMap: string[][]): EnginePart[] {
  25. const engineParts: EnginePart[] = [];
  26. /** The current pointer within the schematics' 2D array */
  27. const schematicsPointer: Vector2 = {
  28. X: 0,
  29. Y: 0,
  30. };
  31. for(; schematicsPointer.Y < schematicsMap.length; schematicsPointer.Y++) {
  32. // Reset the X pointer each line
  33. schematicsPointer.X = 0;
  34. /** A line from the total schematics */
  35. const schematicsLine = schematicsMap[schematicsPointer.Y];
  36. // Create a reusable EnginePart store
  37. let part: EnginePart|null = null;
  38. for(; schematicsPointer.X < schematicsMap[schematicsPointer.Y].length; schematicsPointer.X++) {
  39. const char = schematicsMap[schematicsPointer.Y][schematicsPointer.X];
  40. // Check if the current character is a number
  41. if (/\d/.test(char)) {
  42. // Check if our EnginePart store is initialized
  43. if (part == null) { part = { PartNumber: 0, Coordinates: [] }; }
  44. if (part.PartNumber) {
  45. // Concatenate the number to the existing part of the Part Number
  46. part.PartNumber = Number("" + part.PartNumber + char);
  47. }
  48. else {
  49. // Start the new Part Number
  50. part.PartNumber = Number(char);
  51. }
  52. // Push the coordinates
  53. part.Coordinates.push({
  54. X: schematicsPointer.X,
  55. Y: schematicsPointer.Y,
  56. });
  57. }
  58. // If it's not
  59. else {
  60. // Check if the EnginePart store has a value
  61. if(part != null) {
  62. // If it does, store it and empty it
  63. engineParts.push(part);
  64. part = null;
  65. }
  66. }
  67. }
  68. }
  69. return engineParts;
  70. }
  71. /**
  72. * Validates all previously parsed Engine Parts
  73. *
  74. * An Engine Part is only valid if it's connected, even diagonally, to a
  75. * symbol other than `.`.
  76. *
  77. * @param {EnginePart[]} potentialParts All potential Engine Parts
  78. * @returns {EnginePart[]} A filtered list of all valid Engine Parts
  79. */
  80. function ValidateEngineParts(potentialParts: EnginePart[]): EnginePart[] {
  81. return [];
  82. }
  83. /**
  84. * Split the schematics into a 2D grid of characters
  85. *
  86. * @param {string[]} schematics The array of lines from the schematics
  87. * @returns {string[][]} A 2D grid of characters
  88. */
  89. function BuildSchematicsMap(schematics: string[]): string[][] {
  90. return schematics.map((schematicsLine) => schematicsLine.split(''));
  91. }
  92. /**
  93. * An engine part
  94. */
  95. type EnginePart = {
  96. PartNumber: number,
  97. Coordinates: Vector2[],
  98. };
  99. /**
  100. * A symbol on the schematics map
  101. */
  102. type SchematicsSymbol = {
  103. Symbol: string,
  104. Coordinates: Vector2,
  105. };
  106. /**
  107. * A position within a 2D grid
  108. */
  109. type Vector2 = {
  110. X: number,
  111. Y: number,
  112. };