Skip to content

Instantly share code, notes, and snippets.

@archer884
Created December 3, 2017 06:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save archer884/7a6970c684a52f1fd04e98c77f4bad90 to your computer and use it in GitHub Desktop.
Save archer884/7a6970c684a52f1fd04e98c77f4bad90 to your computer and use it in GitHub Desktop.
AOC/Day 3
#![feature(universal_impl_trait)]
// DO NOT FORGET:
// Y == VERTICAL
// X == HORIZONTAL
const TARGET: i32 = 325489;
fn main() {
println!("{}", first_larger(TARGET));
}
fn first_larger(target: i32) -> i32 {
let mut values = vec![(1, Point { x: 0, y: 0 })];
for point in SpiralIter::at(1, 0) {
let next_value: i32 = values.iter()
.filter(|value| point.is_adjacent(&value.1))
.map(|value| value.0)
.sum();
if next_value > target {
return next_value;
} else {
values.push((next_value, point));
}
}
unreachable!("Get real, man.")
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
struct Point { x: i32, y: i32 }
impl Point {
fn is_adjacent(&self, other: &Self) -> bool {
// I assume this is right. /shrug
self != other && (self.x - other.x).abs() < 2 && (self.y - other.y).abs() < 2
}
}
// Describes the current stage of iteration. Iteration begins in the south and proceeds east,
// north, and west. This is because the first part of the "box" we draw is the bottom line.
enum Stage {
South,
East,
North,
West,
}
struct SpiralIter {
max_distance: i32,
x: i32,
y: i32,
stage: Stage,
}
impl SpiralIter {
fn at(x: i32, y: i32) -> Self {
Self {
max_distance: 1,
x,
y,
stage: Stage::South,
}
}
fn current(&self) -> Point {
Point {
x: self.x,
y: self.y,
}
}
}
impl Iterator for SpiralIter {
type Item = Point;
fn next(&mut self) -> Option<Self::Item> {
match self.stage {
// Increment horizontal until limit.
Stage::South => {
if self.x == self.max_distance {
self.stage = Stage::East;
return self.next();
}
let ret = self.current();
self.x += 1;
Some(ret)
}
// Increment vertical until limit.
Stage::East => {
if self.y == self.max_distance {
self.stage = Stage::North;
return self.next();
}
let ret = self.current();
self.y += 1;
Some(ret)
}
Stage::North => {
if self.x == -self.max_distance {
self.stage = Stage::West;
return self.next();
}
let ret = self.current();
self.x -= 1;
Some(ret)
}
Stage::West => {
if self.y == -self.max_distance {
self.stage = Stage::South;
self.max_distance += 1;
return self.next();
}
let ret = self.current();
self.y -= 1;
Some(ret)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment