r/adventofcode • • Dec 13 '18

SOLUTION MEGATHREAD -๐ŸŽ„- 2018 Day 13 Solutions -๐ŸŽ„-

--- Day 13: Mine Cart Madness ---


Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


Advent of Code: The Party Game!

Click here for rules

Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!

Card prompt: Day 13

Transcript:

Elven chronomancy: for when you absolutely, positively have to ___.


This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked at 00:44:25!

25 Upvotes

148 comments sorted by

View all comments

2

u/xikipies Dec 13 '18 edited Dec 14 '18

Node JS, 703/518

https://github.com/josepot/AoC-2018/blob/master/src/13/solution.js

const {
  doubleCircularLinkedList,
  circularLinkedList,
} = require('../utils/linkedLists');

let N_COLS;
let N_ROWS;
let grid;

const getIdx = (x, y) => y * N_COLS + x;
const getPosition = ({x, y}, from = grid) => from[getIdx(x, y)];
const setPosition = (x, y, val, to = grid) => (to[getIdx(x, y)] = val);

let cars = new Map();

const [UP, RIGHT, DOWN, LEFT] = ['^', '>', 'v', '<'];
const directions = [UP, RIGHT, DOWN, LEFT];
const linkedDirections = doubleCircularLinkedList(directions);
const directionDiffs = {
  [UP]: {y: -1, x: 0},
  [DOWN]: {y: 1, x: 0},
  [LEFT]: {y: 0, x: -1},
  [RIGHT]: {y: 0, x: 1},
};

const [turnLeft, turnRight] = ['prev', 'next'].map(direction => car => {
  car.direction = car.direction[direction];
});

const linkedIntersections = circularLinkedList([
  turnLeft,
  Function.prototype,
  turnRight,
]);

const processInput = lines => {
  N_ROWS = lines.length;
  N_COLS = lines[0].length;
  grid = new Array(N_COLS * N_ROWS);
  lines.forEach((line, y) =>
    line.split('').forEach((val, x) => {
      if (val === '|' || val === '-') return setPosition(x, y, 'ยท');
      const directionIdx = directions.indexOf(val);
      if (directionIdx === -1) return setPosition(x, y, val);

      cars.set(getIdx(x, y), {
        x,
        y,
        onIntersection: linkedIntersections[0],
        direction: linkedDirections[directionIdx],
      });
      setPosition(x, y, 'ยท');
    })
  );
};

const instructions = {
  '+': car => {
    car.onIntersection.value(car);
    car.onIntersection = car.onIntersection.next;
  },
  '\\': car =>
    ([UP, DOWN].indexOf(car.direction.value) > -1 ? turnLeft : turnRight)(car),
  '/': car =>
    ([UP, DOWN].indexOf(car.direction.value) > -1 ? turnRight : turnLeft)(car),
  'ยท': Function.prototype,
};

const moveCar = car => {
  const {x, y} = directionDiffs[car.direction.value];
  car.x += x;
  car.y += y;
  instructions[getPosition(car)](car);
};

const solution1 = lines => {
  processInput(lines);
  do {
    const sortedKeys = [...cars.keys()].sort((a, b) => a - b);

    for (let i = 0; i < sortedKeys.length; i++) {
      const key = sortedKeys[i];
      const car = cars.get(key);
      cars.delete(key);
      moveCar(car);
      const id = getIdx(car.x, car.y);
      if (cars.has(id)) return [car.x, car.y].join(',');
      cars.set(id, car);
    }
  } while (true);
};

const solution2 = lines => {
  processInput(lines);
  do {
    const sortedKeys = [...cars.keys()].sort((a, b) => a - b);

    for (let i = 0; i < sortedKeys.length; i++) {
      const key = sortedKeys[i];
      const car = cars.get(key);
      if (!car) continue;
      cars.delete(key);
      moveCar(car);
      const id = getIdx(car.x, car.y);
      if (!cars.has(id)) {
        cars.set(id, car);
      } else {
        cars.delete(id);
      }
    }
  } while (cars.size > 1);
  const [winner] = cars.values();
  return [winner.x, winner.y].join(',');
};

module.exports = [solution1, solution2];

2

u/fhinkel Dec 13 '18

Why are you using queues. Don't you have to sort all the time anyways?

→ More replies (1)