Skip to content

Commit

Permalink
Day 9!!! 9️⃣♘♞
Browse files Browse the repository at this point in the history
  • Loading branch information
bozdoz committed Dec 10, 2023
1 parent 8a77627 commit f375c62
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 0 deletions.
56 changes: 56 additions & 0 deletions BLOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,61 @@
# What Am I Learning Each Day?

### Day 9

**Difficulty: 1/10 ★☆☆☆☆☆☆☆☆☆**

**Time: ~40 min**

**Run Time: ~3.6ms**

Got:

```
thread 'main' panicked at day-09/src/main.rs:36:48:
is idiomatic: ParseIntError { kind: InvalidDigit }
```

Kind of funny to get that considering I read that `unwrap` is more of a TODO, and you should use `expect` instead:

This was in my parser:

```rust
fn parse(contents: &str) -> Vec<Vec<isize>> {
contents
.lines()
.map(|l| {
l.split_whitespace()
.map(|x| x.parse().expect("is idiomatic"))
.collect()
})
.collect()
}
```

I honestly don't really care about errors since this isn't a production app.

And:

```rust
// now get the last value of all diffs
let mut prediction = 0;

for diff in diffs.iter().rev() {
prediction += diff.last().expect("is this what you like?");
}

prediction
```

Today I only really got tripped up by the parser (above), where I forgot the inner `.collect()`. I also had to remember that `.rev()` is to reverse an iterable, but `.reverse()` is to reverse a vector.

Also, I'm unsure of how performant this is to remove the last item from an iterable (double rev):

```rust
// rev'ing twice to skip last
for (i, v) in cur.iter().rev().skip(1).rev().enumerate() {
```

### Day 8

**Difficulty: 3/10 ★★★☆☆☆☆☆☆☆**
Expand Down
9 changes: 9 additions & 0 deletions day-09/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "day-09"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
lib = { version = "0.1.0", path = "../lib" }
3 changes: 3 additions & 0 deletions day-09/src/example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 3 6 9 12 15
1 3 6 10 15 21
10 13 16 21 30 45
112 changes: 112 additions & 0 deletions day-09/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use std::{ time::Instant, fs, vec };
use lib::get_part;

fn get_extrapolation(history: Vec<isize>) -> isize {
let mut diffs = vec![history];
loop {
let cur = &diffs[diffs.len() - 1];
let mut next: Vec<isize> = vec![];
// rev'ing twice to skip last
for (i, v) in cur.iter().rev().skip(1).rev().enumerate() {
let diff = cur[i + 1] - v;

next.push(diff);
}

if next.iter().all(|x| x == &0) {
break;
}

diffs.push(next);
}
// now get the last value of all diffs
let mut prediction = 0;

for diff in diffs.iter().rev() {
prediction += diff.last().expect("is this what you like?");
}

prediction
}

fn parse(contents: &str) -> Vec<Vec<isize>> {
contents
.lines()
.map(|l| {
l.split_whitespace()
.map(|x| x.parse().expect("is idiomatic"))
.collect()
})
.collect()
}

fn part_one(histories: &Vec<Vec<isize>>) -> isize {
histories
.iter()
.map(|x| get_extrapolation(x.to_vec()))
.sum()
}

fn part_two(histories: &Vec<Vec<isize>>) -> isize {
histories
.iter()
.map(|x|
get_extrapolation({
let mut v = x.to_vec();
// reverse to get left-side instead
v.reverse();
v
})
)
.sum()
}

fn main() {
let (one, two) = get_part();
let start = Instant::now();
let contents = fs::read_to_string("./src/input.txt").unwrap();

let histories = parse(&contents);

if one {
let now = Instant::now();
let ans = part_one(&histories);
println!("Part one: {:?} {:?}", ans, now.elapsed());
}

if two {
let now = Instant::now();
let ans = part_two(&histories);
println!("Part two: {:?} {:?}", ans, now.elapsed());
}

println!("Time: {:?}", start.elapsed())
}

#[cfg(test)]
mod tests {
use super::*;

const EXAMPLE: &str = include_str!("./example.txt");

#[test]
fn test_extrapolation() {
assert_eq!(get_extrapolation(vec![0, 3, 6, 9, 12, 15]), 18);
}

#[test]
fn test_part_one() {
let histories = parse(EXAMPLE);
let ans = part_one(&histories);

assert_eq!(ans, 114);
}

#[test]
fn test_part_two() {
let histories = parse(EXAMPLE);
let ans = part_two(&histories);

assert_eq!(ans, 2);
}
}

0 comments on commit f375c62

Please sign in to comment.