-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
127 changed files
with
15,874 additions
and
3 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
|
||
use std::option::Option::Some; | ||
|
||
pub fn main(&io: &IO) { | ||
let input = io.full_input(); | ||
|
||
let lines = input.split_trim("\n").map(fn(line: String) { | ||
let parts = line.split(" "); | ||
let left = N32::parse(parts.pop_front().unwrap()).unwrap(); | ||
let right = N32::parse(parts.pop_front().unwrap()).unwrap(); | ||
(left, right) | ||
}); | ||
|
||
let left = lines.map(fn((left, _)) left); | ||
let right = lines.map(fn((_, right)) right); | ||
|
||
left.sort_by(N32::ascending); | ||
right.sort_by(N32::ascending); | ||
|
||
let total_dist = 0; | ||
let iter_a = left.into_iter(); | ||
let iter_b = right.into_iter(); | ||
while iter_a.next() is Some(a) && iter_b.next() is Some(b) { | ||
total_dist += if a > b { | ||
a - b | ||
} else { | ||
b - a | ||
}; | ||
} | ||
|
||
io.println("Total Distance: " ++ total_dist.to_string()); | ||
|
||
let similarity = 0; | ||
let iter_a = left.into_iter(); | ||
while iter_a.next() is Some(a) { | ||
let count = 0; | ||
let iter_b = right.into_iter(); | ||
while iter_b.next() is Some(b) { | ||
if a == b { | ||
count += 1; | ||
} | ||
} | ||
similarity += a * count; | ||
} | ||
|
||
io.println("Similarity Score: " ++ similarity.to_string()); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
|
||
use std::{option::Option::{Option, Some, None}, result::Result::{Result, Ok, Err}}; | ||
|
||
pub fn main(&io: &IO) { | ||
let input = io.full_input(); | ||
|
||
let lines = input.split_trim("\n"); | ||
|
||
let safe_count = 0; | ||
let dampened_safe_count = 0; | ||
|
||
let iter = lines.into_iter(); | ||
while iter.next() is Some(line) { | ||
let report = line.split(" ").map(fn(x) N32::parse(x).unwrap()); | ||
if is_safe(report) { | ||
safe_count += 1; | ||
dampened_safe_count += 1; | ||
} else if problem_dampener(report) { | ||
dampened_safe_count += 1; | ||
} | ||
} | ||
|
||
io.println("Safe Count: " ++ safe_count.to_string()); | ||
io.println("Dampened Safe Count: " ++ dampened_safe_count.to_string()); | ||
} | ||
|
||
fn is_safe(report: List[N32]) -> Bool { | ||
let last = None[N32]; | ||
let order = None[Bool]; | ||
let iter = report.into_iter(); | ||
while iter.next() is Some(level) { | ||
if last is Some(last) { | ||
let diff = if last > level { | ||
last - level | ||
} else { | ||
level - last | ||
}; | ||
if !(1 <= diff <= 3) { | ||
return false; | ||
} | ||
if order is Some(order) && order != (last > level) { | ||
return false; | ||
} | ||
order = Some((last > level)); | ||
} | ||
last = Some(level); | ||
} | ||
true | ||
} | ||
|
||
fn problem_dampener(report: List[N32]) -> Bool { | ||
let prefix = []; | ||
let suffix = report; | ||
while suffix.pop_front() is Some(level) { | ||
if is_safe(prefix ++ suffix) { | ||
return true; | ||
} | ||
prefix ++= [level]; | ||
} | ||
false | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
|
||
use std::{option::Option::{Option, Some, None}, result::Result::{Result, Ok, Err}}; | ||
|
||
pub fn main(&io: &IO) { | ||
let input = io.full_input(); | ||
|
||
let part1 = get_muls(input); | ||
|
||
io.println("Part 1: " ++ part1.to_string()); | ||
|
||
let part2 = get_muls(input.split("do()").map(fn(x: String) { | ||
let (a, _) = x.split_once("don't()"); | ||
a | ||
}).join("")); | ||
|
||
io.println("Part 2: " ++ part2.to_string()); | ||
} | ||
|
||
fn get_muls(input: String) -> N32 { | ||
let segments = input.split("mul("); | ||
segments.pop_front(); | ||
|
||
let sum = 0; | ||
while segments.pop_front() is Some(segment) { | ||
if segment.split_once(")") is (args, Some(_)) { | ||
if args.split_once(",") is (first, Some(second)) { | ||
if N32::parse(first) is Some(a) { | ||
if N32::parse(second) is Some(b) { | ||
sum += a * b; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
sum | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
|
||
use std::{option::Option::{Option, Some, None}, result::Result::{Result, Ok, Err}}; | ||
|
||
pub fn main(&io: &IO) { | ||
let lines = []; | ||
while io.read_line() is Some(line) { | ||
lines ++= [line]; | ||
} | ||
|
||
let matches = diamond( | ||
lines, | ||
fn(char: Char, Neighbors(nw, n, ne, w, e, sw, s, se): Neighbors[Char], &matches: &N32) { | ||
if char == 'X' { | ||
nw.send('X'); | ||
n.send('X'); | ||
ne.send('X'); | ||
w.send('X'); | ||
e.send('X'); | ||
sw.send('X'); | ||
s.send('X'); | ||
se.send('X'); | ||
} else if char == 'M' || char == 'A' { | ||
let recv = if char == 'M' { | ||
'X' | ||
} else { | ||
'M' | ||
}; | ||
relay(nw, se, recv, char); | ||
relay(n, s, recv, char); | ||
relay(ne, sw, recv, char); | ||
relay(w, e, recv, char); | ||
} else if char == 'S' { | ||
matches += check(nw, 'A') + check(ne, 'A') + check(sw, 'A') + check(se, 'A'); | ||
let x = check(n, 'A') + check(s, 'A') + check(w, 'A') + check(e, 'A'); | ||
matches += x; | ||
} | ||
}, | ||
'.', | ||
0, | ||
); | ||
|
||
io.println("XMAS: " ++ matches.to_string()); | ||
|
||
let matches = diamond( | ||
lines, | ||
fn(char: Char, Neighbors(nw, _, ne, _, _, sw, _, se): Neighbors[Char], &matches: &N32) { | ||
if char == 'A' { | ||
let nw = nw.send('A'); | ||
let ne = ne.send('A'); | ||
let sw = sw.send('A'); | ||
let se = se.send('A'); | ||
if ((nw == 'M' && se == 'S') || (nw == 'S' && se == 'M')) && ( | ||
(sw == 'M' && ne == 'S') || (sw == 'S' && ne == 'M') | ||
) { | ||
matches += 1; | ||
} | ||
} else { | ||
nw.send(char); | ||
ne.send(char); | ||
sw.send(char); | ||
se.send(char); | ||
} | ||
}, | ||
'.', | ||
0, | ||
); | ||
|
||
io.println("X-MAS: " ++ matches.to_string()); | ||
} | ||
|
||
struct Channel[M](M, ~M); | ||
|
||
mod Channel { | ||
pub fn send[M](Channel(got, ~out): Channel[M], value: M) -> M { | ||
out = value; | ||
got | ||
} | ||
|
||
pub fn get[M](&Channel(i, _): &Channel[M]) -> M { | ||
i | ||
} | ||
} | ||
|
||
fn relay(Channel(ai, ~ao): Channel[Char], Channel(bi, ~bo): Channel[Char], recv: Char, send: Char) { | ||
bo = if ai == recv { | ||
send | ||
} else { | ||
'_' | ||
}; | ||
ao = if bi == recv { | ||
send | ||
} else { | ||
'_' | ||
}; | ||
} | ||
|
||
fn check(Channel(i, ~o): Channel[Char], recv: Char) -> N32 { | ||
o = '_'; | ||
if i == recv { | ||
1 | ||
} else { | ||
0 | ||
} | ||
} | ||
|
||
struct Neighbors[M]( | ||
Channel[M], | ||
Channel[M], | ||
Channel[M], | ||
Channel[M], | ||
Channel[M], | ||
Channel[M], | ||
Channel[M], | ||
Channel[M], | ||
); | ||
|
||
fn diamond[T, M, X](grid: List[List[T]], f: fn(T, Neighbors[M], &X), d: M, state: X) -> X { | ||
let width = (*grid.get(0)).len(); | ||
let north = List::new(width, neglect_channel(d)); | ||
let north_west = List::new(width, neglect_channel(d)); | ||
let north_east = List::new(width, neglect_channel(d)); | ||
while grid.pop_front() is Some(row) { | ||
let west = neglect_channel(d); | ||
{ | ||
let north = north.iter(); | ||
let north_west = north_west.iter(); | ||
let ~north_east = north_east.iter(); | ||
(~north_east).drop() | ||
while row.pop_front() is Some(cell) { | ||
let (w, e) = foo_channel(&west); | ||
let (n, s) = foo_channel(north.next().unwrap()); | ||
let (nw, se) = foo_channel(north_west.next().unwrap()); | ||
let (ne, sw) = foo_channel((~north_east).next().unwrap()); | ||
f(cell, Neighbors(nw, n, ne, w, e, sw, s, se), &state); | ||
} | ||
north.drop() | ||
north_west.drop() | ||
} | ||
west.send(d); | ||
north_west.pop_front().unwrap().send(d); | ||
north_west ++= [neglect_channel(d)]; | ||
north_east.pop_front().unwrap().send(d); | ||
north_east ++= [neglect_channel(d)]; | ||
} | ||
drop_all(north, d); | ||
drop_all(north_west, d); | ||
drop_all(north_east, d); | ||
state | ||
} | ||
|
||
fn drop_all[M](c: List[Channel[M]], d: M) { | ||
while c.pop_front() is Some(c) { | ||
c.send(d); | ||
} | ||
} | ||
|
||
fn foo_channel[M](&c: &Channel[M]) -> (Channel[M], Channel[M]) { | ||
let x = c; | ||
let (a, b) = new_channel(); | ||
c = a; | ||
(x, b) | ||
} | ||
|
||
fn new_channel[M]() -> (Channel[M], Channel[M]) { | ||
let a; | ||
let b; | ||
let x = ~a; | ||
let y = ~b; | ||
(Channel(a, y), Channel(b, x)) | ||
} | ||
|
||
fn neglect_channel[M](d: M) -> Channel[M] { | ||
Channel(d, ~_) | ||
} |
Oops, something went wrong.