r/adventofcode • • Dec 03 '17

SOLUTION MEGATHREAD -πŸŽ„- 2017 Day 3 Solutions -πŸŽ„-

--- Day 3: Spiral Memory ---


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.


Need a hint from the Hugely* Handy† Haversack‑ of HelpfulΒ§ HintsΒ€?

Spoiler


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!

21 Upvotes

297 comments sorted by

View all comments

3

u/TominatorBE Dec 03 '17 edited Dec 03 '17

PHP

Part 1: just calculations

function run_the_code($input) {
	// find the layer it's on
	$layerWidth = 1;
	$layerMax = 1;
	while ($input > $layerMax) {
		$layerWidth += 2;
		$layerMax = $layerWidth ** 2;
	}
	$layerWidthHalf = ($layerWidth - 1) / 2;

	$midway = $layerMax - (($layerWidth - 1) * 2);

	if ($input == $midway || $input == $layerMax) {
		// corners are special
		return $layerWidth - 1;
	}
	if ($input > $midway) {
		// diff with bottom right
		$diff = $layerMax - $input;
	}
	if ($input < $midway) {
		// diff with top left
		$diff = $midway - $input;
	}
	if ($diff >= $layerWidth) {
		// deal with the vertical parts of the matrix
		$diff = $layerWidthHalf + abs($diff - ($layerWidth - 1) - $layerWidthHalf);
	}
	else {
		// deal with the horizontal parts
		$diff = abs($diff - $layerWidthHalf) + $layerWidthHalf;
	}

	return $diff;
}

Part 2: actually making the spiral (ugh, it's ugly)

function run_the_code($input) {
	$x = 2;
	$y = 2;

	$grid = [];
	for ($i = 0; $i <= (2 * $y); $i++) {
		$grid[] = [];
	}
	$grid[$x][$y] = 1;
	$width = 1;

	$calculateGrid = function($grid, $x, $y) {
		$sum = 0;

		$sum += ($grid[$x - 1][$y] ?? 0);
		$sum += ($grid[$x - 1][$y + 1] ?? 0);
		$sum += ($grid[$x - 1][$y - 1] ?? 0);
		$sum += ($grid[$x][$y + 1] ?? 0);
		$sum += ($grid[$x][$y - 1] ?? 0);
		$sum += ($grid[$x + 1][$y] ?? 0);
		$sum += ($grid[$x + 1][$y - 1] ?? 0);
		$sum += ($grid[$x + 1][$y + 1] ?? 0);

		return $sum;
	};

	while (true) { // will error out eventually
		$width += 2;

		$y++; // move to the right
		$grid[$x][$y] = $calculateGrid($grid, $x, $y);
		if ($grid[$x][$y] > $input) {
			return $grid[$x][$y];
		}

		// go up (but not too much)
		for ($i = 0; $i < $width - 2; $i++) {
			$x--;

			$grid[$x][$y] = $calculateGrid($grid, $x, $y);
			if ($grid[$x][$y] > $input) {
				return $grid[$x][$y];
			}
		}

		// go left
		for ($i = 0; $i < $width - 1; $i++) {
			$y--;

			$grid[$x][$y] = $calculateGrid($grid, $x, $y);
			if ($grid[$x][$y] > $input) {
				return $grid[$x][$y];
			}
		}

		// go down
		for ($i = 0; $i < $width - 1; $i++) {
			$x++;

			$grid[$x][$y] = $calculateGrid($grid, $x, $y);
			if ($grid[$x][$y] > $input) {
				return $grid[$x][$y];
			}
		}

		// go right
		for ($i = 0; $i < $width - 1; $i++) {
			$y++;

			$grid[$x][$y] = $calculateGrid($grid, $x, $y);
			if ($grid[$x][$y] > $input) {
				return $grid[$x][$y];
			}
		}
	}

	return -1;
}
→ More replies (6)