2019: switch to anyhow
This commit is contained in:
parent
d91165207f
commit
deb808faf3
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -34,6 +34,7 @@ dependencies = [
|
|||
name = "aoc2019"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"aoc",
|
||||
"criterion",
|
||||
]
|
||||
|
|
|
@ -13,6 +13,7 @@ criterion = "0.3"
|
|||
[dependencies]
|
||||
|
||||
aoc = { path = "../aoc" }
|
||||
anyhow = "1.0"
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
use aoc::Result;
|
||||
use anyhow::Result;
|
||||
|
||||
const INPUT: &str = include_str!("../input/day01.txt");
|
||||
|
||||
|
@ -21,10 +21,7 @@ fn part1(input: &str) -> Result<u64> {
|
|||
input
|
||||
.lines()
|
||||
.map(|line| line.parse::<u64>())
|
||||
.map(|w| match w {
|
||||
Ok(w) => Ok(fuel_needed(w)),
|
||||
Err(e) => Err(Box::from(e)),
|
||||
})
|
||||
.map(|w| w.map(fuel_needed).map_err(anyhow::Error::new))
|
||||
.sum()
|
||||
}
|
||||
|
||||
|
@ -44,10 +41,7 @@ fn part2(input: &str) -> Result<u64> {
|
|||
input
|
||||
.lines()
|
||||
.map(|line| line.parse::<u64>())
|
||||
.map(|w| match w {
|
||||
Ok(w) => Ok(cumulated_fuel_needed(w)),
|
||||
Err(e) => Err(Box::from(e)),
|
||||
})
|
||||
.map(|w| w.map(cumulated_fuel_needed).map_err(anyhow::Error::new))
|
||||
.sum()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
|
||||
use crate::intcode::{parse_memory, Intcode};
|
||||
|
||||
|
@ -28,7 +27,7 @@ fn part1(mut input: Vec<i64>) -> Result<i64> {
|
|||
|
||||
intcode
|
||||
.get_day02_output()
|
||||
.ok_or_else(|| err!("intcode memory was empty!"))
|
||||
.context("intcode memory was empty!")
|
||||
}
|
||||
|
||||
fn part2(input: &[i64], res: i64) -> Result<i64> {
|
||||
|
@ -46,11 +45,11 @@ fn part2(input: &[i64], res: i64) -> Result<i64> {
|
|||
return Ok(noun * 100 + verb);
|
||||
}
|
||||
}
|
||||
None => return Err(err!("intcode memory was empty!")),
|
||||
None => bail!("intcode memory was empty!"),
|
||||
}
|
||||
}
|
||||
|
||||
Err(err!(
|
||||
Err(anyhow!(
|
||||
"couldn't find noun/verb combination that produces {}",
|
||||
res
|
||||
))
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
use std::cmp::{max, min};
|
||||
use std::error::Error;
|
||||
use std::fmt::Write;
|
||||
use std::str::FromStr;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
const INPUT: &str = include_str!("../input/day03.txt");
|
||||
|
||||
|
@ -39,7 +37,7 @@ fn part1(first_wire: &Wire, second_wire: &Wire) -> Result<u64> {
|
|||
})
|
||||
.map(|inter| manhattan_distance(&inter, &Point { x: 0, y: 0 }))
|
||||
.min()
|
||||
.ok_or_else(|| err!("wire was empty"))
|
||||
.context("wire was empty")
|
||||
}
|
||||
|
||||
fn part2(first_wire: &Wire, second_wire: &Wire) -> Result<u64> {
|
||||
|
@ -72,19 +70,13 @@ fn part2(first_wire: &Wire, second_wire: &Wire) -> Result<u64> {
|
|||
first_length += manhattan_distance(&seg1.begin, &seg1.end);
|
||||
}
|
||||
|
||||
min_dist.ok_or_else(|| err!("wire was empty"))
|
||||
min_dist.context("wire was empty")
|
||||
}
|
||||
|
||||
fn parse_wires(input: &str) -> Result<(Wire, Wire)> {
|
||||
let mut lines = input.lines();
|
||||
let first = lines
|
||||
.next()
|
||||
.ok_or_else(|| err!("input missing a line"))?
|
||||
.parse()?;
|
||||
let second = lines
|
||||
.next()
|
||||
.ok_or_else(|| err!("input missing a line"))?
|
||||
.parse()?;
|
||||
let first = lines.next().context("input missing a line")?.parse()?;
|
||||
let second = lines.next().context("input missing a line")?.parse()?;
|
||||
|
||||
Ok((first, second))
|
||||
}
|
||||
|
@ -93,15 +85,14 @@ fn parse_wires(input: &str) -> Result<(Wire, Wire)> {
|
|||
struct Wire(Vec<Segment>);
|
||||
|
||||
impl FromStr for Wire {
|
||||
type Err = Box<dyn Error>;
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Wire> {
|
||||
let moves = s
|
||||
.trim_end()
|
||||
.split(',')
|
||||
.map(|m| m.parse())
|
||||
.collect::<Result<Vec<Move>>>()
|
||||
.map_err(|e| err!("failed to parse wire: {}", e))?;
|
||||
.map(|m| m.parse().context("failed to parse wire"))
|
||||
.collect::<Result<Vec<Move>>>()?;
|
||||
|
||||
let mut pos = Point { x: 0, y: 0 };
|
||||
|
||||
|
@ -194,17 +185,15 @@ struct Move {
|
|||
}
|
||||
|
||||
impl FromStr for Move {
|
||||
type Err = Box<dyn Error>;
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
let direction = s
|
||||
.chars()
|
||||
.nth(0)
|
||||
.ok_or_else(|| err!("couldn't get direction char in move: {}", s))?;
|
||||
.context("couldn't get direction char in move")?;
|
||||
|
||||
let s = s
|
||||
.get(1..)
|
||||
.ok_or_else(|| err!("move missing length: {}", s))?;
|
||||
let s = s.get(1..).context("move missing length")?;
|
||||
|
||||
let length = s.parse()?;
|
||||
|
||||
|
@ -213,7 +202,7 @@ impl FromStr for Move {
|
|||
'D' => Direction::Down,
|
||||
'L' => Direction::Left,
|
||||
'R' => Direction::Right,
|
||||
_ => return Err(err!("couldn't parse direction: {}", direction)),
|
||||
_ => bail!("couldn't parse direction: {}", direction),
|
||||
};
|
||||
|
||||
Ok(Move { direction, length })
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
const INPUT: &str = include_str!("../input/day04.txt");
|
||||
|
||||
|
@ -20,11 +19,11 @@ fn range(input: &str) -> Result<(usize, usize)> {
|
|||
let mut range = input.trim_end().split('-');
|
||||
let begin = range
|
||||
.next()
|
||||
.ok_or_else(|| err!("invalid input: {}", input))?
|
||||
.with_context(|| format!("invalid input: {}", input))?
|
||||
.parse()?;
|
||||
let end = range
|
||||
.next()
|
||||
.ok_or_else(|| err!("invalid input: {}", input))?
|
||||
.with_context(|| format!("invalid input: {}", input))?
|
||||
.parse()?;
|
||||
|
||||
Ok((begin, end))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use crate::intcode::Intcode;
|
||||
|
||||
|
@ -20,18 +19,14 @@ fn part1(input: &str) -> Result<i64> {
|
|||
let mut intcode = Intcode::new(input)?;
|
||||
intcode.add_input(1);
|
||||
intcode.run()?;
|
||||
intcode
|
||||
.get_last_output()
|
||||
.ok_or_else(|| err!("intcode gave no output"))
|
||||
intcode.get_last_output().context("intcode gave no output")
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> Result<i64> {
|
||||
let mut intcode = Intcode::new(input)?;
|
||||
intcode.add_input(5);
|
||||
intcode.run()?;
|
||||
intcode
|
||||
.get_last_output()
|
||||
.ok_or_else(|| err!("intcode gave no output"))
|
||||
intcode.get_last_output().context("intcode gave no output")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -3,8 +3,7 @@ use std::collections::HashSet;
|
|||
use std::fmt::Write;
|
||||
use std::iter;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
const INPUT: &str = include_str!("../input/day06.txt");
|
||||
|
||||
|
@ -42,7 +41,7 @@ fn part1(input: &str) -> Result<u64> {
|
|||
.map(|line| {
|
||||
let paren = line
|
||||
.find(')')
|
||||
.ok_or_else(|| err!("couldn't find `)` in line: {}", line))?;
|
||||
.with_context(|| format!("couldn't find `)` in line: {}", line))?;
|
||||
Ok((line[paren + 1..].to_string(), line[..paren].to_string()))
|
||||
})
|
||||
.collect::<Result<HashMap<String, String>>>()?;
|
||||
|
@ -61,7 +60,7 @@ fn part2(input: &str) -> Result<usize> {
|
|||
.map(|line| {
|
||||
let paren = line
|
||||
.find(')')
|
||||
.ok_or_else(|| err!("couldn't find `)` in line: {}", line))?;
|
||||
.with_context(|| format!("couldn't find `)` in line: {}", line))?;
|
||||
Ok((line[paren + 1..].to_string(), line[..paren].to_string()))
|
||||
})
|
||||
.collect::<Result<HashMap<String, String>>>()?;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::fmt::Write;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use crate::intcode::{parse_memory, Intcode};
|
||||
|
||||
|
@ -59,7 +58,7 @@ fn part1(input: &str) -> Result<i64> {
|
|||
|
||||
output = intcode
|
||||
.get_last_output()
|
||||
.ok_or_else(|| err!("no output at end of pipeline!"))?;
|
||||
.context("no output at end of pipeline!")?;
|
||||
}
|
||||
|
||||
res = std::cmp::max(res, output);
|
||||
|
@ -114,7 +113,7 @@ fn part2(input: &str) -> Result<i64> {
|
|||
res = std::cmp::max(res, signal);
|
||||
break;
|
||||
}
|
||||
None => return Err(err!("last amplifier halted without output")),
|
||||
None => bail!("last amplifier halted without output"),
|
||||
};
|
||||
} else {
|
||||
for out in last.output.iter() {
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::{self, Write};
|
||||
use std::str::FromStr;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
const IMG_WIDTH: usize = 25;
|
||||
const IMG_HEIGHT: usize = 6;
|
||||
|
@ -27,7 +25,7 @@ fn part1(image: &Image) -> Result<usize> {
|
|||
.layers
|
||||
.iter()
|
||||
.min_by_key(|l| l.pixels.iter().flatten().filter(|d| **d == 0).count())
|
||||
.ok_or_else(|| err!("image had 0 layers..."))?;
|
||||
.context("image had 0 layers...")?;
|
||||
|
||||
let one_count = most_zero_layer
|
||||
.pixels
|
||||
|
@ -74,7 +72,7 @@ impl fmt::Display for Image {
|
|||
}
|
||||
|
||||
impl FromStr for Image {
|
||||
type Err = Box<dyn Error>;
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
let s = s.trim_end();
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use crate::intcode::{parse_memory, Intcode};
|
||||
|
||||
|
@ -25,7 +24,7 @@ fn part1(memory: Vec<i64>) -> Result<i64> {
|
|||
intcode.run()?;
|
||||
intcode
|
||||
.get_last_output()
|
||||
.ok_or_else(|| err!("intcode output was empty!"))
|
||||
.context("intcode output was empty!")
|
||||
}
|
||||
|
||||
fn part2(memory: Vec<i64>) -> Result<i64> {
|
||||
|
@ -35,7 +34,7 @@ fn part2(memory: Vec<i64>) -> Result<i64> {
|
|||
intcode.run()?;
|
||||
intcode
|
||||
.get_last_output()
|
||||
.ok_or_else(|| err!("intcode output was empty!"))
|
||||
.context("intcode output was empty!")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use std::collections::HashSet;
|
||||
use std::fmt::Write;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
const INPUT: &str = include_str!("../input/day10.txt");
|
||||
|
||||
|
@ -85,7 +84,7 @@ fn part1(input: &str) -> Result<usize> {
|
|||
};
|
||||
}
|
||||
|
||||
let best = best.ok_or_else(|| err!("zero asteroid provided"))?;
|
||||
let best = best.context("zero asteroid provided")?;
|
||||
Ok(best.len())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fmt::Write;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{bail, Result};
|
||||
|
||||
use crate::intcode::Intcode;
|
||||
|
||||
|
@ -40,7 +39,7 @@ fn part2(input: &str, res: &mut String) -> Result<()> {
|
|||
|
||||
fn write_board(res: &mut String, board: HashMap<Position, bool>) -> Result<()> {
|
||||
if board.is_empty() {
|
||||
return Err(err!("board was empty"));
|
||||
bail!("board was empty");
|
||||
}
|
||||
|
||||
let min_x = board.keys().map(|p| p.x).min().unwrap();
|
||||
|
@ -106,13 +105,13 @@ impl Robot {
|
|||
match color {
|
||||
0 => board.insert(self.pos, false),
|
||||
1 => board.insert(self.pos, true),
|
||||
_ => return Err(err!("robot brain output different from 0 or 1")),
|
||||
_ => bail!("robot brain output different from 0 or 1"),
|
||||
};
|
||||
|
||||
match direction {
|
||||
0 => self.turn_left(),
|
||||
1 => self.turn_right(),
|
||||
_ => return Err(err!("robot brain output different from 0 or 1")),
|
||||
_ => bail!("robot brain output different from 0 or 1"),
|
||||
};
|
||||
self.move_forward();
|
||||
self.brain.output.clear();
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use std::error::Error;
|
||||
use std::fmt::Write;
|
||||
use std::str::FromStr;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
|
||||
const INPUT: &str = include_str!("../input/day12.txt");
|
||||
|
||||
|
@ -178,7 +176,7 @@ fn part2(mut planets: Vec<Planet>) -> Result<usize> {
|
|||
}
|
||||
}
|
||||
|
||||
Err(err!("planets never reached the same state twice"))
|
||||
Err(anyhow!("planets never reached the same state twice"))
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -224,38 +222,38 @@ impl Planet {
|
|||
}
|
||||
|
||||
impl FromStr for Planet {
|
||||
type Err = Box<dyn Error>;
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
let x_equals = s
|
||||
.find("x=")
|
||||
.ok_or_else(|| err!("couldn't find x value for planet: {}", s))?;
|
||||
.with_context(|| format!("couldn't find x value for planet: {}", s))?;
|
||||
|
||||
let comma = s
|
||||
.find(',')
|
||||
.ok_or_else(|| err!("couldn't find comma after x value: {}", s))?;
|
||||
.with_context(|| format!("couldn't find comma after x value: {}", s))?;
|
||||
|
||||
let x = s[(x_equals + 2)..comma].parse()?;
|
||||
let s = &s[(comma + 1)..];
|
||||
|
||||
let y_equals = s
|
||||
.find("y=")
|
||||
.ok_or_else(|| err!("couldn't find y value for planet: {}", s))?;
|
||||
.with_context(|| format!("couldn't find y value for planet: {}", s))?;
|
||||
|
||||
let comma = s
|
||||
.find(',')
|
||||
.ok_or_else(|| err!("couldn't find comma after y value: {}", s))?;
|
||||
.with_context(|| format!("couldn't find comma after y value: {}", s))?;
|
||||
|
||||
let y = s[(y_equals + 2)..comma].parse()?;
|
||||
let s = &s[(comma + 1)..];
|
||||
|
||||
let z_equals = s
|
||||
.find("z=")
|
||||
.ok_or_else(|| err!("couldn't find z value for planet: {}", s))?;
|
||||
.with_context(|| format!("couldn't find z value for planet: {}", s))?;
|
||||
|
||||
let bracket = s
|
||||
.find('>')
|
||||
.ok_or_else(|| err!("couldn't find bracket after z value: {}", s))?;
|
||||
.with_context(|| format!("couldn't find bracket after z value: {}", s))?;
|
||||
|
||||
let z = s[(z_equals + 2)..bracket].parse()?;
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fmt::{self, Display, Write};
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{bail, Result};
|
||||
|
||||
use crate::intcode::{parse_memory, Intcode};
|
||||
|
||||
|
@ -119,7 +118,7 @@ impl Tile {
|
|||
2 => Tile::Block,
|
||||
3 => Tile::Paddle,
|
||||
4 => Tile::Ball,
|
||||
_ => return Err(err!("couldn't associate number with tile: {}", n)),
|
||||
_ => bail!("couldn't associate number with tile: {}", n),
|
||||
};
|
||||
|
||||
Ok(tile)
|
||||
|
|
|
@ -2,8 +2,7 @@ use std::cmp::Ordering;
|
|||
use std::collections::HashMap;
|
||||
use std::fmt::Write;
|
||||
|
||||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
const INPUT: &str = include_str!("../input/day14.txt");
|
||||
|
||||
|
@ -22,7 +21,7 @@ fn parse_recipes(input: &str) -> Result<HashMap<String, Recipe>> {
|
|||
for line in input.lines() {
|
||||
let arrow = line
|
||||
.find(" => ")
|
||||
.ok_or_else(|| err!("couldn't find arrow in line: {}", line))?;
|
||||
.with_context(|| format!("couldn't find arrow in line: {}", line))?;
|
||||
|
||||
let elems = &line[..arrow];
|
||||
let elems = elems
|
||||
|
@ -30,7 +29,7 @@ fn parse_recipes(input: &str) -> Result<HashMap<String, Recipe>> {
|
|||
.map(|elem| {
|
||||
let space = elem
|
||||
.find(' ')
|
||||
.ok_or_else(|| err!("couldn't find separator for elem {}", elem))?;
|
||||
.with_context(|| format!("couldn't find separator for elem {}", elem))?;
|
||||
let amount = elem[..space].parse()?;
|
||||
let name = &elem[(space + 1)..];
|
||||
|
||||
|
@ -44,7 +43,7 @@ fn parse_recipes(input: &str) -> Result<HashMap<String, Recipe>> {
|
|||
let result = &line[(arrow + 4)..].trim_end();
|
||||
let space = result
|
||||
.find(' ')
|
||||
.ok_or_else(|| err!("couldn't find separator for result {}", result))?;
|
||||
.with_context(|| format!("couldn't find separator for result {}", result))?;
|
||||
let result_amount = result[..space].parse()?;
|
||||
let result_name = &result[(space + 1)..];
|
||||
|
||||
|
@ -76,7 +75,7 @@ fn get_ore_cost(
|
|||
if in_stock < quantity {
|
||||
let recipe = recipes
|
||||
.get(&material)
|
||||
.ok_or_else(|| err!("couldn't find recipe for {}", material))?;
|
||||
.with_context(|| format!("couldn't find recipe for {}", material))?;
|
||||
|
||||
let needed = quantity - in_stock;
|
||||
let num_reactions = (needed + recipe.produced - 1) / recipe.produced;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
|
||||
mod parameter;
|
||||
|
||||
|
@ -8,7 +7,7 @@ use parameter::Parameter;
|
|||
pub fn parse_memory(s: &str) -> Result<Vec<i64>> {
|
||||
s.trim_end()
|
||||
.split(',')
|
||||
.map(|x| x.parse().map_err(|e| err!("couldn't parse int: {}", e)))
|
||||
.map(|x| x.parse().map_err(anyhow::Error::new))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -74,7 +73,7 @@ impl Intcode {
|
|||
let dst = Parameter::new(mode3, self.memory.get(self.ip + 3).copied())?;
|
||||
|
||||
if let Parameter::Immediate(_) = dst {
|
||||
Err(err!("add: destination parameter can't be immediate"))
|
||||
Err(anyhow!("add: destination parameter can't be immediate"))
|
||||
} else {
|
||||
Ok(Opcode::Add(op1, op2, dst))
|
||||
}
|
||||
|
@ -85,7 +84,9 @@ impl Intcode {
|
|||
let dst = Parameter::new(mode3, self.memory.get(self.ip + 3).copied())?;
|
||||
|
||||
if let Parameter::Immediate(_) = dst {
|
||||
Err(err!("multiply: destination parameter can't be immediate"))
|
||||
Err(anyhow!(
|
||||
"multiply: destination parameter can't be immediate"
|
||||
))
|
||||
} else {
|
||||
Ok(Opcode::Multiply(op1, op2, dst))
|
||||
}
|
||||
|
@ -94,7 +95,7 @@ impl Intcode {
|
|||
let dst = Parameter::new(mode1, self.memory.get(self.ip + 1).copied())?;
|
||||
|
||||
if let Parameter::Immediate(_) = dst {
|
||||
Err(err!("input: destination parameter can't be immediate"))
|
||||
Err(anyhow!("input: destination parameter can't be immediate"))
|
||||
} else {
|
||||
Ok(Opcode::Input(dst))
|
||||
}
|
||||
|
@ -122,7 +123,9 @@ impl Intcode {
|
|||
let dst = Parameter::new(mode3, self.memory.get(self.ip + 3).copied())?;
|
||||
|
||||
if let Parameter::Immediate(_) = dst {
|
||||
Err(err!("less than: destination parameter can't be immediate"))
|
||||
Err(anyhow!(
|
||||
"less than: destination parameter can't be immediate"
|
||||
))
|
||||
} else {
|
||||
Ok(Opcode::LessThan(op1, op2, dst))
|
||||
}
|
||||
|
@ -133,7 +136,7 @@ impl Intcode {
|
|||
let dst = Parameter::new(mode3, self.memory.get(self.ip + 3).copied())?;
|
||||
|
||||
if let Parameter::Immediate(_) = dst {
|
||||
Err(err!("equals: destination parameter can't be immediate"))
|
||||
Err(anyhow!("equals: destination parameter can't be immediate"))
|
||||
} else {
|
||||
Ok(Opcode::Equals(op1, op2, dst))
|
||||
}
|
||||
|
@ -144,14 +147,14 @@ impl Intcode {
|
|||
Ok(Opcode::AdjustRelBase(offset))
|
||||
}
|
||||
99 => Ok(Opcode::Halt),
|
||||
_ => Err(err!("unknown opcode: {}", opcode)),
|
||||
_ => Err(anyhow!("unknown opcode: {}", opcode)),
|
||||
}
|
||||
}
|
||||
|
||||
fn exec(&mut self) -> Result<bool> {
|
||||
loop {
|
||||
if self.ip >= self.memory.len() {
|
||||
return Err(err!("reached end of program without halting"));
|
||||
bail!("reached end of program without halting");
|
||||
}
|
||||
|
||||
let opcode = self.get_opcode()?;
|
||||
|
@ -181,7 +184,7 @@ impl Intcode {
|
|||
} else if self.wait_input {
|
||||
break Ok(false);
|
||||
} else {
|
||||
break Err(err!("tried to read input but it was empty"));
|
||||
break Err(anyhow!("tried to read input but it was empty"));
|
||||
};
|
||||
dst.set(input, &mut self.memory, self.relative_base)?;
|
||||
|
||||
|
@ -197,7 +200,7 @@ impl Intcode {
|
|||
let val = test.get(&mut self.memory, self.relative_base)?;
|
||||
let dst = dst.get(&mut self.memory, self.relative_base)?;
|
||||
if dst < 0 {
|
||||
return Err(err!("dst must be a valid address: {}", dst));
|
||||
bail!("dst must be a valid address: {}", dst);
|
||||
}
|
||||
|
||||
if val != 0 {
|
||||
|
@ -210,7 +213,7 @@ impl Intcode {
|
|||
let val = test.get(&mut self.memory, self.relative_base)?;
|
||||
let dst = dst.get(&mut self.memory, self.relative_base)?;
|
||||
if dst < 0 {
|
||||
return Err(err!("dst must be a valid address: {}", dst));
|
||||
bail!("dst must be a valid address: {}", dst);
|
||||
}
|
||||
|
||||
if val == 0 {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use aoc::err;
|
||||
use aoc::Result;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Parameter {
|
||||
|
@ -10,13 +9,13 @@ pub enum Parameter {
|
|||
|
||||
impl Parameter {
|
||||
pub fn new(mode: i64, val: Option<i64>) -> Result<Self> {
|
||||
let val = val.ok_or_else(|| err!("parameter value out of bounds"))?;
|
||||
let val = val.context("parameter value out of bounds")?;
|
||||
let mode = mode % 10;
|
||||
|
||||
match mode {
|
||||
0 => {
|
||||
if val < 0 {
|
||||
Err(err!("negative value for position parameter: {}", val))
|
||||
Err(anyhow!("negative value for position parameter: {}", val))
|
||||
} else {
|
||||
let val = val as usize;
|
||||
Ok(Parameter::Position(val))
|
||||
|
@ -24,7 +23,7 @@ impl Parameter {
|
|||
}
|
||||
1 => Ok(Parameter::Immediate(val)),
|
||||
2 => Ok(Parameter::Relative(val)),
|
||||
_ => Err(err!("wrong mode for parameter: {}", mode)),
|
||||
_ => Err(anyhow!("wrong mode for parameter: {}", mode)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +74,7 @@ impl Parameter {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
Parameter::Immediate(_) => Err(err!("cannot write to immediate parameter")),
|
||||
Parameter::Immediate(_) => Err(anyhow!("cannot write to immediate parameter")),
|
||||
Parameter::Relative(offset) => {
|
||||
let address = relative_base.wrapping_add(*offset as usize);
|
||||
let cell = memory.get_mut(address);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use anyhow::Result;
|
||||
|
||||
use aoc::DayFunc;
|
||||
use aoc::Result;
|
||||
|
||||
use aoc2019::day01;
|
||||
use aoc2019::day02;
|
||||
|
|
Loading…
Reference in a new issue