Advent of Code 2022: Day 14

Sands falling onto rocks and things 🏜

by Amy L

HTML

<link rel="stylesheet" href="https://adventofcode.com/static/style.css?30">
<h1><a href="https://adventofcode.com/2022/day/14" target="_blank">Day 14</a></h1>
<diV class="puzzle-input">
  <label for="INPUT_DATA">Input</label>
  <textarea id="INPUT_DATA" autocomplete="off" placeholder="paste your input here" rows="7" cols="50"></textarea>
</diV>
<dl>
<dt>Part 1</dt>
  <dd>
    <label>Answer:
      <input type="text" id="answer1" readonly />
    </label>
  </dd>
  
  <dt>Part 2</dt>
  <dd>
    <label>Answer:
    <input type="text" id="answer2" readonly />
    </label>
  </dd>
</dl>

<canvas id="map1"></canvas>
<canvas id="map2"></canvas>

CSS

canvas {
    display: block;
}

TypeScript

const enum SYMBOLS {
	AIR = '.',
  ROCK = '#',
  SAND_SOURCE = '+',
  SAND ='o'
}
const POSITIONS = Object.freeze({
	SAND_SOURCE: {x: 500, y: 0}
});
const PIXEL_SIZE = 10;
function Day14() {
  async function solvePart1(inputData: string) {
  	const rocksData = parseInputData(inputData);
    const map: RockMap = new RockMap(rocksData);
    const source = new SandSource(POSITIONS.SAND_SOURCE, map);
    const canvas = drawMap(map, 'map1');
    const drawSandFn = drawSand(canvas, map.relativeX, map.relativeY);
    const answerEl = (document.getElementById('answer1') as HTMLInputElement);
    const newSandCallback = (sand: Coordinates) => {
      drawSandFn(sand);
      answerEl.value = source.count.toString();
    };
    return await source.startProducingSand(newSandCallback);
  }
  async function solvePart2(inputData: string) {
    const map: RockMap = new RockMap(buildNewMapDimensions(inputData));
    const source = new SandSource(POSITIONS.SAND_SOURCE, map);
    const canvas = drawMap(map, 'map2');
    const drawSandFn = drawSand(canvas, map.relativeX, map.relativeY);
    const answerEl = (document.getElementById('answer2') as HTMLInputElement);
    const newSandCallback = (sand: Coordinates) => {
      drawSandFn(sand); 
      answerEl.value = source.count.toString();
    };
    return await source.startProducingSand(newSandCallback);

    function buildNewMapDimensions(inputData: string): {
    	rocks: Coordinates[][], 
      max: Coordinates, 
      min: Coordinates
    } {
      const {rocks, max, min} = parseInputData(inputData);
      const newMaxY = max.y + 2;
      const	dY = newMaxY - min.y;
      const	dX = max.x - min.x; 
      const newMaxX = POSITIONS.SAND_SOURCE.x + dY;
      const newMinX = POSITIONS.SAND_SOURCE.x - dY;
      const newRocksdata = {
        rocks,
        min: {x: newMinX, y: min.y},
        max: {x: newMaxX, y: newMaxY}
      };
      console.log('from', min, max)
      console.log('to', newRocksdata.min, newRocksdata.max)

     ...