Created
December 4, 2017 09:00
-
-
Save lilactown/00ad8dfb539a6fe0ffbba22d05e4075c to your computer and use it in GitHub Desktop.
Advent of Code, 2017: Day 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let abs = Js.Math.abs_int; | |
/* | |
Desired output: | |
1 => (0, 0) | |
2 => (1, 0) | |
3 => (1, 1) | |
4 => (0, 1) | |
5 => (-1, 1) | |
6 => (-1, 0) | |
7 => (-1, -1) | |
8 => (0, -1) | |
9 => (1, -1) | |
*/ | |
let spiral = (n) => { | |
let rec next = (x, y, count) => { | |
/* based off https://stackoverflow.com/a/31864777/4379329 | |
the direction is wrong but the distance should stay the same */ | |
let finished = count == n; | |
let pivot = abs(x) <= abs(y) && (x != y || x >= 0); | |
switch (finished, pivot) { | |
| (true, _) => (x, y) | |
| (_, true) => | |
let x' = x + (y >= 0 ? 1 : (-1)); | |
next(x', y, count + 1) | |
| (_, false) => | |
let y' = y + (x >= 0 ? (-1) : 1); | |
next(x, y', count + 1) | |
} | |
}; | |
next(0, 0, 1) | |
}; | |
let distance = ((x, y)) => abs(x) + abs(y); | |
let part1 = (n) => distance(spiral(n)); | |
/** | |
* For part two, I created an actual grid. I allow | |
* coordinates to be placed inside of it for ease of | |
* printing. | |
*/ | |
type element = | |
| Coordinates(int, int) | |
| Number(int); | |
type grid = array(array(element)); | |
let makeGrid: int => grid = | |
(n) => { | |
let d = n / 2; | |
Array.init(n, (y) => Array.init(n, (x) => Coordinates(x - d, - y + d))) | |
}; | |
let get = (grid: grid, d, x, y) => | |
switch grid[- (y - d)][x + d] { | |
| Coordinates(_, _) => 0 | |
| exception (Invalid_argument(_)) => 0 | |
| Number(el) => el | |
}; | |
let set = (grid: grid, d, x, y, el) => grid[- (y - d)][x + d] = el; | |
let part2 = (n, magicNumber) => { | |
let grid = makeGrid(n); | |
let get = get(grid, n / 2); | |
let set = set(grid, n / 2); | |
set(0, 0, Number(1)); | |
let rec next = (x, y) => { | |
/* based off https://stackoverflow.com/a/31864777/4379329 | |
the direction is wrong but the distance should stay the same */ | |
let pivot = abs(x) <= abs(y) && (x != y || x >= 0); | |
/* get all neighbors */ | |
let n1 = get(x + 1, y + 0); | |
let n2 = get(x + 1, y + 1); | |
let n3 = get(x + 0, y + 1); | |
let n4 = get(x - 1, y + 1); | |
let n5 = get(x - 1, y + 0); | |
let n6 = get(x - 1, y - 1); | |
let n7 = get(x + 0, y - 1); | |
let n8 = get(x + 1, y - 1); | |
let sum = n1 + n2 + n3 + n4 + n5 + n6 + n7 + n8; | |
let finished = sum > magicNumber || x == n / 2 && y == n / 2; | |
set(x, y, Number(sum)); | |
switch (finished, pivot) { | |
| (true, _) => sum | |
| (_, true) => | |
let x' = x + (y >= 0 ? 1 : (-1)); | |
next(x', y) | |
| (_, false) => | |
let y' = y + (x >= 0 ? (-1) : 1); | |
next(x, y') | |
} | |
}; | |
next(1, 0) | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment