Skip to content

Instantly share code, notes, and snippets.

@smolck
Last active January 4, 2022 13:21
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 smolck/7c8a141e7a96fbf217113d709e86ed14 to your computer and use it in GitHub Desktop.
Save smolck/7c8a141e7a96fbf217113d709e86ed14 to your computer and use it in GitHub Desktop.

With the above files in the same directory, on my system $ rustc day11.rs -C opt-level=3 && hyperfine -w 10 ./day11 results in:

Benchmark 1: ./day11
  Time (mean ± σ):      83.9 ms ±   5.4 ms    [User: 81.8 ms, System: 1.6 ms]
  Range (min … max):    77.4 ms …  93.0 ms    36 runs

from hyperfine.

$ odin build day11.odin -opt:3 && hyperfine -w 10 ./day11 with latest master at the time of writing this (commit https://github.com/odin-lang/Odin/commit/72862ce30d55891f1b04d3aadd085d7822f1b960) results in:

Benchmark 1: ./day11
  Time (mean ± σ):     279.6 ms ±   2.5 ms    [User: 274.4 ms, System: 4.4 ms]
  Range (min … max):   276.2 ms … 285.2 ms    10 runs

from hyperfine.

package main
import "core:fmt"
import "core:os"
read_input :: proc(fname: string) -> [100]u8 {
ret : [100]u8
contents := #load("input.txt")
idx := 0
for _, i in contents {
if contents[i] == '\n' {
continue
} else {
ret[idx] = contents[i] - '0'
idx += 1
}
}
return ret
}
Position :: struct {
row: int,
col: int,
}
stuff :: #force_inline proc(pos: Position, ret: ^int, arr: ^[100]u8) {
if pos.row < 0 || pos.row > 9 || pos.col < 0 || pos.col > 9 {
return;
}
idx := (pos.row * 10 + pos.col);
if arr[idx] == 0 {
return;
}
arr[idx] += 1;
if arr[idx] > 9 {
ret^ += 1;
arr[idx] = 0;
ret^ += traverse(0, pos, arr);
}
}
traverse :: proc(acc: int, startingPos: Position, arr: ^[100]u8) -> int {
positions : [8]Position
sr := startingPos.row
sc := startingPos.col
ret := acc
stuff(Position { sr - 1, sc - 1, }, &ret, arr)
stuff(Position { sr - 1, sc, }, &ret, arr) // top middle
stuff(Position { sr - 1, sc + 1, }, &ret, arr) // top right
stuff(Position { sr, sc - 1, }, &ret, arr) // left
stuff(Position { sr, sc + 1, }, &ret, arr) // right
stuff(Position { sr + 1, sc - 1, }, &ret, arr) // bottom left
stuff(Position { sr + 1, sc, }, &ret, arr) // bottom middle
stuff(Position { sr + 1, sc + 1, }, &ret, arr) // bottom right
return ret
}
run_step :: proc(v: ^[100]u8) -> int {
flashes := 0
positions := make([dynamic]Position, 0, 10)
defer delete(positions)
for row in 0..<10 {
for col in 0..<10 {
idx := row * 10 + col
v[idx] += 1
if v[idx] > 9 {
flashes += 1
v[idx] = 0
append(&positions, Position{row, col})
}
}
}
for _, i in positions {
flashes += traverse(0, positions[i], v)
}
return flashes
}
main :: proc() {
input := read_input("input.txt")
for _ in 0..<1000 {
input := input
flashes := 0
for i in 0..<100 {
flashes += run_step(&input)
}
step := 100
num_flashed := 0
for {
num_flashed = run_step(&input)
step += 1
if num_flashed == 100 {
break
}
}
}
}
fn input() -> [u8; 100] {
let input = include_str!("input.txt");
let mut ret = [0; 100];
let mut idx: usize = 0;
for c in input.chars() {
if c != '\n' {
ret[idx] = (c as u8) - ('0' as u8);
idx += 1;
}
}
return ret;
}
#[derive(Clone, Copy)]
struct Position {
row: i32,
col: i32,
}
#[inline(always)]
fn stuff(pos: Position, ret: &mut i32, arr: &mut [u8; 100]) {
if pos.row < 0 || pos.row > 9 || pos.col < 0 || pos.col > 9 {
return;
}
let idx = (pos.row * 10 + pos.col) as usize;
if arr[idx] == 0 {
return;
}
arr[idx] += 1;
if arr[idx] > 9 {
*ret += 1;
arr[idx] = 0;
*ret += traverse(0, pos, arr);
}
}
fn traverse(acc: i32, starting_pos: Position, arr: &mut [u8; 100]) -> i32 {
let Position { row: sr, col: sc } = starting_pos;
let mut ret = acc;
stuff(Position { row: sr - 1, col: sc - 1, }, &mut ret, arr);
stuff(Position { row: sr - 1, col: sc, }, &mut ret, arr); // top middle
stuff(Position { row: sr - 1, col: sc + 1, }, &mut ret, arr); // top right
stuff(Position { row: sr, col: sc - 1, }, &mut ret, arr); // left
stuff(Position { row: sr, col: sc + 1, }, &mut ret, arr); // right
stuff(Position { row: sr + 1, col: sc - 1, }, &mut ret, arr); // bottom left
stuff(Position { row: sr + 1, col: sc, }, &mut ret, arr); // bottom middle
stuff(Position { row: sr + 1, col: sc + 1, }, &mut ret, arr); // bottom right
return ret;
}
fn run_step(v: &mut [u8; 100]) -> i32 {
let mut flashes = 0;
let mut positions = Vec::with_capacity(10);
for row in 0..10 {
for col in 0..10 {
let idx = (row * 10 + col) as usize;
v[idx] += 1;
if v[idx] > 9 {
flashes += 1;
v[idx] = 0;
positions.push(Position { row: row as i32, col: col as i32 });
}
}
}
for pos in positions {
flashes += traverse(0, pos, v);
}
return flashes;
}
fn main() {
let input = input();
for _ in 0..1000 {
let mut input = input;
let mut flashes = 0;
for _ in 0..100 {
flashes += run_step(&mut input);
}
let mut step = 100;
let mut num_flashed = 0;
while num_flashed != 100 {
num_flashed = run_step(&mut input);
step += 1;
}
}
}
1443668646
7686735716
4261576231
3361258654
4852532611
5587113732
1224426757
5155565133
6488377862
8267833811
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment