Add 9 first days

This commit is contained in:
2021-01-08 23:41:37 +11:00
parent 4846e7c811
commit 2fd73ae5d1
49 changed files with 9734 additions and 0 deletions

1
1-report_repair/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

13
1-report_repair/.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,13 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "cargo",
"command": "run",
"problemMatcher": [
"$rustc"
],
"label": "rust: cargo run"
}
]
}

239
1-report_repair/Cargo.lock generated Normal file
View File

@@ -0,0 +1,239 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "heck"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
dependencies = [
"libc",
]
[[package]]
name = "itertools"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
dependencies = [
"either",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2",
]
[[package]]
name = "report_repair"
version = "0.1.0"
dependencies = [
"itertools",
"structopt",
]
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "structopt"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c"
dependencies = [
"clap",
"lazy_static",
"structopt-derive",
]
[[package]]
name = "structopt-derive"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "unicode-segmentation"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@@ -0,0 +1,11 @@
[package]
name = "report_repair"
version = "0.1.0"
authors = ["Guilhem MARION <gmarion@netc.fr>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
itertools = "0.9.0"
structopt = "0.3.20"

View File

@@ -0,0 +1,200 @@
1749
1897
881
1736
1161
1720
1676
305
264
1904
1880
1173
483
1978
1428
1635
1386
1858
1602
1916
1906
1212
1730
1777
1698
1845
1812
1922
1729
1803
1761
1901
1748
1188
1964
1935
1919
1810
1567
1849
1417
1452
54
1722
1784
1261
1744
1594
1526
1771
1762
1894
1717
1716
51
1955
1143
1741
1999
1775
1944
1983
1962
1198
1553
1835
1867
1662
1461
1811
1764
1726
1927
1179
1468
1948
1813
1213
1905
1371
1751
1215
1392
1798
1823
1815
1923
1942
1987
1887
1838
1395
2007
1479
1752
1945
1621
1538
1937
565
1969
1493
1291
1438
1578
1770
2005
1703
1712
1943
2003
1499
1903
1760
1950
1990
1185
1809
1337
1358
1743
1707
1671
1788
1785
1972
1863
1690
1512
1963
1825
1460
1828
1902
1874
1755
1951
1830
1767
1787
1373
1709
1514
1807
1791
1724
1859
1590
1976
1572
1947
1913
1995
1728
1624
1731
1706
1782
1994
1851
1843
1773
1982
1685
2001
1346
1200
1746
1520
972
1834
1909
2008
1733
1960
1280
1879
1203
1979
1133
1647
1282
1684
860
1444
1780
1989
1795
1819
1797
1842
1796
1457
1839
1853
1711
1883
1146
1734
1389

View File

@@ -0,0 +1,66 @@
use std::io::{BufRead, BufReader};
use std::path::{PathBuf, Path};
use std::fs::File;
use itertools::Itertools;
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
struct Opt {
/// Input file
#[structopt(parse(from_os_str))]
input_file: PathBuf,
}
fn main() {
// Check argv
let opts = Opt::from_args();
// eprintln!("opts = {:?}", opts);
// Load file if possible
let file_path = Path::new(&opts.input_file);
let input = File::open(file_path).unwrap();
let buffered_input = BufReader::new(input);
let lines: Vec<String> = buffered_input.lines().filter_map(Result::ok).collect();
// eprintln!("lines_iter = {:?}", lines_iter);
/* First, naïve solution */
// while let Some(line) = lines_iter.next() {
// let iter_clone = lines_iter.clone();
// // eprintln!("iter_clone = {:#?}", iter_clone);
// for line2 in iter_clone {
// let l1: i64 = line.parse().unwrap();
// let l2: i64 = line2.parse().unwrap();
// if l1 + l2 == 2020 {
// eprintln!("l1 = {:#?}", l1);
// eprintln!("l2 = {:#?}", l2);
// dbg!(l1 + l2);
// dbg!(l1 * l2);
// }
// }
// }
let res_two = find_2_sum_to_2020(lines.iter().filter_map(|x| Result::ok(x.parse::<i64>())).collect());
let res_three = find_3_sum_to_2020(lines.iter().filter_map(|x| Result::ok(x.parse::<i64>())).collect());
//let res_three = find_sum_to_2020(3);
}
fn find_3_sum_to_2020(numbers: Vec<i64>) -> Option<(i64,i64, i64)> {
for (i,j, k) in numbers.into_iter().tuple_combinations() {
if i + j + k == 2020 {
println!("Found {} and {} and {} whose sum is {} and whose product is {}", i, j, k, i+j+k, i*j*k);
return Some((i,j,k));
}
}
None
}
fn find_2_sum_to_2020(numbers: Vec<i64>) -> Option<(i64,i64)> {
for (i,j) in numbers.iter().tuple_combinations() {
if i + j == 2020 {
println!("Found {} and {} whose sum is {} and whose product is {}", i, j, i+j, i*j);
return Some((*i,*j));
}
}
None
}

1
2-password_philosophy/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

70
2-password_philosophy/Cargo.lock generated Normal file
View File

@@ -0,0 +1,70 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "anyhow"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4"
[[package]]
name = "password_philosophy"
version = "0.1.0"
dependencies = [
"anyhow",
"thiserror",
]
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "thiserror"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"

View File

@@ -0,0 +1,11 @@
[package]
name = "password_philosophy"
version = "0.1.0"
authors = ["Guilhem MARION <gmarion@netc.fr>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.35"
thiserror = "1.0.22"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,111 @@
use std::ops::RangeInclusive;
use anyhow::Result;
#[derive(Debug, PartialEq)]
struct PasswordPolicy {
char: u8,
range: RangeInclusive<usize>,
}
impl PasswordPolicy {
fn check_password(&self, password: &str) -> bool {
self.range.contains(
&password
.as_bytes()
.iter().
filter(|&&c| c == self.char)
.count()
)
}
fn check_password_newpolicy(&self, password: &str) -> bool {
(password.chars().nth(self.range.start()-1).unwrap() as u8 == self.char) ^ (password.chars().nth(self.range.end()-1).unwrap() as u8 == self.char)
}
}
#[derive(Debug, thiserror::Error)]
enum ParseError {
#[error("Expected {0}")]
Expected(&'static str)
}
fn parse_line(line: &str) -> Result<(PasswordPolicy,String)> {
let (policy_s, password) = {
let mut tokens = line.split(": ");
(
tokens.next().ok_or(ParseError::Expected("Coucou"))?,
tokens.next().ok_or(ParseError::Expected("Coincoin"))?,
)
};
let policy = {
let (range_s, char_s) = {
let mut tokens = policy_s.split(' ');
(
tokens.next().ok_or(ParseError::Expected("Range"))?,
tokens.next().ok_or(ParseError::Expected("Char"))?,
)
};
let (min_s, max_s) = {
let mut tokens = range_s.split('-');
(
tokens.next().ok_or(ParseError::Expected("Min"))?,
tokens.next().ok_or(ParseError::Expected("Max"))?,
)
};
PasswordPolicy {
char: if char_s.len() == 1 {
char_s.as_bytes()[0]
} else {
// return Err(ParseError::Expected("policy byte to be exactly one byte"));
return Err(ParseError::Expected("password policy byte to be exactly 1 byte").into());
},
range: (min_s.parse()?)..=(max_s.parse()?),
}
};
Ok((policy, password.to_string()))
}
fn main() -> Result<()> {
let count = include_str!("../data/input.txt")
.lines()
.map(parse_line)
.map(Result::unwrap)
.filter(|(policy,password)| policy.check_password(password))
.count();
println!("{} passes are valid", count);
let count_new_policy = include_str!("../data/input.txt")
.lines()
.map(parse_line)
.map(Result::unwrap)
.filter(|(policy,password)| policy.check_password_newpolicy(password))
.count();
println!("{} passes are valid with new policy", count_new_policy);
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_valid() {
let policy = PasswordPolicy{ char: b'b', range: 1..=4 };
assert_eq!(policy.check_password("boumbaby"), true);
assert_eq!(policy.check_password("b-b-b-boumbaby"), false);
assert_eq!(policy.check_password("oumay"), false);
}
#[test]
fn test_parse_line() {
assert_eq!(
parse_line("1-5 b: boulbi").unwrap(),
(
PasswordPolicy {
char: b'b',
range: 1..=5,
},
"boulbi".to_owned(),
)
)
}
}

1
3-toboggan_trajectory/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

5
3-toboggan_trajectory/Cargo.lock generated Normal file
View File

@@ -0,0 +1,5 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "toboggan_trajectory"
version = "0.1.0"

View File

@@ -0,0 +1,9 @@
[package]
name = "toboggan_trajectory"
version = "0.1.0"
authors = ["Guilhem MARION <gmarion@netc.fr>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -0,0 +1,323 @@
.#.#....##.......#..........#..
...#...........##...#..#.......
#.####......##.#...#......#.#..
##.....#.#.#..#.#............#.
##.....#....#.........#...##...
###..#.....#....#..............
..........#..#.#..#.#....#.....
##.....#....#.#...#.##.........
#...#......#....##....#..#.#...
.##.##...#....##..#.#.....#...#
.....#.#..........##.#........#
.##..................#..#..##.#
#.#..........##....#.####......
.#......#.#......#.........#...
#....#..##.##..##........#.#...
##..#.##..#...#..####.#..#.....
###....#.###.##...........##..#
.....#.##.....##.#..#####....##
....#.###....#..##....##...#...
..###.#...##.....#.##..#..#.#..
#...#..#..#.........#..#.......
##..#.#.....#.#.#.......#...#.#
...#...##.#........#...#.......
..#..#.#..#...#...#...........#
........#.....#......#...##....
#........##.##.#.#...#...#.....
####.......#.##.###.#....#.....
...#...........#...#......#...#
##...#...#............#.......#
....#...........##.......#.....
###......#.....#....#...#.#...#
.....##..........#.......#.#...
##.##.##...#......#....#.......
##..#.#..#......#...#..#.......
....#....##.##............####.
..#.###..#.##.###..#.##.......#
#.##..#.#.....#..#.....##......
..##..#.....##.#.##........#...
.#..#.#......#..#............#.
.....#..#.#...#....#.##.#......
.#...##.#..#.#...##...##..##...
###............#.#..#..#...#...
..#..##.####.#.....#.....##.###
#....#.##..##....#..#...#.##.#.
.....#.##.........##...##......
.........####.#....#.#......#.#
.........#.#..#...#.#..#.#....#
.#.....#..##.##..##....#.......
..........##......#.##.###....#
.##...###..##.#...#........##..
..............#.#....#.#.###.##
..##.##.......#.#......##...#..
.#.....#..##..#.###...#..#.##.#
#.....#.#..#...#........#...#..
.#......#....#.#.....###...#..#
..##.#....#..##......#.....#...
..#.#.##..#.....#.####..###....
.........#......#..#...........
..#........#.##.#.....##.##..#.
.......#.........#....#...#.#..
.##.....#.#....#.#.......#.....
..........#.##........##...##..
###..###.#.#..#..#####.##.#.##.
..##..##.#.#...#..#.#.#......#.
#..#..#..#..##..#.....#......#.
..#....#.##..#......##.........
..#.##......#...##.#......#....
.......#..#.##.#.....#.........
.......#.#.#.###...##......#...
.....#.#..........#..#...#.....
....##..........#..........##..
..#......#.....#.##.#..#...#.#.
....#.....#..#...#..#.#.##..###
.####....#........#...#........
...##.#.##.#..#...##...#.##....
....#...#...#.#.#.#...#..#.....
.....#...#.#.....#.#........##.
..#.#.......###.#.....##.......
......#.........##....#....#..#
.............##.....##.........
.........##...##.......#.....#.
##.........#..........#.###..##
...#.....#......#....#..##.....
##..#...#...##.#.....#.#......#
..#...##.#.......#.#......#.##.
......#.......#.#...........#..
..........#.....##............#
#........#...#..#.......###.##.
.##...........#.#........#.#.#.
...#..##...#.#....#####.#......
.....##...###...#..#.##...####.
...#....#.....#..#.......#.....
#....#....#...#..#..#.######..#
#.###...........#......#...#..#
.#.#.#.#..#....#....#...##.#...
.#..#.........#.#....###...#...
......#..##.##..........#....##
.....#......##....##.....#...#.
.#...#.#.#....##....#..#....#.#
..................#..###.#..##.
..#.........#......#....#..###.
#.#.....#..#..#....###..###....
..##..##.#..##........##...##..
##..#........##..###..#.....#.#
..#..###..#......#....#...#...#
#..#.#..............##.#..#.#..
.....####....#...####.....#.#..
.....#....##.#......###........
##.##...#.#.#.#.......#....##..
.#......#...#.#....#..##.#.##.#
#.#.##.#.#......#..##........##
...##.....#.....#...#..###...#.
........###.....#.....#...##..#
.....#.##.##......#.#....#...#.
.#....##.......#..#.####.......
.#..#....#..........#......#.#.
.#.##.##.....###.#.#...........
.........#......#..##..........
....#...##.#.#.#..#.#.........#
..#.....#.##...#..#..#.###....#
...#.##......#.....##....#.....
###............#.#....#...#....
.......#.....#..#.#.#....#..#.#
...#......#.#..##..#....#...#.#
............##........##..##...
..#..#.##..#......###..#.......
........#.........#............
..#...#.#########.#...##..###..
#....#......#.......#.#.....#..
#.#..#....###.###....#...#.#...
#...###.#.#.......#.##......#..
.................#...#.#.#.....
##....#...#........#....#.#..#.
......#.....#...#..........#.#.
##..........#...#..........#.##
..#.#.##.#....#.#......#...##..
.....#.......#..#.....#........
#.##.#..##..#.......##.........
....#......#..#..#.#...#.......
...#....#................###...
.##.....#.#....#.#..........##.
...#..#....#.##.##......#......
..#.#....#.......#.#..##.......
....#.....#..........##.#.#####
#.....................##..#..#.
.###..#.##.......##.#...#..#...
...###.......#..#...#......#..#
#..#...#.#..#.#..#..#.##.......
#...##.......#..#..#.##..###...
......#....#.#.#........#.##..#
..##..#....#....#..#.#..#......
..##.#...#.#######..#...#.....#
..#....#..#.........#..##......
...#....#.#......#..#..#.#.....
#..#....#........#.#..##....###
#....#..##......##.##.....#.###
...#.#..........#..#.#.#.#.##..
......##..#.#..#.#....#....#...
##....#....#..#..#.##......#...
....#.#..##.#.#...###....##.#..
...#.......##..#.......#...#...
......##.......#..##.....#...#.
...#.#...#...........#...#.....
.#....#...#......##.##..###..#.
.#..........#...#...#...##.##..
.....###..#.....#..##....#.####
..#.###..#..##..##.....#.#.....
.............#.###...##.#.....#
....###.......###.#.....#..#.#.
........##.#.........#.....###.
.....###.#..#.....#...#..#.....
.#....#..##.#..#.#....#.......#
........#......#.#..#.#..#...##
...#.##.##......#..............
.#.....##.#.....#..#......##...
#..#..#.....#.....#.....###....
.##...........#..#.##.....#....
..#.#......#.#...#.##.#..#...##
...#..........#.....#..........
#.#.#.#.#...#....#...#.....##..
#......##...#...#..........#.#.
....##........#.#..............
#..#.#.#..#........##......#.##
........####...##.#.....#......
....#........#.#..#..##..#.#...
.#.....#..###...#..#.....#..#..
#......###.#..#....#..#.#......
....#.....##.##..#...#.#..##.#.
..##..#...#.#......#....#...#.#
#..##...##..#...###...#..#.....
.......#.....#...........##....
#..##....#........#....##..#.#.
.#........#..##...###.#..#.....
.#.#....#..##...#...##.#..###..
#.........#.......#.....#.#....
#..#.....#.#.###.#..#......#...
....#..#.#....#..##..###....###
###.##.#.#..#...........#.#.#..
..##.#.......#......#..##....#.
.....#.#.#.......##.......#...#
...........#.##....##.##....#.#
...#.......#..#.##..#......#..#
#.#.#...#......##.#...........#
##........#...........###.#..#.
..........#.#.#....#.#..##.#.#.
...#.#.#....#..........#..#....
#.#....###.#.#..#.......###...#
.#....#......#.#.#..#..#.......
......##.............#....#.#.#
.#..........#.........#.##.....
##....#....##....#..#.......#..
#.##.##.#..#..#.....#..#.##.#..
.#..#.......##..#.....##.##....
.......#..........#.#.##..#.##.
....#.....#.#...##....##.......
.......#.........#...##....##.#
#.....#......#..........#...#..
...#.#.......#.#..#....###..#..
.....#.#.#.........#...........
.#..###.#.#........#.#.........
.........#..#......##...##....#
...###..#.....##.....#.###....#
.##...#...#........###.#..#....
.##........#..#.###.######.##.#
##.#...#.#....#..##.#....##....
.......##.....##.#..###.#......
..##...##........#.......#....#
#..##...#.####...###......#...#
.##.....#.##.#.#.....###.#..##.
..###....#.#.###.#....#........
....#..###..#...#....#..#..#.#.
#.#.##....##...##.......#......
.........#...#....#..#.........
.............#...#..##.#.......
...#.##.......#...#.#..##.##...
.####.#.##..#.#......#.##...#.#
.#..#.#.....#.................#
..#.##..###....#...#......####.
..##..##...........#....#...#..
....#...#...#...#.......#....#.
#.#...###...#...#.#...#....##.#
......#...#.#.......#.....#...#
....##...#.#.#....#....#.#....#
.....#.....#...##..#...#....##.
#.....#....#......##.##....#...
...#.#....#...#....#.#....##..#
...#.#..#...##....###..#.......
...##......###...###.#...#..#..
##.......#.......###.......#..#
..##.##..###.#............#...#
#.....##..#..##....##..#.......
......#.#...#......#.....#.....
#...........#....#..##.##.#....
.......#..#......#...#....#...#
.#...##...........#......#...#.
#........#....##...###.#....#..
.....#.......##.........#.##...
.#.###..#....#..##.#..#.#..#...
#.......#.##.#.#....#.#..#....#
###.....#.#.......#..#......#.#
#..#.#.......#.#..##..##.#.#...
#..#.#.#.###........#.....#...#
#.#.#..#..##.....#...........#.
..#.#..#.....#...#...#...##....
...#.##......#...##.#...#.#.#.#
#..#.#.#.#.......####..........
..#......#.#......##.###.....##
..#...##..#.........##....#.##.
##.##.##.#.#.....#..........##.
.#.....###.#..#....#..#.###...#
#...##.......###....#.#..#.....
..#....##.........##.........##
......#....#.##.......#........
..#.#.#..#...#...#...##.#...#..
......#..##.#.#.#...##...#.#.##
#..#...##.#.....#...#.##.......
..#..#.........##.#...#.##...##
##.##.#....#.......#.##..#.....
.....##...##.##...##.........##
#......#...#.......#...#...#...
...##...........#...#..#.......
.#.##.#..#........#....#.......
#.#...#..#......##...#.#.##....
##........####..#.#...#.#.##.##
#..#.#.##......##.#.#..#.......
.....#.........#..#.####....#..
......##..#....#...#.#....#....
#...##........#.........#.....#
.#.#...#.#.#..#............##.#
.#..#....#....#.....#...#.....#
..###...#..#.....#.##.###...#.#
.#.###..#..#...#.#...#.#......#
#...#####......###........##...
.....#.....#..#.#....#..##.....
....##...#.#.##.#####...#....#.
.#.#.........##.#.......#..##..
.#...#.#...#...#....#.#...##.#.
.##...#..#.#..#......#.#.#..##.
..#.....#..#.....##.....#......
..#........#..##...#.......###.
.#....#.......#....#....#..#...
....#......#.#.#.........#.....
..##...#.#.#...#.#........#....
.#.....####...##.#..#...##.....
...#.....#...#...#....#....#...
.........#..#.#.....#..#.#..#..
.........##...........#.......#
......#..#.....##...#.##.#.....
.#......##........##...#.#.##..
.....#.#..##...........#..#..#.
...#.......#...#.#..#.##..#.##.
...#.......#.....#.#...#.##.#..
#.....#.............##.#..####.
.#...#......#...##.#....#.#....
.##..##.##....#.#.....#.......#
...#...#....#....##.#..#....##.
..............##....#.......#.#
.#.#.#...##..#..#...###.#..#...
.#.#...#.#..#.#..#...######..#.
........#......#.#..#.#....#...
..###.....###.#.##....#...##...
.##.#.....#.......##.......#...
..#..##...#..........#.#....#.#

View File

@@ -0,0 +1,133 @@
use std::{fmt};
#[derive(Clone, Copy, PartialEq)]
pub enum Terrain {
Plain,
Tree,
}
impl Default for Terrain {
fn default() -> Self {
Terrain::Plain
}
}
impl fmt::Debug for Terrain {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", match self {
Terrain::Plain => '.',
Terrain::Tree => '#',
})
}
}
#[derive(Debug, Copy, Clone, PartialEq, Default)]
pub struct Vec2 {
pub x: i64,
pub y: i64,
}
impl From<(i64, i64)> for Vec2 {
fn from((x,y): (i64, i64)) -> Self {
Self { x, y }
}
}
#[derive(Clone)]
pub struct Map {
size: Vec2,
tiles: Vec<Terrain>
}
impl fmt::Debug for Map {
fn fmt(&self,f: &mut fmt::Formatter) -> fmt::Result {
// A most honourable moment, but chaining debugs means lots of spare ""[]
//let dd: Vec<String> = self.tiles.chunks_exact(self.size.x as usize).map(|x| format!("{:?}", x)).collect();
for line in self.tiles.chunks_exact(self.size.x as usize) {
let line_s: String = line.iter().map(|x| format!("{:?}", x)).collect();
writeln!(f, "{}", line_s)?
}
// let banana = self.tiles
// .chunks_exact(self.size.x as usize)
// .map(|x| format!("{:?}", x))
// .collect::<Vec<String>>()
// .join("\n");
// writeln!(f, "{}", banana)
Ok(())
}
}
impl Map {
pub fn new(size: Vec2) -> Self {
Self {
size,
tiles: vec![Default::default();(size.x*size.y) as usize]
}
}
pub fn get(&self, pos: Vec2) -> Terrain {
self.tiles[self.idx(pos).unwrap_or_default()]
}
pub fn set(&mut self, pos: Vec2, tile: Terrain) {
if let Some(idx) = self.idx(pos) {
self.tiles[idx] = tile;
}
}
fn wrap_coords(&self, pos: Vec2) -> Option<Vec2> {
if !(0..=self.size.y).contains(&pos.y) {
None
} else {
Some(Vec2{
x: pos.x % self.size.x,
y: pos.y})
}
}
fn idx(&self, pos: Vec2) -> Option<usize> {
self.wrap_coords(pos).map(|pos| (pos.x + pos.y * self.size.x) as usize)
}
pub fn from_bytes(s: &[u8]) -> Self {
let rows = s.iter().filter(|&&x| x == b'\n').count();
let cols = (s.len() - rows) / rows;
println!("Size : {} {}", rows, cols);
let mut res = Self::new((cols as i64,rows as i64).into());
let mut pos = Vec2 { x: 0, y: 0 };
for tile in s {
match tile {
b'\n' => {
pos.y += 1;
pos.x = 0;
}
b'#' => {
res.set(pos, Terrain::Tree);
pos.x += 1;
}
_ => {
res.set(pos, Terrain::Plain);
pos.x += 1;
}
}
}
res
}
pub fn solve(&self, slope: (i64, i64)) -> i64 {
let mut seek_pos = Vec2 { x: 0, y: 0};
let mut tree_count = 0;
loop {
if self.get(seek_pos) == Terrain::Tree {
tree_count += 1;
}
if seek_pos.y + slope.1 >= self.size.y {
break;
}
seek_pos.y += slope.1;
seek_pos.x += slope.0;
}
tree_count
}
}

View File

@@ -0,0 +1,17 @@
use toboggan_trajectory::*;
fn main() {
let map_str = include_str!("../data/input.txt");
// println!("{}", map_str);
let map: Map = Map::from_bytes(map_str.as_bytes());
// println!("{:#?}", map);
eprintln!("First part solution = {}", map.solve((3,1)));
let sols: i64 = vec![
(1, 1),
(3, 1),
(5, 1),
(7, 1),
(1, 2),
].iter().map(|slope| map.solve(*slope)).product();
println!("Second part solution = {}", sols);
}

View File

@@ -0,0 +1,54 @@
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vec2_from_tuple() {
// let v: Vec2 = (32, 75).into();
let v = Vec2::from((32, 75));
assert_eq!(v, Vec2 {x: 32, y: 75})
}
#[test]
fn test_format_map() {
let m = Map{
size: Vec2{x: 2, y:2},
tiles: vec!(Terrain::Tree, Terrain::Plain, Terrain::Plain, Terrain::Plain)
};
assert_eq!(format!("{:?}", m), "#.\n..\n")
}
#[test]
fn test_normalize_pos() {
let m = Map::new((2, 2).into());
assert_eq!(m.normalize_pos((0, 0).into()), Some((0, 0).into()));
assert_eq!(m.normalize_pos((1, 0).into()), Some((1, 0).into()));
assert_eq!(m.normalize_pos((2, 0).into()), Some((0, 0).into()));
assert_eq!(m.normalize_pos((-1, 0).into()), Some((1, 0).into()));
assert_eq!(m.normalize_pos((-2, 0).into()), Some((0, 0).into()));
assert_eq!(m.normalize_pos((0, -1).into()), None);
assert_eq!(m.normalize_pos((0, 2).into()), None);
}
#[test]
fn test_index() {
let m = Map::new((3, 5).into());
assert_eq!(m.index((0, 0).into()), Some(0));
assert_eq!(m.index((2, 0).into()), Some(2));
assert_eq!(m.index((0, 1).into()), Some(3));
assert_eq!(m.index((2, 1).into()), Some(5));
}
#[test]
fn test_create_map() {
let mut map = Map::new(Vec2{x:5,y:5});
let trees: Vec<Vec2> = vec![
(1,2).into(),
(2,1).into(),
(3,3).into(),
(1,4).into(),
(5,1).into(),
];
trees.iter().for_each(|pos| map.set(*pos, Terrain::Tree));
println!("{:?}", map)
}
}

1
4-passport_processing/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

119
4-passport_processing/Cargo.lock generated Normal file
View File

@@ -0,0 +1,119 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68803225a7b13e47191bab76f2687382b60d259e8cf37f6e1893658b84bb9479"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "memchr"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "passport_processing"
version = "0.1.0"
dependencies = [
"anyhow",
"regex",
"thiserror",
]
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-syntax"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
[[package]]
name = "syn"
version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "thiserror"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
dependencies = [
"lazy_static",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"

View File

@@ -0,0 +1,10 @@
[package]
name = "passport_processing"
version = "0.1.0"
authors = ["Guilhem MARION <gmarion@netc.fr>"]
edition = "2018"
[dependencies]
anyhow = "1.0.36"
regex = "1.4.2"
thiserror = "1.0.22"

View File

@@ -0,0 +1,953 @@
ecl:amb
pid:690616023
byr:1994 iyr:2014 hgt:172cm hcl:#c0946f eyr:2022
eyr:1980 cid:97
hcl:z ecl:#102145 iyr:2011 byr:1945
pid:187cm hgt:179in
ecl:amb
iyr:2011
cid:113
eyr:2021 hcl:#b6652a pid:004682943 byr:1940
hgt:173cm
iyr:2023
cid:146 byr:2022 ecl:dne hgt:76in eyr:2040 hcl:z
hcl:#f97e30
cid:73 iyr:2013 byr:1929 hgt:157cm
eyr:2024 ecl:blu pid:673398662
hcl:5343fe
hgt:152 byr:2018
eyr:1992 pid:85999926 iyr:1938 ecl:#15bd97
byr:1975 hcl:z eyr:1988 pid:#c36f52
iyr:2018
hgt:184cm
byr:1954 eyr:2023 hgt:170cm iyr:2012 ecl:blu pid:299556897 hcl:#b6652a
hgt:191cm ecl:oth hcl:#7d3b0c
iyr:2016 pid:187567535
byr:1999 eyr:2023
pid:814358147 eyr:2022 iyr:2000 byr:2001 hcl:#18171d
ecl:blu
hgt:76in
ecl:hzl
hgt:163cm byr:1955 iyr:2018 eyr:2024 hcl:#6b5442 pid:343362099
eyr:2020 pid:185090160 ecl:#21a5e6
iyr:1928 byr:2006 hcl:a2ebbf hgt:104
hgt:153cm
hcl:#a97842 ecl:blu eyr:2028 byr:1969 iyr:2019
pid:729700590
iyr:2019 byr:1981 hgt:150cm pid:606092356 hcl:#18171d eyr:2026
ecl:grn
pid:760899887
eyr:2023 hcl:#866857 hgt:185cm iyr:2017
byr:1976 ecl:gry
byr:1965 eyr:2026
hcl:#623a2f
ecl:blu pid:483363116 iyr:2010 hgt:178cm cid:204
ecl:oth eyr:2022
pid:268557763 byr:1965 iyr:2015 hcl:#c0946f hgt:164cm
ecl:gry hgt:168cm hcl:#623a2f eyr:2020 cid:163 pid:124082663 iyr:2016 byr:1996
hcl:4c44fb iyr:1957 eyr:2039 ecl:grt hgt:63cm byr:2012 cid:104
byr:2024 iyr:2023
ecl:gry
eyr:2007 pid:170cm hgt:68 hcl:d57b67 cid:333
byr:1956
hgt:169cm iyr:2013 pid:370491367
ecl:gry hcl:#5bc41d
eyr:2023 iyr:2028 byr:1969 ecl:lzr hcl:1989b1 hgt:71cm pid:#12c226
cid:304 pid:866132461
byr:2022
hcl:z hgt:191in ecl:lzr iyr:2029 eyr:1989
ecl:brn hcl:#9a45a7
hgt:176cm
byr:1974 pid:758747330 iyr:2014 eyr:2020
cid:190 ecl:hzl iyr:2014 byr:1990 hgt:69in eyr:2037 pid:384015829 hcl:#ceb3a1
byr:1998 eyr:2022 iyr:2018 hgt:153cm
hcl:#733820 pid:424512443
ecl:blu
hcl:27c41f byr:1972 eyr:1994 pid:777840405
ecl:gry
hgt:179cm
iyr:2021
hgt:166cm eyr:2032 ecl:gry byr:1936
pid:41703652
hcl:#efcc98 iyr:2019 byr:1936 pid:985830958 eyr:2021
hgt:175cm ecl:brn
eyr:2025 pid:972163513 hgt:155cm ecl:brn cid:169 iyr:2015
hcl:#6b5442
eyr:2026
hgt:173cm
byr:1984
cid:191
pid:791209101 hcl:#341e13 iyr:2020 ecl:hzl
hgt:64cm
iyr:2010 byr:1978
pid:618891746 hcl:#d6ac23 eyr:2023 ecl:brn
eyr:2021 hcl:#341e13 iyr:2018 pid:502081929
ecl:blu
ecl:amb
iyr:2018 pid:8933462515
hgt:160cm hcl:e330f0 eyr:2030 byr:2007
ecl:gry byr:1980 hcl:#341e13 iyr:2015 pid:830724822 hgt:167cm cid:156
eyr:2023
ecl:gry hcl:#c39b75 byr:1995 hgt:153cm
eyr:2029 pid:83056475 iyr:2013
byr:1965 cid:250
ecl:oth iyr:2016
pid:242792947 eyr:2025 hcl:#efcc98
byr:2011 ecl:#62fe2d hcl:#2b434a hgt:190cm
eyr:2031 iyr:1964 pid:7096872943
cid:258 hcl:#c0946f pid:698224453 eyr:2029 hgt:189cm iyr:2012 ecl:blu byr:1963
eyr:2028 byr:1942 hgt:156cm pid:836243052 iyr:2016
hcl:#888785 cid:310 ecl:brn
hcl:#a97842 pid:740164307 ecl:oth byr:1997
hgt:166cm
iyr:2015 eyr:2026
hcl:4ee9da iyr:2020
eyr:1933 hgt:136 ecl:#8dee29 pid:44266010 byr:1966 cid:82
ecl:amb byr:1921 hgt:182cm eyr:2026
hcl:#c0946f iyr:2010
hgt:178cm cid:343 eyr:2023 pid:197119382 hcl:#623a2f iyr:2017
ecl:brn byr:2002
eyr:2030 byr:1967 ecl:blu hgt:166cm iyr:2017
pid:655602762 hcl:#6b5442
cid:143 hgt:152cm eyr:2026 iyr:2018 byr:1950 ecl:grn hcl:#866857 pid:067535973
byr:2019 ecl:#e3c288 iyr:1948 hgt:72cm hcl:7da71b eyr:1956
hcl:#cfa07d
pid:688405238 cid:200 byr:1950
iyr:2020 ecl:hzl hgt:170cm
eyr:2026 hgt:164cm iyr:2010 hcl:#b6652a pid:404835595 byr:1924 ecl:blu
iyr:2016 hcl:#866857
ecl:gry
eyr:2023 pid:986813245 cid:247 byr:1977
hgt:173cm
ecl:#a59335 eyr:2023
hcl:033f22 byr:1947 hgt:152
iyr:2029 pid:#1e686a cid:305
byr:2005
ecl:amb hcl:#a97842
iyr:1972
eyr:1967 pid:274884869
eyr:2038 iyr:2018
pid:181cm ecl:xry hgt:185in
hcl:109b28 cid:287
ecl:amb byr:1943 pid:002483342 hgt:178cm
hcl:#c0946f eyr:2030
iyr:2014
iyr:2020 byr:1963 cid:131 hcl:#18171d hgt:181cm pid:146726616 eyr:2021
pid:062629370 byr:1931 hgt:188cm eyr:2021 ecl:gry
hcl:#166b3d
pid:007028786 ecl:blu hgt:156cm byr:1981 hcl:#888785 cid:53 iyr:2019
iyr:2014 hcl:#623a2f
ecl:hzl eyr:2029 byr:1988
pid:849096536 hgt:167cm cid:322
pid:160824363
hcl:#19bed3
eyr:2024 hgt:171cm
byr:1968 iyr:2019
eyr:2024 hcl:#dd66d0
byr:1986
cid:105 pid:816153574 ecl:hzl iyr:2013
hgt:173cm
hcl:#ceb3a1 hgt:62in ecl:gry
iyr:2017 cid:234 byr:1963
eyr:2029
pid:514406488
hcl:#fffffd ecl:blu
eyr:2020 iyr:2010
pid:544347103 hgt:164cm byr:1939
eyr:2021
pid:999479324 hgt:164in ecl:brn iyr:2016
hcl:#a97842 byr:2020
pid:053149570 byr:1920 eyr:2027 hgt:190cm iyr:2011 hcl:#fffffd ecl:oth
hgt:165cm
hcl:#cfa07d
ecl:oth
eyr:2023
pid:186cm
byr:1937 iyr:2012
eyr:2026 hgt:64cm hcl:#ac426a byr:1969
cid:345 iyr:1960
pid:#df648a ecl:blu
byr:1923 iyr:2017
eyr:2027 pid:798497862 hgt:182cm
hcl:#ceb3a1 ecl:oth
hgt:182cm eyr:1990 ecl:grn hcl:#efcc98 byr:1968
pid:005962011
iyr:2010
cid:74 eyr:2020 hgt:71in
iyr:2015 pid:487940408 byr:1952
hcl:#733820
hgt:75cm cid:249
ecl:hzl
hcl:#6b5442 pid:4860441 eyr:2020
ecl:hzl eyr:2025 hgt:183cm
iyr:2020 byr:1993 pid:572766871 hcl:#866857
hcl:#888785 pid:200125941 hgt:155cm byr:1923
eyr:2021 iyr:2010 ecl:gry
pid:502547835 iyr:2014 hcl:#b6652a
byr:1985 hgt:189cm eyr:2024
eyr:2024 hcl:#fffffd ecl:amb byr:1952
pid:724639818
iyr:2013 hgt:183cm
byr:2023
iyr:2026 ecl:gry eyr:2032 hcl:3e0fc4 pid:5620497552
hgt:84
cid:79
hgt:68cm
iyr:2021
pid:#365b83 byr:1928
ecl:#79a6b3 eyr:2027 hcl:54130e
hgt:74cm byr:1953
cid:263 iyr:2018
ecl:zzz
hcl:#efcc98
pid:154cm eyr:1951
cid:272 pid:0638528559 hcl:z hgt:63cm byr:2029 ecl:zzz
eyr:2033
iyr:2016
hgt:193cm hcl:#6b5442 pid:715518898 ecl:brn cid:195
eyr:2025
ecl:oth
eyr:2025 hgt:166cm byr:1944
iyr:2017 pid:814141652
eyr:2025 cid:140 ecl:hzl hcl:#c0946f pid:824866056 iyr:2011 hgt:65in byr:1947
iyr:2016
ecl:brn eyr:2021
hgt:161cm
byr:1984 hcl:#602927 pid:821539320
hgt:175cm cid:190 hcl:#ceb3a1 ecl:brn byr:1927 iyr:2017 eyr:2029 pid:836598854
eyr:2026 ecl:brn hgt:157cm pid:038645205 byr:1995
iyr:2019 cid:339
ecl:brn hgt:70in hcl:#c0946f
pid:535498918 cid:153
iyr:2012 eyr:2030
byr:1995
hcl:#efcc98 hgt:174cm eyr:2030 pid:180839761
ecl:grn iyr:2010
hgt:59cm eyr:2035 byr:2021 iyr:2012 ecl:hzl pid:219328725 hcl:#888785
ecl:oth hgt:184cm byr:1984 iyr:2016
hcl:#cfa07d
iyr:1998 byr:2024 ecl:lzr hgt:187 hcl:z eyr:1935 pid:#789b56
iyr:1967 hcl:z pid:828930046 hgt:59in
cid:153
byr:2021
ecl:grn
eyr:1935
byr:1991
hcl:#341e13 ecl:gry iyr:2018
hgt:67in pid:157970631 eyr:2021
byr:1941 hgt:169cm pid:322510952 hcl:#cfa07d cid:75 ecl:oth
eyr:2021 iyr:2020
hcl:#7d3b0c iyr:2013 cid:78 hgt:167cm ecl:brn byr:1974 pid:237404828
pid:1567157833
hcl:#7d3b0c iyr:2025 eyr:2023
byr:2002 ecl:oth hgt:191cm
ecl:amb iyr:2014 hgt:182cm pid:526612838
cid:287 eyr:2025 byr:1988
hcl:#866857
hcl:#866857 hgt:174cm byr:1992 eyr:2028 iyr:2015
eyr:2029
hgt:190cm
hcl:#18171d
cid:245
ecl:oth pid:3636033742 byr:2024
iyr:2019
byr:1972 hgt:163cm eyr:2020 hcl:#b6652a
pid:360516396 iyr:2019 ecl:grn
iyr:1997 ecl:#be02d2
eyr:2020 cid:259 byr:1953
hcl:#6b5442
hgt:177cm pid:978155362
pid:377596476 cid:153
eyr:2025 byr:2000 hgt:181cm iyr:2014 hcl:#abc5cb ecl:hzl
cid:171 ecl:lzr iyr:2013 eyr:1973 byr:2004
pid:#267099 hgt:101
hcl:#623a2f
pid:029193661
hgt:183cm
ecl:hzl eyr:2029 iyr:2013
byr:1977
ecl:amb eyr:2021 hgt:159cm byr:1970 cid:152
hcl:#b6652a iyr:2020 pid:180512119
eyr:2025
ecl:grn
hgt:60in iyr:2013 pid:697352361
hcl:#18171d byr:1989
byr:1934 hgt:165cm pid:703537570 ecl:hzl iyr:2015
hcl:#888785
ecl:gmt
hcl:6dd6a5
byr:1951
pid:#7ab761 cid:304 iyr:1924 eyr:1953 hgt:71in
ecl:amb hcl:#733820 eyr:2030 hgt:178cm
pid:692422832 iyr:2019
cid:276
iyr:2012 ecl:oth
pid:674969358
eyr:2027 hgt:157cm cid:247 hcl:#a97842
byr:2017 eyr:2031 hgt:180cm hcl:#ceb3a1 pid:372071110
iyr:2015 ecl:amb
hgt:165cm iyr:2015
eyr:2021 ecl:amb byr:2000 cid:235
eyr:2027 hcl:#623a2f pid:595874068
ecl:amb
hgt:177cm iyr:2019 byr:1929
pid:8150929412 hgt:191in eyr:2031 cid:233 byr:2027
iyr:2026 ecl:#e94348 hcl:z
hgt:65 byr:2009 iyr:2029 hcl:#fffffd eyr:1950 pid:950012410 cid:212 ecl:#5a6042
ecl:#44c561 hgt:178cm eyr:2021 pid:753771724
iyr:2014
hcl:#70adb2 byr:1989
iyr:2018 pid:809109448 ecl:amb hcl:#b6652a hgt:63in byr:1976 cid:96
byr:2021 ecl:grn pid:9284377919 iyr:2011 hgt:75cm hcl:#18171d eyr:2026
ecl:oth
byr:1926
hgt:63 iyr:1948 cid:61 hcl:a528d1 eyr:2034
byr:1978 pid:150503169 iyr:2015 ecl:grn hgt:172cm cid:70 eyr:2022 hcl:#7d3b0c
byr:1957 hcl:#cfa07d iyr:2010 ecl:amb eyr:2025 pid:921901279
ecl:utc pid:154cm
byr:1964 eyr:1978 hgt:114 hcl:z
byr:1929 ecl:amb eyr:2028 iyr:2013
hcl:#fffffd pid:479814281
cid:105 hgt:64in
pid:949640425
cid:205 hcl:#341e13 ecl:amb
hgt:171cm byr:1998
hgt:190cm cid:113 ecl:grn eyr:2037
hcl:#ceb3a1 pid:7994792779 iyr:2011
hgt:152cm iyr:2010
byr:1992 eyr:2020
hcl:#602927
cid:66
pid:604149642
eyr:2028
byr:1961 hgt:71in
iyr:2013 cid:135
pid:534090716 hcl:#ceb3a1 ecl:oth
iyr:1937 byr:1995 cid:200
eyr:2037 pid:#daf9af
hcl:052017 ecl:zzz hgt:73cm
ecl:amb
hcl:#a97842
iyr:2018
hgt:153cm
cid:149 eyr:2023 pid:533403632
cid:275 ecl:brn iyr:2017 pid:087665205 byr:1945 hcl:#7d3b0c
eyr:2025
eyr:2030 hgt:177cm hcl:#cfa07d iyr:2018 pid:734113761
byr:1965
hgt:163cm byr:1924 ecl:blu cid:125
eyr:2027 hcl:#fffffd pid:137238888
hgt:174cm hcl:#623a2f eyr:2023 ecl:gry pid:585758460
iyr:2011
cid:183
byr:1928 pid:471385060
hgt:192cm
ecl:oth iyr:2010 hcl:#623a2f eyr:2020
hgt:177cm
cid:273 ecl:oth eyr:2020
hcl:#efcc98
iyr:2012 pid:246299733
byr:1954
pid:052203766 cid:146 ecl:hzl byr:1974 hcl:#6b5442
eyr:2030 hgt:173cm
iyr:2011
hgt:167cm
byr:1972 iyr:2010
pid:783359411 ecl:hzl hcl:#9f8cc9 eyr:2028
iyr:2020 hcl:#18171d ecl:grn
byr:1992
hgt:189cm
eyr:2023 pid:736882272
cid:230 ecl:utc iyr:2022
pid:170cm
byr:2015 hcl:#c0946f
eyr:2031
cid:261
byr:1922 hgt:170cm ecl:brn eyr:2021
pid:593276915 hcl:#18171d
iyr:2017
hcl:#341e13 pid:038417039 hgt:61in eyr:2025 iyr:2017
cid:117
iyr:2017 eyr:2026 pid:441484223
hgt:155cm byr:1968 hcl:#ceb3a1 ecl:hzl
eyr:2021
hgt:64in
ecl:oth hcl:#b6652a byr:1954 pid:204959612 iyr:2016
hcl:z eyr:1969
pid:162cm ecl:#944b0f
iyr:2030 byr:2029
hgt:114 eyr:2034 byr:2026 hcl:84fa1a
pid:47909473
iyr:2028
ecl:utc
eyr:2025 ecl:blu hgt:157cm iyr:2014 hcl:#a97842 byr:1974 pid:702610675 cid:241
pid:732388109
hcl:#6b5442 cid:272 eyr:2026 hgt:193cm
ecl:amb byr:1982
eyr:2030 byr:1994
hgt:177in ecl:amb pid:1589147420 iyr:2011 hcl:#4bf920
cid:252
ecl:oth eyr:2022
byr:1948
pid:177cm cid:90 hgt:102 hcl:z iyr:2028
hgt:157cm pid:233347213
hcl:z
byr:2009 eyr:2027 cid:235 ecl:blu
iyr:1965
ecl:blu iyr:2030 eyr:2028 hcl:#18171d pid:322593908 byr:1954
cid:215 hgt:63in
hgt:72cm
cid:345 pid:911728732 eyr:2025
byr:2004 ecl:#0c4af7 hcl:3bb675
pid:171714794 byr:2019
hcl:#866857
cid:290 hgt:183in ecl:#d0c30f eyr:2032
iyr:2016 pid:905945155 hcl:#ceb3a1 byr:1958 hgt:159cm eyr:2028 cid:180 ecl:oth
hcl:efb614
eyr:2022 hgt:177cm pid:46962273
byr:1974
ecl:#089bdd iyr:1988
pid:662993164 iyr:2011 eyr:2025 ecl:hzl
byr:1942 hcl:#fffffd
hgt:175cm
hcl:#7d3b0c iyr:2016 hgt:175cm eyr:2022 pid:953132241
byr:1963 cid:261 ecl:grn
iyr:2013 hgt:180cm cid:318
ecl:amb
byr:1985 pid:439097817 eyr:2029 hcl:#602927
hgt:162cm ecl:blu
pid:675749832 cid:73
byr:1940 hcl:#888785
eyr:2026
pid:275352007 iyr:2012 eyr:2020
ecl:amb hcl:#623a2f hgt:175cm cid:317 byr:1988
hcl:z hgt:164in
iyr:2026 eyr:1961 ecl:#2df35e pid:#5c9ed5 cid:341
pid:848086119 ecl:oth eyr:2021 iyr:2011 hgt:180cm byr:1923 hcl:#93461b
eyr:2028
iyr:2014
byr:1978
hgt:184cm
pid:966277564 ecl:hzl
cid:176
hcl:#888785 ecl:amb cid:329 pid:835961958 byr:1927 eyr:2028 iyr:2016
pid:160cm eyr:2026 hcl:#08714b
ecl:hzl iyr:1961
hgt:156cm byr:1984
ecl:gry cid:302
byr:1965
iyr:2019 hcl:#ceb3a1 eyr:2027 pid:458192010 hgt:156cm
pid:058273969 byr:1942 eyr:2027
hcl:#c0946f iyr:2013 hgt:179cm
iyr:2019 hgt:193in pid:52144528 eyr:2036
cid:169 ecl:grt hcl:7e7039
hgt:192cm ecl:blu iyr:2015 pid:544936486 eyr:2024
byr:1972 hcl:#c0946f
eyr:2000
hcl:78de23 byr:2020
hgt:171in pid:160cm cid:68
iyr:1956 ecl:gmt
hcl:#733820 ecl:grn iyr:2018
byr:2001 pid:770957230
cid:103 ecl:grn iyr:2018
pid:068344094
eyr:2023 hgt:69in byr:1984 hcl:#6b5442
hgt:193cm eyr:2021 ecl:grn hcl:#602927 byr:1938 iyr:2011
iyr:1931
hcl:c0a318
pid:99195939
byr:2028 ecl:grt hgt:164 eyr:2017
eyr:1980
ecl:zzz
hgt:98 cid:161
pid:#96fe01 hcl:z
iyr:1974
byr:1936 hgt:176cm pid:56797167 iyr:2015
ecl:#07ad47
hcl:z
pid:48720181 hcl:270e76
byr:2022
hgt:180cm ecl:#dde399
eyr:2035 iyr:2023
eyr:2030 byr:2022 iyr:2018 hgt:162in ecl:gry
hcl:#63e2ec pid:615812600
ecl:grn
cid:56 hcl:#623a2f eyr:2020 hgt:167cm byr:1971 iyr:2012
pid:262692066
hgt:61 hcl:#efcc98 iyr:2011 eyr:2026
byr:1938
ecl:amb pid:385025739
pid:972423724 hcl:#602927 eyr:2027 ecl:oth iyr:2015
hgt:158cm byr:1956
pid:530035096
ecl:hzl
iyr:2017
eyr:2024 hcl:#888785 byr:1962 hgt:64in
byr:1935 eyr:2022 ecl:grn hcl:#7d3b0c pid:294714199
eyr:2029
iyr:2013
byr:1927 hgt:175cm pid:058261075 hcl:#cfa07d ecl:amb
ecl:blu pid:188764763 hgt:155cm byr:1921
iyr:2018 eyr:2029 hcl:#b6652a
byr:1975 hcl:930e76 iyr:2019
pid:169cm eyr:2009 hgt:191
ecl:#d28c56
hcl:z
pid:3190617557
hgt:160cm cid:80 ecl:oth iyr:2022 eyr:2008
byr:2016
hcl:#888785 byr:1999 ecl:blu cid:238 iyr:2018 hgt:160cm
eyr:2028 pid:174517111
eyr:2035
hcl:z byr:2020
pid:262135957 cid:324 iyr:2016 hgt:161cm ecl:grn
byr:1936
ecl:grn
iyr:2013 hcl:#623a2f eyr:2029 hgt:166cm
hcl:#cfa07d hgt:159cm eyr:2021
ecl:hzl
iyr:2014 pid:816039817 byr:1935
pid:596634790 hgt:161cm
eyr:2036 iyr:2016
hcl:#7d3b0c byr:2015 ecl:brn
byr:1952
hgt:157cm eyr:2024 cid:60 pid:876160626
ecl:blu iyr:2011 hcl:z
hgt:193cm iyr:2020 eyr:2026
pid:0136642346 ecl:hzl hcl:#efcc98 byr:1995
byr:1934 hgt:177cm
pid:445993865
ecl:brn iyr:2018
eyr:2030
hcl:#733820
eyr:2021 hgt:71in
pid:918630878
hcl:#602927 iyr:2017 byr:1943
ecl:gry
ecl:#81de2c iyr:2021 hgt:176cm eyr:1947 hcl:#888785 pid:1370052400
ecl:amb
byr:1922 iyr:2012 eyr:2022 pid:098866466 hcl:#18171d hgt:63in
eyr:2028 iyr:2010 hcl:184355
byr:1968 pid:337089458 ecl:brn hgt:181cm
hcl:#733820 pid:225958483 ecl:gry eyr:2030 hgt:62in iyr:2012 byr:1987
eyr:1955
hcl:03199c
pid:#3e832e
byr:2014 ecl:#453931 hgt:70cm
byr:1975
ecl:blu hcl:#7d3b0c
cid:169 pid:582470437 hgt:151cm
iyr:2019 eyr:2027
iyr:2017 byr:1971 pid:343492418 hgt:150cm hcl:#fffffd eyr:2024
byr:1997
eyr:2026
cid:257 hcl:#7d3b0c ecl:blu hgt:166cm iyr:2016 pid:117625518
iyr:2014 cid:248 hgt:165cm hcl:#18171d pid:294270262
byr:1925 ecl:amb
eyr:2028
hgt:167in ecl:dne pid:174cm iyr:2019 byr:2005 hcl:b29331 cid:86
hcl:#733820 pid:259969636 eyr:2023
ecl:hzl cid:317
hgt:185cm byr:2025
iyr:2012
hcl:#cfa07d hgt:152cm pid:807755992 iyr:2020
byr:1922 ecl:grn eyr:2025 cid:241
pid:997807107 byr:1958 ecl:dne iyr:2013 eyr:2023 hcl:#18171d
hgt:152cm
ecl:blu hgt:170cm
byr:1932
pid:775223495 eyr:2024 iyr:2015
iyr:2011
ecl:grn hcl:#ceb3a1 pid:190577415
hgt:63in
eyr:2021
byr:1986
ecl:oth eyr:2025 hgt:180cm
pid:258195402 iyr:2017
byr:1961
cid:109 hcl:#888785
hgt:178cm byr:1952 eyr:2023 hcl:#733820
pid:106939563 ecl:brn iyr:2012
hgt:188cm iyr:2012 hcl:#fffffd byr:1942
ecl:brn pid:804371742
byr:1978 cid:120
eyr:2026 pid:405714523 hgt:60in
hcl:#a97842 ecl:blu
iyr:2017
iyr:2015 byr:1958 ecl:grn
hcl:#b6652a pid:#9e8af3
eyr:2026 hgt:167cm
hgt:171cm hcl:#888785
cid:274
ecl:grn pid:919263460 eyr:2023 iyr:2020
pid:606726472 eyr:2022
byr:2008
ecl:zzz cid:72 hgt:173in
eyr:2032 byr:2004
hcl:z iyr:2011 ecl:hzl
pid:523494728
hgt:70cm
hgt:169cm pid:755822781 byr:1984 ecl:hzl hcl:#6b5442 iyr:2014
eyr:2020
byr:1942 cid:85
hgt:157cm pid:558287447 hcl:#efcc98
ecl:hzl
byr:1980 cid:225 pid:367501996 iyr:2016 ecl:grn hcl:#efcc98
hgt:175cm eyr:2029
pid:264780775 hgt:182cm ecl:grn
hcl:#18171d
eyr:2024
byr:1926 iyr:2013
byr:1969 iyr:2015
eyr:2026 ecl:blu
hcl:#fffffd
pid:005695878 cid:273
ecl:brn byr:2006 hgt:152cm
hcl:#888785
pid:171cm cid:249 iyr:2026
eyr:2022
byr:2011 iyr:2020 ecl:zzz hcl:z pid:412624100
eyr:2031
cid:111 hcl:df9bd0
iyr:2022 ecl:#32fdf9
byr:2017 eyr:2000
hgt:166in pid:0654651026
eyr:2021
ecl:gry pid:587324819 hgt:187cm byr:1951 hcl:#6b5442
iyr:2011
pid:180780096 hcl:#623a2f ecl:amb hgt:160cm byr:1991 eyr:2026
byr:2022 hgt:152cm eyr:2023 cid:70 ecl:grn
hcl:e0a24e
iyr:1959 pid:77110462
pid:251982311 byr:1994 ecl:gry hgt:165cm eyr:2021
hcl:#623a2f
iyr:2019
ecl:blu byr:1945
cid:241
pid:732768808 hcl:#efcc98
hgt:171cm eyr:2020 iyr:2012
cid:243 eyr:2001
hcl:01a022
hgt:162 pid:507703455
byr:2003 ecl:#c6a07b
iyr:1941
hcl:#733820 cid:150
ecl:hzl pid:843607639 hgt:190cm
byr:1958
eyr:2025
eyr:2030
pid:489370607 iyr:2014 ecl:oth hcl:#cfa07d byr:1995 hgt:193cm
hgt:68in
byr:1933
iyr:2010 ecl:brn
pid:380075958
hcl:#623a2f cid:279
eyr:2025
iyr:2019
byr:2001
hcl:#cfa07d ecl:brn pid:349877352
hgt:161cm eyr:2029
hgt:171cm
eyr:2040 ecl:dne hcl:#6b5442 iyr:2020 byr:1990
hcl:#fffffd
hgt:154cm
byr:1979 eyr:2020 iyr:2018
pid:118713281 cid:174
hcl:#7d3b0c eyr:2030 ecl:brn iyr:2017
cid:184 hgt:180cm pid:504181498 byr:1925
hgt:150cm
eyr:2020 byr:1999 hcl:#a97842 iyr:2011 ecl:grn pid:620166468
hcl:#602927
iyr:2015
byr:1928
pid:083747352
eyr:2027 hgt:193cm
ecl:hzl
byr:1938 ecl:gry
pid:511669464 eyr:1973 hgt:70cm
cid:262 iyr:2015 hcl:#c0946f
eyr:2029
byr:1923 hgt:160cm hcl:#7d3b0c iyr:2013 pid:525837692 ecl:gry
hcl:#602927 eyr:2025
pid:232338168 hgt:174cm cid:322 iyr:2010 ecl:oth
hgt:192in cid:126 hcl:#6b5442
pid:101406211 byr:1922 ecl:hzl eyr:2022 iyr:2013
eyr:2026 ecl:amb
byr:1921
cid:336
iyr:2020 hgt:182cm pid:533626984
pid:411943955 ecl:amb eyr:2025 hgt:166cm byr:1964 hcl:#341e13 cid:285
iyr:2010
ecl:grn byr:1933 eyr:2024
hgt:153cm
hcl:#5cfb31 iyr:2019 pid:773885967
ecl:hzl pid:426060511
hgt:159cm
byr:1922 hcl:#6ffd04 iyr:2017
byr:2025 pid:#097d1b iyr:2020 eyr:2029 hcl:73d113 hgt:69cm ecl:utc
ecl:amb hgt:170cm eyr:2025 byr:1930 iyr:2018 hcl:#733820
cid:262
iyr:2019
eyr:2021
cid:65 pid:258615618
ecl:oth byr:1987
hcl:#efcc98
hgt:178cm
hcl:z eyr:1980 ecl:#1c5fd1 hgt:65cm byr:2014
cid:222 pid:#c69fd5 iyr:2020
cid:271 pid:#4b8380 hcl:80fab0
byr:2024 ecl:#20e25f
iyr:1945
eyr:1935 hgt:159cm

View File

@@ -0,0 +1,191 @@
use std::{collections::HashMap, str::FromStr};
use anyhow::Result;
use regex::Regex;
#[derive(Debug,thiserror::Error)]
enum ParseError {
#[error("Expected {0}")]
Expected(String)
}
#[derive(Debug,PartialEq, Eq, Hash)]
enum EntryType {
Byr,
Iyr,
Eyr,
Hgt,
Hcl,
Ecl,
Pid,
Cid,
}
impl FromStr for EntryType {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"byr" => Ok(Self::Byr),
"iyr" => Ok(Self::Iyr),
"eyr" => Ok(Self::Eyr),
"hgt" => Ok(Self::Hgt),
"hcl" => Ok(Self::Hcl),
"ecl" => Ok(Self::Ecl),
"pid" => Ok(Self::Pid),
"cid" => Ok(Self::Cid),
_ => Err(ParseError::Expected(format!("byr, iyr, eyr, hgt, hcl, ecl, pid, cid, but got {}", s)))
}
}
}
impl EntryType {
pub fn is_valid(&self, value: &Option<&str>) -> bool {
match (*value, self) {
(Some(value), EntryType::Byr) => {
// four digits; at least 1920 and at most 2002.
match str::parse::<i64>(value) {
Ok(number) => {
(1920..=2002).contains(&number)
}
Err(_) => { false }
}
}
(Some(value), EntryType::Iyr) => {
// four digits; at least 2010 and at most 2020.
match str::parse::<i64>(value) {
Ok(number) => {
(2010..=2020).contains(&number)
}
Err(_) => { false }
}
}
(Some(value), EntryType::Eyr) => {
// four digits; at least 2020 and at most 2030.
match str::parse::<i64>(value) {
Ok(number) if (2020..=2030)
.contains(&number) => true,
_ => false
}
}
(Some(value), EntryType::Hgt) => {
// a number followed by either cm or in:
// if cm, the number must be at least 150 and at most 193.
// if in, the number must be at least 59 and at most 76.
let rex_cm = Regex::new(r"(\d*)cm").unwrap();
let rex_in = Regex::new(r"(\d*)in").unwrap();
if rex_cm.is_match(value) {
let m = rex_cm.captures(value);
// At least "None" fails the test
match str::parse::<i64>(m.unwrap().get(1).unwrap().as_str()) {
Ok(height) if (150..=193).contains(&height) => true,
_ => false
}
} else if rex_in.is_match(value) {
let m = rex_in.captures(value);
// At least "None" fails the test
match str::parse::<i64>(m.unwrap().get(1).unwrap().as_str()) {
Ok(height) if (59..=76).contains(&height) => true,
_ => false
}
} else {
false
}
}
(Some(value), EntryType::Hcl) => {
// a # followed by exactly six characters 0-9 or a-f.
//probably ok as long as we deal with ascii right ?
let rex = Regex::new(r"([a-z]|[0-9]){6}").unwrap();
value.starts_with('#') && rex.is_match(&(value.chars().skip(1).collect::<String>()))
}
(Some(value), EntryType::Ecl) => {
// exactly one of: amb blu brn gry grn hzl oth.
let valid_values = vec!["amb", "blu", "brn", "gry", "grn", "hzl", "oth"];
valid_values.contains(&value)
}
(Some(value), EntryType::Pid) => {
// a nine-digit number, including leading zeroes.
// probably ok if we deal only with ascii right ?
value.as_bytes().len() == 9 && str::parse::<i64>(value).is_ok()
}
(_, EntryType::Cid) => {
// ignored, missing or not
true
}
_ => false
}
}
}
#[derive(Debug)]
struct Passport<'a> {
fields: HashMap<EntryType, Option<&'a str>>
}
impl<'a> Passport<'a> {
fn new() -> Self {
let mut res = Self {
fields: HashMap::new()
};
res.fields.insert(EntryType::Byr, None);
res.fields.insert(EntryType::Iyr, None);
res.fields.insert(EntryType::Eyr, None);
res.fields.insert(EntryType::Hgt, None);
res.fields.insert(EntryType::Hcl, None);
res.fields.insert(EntryType::Ecl, None);
res.fields.insert(EntryType::Pid, None);
res.fields.insert(EntryType::Cid, None);
res
}
fn parse(&mut self, s: &'static str) {
for entry_s in s.split(&[' ', '\n'][..]) {
let mut tokens = entry_s.split(':');
if let Ok(etype) = EntryType::from_str(tokens.next().unwrap()) {
self.fields.insert(etype, tokens.next());
}
}
}
fn is_valid_legacy(&self, mandatory_cid: bool) -> bool {
self.fields.iter().all(|(key, value)| {
(!mandatory_cid && *key == EntryType::Cid) ||
*value != None
})
}
fn is_valid(&self) -> bool {
self.fields.iter().all(|(key, value)| {
key.is_valid(value)
})
}
}
fn main() {
let data = include_str!("../data/input.txt");
// eprintln!("data = {}", data);
//eprintln!("data.split() = {:?}", data.split("\n\n").collect::<Vec<&str>>());
let passports: Vec<Passport> = data.split("\n\n").map(|pass_str| {
let mut res = Passport::new();
res.parse(pass_str);
res
}).collect();
// eprintln!("passports = {:#?}", passports);
// eprintln!("passports.size() = {:#?}", passports.len());
let nb_valid = passports.iter().filter(|p| (*p).is_valid_legacy(false)).count();
eprintln!("nb_valid = {:#?}", nb_valid);
let nb_valid_secondpass = passports.iter().filter(|p| p.is_valid()).count();
eprintln!("nb_valid_secondpass = {:#?}", nb_valid_secondpass);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validation() {
let mut pass = Passport::new();
pass.parse("cid:271 pid:009457684 hcl:#80fab0\nbyr:1999 ecl:blu\niyr:2015\neyr:2029 hgt:159cm");
eprintln!("pass = {:#?}", pass);
assert_eq!(pass.is_valid(), true)
}
}

1
5-binary_boarding/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

70
5-binary_boarding/Cargo.lock generated Normal file
View File

@@ -0,0 +1,70 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "anyhow"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68803225a7b13e47191bab76f2687382b60d259e8cf37f6e1893658b84bb9479"
[[package]]
name = "binary_boarding"
version = "0.1.0"
dependencies = [
"anyhow",
"thiserror",
]
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a571a711dddd09019ccc628e1b17fe87c59b09d513c06c026877aa708334f37a"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "thiserror"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"

View File

@@ -0,0 +1,11 @@
[package]
name = "binary_boarding"
version = "0.1.0"
authors = ["Guilhem MARION <gmarion@netc.fr>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.36"
thiserror = "1.0.22"

View File

@@ -0,0 +1,932 @@
FFBBFFFLRL
FFBBFBBRRL
FBBBFFBLRL
BBFBFFBLRR
BFBBBFFLLL
BFBBBBBLLR
FBFBFBFLLR
BFBFBBFLLR
FBBFBFBLLL
BBBFBFBRLL
BFBBBFBLRL
FBBFFFBLLR
BFFBFBFLRL
FBBBBFBRLR
FFBBBBBRRL
FBBFBFFLRL
FBBBBBBLLR
FBBFBBBRRL
FBBFFBFRLL
FBFBBBBRRR
BFFBFBFRRL
BFBFBBBLLR
FFFFBFBLRL
FBFFBFFLRL
FFBFBBBRRR
FFBFFFFLRR
FBBBFFFLLR
FFFFFBFLLL
BFFFFFFLRL
FBBBBBFRLR
BBBFFBBRRR
FFFFBBBRLL
FBFFBBBRLR
BFBBBFFRRL
BBFBBFBLRL
BFBFBFFRRR
BBFBFFFLLL
FBFBFBFRRR
BFBFBFFRRL
BBFBBFBRRL
FFBBFBFLRL
FBFFFFFRLR
FBBFFFBLLL
FBBBBFFRLL
FFBBBBBLLL
BFFBBFFRLR
FFFBBFBRRR
FBBBFFFRLL
FFFBFBFLRL
BFFBBFFLRL
BFBBBBBLRL
BFFFFFBRRR
FFFBBFBLRL
FBBBFBFRLL
FBBFBFBLRR
BBFBBFFLRR
FBFFBBFLLL
FFFFFBBRLL
FFBBFFBRLR
BBFFFFFLLL
BFFFFBFLRR
FBFBBFFRRL
BFBFFBBLLR
FBBBFBBRLR
BBBFBFFRLL
BBFFBBFRLR
FFBFFBBRLR
FFBBBFBRLR
BBBFFFBLRR
BBFBFBFLRR
BFBBBBBRLR
BFFFFFBLLR
FBFFBFFRLL
BBBFFBBRLR
FFBBBFBRRR
BFBBBFBRLR
FBFFFBBLRL
FFFBFFFRLL
BBFFBFFLLL
BFFBBFFRRR
FFBFBFBRRL
FFBBBFBRRL
FBBFFBBRLR
FBFFBBFRLR
BFBFFBBRRR
BBFBFBBRLR
FFBFFFFRRL
BBFFBFFLLR
FBBFBFBRRR
BFBFBBBRRL
FBFBFFBRRL
FFFBBFFRLL
BFBFFFFRRR
FBBFFBFLLR
FFBFBFFRLL
FBFFBFBLLL
FBFBFFFLRL
BBFFFFFRRR
FBFFBBFLRR
FBFFFBFLRL
FBBBFBBRRL
BFFBFFFRLR
FFBBBBFLLR
BFFFFBFLRL
BFFBFFBRRR
FFBFBFBLRL
BBFFFBBRLL
FFBFBBFRRR
FFFBFBFRRL
FBFFBFBRRR
FBBBBFBRRL
FBFFFFFLLR
FFBFFFFLLR
FBBBBFFRLR
BBBFFBBLRR
BBBFFBFLRR
FBBFBBBLRR
FBBFBBFRRL
FFFBFFBLLL
FBFFFFBLLL
BBFFFFBLLL
FBFFFBFLRR
FFBFBFFLRR
BBFBFFFRLL
FFFBBBFRLR
FFBFFBBRLL
BBBFBFFRRL
BFFBBBBLRR
BFFFFFFLLL
BBBFFFBLLL
FBBBBBFRLL
FBBFBBBLLR
BBFBFFFRRR
BBFFFBBLLL
FBBFFBFLRL
BBFBFFFLRR
BFBFFBFRLL
BFFFBFBLLR
BBBFBFBLLL
BBBFFBFRLR
FBFFBFBRLR
BFBBFFFLLL
BBFFFFBLRR
BBFFFBBRRL
BBBFBFFLLL
BFBFFBFLLL
FBBBBFFLLR
FFBFFFFRLR
FFBBBFBRLL
BFFFFFFRRL
BFBFFBBLRL
BBFBBBFRLL
BFFFBFFLLR
BBFBFFBRLL
BFBBFFFRLL
BBFBBFBRLR
FFFBBFBRLR
BFFFBBFLRL
FFBFFBFRLL
FFFBFFBLRL
BFBBBFFRLR
BBBFFBBLRL
BFFBBBBRRL
FFBBFFFRLL
BFBFFBFLRL
BFFBBBBRRR
BBFBFBFRRL
BBBFFBFRRL
BFFFBFBLRL
FFFBFBFRLR
FBFFBBBLRR
FFFFBBBLLL
BBBFBBFLLR
BFFBFBFRRR
BFBFFFBRRR
BBFBBBBLLR
FFBBBBBLRL
FFBFFBFLRR
FFBBBFBLRR
BBFBBFBRRR
FFFFFFBRRR
BFBFBFBRRL
BBFFBBBLRR
BBFBFFFRLR
FBBFBFBLLR
BFBBFFBRLL
FFFFBFBLLR
BFBFFBBRLR
FBFFFBFRRR
BFFBFFFRLL
FBBBFFFRRR
FFFBBBFLLL
FBBBBBBRRL
FBBFFBBLLR
BBBFBFFLRR
BFBBFBFLRR
FFFBBBBRRR
BFFFBBFRLR
FBFFBBFLLR
FBFFFFFRRL
BBBFBBFLLL
BBBFFFFRLR
FFFFBBBRRR
FBBBFBBLLL
BFFBFFBLLL
FBFBBFBRLR
FFBFFBBLLR
FFFFBFFLRR
FBBFFBFLLL
FBFBBFBRRR
BBBFBFBLLR
BBFFBFBLLL
FFBFFBFRLR
FBBBFBBLRR
BBFBBFBLLL
FFBFFBFRRR
FBBBBFFLRL
BFBBFBFLLR
FBFBBBFRLR
BFBBFFBLLR
FFFBBBFLLR
FFFBBBFRRL
BFFFBFBRLR
BBBFBBFLRR
BBFBBFFLLR
BBFBBBBRLR
FBBFFFFLRR
FBFBBFFRLL
FFBFFFFRRR
FFFBBFFRRL
FFFBBFBRRL
FFFBFBFLLR
FFBBBBFRRR
BFFFFBBRRL
BFFFFBFRRR
BFBBBFBLRR
FFBBFFFRRL
FBBBBBBRRR
BBFBFFBLLR
FBFFFFBRLL
BFBBFBFLLL
FBFFFBBRLL
FBBBFFBLLR
BBFBBBFRLR
FBFBBFBLRR
FFFFFBFLLR
FBFBBBFLRL
FFBFFFBRRR
FFFBBFFLRL
BBBFFFFLLR
BFBFFFFRRL
FBFBFBBLLR
FBBBFBFRRL
BBFBBBBRRL
BFBBFBFLRL
BFFBBFFLLR
BFBFFBBRLL
FBFFBFFRLR
FBFBFBFLRR
BFBFBBFRRR
FBBBBFBLRL
FFBBBFFRRR
FFBBFFBRLL
FFBBBBBRLL
FBFFFBFRRL
FFFBBBFLRL
BBBFBFFRRR
FFFBFFFRRR
FBFFBFFLLL
FFBBFFBRRL
BFFBFFBRRL
FFBBBFFRLR
BBBFFFFRRR
BBFBFBBRRR
FBFBBBBLRR
BFBFBFBLLL
FFBBFFBLLR
BFFFBBBRLR
BFBBFBBRLR
BFFFFBBLLR
FBFBFBBRLR
BFFBBBFLLR
FBFFBFBLRL
BFBFBBBRLL
BFBBBFFLRL
FFFBFFFLRR
BFFBBFBRLL
FFBBBBFRLL
BBFFFBBLLR
FBFBFBFRLR
BBBFFFBRLR
BFFFFFBRLR
BBBFFFFLLL
FFFBBFBRLL
BFFFFFBRRL
FBFFBBBRRL
FBFBFBBLLL
FBFBBFBRRL
FBBFBBBRRR
BFBFFBBRRL
FBBBBFBLLL
FBBBBBBRLR
BBFFFBFRRL
FFFFBFBLLL
FFFFBBFLRR
FFFFBFFLRL
BFFFBBFRLL
BBFFFFBRRR
BFBFFFFRLL
BFFFFBFLLR
BBBFFBBRRL
BBFBBFBLLR
BFFFFBFRLR
FBBBFBFLLR
FFFFFBBLRR
BFBFFFFLRR
FBFBBFFLRL
FBFFFBBRRR
BBFBBBFLRL
BFBBBFFLLR
BFBFBBFRRL
FBFFFFBLRL
FBBFBFFRLR
BFBFBBBLRR
BFBFBBFLRL
BBFFBFFRLL
FBFFBBBLRL
BFBFBFFLLR
FFFBFFBLLR
FFFBFBBRRR
BBFBFFFLLR
FBBBFBFRLR
FBFFBBBLLL
FFBFBBFLRR
FBFBFFFLLL
BBFFFFFLRL
FBFBBFBLRL
BBFFFBFLLR
BBFBBBBRRR
BFBBBFFRRR
FFFBFFBRLL
FBBBFFFRLR
BBBFBFBLRL
FBFFFFBRLR
BFFFFFBLLL
FBFFFFBLLR
BFBBFFBLRR
BFBFBBBRRR
BBBFBFBRRR
FFFBBFFRRR
FBBBFFFLRR
BBFBFFFRRL
BFBFBBFRLR
BFFFBFBRLL
FBFFFFFLLL
FFFBBBBLRL
FFFBBFFLLL
FBFFFFBRRR
FFBFBFBRLR
BFBFFFBLRR
BFFFBFBLLL
FBBFBFFRLL
FBFBFFFRLL
FBBBFFBRRR
FBBBFFBRLL
FFBBFBBLLL
FBBBBFBRRR
BFBBBFBLLR
FBBBBBFLLR
FFBBFBFLRR
BFFBBFBLLR
FBFFFFBLRR
BFFBFFFRRR
BFFFBBBRLL
FBFBBBFRLL
BFBBBFBRRL
FFBFFFBRRL
FBBFFFFRLR
BFBFBFFLLL
FFBFBFBLLL
FBFBBFBRLL
FBFBFFBRLR
BFFFFFBLRR
FBBBFFBRLR
BFBBFBBLLL
BBFFBFBRRR
FFFBFBBRRL
FFBBBFFRLL
BFFFFFFRLL
BFBFFFBRLL
FFFFFBFRLL
BBBFFFBRRL
FFBBBBFRRL
BFFFBBBLRL
FFFFFBBLLR
BFFFFBBLRR
BFBFFFBLLL
FFFFFBBRLR
BBFBFBFLLL
FBFBBBBRLR
FBBFBFBRRL
FFBFBFBRRR
FBBBBBFLRL
BBFBFFBLLL
BBFFFFBRLL
BBBFBFBRLR
BBFBFBBLLL
BFBBBBBLRR
BBFFFBFRRR
FFFBFBFRLL
BFFBBFBLLL
FBFFBBBRRR
FFFBFBFLLL
BBFFBBFLRL
BBFFFFBRLR
BFBFBBBRLR
BBBFBFFLLR
FFBBBBFRLR
BBFFBFFRRL
BBFBFFBRRR
BFBFFBFLLR
FBFFBBFRLL
BBFFFFBLLR
FBFBFFFRLR
FFBFBFBLLR
BFBBFFBRRL
FBBFFBBRRL
BBFFBFBRLR
FFFFBFBLRR
FFFFBBBLRR
FFBFBFFLLL
FFBBBFFRRL
BBFFFBFRLL
FBFBBBFLRR
FBBFBFFRRR
FBBFBFFLLR
BFFBBBFLRR
FBBFBBFRLR
BFFBBBFLLL
BBFBBFBRLL
BBBFFBBLLR
BBBFBFBRRL
FBFBBBFRRL
FBBFFFBRLR
BFBBFBBLRL
FFBBFFFRRR
BFBFFFFRLR
BBFFFFFLLR
BBFBFFBRLR
BBFBFBFLRL
FBFFFFFLRL
FFBBBFFLRL
FBFBFBBLRR
FFBFBBBRLL
FFBFBFFRLR
FBBBFBFLRR
FBFFBFFLRR
BBFFBFBRRL
FBBFFFFLRL
FFFFBBFLRL
FFBBFFBLRR
BFBFFFBLLR
BFBFBBFLRR
BFBFBFBLLR
BFBBFBFRLL
BFBBFFBRLR
FBFFFBBLLL
FFFBBBBRRL
FBBFBFFLLL
FBFFBFBRLL
BFFBFFFRRL
FBFBFFBLLR
BBFFBBFLLL
FFBBBFBLLR
BFBBFFFLLR
FBBBFBFRRR
FBBBFFBRRL
FFFFBBFRRR
FFBFFFFLRL
FBBFBBFLRR
FFBBBFBLLL
FBFFFBFRLR
FFBFFBBRRL
FFFFBBFRRL
BBBFFFFLRL
FBBFFFBLRL
FFBFBFBLRR
FFFFBFFRRR
FFFBFBFRRR
BBFBBBBLLL
FFBBFFBRRR
FBBFFBBLRR
FBBFBBFLLL
BBFBBBFRRL
FFFBBBBLLR
FFBFFBBLRR
BBFBBFFRLL
BFBBBBFRLL
BBFBFFBRRL
BFFFBBFRRL
FBBBBBBLLL
FFBBFFBLLL
FFBBFBBLRR
BFBFBFBLRR
FBBBFBBLLR
BBFBFBFRLL
FBBFBFFLRR
FBBBFBFLLL
FFBBFFFLRR
BFFBBBFRLL
FBBBBFBLLR
BFBFFFFLRL
FFBFBBBLLL
FFBFFFBLRR
BFBFBFBRLL
FBFBFBFRLL
BFBBBBBLLL
FFBFBFBRLL
BFBFFFFLLR
BFFBBBBLLL
FFBBFBBRLL
FFFFBFBRLR
FBFBBFFLLR
BFBFBBFRLL
FFBFFFFLLL
FBBFFBFLRR
FFBFFFBRLL
FFFFBBBLLR
BFBBBBBRLL
FBBFBBBLRL
FBFFBBBRLL
FBFFFBBLLR
FFBBBFBLRL
FFFFBFFRLL
BBFFFBBLRL
BFFFBFFRRL
BFFBFBFLLL
BBFFFBFLLL
FFFFFBFLRL
FBBFFFFRRR
FBBBBBFLRR
FFBFFFBRLR
FBBBFFFLLL
FFBFBBBLRL
FFBFFFBLLL
FBFFBBBLLR
BBBFBFFRLR
FFFBFFFRLR
BBFBBBFLLR
FFBBFFFRLR
FFFFFBFRLR
FBBFFFBRRL
BFFBBBBRLR
BFFBFFBRLL
BFBBBFBRLL
FBFFBBFRRR
FBFBBFFLLL
BBFBFBBLRL
BBBFBBFLRL
FBFBFFBLRR
FBFFFFFRLL
BFBBFBFRRR
BFBFBBBLLL
FFBBBFFLRR
BFBBFBBLLR
FBBBBFFRRR
BFFFBFFLRL
FFFFBFBRLL
BFFFFBBLLL
BFFBFBBLLL
BFFBFBBRRL
BBBFFFBLRL
BBBFFFBRRR
BFFFBBFLRR
FFBBFBFRLL
BFFBBFBRLR
FFBFFBFLLR
FBFBBBBLRL
BFFBBFFRRL
BBFFFBBRRR
FBBBFBBRRR
BFFFFBFRRL
FFBFBBBRRL
BFFFBBBRRR
BFBBBFBRRR
BFBFBFFRLR
FFFFFBBRRR
FBFBFBFLRL
FFBBBBBLRR
BBFFFFBLRL
FFFBFFFLLR
FFFBFFFRRL
FBBBFBBLRL
BBFFBBFLLR
BBFFBFFLRR
BFFFFFFRLR
FBBFBBFRLL
BFBBBBFRRR
FBFBBBBLLR
FFFBBFFRLR
FBBFBBBRLR
FBBFBFBRLR
FBBBFFFLRL
FFBBFBBRLR
BFFFBBBLLL
BBFBBFFRRR
FBFBFFFLRR
BBFFBBFRRR
FBBFBFFRRL
BFFFFBFLLL
BBBFFBBLLL
BFBBBBFRRL
FBBFFFBRRR
BFBBBBFLLL
FFFBFFBRRL
BFFBFFBLLR
FFBBFBFRRL
FBFFFBBRLR
BFFFBBBLRR
FFBFBFFRRR
FBFBFFBRLL
BFBBBBFLRL
BFBBFFFRRR
FBFBFBFRRL
BBFBBFFLRL
FBBFFFFLLL
BBBFFBBRLL
FBFFFBBRRL
FFBFBFFLRL
FBFFBBFLRL
BFFBFBFLRR
BFFFFBBLRL
BBFBBBBLRL
FFBFBBFRLL
FBFFFBFLLL
BFFBFFBLRL
FBBFFFBLRR
FFFFBFFRRL
FBBFFBFRLR
BFFFBFFRRR
FFFFBFBRRL
BBFFBFBLRL
FBBFBFBRLL
BFBBFFFLRL
FFFBBBFRRR
BFFFFFFLLR
FBFBBFFRRR
BFFFFFBRLL
FFFFBBBRRL
BFFBFBFLLR
FFFFBFFRLR
BFFBBBFRRL
BFBBFBBRLL
FFFFFBFRRL
FFBBBBFLRL
FFBBFBFLLR
BBFFBBBRLL
BFFBFFFLLR
BBFBBBBRLL
BFFBFBBRLR
FFBFBFFRRL
FBBFBBFLRL
FFBFFBBLRL
BFBFFFBRLR
BFFBFFFLRR
BFFBBBBLRL
FFFBFBBRLR
FBBBBBFRRR
BFBFBFFLRL
BFBFFFBLRL
FBBBFBBRLL
FBFBFBFLLL
FBBFFBFRRR
FFFBFBBLRR
FFFBFFFLRL
BFBFBFBRRR
BFFBBFFLLL
BFFBFBBRRR
FFBFFBFRRL
FBFFFBFRLL
FFBFBBFLLL
FFBBFFBLRL
FBFBBBBRRL
BFFBBFBRRL
FBFBFBBLRL
BBFBFBFRLR
FBFFFFFLRR
BBBFFBFRLL
BFBFBFFRLL
FBBFFBBLRL
FBFBFBBRRL
FFBBBBBRLR
FBBFBBFLLR
FFFBFBBRLL
BBFFFFBRRL
BFBFBFBLRL
FBFBBFBLLR
BBBFBFBLRR
FFFFBBFRLL
FFBBBBBRRR
BFBBFFBRRR
BFFFBBBLLR
FBBBBBBRLL
FFBFBBFRLR
BBFFBBFRLL
BFFBFFFLRL
FFBBFFFLLL
BFFBFBBLRL
BBBFFFFRLL
BBFBBBFRRR
FBFFBFFRRR
FBBFFFFRLL
BFFFBBBRRL
FBFBBBFLLL
FFFFBBFLLR
FBBFBBFRRR
BBFFBBBRLR
BBFBBFBLRR
BFFFBFFLLL
BBFBFBFRRR
FFBFFFBLRL
BBFFFBBRLR
FBFBFBBRRR
BFBBFFBLRL
BFFFFBFRLL
BBFBFBBRLL
BFFFFBBRLL
FFFFBFFLLR
FFBBBBFLRR
FBFBFFFRRR
FFFBBFBLLR
FFBBFBFRRR
BFBBFBBRRR
FFBFBBBLLR
FFBFFBFLLL
FFFFBBBLRL
FFBFBFFLLR
BFBBBFFLRR
FBBFFFFLLR
FBFFFFBRRL
BFFBBFFLRR
FFBBFBBRRR
FFFFBFBRRR
BFBBBBFLLR
FBBFFBBRRR
BBFBFBBLRR
FFFBBBBLRR
FBFFFBBLRR
BFFBFBFRLR
BFBFFBFRLR
BFBBFFFRLR
FFBBFFFLLR
FFFFFBFLRR
BFFBBFBLRR
FFFFBBFRLR
BFFFBBFLLR
FBFBFFBRRR
BBFBFBBRRL
FBFBBFFLRR
BFBFFBFLRR
BBFFFBBLRR
FBFFBBFRRL
FBBBBBBLRL
FBBFFBBLLL
BFBFBBBLRL
BBBFFFBLLR
BFFFBFFLRR
BBFFBBFRRL
BFBFBBFLLL
FFBBBFFLLR
BFBBFBFRRL
FBFFBFFRRL
BFFFBFBLRR
BFBBFBBRRL
BBFBFFBLRL
BFFBBBFRRR
FBFBBFBLLL
BBFFBFFRRR
BBFFBFBRLL
BBBFFBFLLR
FFFBBFBLLL
FBBBFFFRRL
BFFBFFBLRR
BBFBFBBLLR
FFBBFBFRLR
BBFFFFFRLR
FBFFBFBLRR
BFFFFFFRRR
FFBBFBFLLL
BFBBFBBLRR
BBFFFBFRLR
BBBFFBFRRR
FFFFBBFLLL
BBFFBFBLRR
BFFBFBBRLL
FBFFFBFLLR
BFFFBBFRRR
FFBFBBFRRL
BFBFFBBLRR
FBBFFBFRRL
FFBBBBBLLR
BFBFFBBLLL
BFBBBBFLRR
FFFFBBBRLR
BFFBBBBLLR
BFFFFFFLRR
BFFFFBBRLR
FFFBBBBRLL
BFBBFFFLRR
BFFBBBFRLR
BFFBBFFRLL
FBFBBBBLLL
BFBFBFBRLR
BBFBBFFLLL
BBFBBBBLRR
FFBBFBBLLR
FBBFFFBRLL
FBBBBFFRRL
FFFBBFBLRR
FFFBFBBLLR
FFFFFBBRRL
FBFBBBFRRR
BBFFFBFLRL
FBFBFFBLLL
FBFBFFFRRL
BFBFFFBRRL
BBFFBFFRLR
BBFFBFBLLR
FFFBFBFLRR
BBFBBBFLLL
BFBBBFFRLL
BFFFBFBRRL
FFFFBFFLLL
FBBBBBFRRL
FBFBFFBLRL
FBBBBBBLRR
FFFBBBBRLR
BFFBFBBLLR
BBFFBBFLRR
BFFFFFBLRL
FFBBBBFLLL
BFFBFBBLRR
FFFBBBFLRR
FFBFBBFLRL
FBBFBFBLRL
BBBFFFFRRL
BBFBFBFLLR
BFBBBFBLLL
FFBFBBBLRR
BFFBFFBRLR
FFFBBBBLLL
BFFFBFFRLR
BFFFBBFLLL
FBBBBFBLRR
FBBFBBBRLL
BFBFFBFRRL
BFFFFBBRRR
BBFFBBBLRL
FBBBBFBRLL
BFBBFFFRRL
BBBFFBFLLL
BFBFFBFRRR
FFBFFBBRRR
FFBFBBBRLR
FBBBBFFLRR
BFBFBFFLRR
BFBBBBFRLR
FFFFFBFRRR
BFFBBFBRRR
BFBBBBBRRL
BFFBBFBLRL
FFFBFBBLRL
FFFBFBBLLL
FFBBFBBLRL
BBBFFFFLRR
FFFFFBBLRL
FBFFBFBLLR
FBFBBBBRLL
BFFBFBFRLL
BFFFBFFRLL
BFFFBFBRRR
BBBFBFFLRL
BFFBFFFLLL
BBFFFFFRRL
FBFBFFFLLR
FFBFFBBLLL
BBFFBFFLRL
BBFFBBBLLL
FFFFFBBLLL
BFBBFFBLLL
FFFBFFBRLR
FBBFFBBRLL
FBFBFBBRLL
BFFBBBFLRL
FFFBFFBLRR
FBFBBFFRLR
FFFBBFFLLR
FBFBBBFLLR
FBBFFFFRRL
BBFBBBFLRR
BFBBFBFRLR
FFBFFFBLLR
FFBFFBFLRL
BBFFBBBRRR
BBFFFFFLRR
FBFFBFBRRL
FBFFBFFLLR
FBBBFFBLLL
FBBBFFBLRR
BFBBBBBRRR
BBBFFFBRLL
FBFFFFFRRR
BBFBBFFRLR
BBFFBBBLLR
BBBFFBFLRL
BBFFFBFLRR
FFFBFFFLLL
FFBFBBFLLR
BBFFFFFRLL
BBFBBFFRRL
FBBFBBBLLL
FFFBFFBRRR
FBBBBFFLLL
FFFBBFFLRR
BBFFBBBRRL
FFBBBFFLLL
FBBBFBFLRL
BBFBFFFLRL
FFBFFFFRLL
FFFBBBFRLL
FBBBBBFLLL
BFBFFFFLLL

View File

@@ -0,0 +1,82 @@
use std::convert::TryFrom;
use std::str::FromStr;
use anyhow::Result;
struct Plane {
cols: usize,
rows: usize,
}
const my_plane: Plane = Plane { cols: 8, rows: 128};
#[derive(Debug, thiserror::Error, PartialEq)]
enum ParseError {
#[error("Expected {0}")]
Expected(&'static str),
}
#[derive(Debug, PartialEq)]
struct Seat {
col: usize,
row: usize,
}
impl FromStr for Seat {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.len() != 10 { return Err(ParseError::Expected("10-char string")) }
// split_at not supposed to fail as we are only working with ASCII chars here
let s_bit = s
.replace("F", "0")
.replace("B", "1")
.replace("R","1")
.replace("L", "0")
.chars()
.collect::<String>();
let (rowcode, colcode) = s_bit.split_at(7);
Ok(Self {
row: usize::from_str_radix(&rowcode, 2).unwrap(),
col: usize::from_str_radix(&colcode, 2).unwrap(),
})
}
}
impl Seat {
fn seat_id(&self) -> usize {
8 * self.row + self.col
}
}
fn main() {
let input = include_str!("../data/input.txt");
let mut seat_ids: Vec<usize> = input.lines().map(|l| Seat::from_str(l).unwrap().seat_id()).collect();
seat_ids.sort();
println!("Max seat id: {:?}", seat_ids.iter().max());
let banana = seat_ids
.windows(2)
.flat_map(<&[usize;2]>::try_from) // Because windows() makes no promise on slice size
.find(|[a, b]| *b == *a + 2);
eprintln!("banana = {:#?}", banana);
}
#[cfg(test)]
mod tests {
use super::*;
const AOC_INPUT: &str = "FBFBBFFRLR";
#[test]
fn test_build_seat() {
assert_eq!(
Seat::from_str(AOC_INPUT),
Ok(Seat { row: 44, col: 5 })
);
}
#[test]
fn test_seat_id() {
assert_eq!(
Seat::from_str(AOC_INPUT).unwrap().seat_id(),
357
);
}
}

1
6-custom_customs/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

23
6-custom_customs/Cargo.lock generated Normal file
View File

@@ -0,0 +1,23 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "custom_customs"
version = "0.1.0"
dependencies = [
"itertools",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "itertools"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
dependencies = [
"either",
]

View File

@@ -0,0 +1,10 @@
[package]
name = "custom_customs"
version = "0.1.0"
authors = ["Guilhem MARION <gmarion@netc.fr>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
itertools = "0.9.0"

File diff suppressed because it is too large Load Diff

1
6-custom_customs/element Normal file
View File

@@ -0,0 +1 @@
E: You must give at least one search pattern

1
6-custom_customs/riot Normal file
View File

@@ -0,0 +1 @@
E: You must give at least one search pattern

View File

@@ -0,0 +1,81 @@
use std::{collections::HashSet, todo};
use itertools::Itertools;
fn count_scores(input: &str) -> Vec<usize> {
input
.split("\n\n")
.map(|l| l.chars()
.unique()
.filter(|&c| c != '\n')
.count())
.collect()
}
fn count_scores_v2(input: &str) -> Vec<usize> {
input
.split("\n\n")
.map(|group| {
group
.lines()
.map(|l| l.chars().collect::<HashSet<char>>())
.fold1(|acc: HashSet<char>, hset| {
acc.intersection(&hset).cloned().collect()
})
.unwrap()
.len()
})
.collect()
}
fn main() {
let input = include_str!("../data/input.txt");
let scores = count_scores(input);
println!("Sum of scores : {}", scores.iter().sum::<usize>());
println!("Sum of scores v2 : {}", count_scores_v2(input).iter().sum::<usize>())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_count_scores() {
let input = r#"abc
a
b
c
ab
ac
a
a
a
a
b"#;
assert_eq!(count_scores(input).iter().sum::<usize>(), 11)
}
#[test]
fn test_count_scores_v2() {
let input = r#"abc
a
b
c
ab
ac
a
a
a
a
b"#;
assert_eq!(count_scores_v2(input).iter().sum::<usize>(), 6);
}
}

1
7-handy_haversacs/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

75
7-handy_haversacs/Cargo.lock generated Normal file
View File

@@ -0,0 +1,75 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "handy_haversacs"
version = "0.1.0"
dependencies = [
"multimap",
"peg",
]
[[package]]
name = "multimap"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333"
dependencies = [
"serde",
]
[[package]]
name = "peg"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f76678828272f177ac33b7e2ac2e3e73cc6c1cd1e3e387928aa69562fa51367"
dependencies = [
"peg-macros",
"peg-runtime",
]
[[package]]
name = "peg-macros"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "636d60acf97633e48d266d7415a9355d4389cea327a193f87df395d88cd2b14d"
dependencies = [
"peg-runtime",
"proc-macro2",
"quote",
]
[[package]]
name = "peg-runtime"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555b1514d2d99d78150d3c799d4c357a3e2c2a8062cd108e93a06d9057629c5"
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"

View File

@@ -0,0 +1,11 @@
[package]
name = "handy_haversacs"
version = "0.1.0"
authors = ["Guilhem MARION <gmarion@netc.fr>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
multimap = "0.8.2"
peg = "0.6.3"

View File

@@ -0,0 +1,594 @@
plaid fuchsia bags contain 5 light violet bags, 1 light yellow bag.
striped aqua bags contain 2 striped teal bags.
clear coral bags contain 2 plaid green bags, 5 mirrored gold bags.
dull tan bags contain 4 faded blue bags, 3 faded olive bags, 5 dull salmon bags.
plaid green bags contain 3 faded green bags.
light tomato bags contain 1 drab chartreuse bag, 1 dotted tomato bag, 3 striped red bags, 2 vibrant violet bags.
dim tomato bags contain 4 striped gold bags, 5 bright lavender bags, 1 pale beige bag, 4 pale tan bags.
vibrant green bags contain 4 faded teal bags.
shiny crimson bags contain 2 dull green bags.
vibrant black bags contain 5 dark beige bags, 3 dark bronze bags.
light tan bags contain 1 striped tomato bag.
vibrant teal bags contain 1 shiny silver bag.
pale chartreuse bags contain 2 dotted plum bags.
plaid coral bags contain 2 pale green bags, 2 faded tomato bags, 2 dark salmon bags, 1 vibrant magenta bag.
dull gray bags contain 1 dark tan bag, 3 dotted tan bags.
muted gray bags contain 5 bright indigo bags, 5 dotted purple bags.
vibrant red bags contain 4 bright tomato bags, 4 shiny orange bags.
faded tan bags contain 1 dull crimson bag, 5 faded red bags.
pale magenta bags contain 3 posh chartreuse bags, 4 vibrant purple bags.
shiny gray bags contain 2 wavy purple bags.
light crimson bags contain 5 clear teal bags.
striped turquoise bags contain 3 pale tomato bags, 2 posh teal bags.
striped purple bags contain 4 dark silver bags, 4 vibrant gray bags, 2 dim bronze bags, 2 clear aqua bags.
muted magenta bags contain 4 striped tomato bags.
light teal bags contain 2 faded brown bags, 2 posh purple bags, 1 faded olive bag.
clear cyan bags contain 1 clear coral bag, 5 clear aqua bags.
dull cyan bags contain 5 wavy crimson bags, 1 pale orange bag.
shiny tan bags contain 2 bright red bags, 4 plaid cyan bags.
light brown bags contain 3 dim yellow bags, 4 dull orange bags, 1 vibrant yellow bag.
pale tan bags contain 2 striped orange bags, 5 dull plum bags.
wavy salmon bags contain 2 dark blue bags, 5 dim plum bags.
mirrored cyan bags contain 2 plaid turquoise bags, 5 dull plum bags, 3 muted indigo bags, 2 plaid white bags.
dark aqua bags contain 3 bright red bags, 2 wavy purple bags, 2 plaid tan bags.
wavy purple bags contain 5 wavy brown bags.
clear magenta bags contain 4 muted green bags, 3 dull cyan bags, 4 striped teal bags, 2 faded blue bags.
bright red bags contain 5 vibrant tomato bags, 2 dull orange bags.
pale purple bags contain 3 plaid turquoise bags, 4 light tan bags, 1 faded black bag, 5 light yellow bags.
bright orange bags contain 1 mirrored orange bag, 2 faded bronze bags, 1 wavy turquoise bag, 1 bright yellow bag.
faded lavender bags contain 1 plaid brown bag.
dark salmon bags contain 3 dotted crimson bags, 1 posh bronze bag.
mirrored coral bags contain 3 dark red bags, 1 dull fuchsia bag, 2 drab magenta bags, 4 dull indigo bags.
clear black bags contain 5 mirrored salmon bags, 3 drab gold bags, 3 muted fuchsia bags.
faded fuchsia bags contain 1 shiny silver bag, 2 posh orange bags, 5 plaid bronze bags.
dotted red bags contain 4 faded yellow bags, 5 dull brown bags, 3 clear red bags.
light purple bags contain 2 plaid magenta bags, 3 vibrant coral bags, 2 wavy black bags.
faded beige bags contain no other bags.
dull fuchsia bags contain 3 dim lavender bags, 1 dull aqua bag, 2 pale fuchsia bags.
wavy olive bags contain 5 dotted cyan bags, 1 dull lime bag.
dim teal bags contain 1 dull green bag.
dull orange bags contain 5 striped tomato bags, 5 drab blue bags, 5 faded blue bags, 2 pale brown bags.
muted brown bags contain 3 dotted orange bags, 1 bright tan bag.
vibrant coral bags contain 2 wavy turquoise bags.
clear aqua bags contain 5 posh bronze bags, 5 dim orange bags, 5 posh chartreuse bags.
dull plum bags contain 4 drab tan bags.
wavy tomato bags contain 4 wavy cyan bags, 1 bright silver bag, 3 dotted gray bags, 1 dark tomato bag.
shiny fuchsia bags contain 1 dotted silver bag, 5 dull lime bags, 3 drab teal bags.
pale fuchsia bags contain 3 pale beige bags.
plaid plum bags contain 4 dotted plum bags, 1 mirrored brown bag, 3 dim yellow bags, 2 vibrant bronze bags.
posh green bags contain 5 plaid indigo bags, 1 wavy red bag, 5 dim indigo bags, 4 wavy indigo bags.
muted aqua bags contain 3 bright tan bags, 3 dull yellow bags, 1 faded blue bag.
mirrored white bags contain 5 dark coral bags, 1 plaid red bag, 4 dull violet bags, 5 clear gray bags.
dotted aqua bags contain 4 drab aqua bags, 3 faded tomato bags.
bright indigo bags contain 4 faded tan bags, 3 clear turquoise bags, 1 plaid indigo bag, 4 bright gray bags.
posh silver bags contain 5 striped red bags, 3 faded blue bags, 3 dim plum bags, 3 vibrant beige bags.
bright olive bags contain 3 dull silver bags, 5 drab tomato bags.
muted beige bags contain 1 drab crimson bag.
shiny beige bags contain 3 clear blue bags.
wavy brown bags contain 2 striped coral bags, 2 light purple bags.
wavy black bags contain 4 faded beige bags, 2 striped red bags, 2 pale brown bags, 3 dull yellow bags.
faded salmon bags contain 1 light indigo bag, 5 plaid cyan bags, 2 pale salmon bags.
dark gold bags contain 1 mirrored plum bag, 2 dark tomato bags, 5 dull green bags, 2 light lime bags.
mirrored lavender bags contain 5 muted brown bags, 1 shiny blue bag, 5 dull blue bags, 3 wavy indigo bags.
wavy beige bags contain 3 mirrored purple bags, 3 posh yellow bags, 4 plaid green bags.
striped fuchsia bags contain 5 drab bronze bags, 4 posh tomato bags, 1 drab maroon bag, 1 dim beige bag.
faded blue bags contain 1 striped tomato bag, 3 dark olive bags, 2 drab tan bags.
drab gray bags contain 1 posh teal bag.
dim cyan bags contain 4 dark fuchsia bags, 3 wavy maroon bags, 5 posh silver bags, 4 posh chartreuse bags.
dotted purple bags contain 3 wavy white bags.
shiny brown bags contain 5 light silver bags, 4 light turquoise bags, 4 posh bronze bags.
vibrant tomato bags contain 3 dotted cyan bags, 3 posh teal bags, 1 clear magenta bag, 5 dull lime bags.
dark bronze bags contain 2 vibrant maroon bags, 2 mirrored olive bags.
wavy silver bags contain 4 striped magenta bags, 3 dim fuchsia bags.
striped yellow bags contain 5 faded black bags, 5 light beige bags, 1 vibrant beige bag, 2 mirrored beige bags.
faded chartreuse bags contain 4 clear gray bags, 5 dotted gray bags.
faded tomato bags contain 5 faded gray bags, 4 faded fuchsia bags, 3 drab teal bags.
dull gold bags contain 1 dark plum bag, 4 striped black bags.
muted turquoise bags contain 1 mirrored bronze bag, 5 shiny aqua bags, 1 clear plum bag.
dotted lime bags contain 1 dark black bag, 5 pale brown bags.
vibrant violet bags contain 5 faded lime bags, 1 pale fuchsia bag, 5 dull plum bags.
faded black bags contain 2 striped teal bags, 5 faded beige bags, 4 wavy black bags, 1 striped lavender bag.
drab teal bags contain 1 clear gold bag, 4 muted crimson bags, 1 light teal bag.
dull purple bags contain 1 posh crimson bag, 2 clear blue bags.
dotted teal bags contain 2 dark tan bags.
dark red bags contain 3 dotted cyan bags, 3 posh red bags, 2 bright red bags, 3 faded magenta bags.
light black bags contain 5 dull yellow bags.
light salmon bags contain 3 faded beige bags.
dull brown bags contain 1 light indigo bag, 4 mirrored yellow bags, 5 faded silver bags.
dark black bags contain 5 dull yellow bags, 3 dull lime bags, 5 posh aqua bags.
faded crimson bags contain 3 light fuchsia bags, 5 muted chartreuse bags.
drab yellow bags contain 5 drab indigo bags, 2 shiny brown bags, 4 muted lime bags.
muted tomato bags contain 3 posh salmon bags, 2 plaid indigo bags, 5 striped aqua bags.
pale teal bags contain 2 muted red bags, 5 mirrored brown bags, 4 mirrored tan bags.
posh violet bags contain 4 posh tomato bags.
dim plum bags contain 1 faded magenta bag, 5 drab silver bags, 1 pale brown bag.
light fuchsia bags contain 2 dotted silver bags, 3 dotted lavender bags, 3 shiny gold bags, 5 clear magenta bags.
vibrant orange bags contain 5 shiny blue bags, 5 dull maroon bags.
shiny white bags contain 5 mirrored yellow bags, 2 pale fuchsia bags, 4 shiny turquoise bags.
drab green bags contain 1 mirrored lavender bag, 3 posh tan bags.
faded silver bags contain 5 vibrant coral bags, 3 striped lavender bags, 4 dotted cyan bags, 5 plaid turquoise bags.
faded gold bags contain 4 faded magenta bags.
dark coral bags contain 3 light maroon bags, 1 drab silver bag.
striped olive bags contain 4 dotted maroon bags, 3 wavy brown bags, 1 wavy crimson bag, 5 shiny silver bags.
wavy lavender bags contain 3 mirrored yellow bags, 5 shiny crimson bags, 4 dark indigo bags.
bright fuchsia bags contain 2 vibrant green bags, 5 drab blue bags.
dotted turquoise bags contain 3 striped red bags.
drab black bags contain 1 faded tan bag.
pale silver bags contain 1 faded yellow bag, 1 drab tan bag, 5 muted salmon bags, 3 shiny white bags.
striped magenta bags contain 4 dark turquoise bags, 4 shiny blue bags, 3 shiny crimson bags.
dotted beige bags contain 2 mirrored black bags, 2 faded brown bags, 1 bright red bag, 2 clear coral bags.
clear maroon bags contain 5 bright bronze bags.
shiny olive bags contain 2 dull blue bags.
pale violet bags contain 1 light purple bag, 1 pale tomato bag, 4 plaid aqua bags, 4 light magenta bags.
dotted white bags contain 3 bright purple bags, 4 dull orange bags, 2 plaid salmon bags.
plaid blue bags contain 5 faded blue bags, 4 muted green bags, 4 bright bronze bags.
mirrored lime bags contain 1 faded green bag, 4 striped black bags, 1 mirrored purple bag.
wavy violet bags contain 1 muted bronze bag.
light silver bags contain 2 dull cyan bags, 1 drab tan bag.
dark tomato bags contain 1 vibrant tomato bag, 1 striped tomato bag.
wavy teal bags contain 5 wavy red bags, 2 drab brown bags, 1 posh olive bag.
dim green bags contain 2 striped teal bags, 1 drab blue bag.
wavy crimson bags contain no other bags.
mirrored aqua bags contain 3 posh tan bags, 5 muted teal bags, 3 light violet bags.
light cyan bags contain 4 vibrant chartreuse bags, 1 faded lime bag, 2 drab purple bags, 2 shiny white bags.
shiny gold bags contain 4 drab blue bags, 4 posh purple bags, 2 drab silver bags, 4 wavy turquoise bags.
plaid chartreuse bags contain 5 mirrored olive bags, 2 vibrant orange bags, 2 shiny purple bags.
dim yellow bags contain 1 faded green bag, 4 wavy fuchsia bags.
pale turquoise bags contain 1 drab turquoise bag.
clear red bags contain 1 pale bronze bag, 4 drab tan bags.
shiny teal bags contain 3 bright aqua bags.
dotted tomato bags contain 3 dotted orange bags, 5 light silver bags, 2 dull green bags, 5 wavy chartreuse bags.
striped tan bags contain 1 light turquoise bag, 2 dotted salmon bags, 4 shiny orange bags, 2 clear red bags.
dim bronze bags contain 1 wavy gold bag.
posh crimson bags contain 4 posh aqua bags.
plaid salmon bags contain 2 dull tan bags.
mirrored salmon bags contain 2 muted aqua bags, 5 muted salmon bags.
striped blue bags contain 3 wavy white bags, 4 drab blue bags, 1 drab chartreuse bag, 4 dull orange bags.
pale red bags contain 1 striped red bag.
muted black bags contain 4 faded gold bags.
clear orange bags contain 2 faded red bags.
mirrored maroon bags contain 2 plaid tan bags.
dull aqua bags contain 4 pale gold bags.
posh coral bags contain 3 striped gold bags.
posh purple bags contain 4 pale orange bags, 5 dull salmon bags, 2 striped teal bags.
muted tan bags contain 3 clear coral bags, 4 pale salmon bags.
mirrored orange bags contain 5 pale bronze bags.
striped teal bags contain no other bags.
dark blue bags contain no other bags.
clear bronze bags contain 4 vibrant gray bags.
light magenta bags contain 4 dim green bags.
drab coral bags contain 5 dotted chartreuse bags, 4 vibrant crimson bags, 2 muted green bags.
drab brown bags contain 2 dull tomato bags, 5 vibrant bronze bags.
bright coral bags contain 1 posh plum bag, 1 wavy gold bag, 2 drab lavender bags, 2 muted lavender bags.
dim white bags contain 4 shiny aqua bags.
plaid bronze bags contain 4 drab tan bags, 3 plaid salmon bags, 4 striped coral bags.
faded teal bags contain 1 vibrant white bag, 5 wavy purple bags.
drab turquoise bags contain 3 pale tomato bags, 1 bright indigo bag.
muted white bags contain 3 striped brown bags, 1 light blue bag.
clear crimson bags contain 1 dark magenta bag.
shiny magenta bags contain 4 wavy tomato bags, 4 shiny bronze bags, 4 vibrant coral bags, 5 bright lime bags.
bright magenta bags contain 3 wavy brown bags.
bright tomato bags contain 4 vibrant fuchsia bags, 1 clear aqua bag.
wavy coral bags contain 4 striped gold bags, 1 light purple bag, 4 vibrant purple bags.
muted indigo bags contain 2 posh purple bags, 2 light gold bags, 3 striped lavender bags.
clear violet bags contain 2 wavy cyan bags, 5 pale brown bags, 4 faded magenta bags, 2 bright purple bags.
dull white bags contain 4 wavy olive bags, 3 mirrored olive bags, 3 faded magenta bags, 4 dull green bags.
dull magenta bags contain 4 dim beige bags.
dotted blue bags contain 4 posh beige bags, 1 pale purple bag, 4 shiny red bags.
dotted lavender bags contain 3 posh purple bags.
light white bags contain 4 striped lavender bags.
dark turquoise bags contain 5 light teal bags.
faded turquoise bags contain 5 striped violet bags, 4 dull crimson bags, 2 dim purple bags, 1 light silver bag.
striped chartreuse bags contain 3 pale white bags, 3 dim fuchsia bags.
pale gold bags contain 2 clear teal bags, 3 wavy turquoise bags, 5 light gold bags.
posh blue bags contain 4 muted yellow bags, 1 dull crimson bag, 3 wavy violet bags, 5 mirrored fuchsia bags.
dotted gray bags contain 3 wavy fuchsia bags.
plaid magenta bags contain 3 plaid black bags.
pale beige bags contain 1 pale white bag, 2 dim salmon bags, 5 mirrored gold bags.
striped bronze bags contain 2 dull yellow bags, 2 dark blue bags.
dark lime bags contain 2 pale magenta bags, 4 clear cyan bags.
bright turquoise bags contain 2 light white bags, 3 plaid salmon bags, 2 clear aqua bags, 5 dull silver bags.
posh salmon bags contain 1 drab turquoise bag.
muted bronze bags contain 1 pale bronze bag, 3 clear maroon bags.
faded coral bags contain 1 clear gray bag, 5 plaid gray bags, 3 bright silver bags, 4 posh yellow bags.
mirrored gray bags contain 1 dark coral bag, 2 plaid blue bags, 4 mirrored coral bags, 1 mirrored olive bag.
vibrant olive bags contain 5 pale chartreuse bags, 4 plaid green bags, 4 dark coral bags.
dotted magenta bags contain 4 light chartreuse bags, 3 plaid indigo bags, 2 dull tan bags.
light violet bags contain 2 muted green bags.
dim fuchsia bags contain 5 dim tan bags, 5 faded black bags, 1 drab white bag.
dotted black bags contain 3 bright gold bags, 2 faded gold bags.
striped indigo bags contain 3 posh aqua bags.
posh cyan bags contain 5 dull fuchsia bags.
vibrant turquoise bags contain 2 muted chartreuse bags, 2 clear magenta bags, 5 drab chartreuse bags.
mirrored magenta bags contain 1 dull lime bag.
mirrored violet bags contain 2 posh magenta bags, 1 plaid white bag, 4 wavy turquoise bags, 5 dull salmon bags.
pale tomato bags contain 4 wavy maroon bags, 3 clear aqua bags, 2 striped lavender bags.
clear fuchsia bags contain 5 dark cyan bags, 1 plaid cyan bag.
drab orange bags contain 3 mirrored purple bags, 1 striped orange bag.
bright blue bags contain 1 bright cyan bag, 4 plaid green bags.
muted chartreuse bags contain 4 faded beige bags, 3 faded green bags.
plaid teal bags contain 2 mirrored orange bags, 5 plaid plum bags.
light blue bags contain 4 faded silver bags, 3 light turquoise bags, 2 dim aqua bags, 5 posh silver bags.
bright tan bags contain 4 striped coral bags, 1 dark fuchsia bag.
shiny black bags contain 1 light green bag.
plaid violet bags contain 1 faded magenta bag, 1 shiny bronze bag, 2 vibrant tomato bags.
posh bronze bags contain 4 shiny gold bags, 1 bright yellow bag, 1 dull cyan bag.
light red bags contain 3 dotted black bags, 5 pale coral bags.
striped red bags contain no other bags.
clear tan bags contain 2 faded brown bags, 1 bright brown bag, 2 bright gold bags.
dull turquoise bags contain 5 mirrored yellow bags, 3 wavy red bags, 5 faded purple bags, 4 clear green bags.
plaid yellow bags contain 4 dark red bags, 3 dull tomato bags, 5 faded violet bags.
dotted gold bags contain 2 dotted lime bags, 2 faded gray bags, 3 clear coral bags.
dull bronze bags contain 2 pale red bags, 3 dim indigo bags.
shiny green bags contain 2 pale red bags, 1 mirrored silver bag, 4 bright lime bags, 5 pale indigo bags.
bright black bags contain 2 striped plum bags, 1 clear black bag, 4 clear olive bags.
bright gold bags contain 3 wavy cyan bags, 1 dotted magenta bag, 1 muted salmon bag, 4 light maroon bags.
muted violet bags contain 5 wavy cyan bags, 4 dim tan bags, 1 posh gray bag, 5 vibrant brown bags.
dim turquoise bags contain 1 pale tomato bag, 2 dotted silver bags, 5 mirrored coral bags.
drab lime bags contain 5 shiny gold bags.
wavy bronze bags contain 1 shiny red bag, 4 dotted cyan bags.
vibrant purple bags contain 4 drab chartreuse bags, 4 dotted yellow bags.
plaid purple bags contain 2 drab beige bags, 3 pale aqua bags, 3 muted magenta bags.
faded brown bags contain 3 faded beige bags, 1 light chartreuse bag, 4 mirrored gold bags.
pale lavender bags contain 1 mirrored tomato bag, 5 wavy maroon bags, 4 wavy lime bags.
posh fuchsia bags contain 5 posh orange bags.
drab fuchsia bags contain 1 dim plum bag, 1 dark coral bag, 3 dark red bags.
striped crimson bags contain 5 pale orange bags, 5 faded beige bags, 5 faded brown bags.
wavy lime bags contain 5 dull crimson bags.
vibrant fuchsia bags contain 2 wavy white bags.
vibrant plum bags contain 4 dim salmon bags, 2 plaid tan bags, 3 dull blue bags.
muted cyan bags contain 3 striped beige bags.
clear teal bags contain 2 wavy aqua bags, 3 dotted plum bags.
dark maroon bags contain 1 light violet bag, 3 clear plum bags, 5 dotted fuchsia bags, 2 vibrant tomato bags.
dull black bags contain 5 muted olive bags.
light yellow bags contain 1 dull white bag, 5 dark aqua bags, 3 light purple bags, 4 dim green bags.
pale bronze bags contain 1 wavy aqua bag.
plaid red bags contain 5 pale plum bags, 2 muted brown bags, 2 dull bronze bags.
dim gray bags contain 2 muted lavender bags.
plaid gray bags contain 5 muted aqua bags.
vibrant blue bags contain 4 light tomato bags, 1 plaid beige bag.
clear blue bags contain 5 clear plum bags, 5 drab chartreuse bags.
dotted green bags contain 5 plaid white bags, 5 vibrant turquoise bags, 1 drab silver bag.
dull crimson bags contain 3 mirrored yellow bags, 3 posh red bags, 3 faded brown bags.
striped maroon bags contain 1 shiny magenta bag, 2 light brown bags, 4 dull green bags.
dark yellow bags contain 4 faded silver bags, 5 shiny lavender bags, 4 dim crimson bags, 2 plaid bronze bags.
pale indigo bags contain 4 plaid salmon bags, 3 striped purple bags, 5 pale magenta bags, 1 dotted lime bag.
faded maroon bags contain 5 light silver bags, 5 dim bronze bags, 4 faded tan bags, 5 striped crimson bags.
pale green bags contain 4 vibrant white bags.
muted maroon bags contain 2 light black bags, 2 mirrored fuchsia bags.
pale yellow bags contain 2 dull bronze bags, 4 bright maroon bags, 5 wavy cyan bags, 4 dotted lavender bags.
posh white bags contain 3 mirrored turquoise bags, 3 shiny aqua bags, 2 striped blue bags, 4 faded coral bags.
wavy orange bags contain 4 wavy crimson bags, 2 bright brown bags, 3 bright magenta bags, 1 dotted gold bag.
dark beige bags contain 3 muted white bags.
dotted salmon bags contain 5 dim bronze bags, 5 striped orange bags.
dotted fuchsia bags contain 1 striped red bag, 4 bright purple bags.
pale cyan bags contain 1 dull blue bag.
mirrored purple bags contain 5 light turquoise bags, 2 faded silver bags.
drab violet bags contain 1 vibrant turquoise bag, 2 muted chartreuse bags, 5 pale bronze bags.
wavy gray bags contain 1 dark purple bag, 4 muted green bags.
wavy magenta bags contain 5 dark white bags, 4 vibrant black bags, 4 muted coral bags.
pale plum bags contain 5 mirrored brown bags, 2 pale red bags.
light plum bags contain 4 dark tomato bags, 4 wavy gold bags.
pale aqua bags contain 1 striped red bag, 2 dim crimson bags, 3 mirrored orange bags.
muted green bags contain 1 mirrored yellow bag.
bright purple bags contain 5 light violet bags, 5 clear magenta bags, 1 faded lime bag.
dark green bags contain 2 shiny aqua bags.
dark orange bags contain 3 striped coral bags.
dotted chartreuse bags contain 1 bright lime bag, 1 light olive bag, 4 muted red bags, 1 posh chartreuse bag.
shiny chartreuse bags contain 1 bright salmon bag, 1 plaid indigo bag.
clear gold bags contain 5 dull lime bags, 4 shiny brown bags, 1 dull plum bag, 4 dull salmon bags.
shiny salmon bags contain 2 muted salmon bags, 2 dotted lavender bags.
striped cyan bags contain 3 drab tan bags, 5 dotted cyan bags, 1 posh aqua bag, 1 plaid magenta bag.
dark plum bags contain 1 clear orange bag, 2 striped black bags.
vibrant magenta bags contain 1 plaid tan bag, 3 muted bronze bags, 3 bright chartreuse bags.
clear beige bags contain 4 muted tan bags, 1 clear turquoise bag, 4 mirrored turquoise bags, 2 bright silver bags.
drab lavender bags contain 1 dotted cyan bag, 4 clear plum bags.
shiny coral bags contain 2 drab beige bags.
light bronze bags contain 2 mirrored plum bags, 2 light black bags.
vibrant yellow bags contain 4 vibrant coral bags, 5 mirrored olive bags, 1 light lime bag, 2 muted crimson bags.
vibrant salmon bags contain 4 faded beige bags, 2 faded olive bags, 1 pale brown bag.
dim tan bags contain 3 faded beige bags, 4 light tan bags.
vibrant silver bags contain 1 dark tomato bag.
striped salmon bags contain 5 faded brown bags.
shiny purple bags contain 1 pale lavender bag, 3 plaid black bags, 1 drab indigo bag.
light turquoise bags contain 4 dark silver bags.
dark chartreuse bags contain 5 dark silver bags.
mirrored indigo bags contain 5 mirrored gold bags, 1 dotted white bag.
faded olive bags contain 1 pale brown bag, 3 faded beige bags, 2 light chartreuse bags.
mirrored black bags contain 5 posh purple bags.
clear green bags contain 2 dark magenta bags, 5 faded gold bags, 4 striped teal bags, 4 dark purple bags.
bright beige bags contain 3 light olive bags, 3 wavy orange bags, 4 dotted lavender bags.
plaid brown bags contain 4 dull lavender bags, 3 drab gold bags.
vibrant chartreuse bags contain 1 bright bronze bag, 5 wavy crimson bags.
posh aqua bags contain 5 muted green bags, 2 dim green bags, 1 dim crimson bag, 1 posh red bag.
vibrant gold bags contain 5 wavy chartreuse bags, 3 drab gold bags, 2 striped blue bags, 3 posh yellow bags.
posh tan bags contain 1 shiny chartreuse bag, 2 drab bronze bags.
bright violet bags contain 1 pale lavender bag, 5 mirrored olive bags, 1 posh turquoise bag.
faded lime bags contain 5 pale brown bags, 4 faded black bags, 1 faded beige bag.
vibrant gray bags contain 3 vibrant chartreuse bags, 3 bright purple bags.
dull silver bags contain 5 pale tomato bags, 5 shiny turquoise bags, 2 mirrored yellow bags.
pale maroon bags contain 3 posh red bags, 1 plaid bronze bag, 5 striped red bags.
dull lavender bags contain 4 vibrant violet bags, 1 bright yellow bag, 3 bright aqua bags.
light aqua bags contain 5 vibrant turquoise bags.
striped violet bags contain 4 drab silver bags, 3 posh magenta bags, 3 wavy turquoise bags.
bright green bags contain 3 drab teal bags.
light coral bags contain 5 dotted violet bags, 4 pale chartreuse bags.
muted salmon bags contain 4 vibrant turquoise bags, 5 clear chartreuse bags, 1 dark fuchsia bag, 5 bright bronze bags.
wavy cyan bags contain 4 dim orange bags, 1 dull orange bag, 4 plaid indigo bags, 4 dim salmon bags.
shiny red bags contain 1 dim blue bag, 4 clear plum bags.
vibrant beige bags contain 3 posh red bags.
shiny maroon bags contain 3 striped tomato bags, 2 faded lime bags.
shiny aqua bags contain 3 bright yellow bags.
bright aqua bags contain 5 wavy lavender bags, 4 striped coral bags, 5 dotted cyan bags, 3 drab cyan bags.
dim olive bags contain 2 posh blue bags, 5 vibrant violet bags, 3 drab brown bags, 1 dull purple bag.
shiny silver bags contain 5 dim green bags, 4 dull cyan bags.
dim brown bags contain 1 wavy brown bag, 3 drab black bags.
dotted brown bags contain 3 drab crimson bags, 1 shiny red bag.
striped coral bags contain 4 striped red bags, 1 dotted cyan bag.
dotted plum bags contain 3 faded lime bags, 2 striped lavender bags, 2 wavy crimson bags, 2 faded brown bags.
light gold bags contain 1 light silver bag, 3 posh teal bags, 3 dark orange bags, 4 bright bronze bags.
dark tan bags contain 5 drab black bags, 2 plaid cyan bags, 3 faded yellow bags, 1 dim blue bag.
posh olive bags contain 4 drab olive bags, 5 dull tan bags, 1 wavy chartreuse bag, 5 muted magenta bags.
dull red bags contain 1 vibrant teal bag, 4 dim salmon bags, 1 bright violet bag, 1 dark lavender bag.
plaid turquoise bags contain 3 faded green bags, 5 wavy crimson bags.
plaid cyan bags contain 2 dull yellow bags, 2 dotted cyan bags, 1 light chartreuse bag, 2 faded green bags.
dull indigo bags contain 2 faded silver bags.
pale brown bags contain no other bags.
striped plum bags contain 5 dull lime bags, 2 muted white bags, 3 striped teal bags.
dotted coral bags contain 4 faded silver bags, 2 wavy aqua bags, 2 light chartreuse bags, 5 posh indigo bags.
mirrored beige bags contain 1 plaid black bag, 2 plaid tan bags, 2 pale bronze bags.
vibrant cyan bags contain 4 wavy beige bags, 1 shiny orange bag.
wavy fuchsia bags contain 5 pale maroon bags, 3 drab violet bags, 2 shiny orange bags.
drab silver bags contain 2 dark blue bags, 3 light chartreuse bags, 3 mirrored gold bags.
wavy turquoise bags contain 5 posh red bags, 4 striped teal bags.
bright cyan bags contain 4 bright silver bags, 1 muted gray bag, 5 faded aqua bags, 3 wavy aqua bags.
wavy green bags contain 4 clear violet bags, 4 dark olive bags, 2 clear magenta bags, 1 mirrored black bag.
mirrored gold bags contain 2 dark olive bags.
wavy gold bags contain 4 plaid indigo bags.
dotted yellow bags contain 3 dull orange bags, 2 faded green bags.
light beige bags contain 4 dull cyan bags.
bright crimson bags contain 1 faded tan bag, 1 faded chartreuse bag, 5 vibrant brown bags.
dotted bronze bags contain 5 striped white bags.
mirrored yellow bags contain 3 wavy crimson bags, 4 dark olive bags, 5 drab tan bags.
plaid lavender bags contain 1 light tomato bag, 5 dull blue bags, 2 wavy indigo bags, 3 bright gray bags.
drab purple bags contain 3 dotted plum bags, 5 drab olive bags, 1 drab tan bag, 3 dark black bags.
shiny lime bags contain 2 plaid bronze bags, 1 shiny gold bag.
drab chartreuse bags contain 2 bright bronze bags, 4 light teal bags, 1 mirrored yellow bag.
bright plum bags contain 3 drab turquoise bags.
light orange bags contain 1 shiny lavender bag, 2 dark fuchsia bags, 1 muted olive bag, 4 wavy olive bags.
striped beige bags contain 4 dull crimson bags, 5 dotted fuchsia bags.
wavy chartreuse bags contain 2 bright salmon bags, 5 faded green bags, 1 mirrored black bag.
striped tomato bags contain no other bags.
plaid aqua bags contain 1 light magenta bag, 3 pale white bags, 3 clear blue bags, 4 dull crimson bags.
plaid tan bags contain 3 dull green bags, 1 light silver bag, 5 dim orange bags, 1 dark blue bag.
dotted cyan bags contain 2 wavy black bags, 3 striped teal bags.
dull green bags contain 1 plaid magenta bag, 3 dull plum bags, 4 dim green bags.
faded purple bags contain 5 mirrored cyan bags, 1 dull beige bag, 4 vibrant purple bags.
dotted maroon bags contain 1 vibrant beige bag, 3 plaid magenta bags.
faded aqua bags contain 4 plaid gold bags, 1 plaid yellow bag, 2 bright lime bags.
pale lime bags contain 1 light blue bag.
dark indigo bags contain 1 light gold bag.
shiny orange bags contain 2 plaid black bags, 2 faded brown bags, 4 plaid indigo bags.
muted olive bags contain 1 wavy chartreuse bag.
muted purple bags contain 4 dotted silver bags.
plaid black bags contain 3 drab silver bags.
striped lavender bags contain 5 wavy crimson bags.
posh chartreuse bags contain 5 drab chartreuse bags.
clear purple bags contain 3 faded green bags, 2 bright gold bags.
dark crimson bags contain 4 plaid teal bags, 4 muted cyan bags.
clear silver bags contain 3 pale beige bags, 2 mirrored tomato bags.
dotted indigo bags contain 2 dark plum bags, 2 clear magenta bags, 3 light olive bags.
dull chartreuse bags contain 2 light turquoise bags, 3 drab brown bags.
bright brown bags contain 4 light purple bags, 1 vibrant coral bag.
dim salmon bags contain 2 dull salmon bags.
muted lime bags contain 4 muted violet bags, 5 shiny white bags.
vibrant lime bags contain 2 mirrored bronze bags, 1 dotted crimson bag, 5 dim yellow bags, 2 mirrored gold bags.
muted silver bags contain 1 striped orange bag, 3 drab purple bags.
mirrored bronze bags contain 4 dull bronze bags.
light olive bags contain 4 mirrored olive bags, 2 dim lime bags, 1 clear magenta bag.
vibrant tan bags contain 2 shiny teal bags.
posh red bags contain 2 bright bronze bags, 5 striped teal bags, 5 faded beige bags, 4 faded olive bags.
faded red bags contain 4 striped lavender bags, 4 posh red bags.
mirrored brown bags contain 3 dim salmon bags, 4 drab chartreuse bags, 1 wavy tomato bag.
dark gray bags contain 1 muted tan bag, 4 faded blue bags, 2 dim chartreuse bags.
dark white bags contain 4 vibrant lime bags, 4 pale olive bags.
striped silver bags contain 4 dim cyan bags.
clear salmon bags contain 5 pale magenta bags, 1 mirrored salmon bag.
pale white bags contain 5 wavy crimson bags, 4 plaid indigo bags, 5 striped crimson bags, 3 drab violet bags.
vibrant indigo bags contain 1 mirrored gold bag, 1 striped turquoise bag, 3 posh beige bags.
drab aqua bags contain 5 faded crimson bags, 3 wavy gold bags, 3 striped tomato bags.
clear brown bags contain 5 bright lavender bags.
posh indigo bags contain 5 mirrored red bags, 5 clear coral bags.
posh black bags contain 4 dim fuchsia bags, 5 muted olive bags, 3 mirrored red bags.
shiny lavender bags contain 2 muted aqua bags, 3 striped black bags, 3 wavy salmon bags, 3 mirrored purple bags.
vibrant bronze bags contain 1 bright tan bag, 5 faded beige bags, 5 pale red bags, 1 plaid cyan bag.
clear chartreuse bags contain 2 shiny gold bags, 1 wavy turquoise bag, 2 muted crimson bags.
drab tan bags contain no other bags.
posh gold bags contain 5 dotted beige bags, 1 striped crimson bag, 5 drab purple bags, 1 bright gray bag.
clear olive bags contain 3 dark tomato bags.
dim aqua bags contain 4 wavy black bags, 5 clear chartreuse bags, 5 clear aqua bags.
pale coral bags contain 2 shiny orange bags, 5 dark black bags, 3 vibrant coral bags.
drab blue bags contain 5 dull salmon bags.
vibrant white bags contain 2 mirrored yellow bags.
faded indigo bags contain 5 clear aqua bags.
posh turquoise bags contain 1 light purple bag, 4 mirrored salmon bags.
dotted orange bags contain 5 dark blue bags, 1 shiny lavender bag, 2 dim plum bags, 3 clear violet bags.
muted crimson bags contain 4 wavy crimson bags, 1 light magenta bag, 3 clear plum bags.
dim coral bags contain 1 vibrant red bag, 2 vibrant magenta bags.
mirrored plum bags contain 5 light olive bags.
dull violet bags contain 2 dim aqua bags.
faded violet bags contain 5 clear violet bags, 5 muted indigo bags, 3 clear red bags, 1 posh tan bag.
vibrant crimson bags contain 1 shiny crimson bag.
muted plum bags contain 3 drab beige bags, 4 posh maroon bags.
dim orange bags contain 5 bright salmon bags.
dim blue bags contain 1 mirrored black bag, 3 faded blue bags.
mirrored tan bags contain 5 plaid plum bags.
pale crimson bags contain 4 dim green bags, 2 pale fuchsia bags.
bright white bags contain 2 drab gold bags, 2 shiny maroon bags, 5 mirrored lime bags.
dim indigo bags contain 1 mirrored cyan bag, 1 wavy purple bag, 1 drab brown bag.
dotted violet bags contain 4 bright teal bags, 2 vibrant plum bags.
wavy indigo bags contain 2 drab silver bags, 1 muted chartreuse bag, 1 drab aqua bag, 3 mirrored teal bags.
dark cyan bags contain 1 muted magenta bag, 3 vibrant violet bags, 4 mirrored aqua bags, 5 drab violet bags.
posh maroon bags contain 5 muted chartreuse bags, 4 dark olive bags.
drab tomato bags contain 2 plaid tan bags, 2 posh purple bags, 2 posh beige bags.
wavy tan bags contain 5 light cyan bags, 5 muted brown bags, 5 mirrored coral bags, 5 light chartreuse bags.
faded bronze bags contain 4 dotted magenta bags.
pale blue bags contain 5 pale purple bags.
dim magenta bags contain 5 posh aqua bags, 5 dim crimson bags, 4 wavy gold bags, 2 shiny orange bags.
dark fuchsia bags contain 2 drab silver bags.
wavy white bags contain 4 vibrant turquoise bags, 2 clear violet bags, 1 dull salmon bag.
drab maroon bags contain 3 pale tomato bags, 2 dim chartreuse bags, 5 mirrored orange bags, 4 drab violet bags.
muted fuchsia bags contain 4 muted bronze bags, 4 plaid brown bags, 1 faded white bag.
plaid gold bags contain 3 vibrant bronze bags, 5 striped chartreuse bags.
faded green bags contain 2 dull cyan bags, 5 posh purple bags.
light indigo bags contain 5 mirrored tomato bags.
striped white bags contain 5 clear plum bags.
posh magenta bags contain 5 wavy crimson bags, 3 striped coral bags.
drab olive bags contain 4 striped orange bags.
plaid indigo bags contain 1 plaid turquoise bag.
dark brown bags contain 2 faded tan bags, 5 wavy green bags.
faded cyan bags contain 2 bright violet bags, 3 mirrored salmon bags.
dim lavender bags contain 2 mirrored fuchsia bags, 3 pale magenta bags, 2 dotted tan bags, 4 posh bronze bags.
dull maroon bags contain 3 dark silver bags, 5 dim plum bags.
dull teal bags contain 3 pale green bags.
shiny yellow bags contain 4 dotted fuchsia bags.
mirrored crimson bags contain 5 dotted plum bags.
drab beige bags contain 3 faded orange bags, 3 dark orange bags, 4 clear orange bags.
dull olive bags contain 2 vibrant bronze bags, 4 shiny chartreuse bags.
wavy red bags contain 2 wavy brown bags, 1 wavy olive bag, 3 striped cyan bags.
light gray bags contain 1 pale salmon bag, 2 plaid bronze bags, 5 dull yellow bags.
faded gray bags contain 4 muted green bags, 5 faded red bags, 3 muted magenta bags, 5 bright magenta bags.
drab indigo bags contain 1 posh gold bag, 2 dull lime bags, 1 pale orange bag.
bright yellow bags contain 4 posh red bags, 4 shiny gold bags.
drab bronze bags contain 4 dark indigo bags.
striped gold bags contain 3 faded yellow bags, 2 mirrored tomato bags, 1 bright lime bag.
muted gold bags contain 4 dim violet bags.
plaid olive bags contain 3 wavy fuchsia bags.
bright gray bags contain 4 bright bronze bags, 1 plaid white bag, 1 pale bronze bag.
clear turquoise bags contain 2 mirrored purple bags, 2 light gold bags, 4 dim cyan bags, 5 wavy olive bags.
wavy plum bags contain 4 bright yellow bags.
dull blue bags contain 4 dotted lavender bags.
posh gray bags contain 4 faded blue bags, 2 dull brown bags, 1 clear cyan bag.
pale black bags contain 5 dim cyan bags, 4 bright white bags.
wavy blue bags contain 3 faded olive bags, 5 bright lavender bags, 1 wavy black bag, 2 posh magenta bags.
posh beige bags contain 2 light cyan bags, 1 wavy violet bag, 1 muted olive bag.
clear plum bags contain 3 dull cyan bags.
drab cyan bags contain 5 plaid green bags.
vibrant aqua bags contain 5 posh maroon bags.
dim silver bags contain 5 shiny gold bags, 5 posh magenta bags, 1 light white bag.
posh brown bags contain 4 plaid salmon bags, 2 vibrant blue bags, 2 posh olive bags.
dark teal bags contain 1 faded brown bag.
clear white bags contain 5 vibrant tan bags, 5 light purple bags, 3 posh tan bags, 4 faded beige bags.
dim maroon bags contain 2 plaid chartreuse bags, 1 dim gray bag, 2 drab gold bags, 5 light white bags.
dull salmon bags contain 5 striped teal bags, 3 dark blue bags, 3 drab tan bags, 5 wavy crimson bags.
dull coral bags contain 1 faded red bag, 2 shiny teal bags, 3 bright gray bags, 1 pale brown bag.
dark violet bags contain 1 clear cyan bag, 4 mirrored beige bags, 2 vibrant turquoise bags.
vibrant maroon bags contain 1 muted magenta bag, 3 muted olive bags, 2 shiny turquoise bags.
posh orange bags contain 5 dark black bags, 3 pale maroon bags, 5 dull plum bags.
clear indigo bags contain 4 faded tan bags, 3 clear orange bags, 1 vibrant aqua bag.
clear gray bags contain 4 dull salmon bags, 5 dark magenta bags.
shiny turquoise bags contain 4 muted green bags, 4 vibrant beige bags, 5 mirrored cyan bags, 4 striped blue bags.
pale salmon bags contain 1 dark silver bag, 4 dim green bags.
striped gray bags contain 3 dark lavender bags.
dull yellow bags contain 2 dark blue bags, 4 striped tomato bags, 2 striped red bags, 3 pale brown bags.
posh yellow bags contain 1 dull green bag, 1 dull plum bag.
plaid white bags contain 3 plaid turquoise bags, 4 dotted cyan bags, 3 shiny gold bags, 5 clear plum bags.
faded orange bags contain 1 dull silver bag, 4 clear gray bags, 1 posh tomato bag, 2 wavy yellow bags.
dim violet bags contain 4 drab silver bags, 1 dull yellow bag, 3 faded blue bags.
light green bags contain 3 drab gold bags, 4 wavy purple bags.
dark magenta bags contain 2 light gold bags, 5 drab violet bags.
dark purple bags contain 5 plaid beige bags.
mirrored blue bags contain 2 plaid tan bags.
dim lime bags contain 1 dotted beige bag, 2 striped white bags, 5 dim blue bags, 5 wavy blue bags.
bright chartreuse bags contain 3 clear orange bags.
vibrant brown bags contain 3 mirrored violet bags, 5 dull green bags, 2 pale magenta bags.
drab salmon bags contain 4 muted magenta bags.
muted teal bags contain 5 dark black bags, 5 light gold bags.
striped lime bags contain 1 dim orange bag.
plaid crimson bags contain 4 dim teal bags, 3 dull salmon bags.
posh plum bags contain 5 pale gray bags.
light maroon bags contain 4 drab violet bags, 2 faded brown bags, 2 striped black bags, 3 striped coral bags.
pale gray bags contain 1 dark aqua bag, 3 mirrored tomato bags.
light chartreuse bags contain no other bags.
dim crimson bags contain 5 faded blue bags, 1 dark blue bag, 2 striped teal bags.
dim beige bags contain 5 wavy silver bags, 1 wavy orange bag, 1 dim lime bag, 2 mirrored lime bags.
bright teal bags contain 1 dull violet bag, 1 faded beige bag, 3 faded orange bags.
striped green bags contain 2 drab gold bags, 5 posh olive bags, 4 light indigo bags, 1 clear yellow bag.
striped black bags contain 4 striped crimson bags, 1 pale red bag.
plaid beige bags contain 3 pale tomato bags.
drab plum bags contain 4 striped coral bags, 3 dotted crimson bags.
plaid orange bags contain 4 bright aqua bags.
wavy maroon bags contain 1 dim orange bag, 1 dim violet bag, 4 posh chartreuse bags, 5 plaid tan bags.
dim purple bags contain 1 mirrored black bag, 1 plaid plum bag, 4 striped teal bags, 1 posh aqua bag.
mirrored red bags contain 2 shiny salmon bags, 3 bright salmon bags, 1 vibrant salmon bag.
striped brown bags contain 3 light lime bags, 1 drab black bag, 2 dull white bags, 5 drab lavender bags.
dim red bags contain 2 mirrored black bags.
clear lavender bags contain 5 pale fuchsia bags.
bright bronze bags contain 2 striped teal bags, 4 clear plum bags, 3 dim crimson bags, 5 faded black bags.
shiny violet bags contain 2 dark gold bags, 3 posh maroon bags.
bright lime bags contain 2 clear magenta bags, 3 dark blue bags, 4 striped lavender bags, 1 dull crimson bag.
mirrored silver bags contain 1 vibrant tomato bag, 4 dull salmon bags, 5 plaid green bags, 4 wavy brown bags.
dotted olive bags contain 5 faded beige bags.
posh tomato bags contain 2 faded purple bags.
posh teal bags contain 2 drab tan bags, 3 striped red bags, 3 dull salmon bags, 1 striped lavender bag.
shiny tomato bags contain 3 posh indigo bags.
dotted crimson bags contain 1 pale gray bag.
shiny indigo bags contain 1 pale beige bag.
plaid lime bags contain 1 light maroon bag.
mirrored turquoise bags contain 5 faded bronze bags.
drab crimson bags contain 1 vibrant plum bag.
dim black bags contain 3 muted tan bags, 3 drab silver bags, 4 dull white bags.
faded yellow bags contain 5 faded black bags.
faded white bags contain 2 wavy lavender bags, 1 shiny orange bag.
plaid tomato bags contain 2 shiny brown bags, 3 clear red bags.
drab white bags contain 5 dark yellow bags.
mirrored tomato bags contain 2 light gold bags, 1 mirrored gold bag, 4 dim plum bags.
plaid maroon bags contain 2 mirrored lime bags, 3 plaid salmon bags, 2 shiny chartreuse bags.
drab gold bags contain 1 dim plum bag, 2 mirrored violet bags.
muted orange bags contain 3 mirrored lime bags, 1 muted maroon bag, 5 drab violet bags, 2 posh green bags.
mirrored fuchsia bags contain 3 dim plum bags, 2 muted olive bags, 2 wavy white bags, 1 dotted cyan bag.
plaid silver bags contain 3 pale violet bags, 5 striped purple bags, 5 dull purple bags.
dotted silver bags contain 2 vibrant coral bags.
shiny cyan bags contain 4 mirrored teal bags, 4 faded magenta bags, 4 bright lime bags, 1 vibrant teal bag.
clear yellow bags contain 1 muted brown bag, 5 wavy lime bags.
muted red bags contain 5 muted coral bags, 2 light violet bags, 2 muted indigo bags, 4 dotted tan bags.
dull beige bags contain 5 plaid black bags, 2 pale white bags, 2 light violet bags, 1 pale crimson bag.
vibrant lavender bags contain 3 dark chartreuse bags, 4 bright lavender bags.
posh lime bags contain 1 shiny cyan bag, 4 dotted blue bags, 3 mirrored chartreuse bags.
shiny blue bags contain 1 dotted magenta bag.
muted yellow bags contain 4 plaid salmon bags, 4 dull tomato bags.
muted blue bags contain 5 wavy magenta bags, 3 vibrant gray bags.
dotted tan bags contain 1 wavy green bag, 1 dim plum bag.
drab red bags contain 2 dark olive bags, 5 mirrored tan bags, 3 dull coral bags, 4 plaid yellow bags.
dull tomato bags contain 2 clear aqua bags, 2 dark fuchsia bags, 2 light teal bags.
bright salmon bags contain 5 dark blue bags.
pale olive bags contain 1 light violet bag, 3 shiny bronze bags, 2 dotted magenta bags, 4 posh silver bags.
mirrored teal bags contain 4 posh chartreuse bags, 5 vibrant bronze bags.
mirrored chartreuse bags contain 3 striped olive bags, 3 mirrored maroon bags, 5 faded black bags, 3 pale plum bags.
pale orange bags contain 4 mirrored gold bags, 3 faded brown bags, 2 dark olive bags.
dark olive bags contain no other bags.
faded plum bags contain 5 bright green bags, 5 shiny beige bags, 2 vibrant indigo bags, 1 mirrored orange bag.
drab magenta bags contain 5 dark fuchsia bags, 5 striped salmon bags.
dark lavender bags contain 5 mirrored red bags, 4 vibrant aqua bags, 2 dotted tan bags.
shiny bronze bags contain 2 clear aqua bags, 2 dull salmon bags, 1 plaid turquoise bag, 3 plaid bronze bags.
faded magenta bags contain 2 mirrored gold bags, 5 dim orange bags.
light lavender bags contain 3 striped magenta bags, 5 light yellow bags.
clear tomato bags contain 3 dark bronze bags, 5 plaid aqua bags, 2 faded lime bags, 2 bright salmon bags.
clear lime bags contain 1 mirrored lavender bag, 3 bright silver bags, 3 pale teal bags.
light lime bags contain 4 dim crimson bags, 2 vibrant tomato bags, 4 posh red bags.
wavy yellow bags contain 3 muted chartreuse bags, 3 drab teal bags, 4 striped tomato bags.
dark silver bags contain 5 posh magenta bags, 1 plaid black bag, 3 faded brown bags.
bright maroon bags contain 5 dotted turquoise bags, 3 wavy silver bags, 2 dotted lime bags.
striped orange bags contain 5 striped coral bags, 3 posh teal bags.
bright silver bags contain 3 mirrored violet bags, 5 striped gold bags, 1 striped white bag, 4 clear chartreuse bags.
mirrored olive bags contain 4 light silver bags, 1 muted crimson bag.
dim gold bags contain 3 clear magenta bags.
shiny plum bags contain 5 muted olive bags, 5 dark turquoise bags, 2 dull green bags, 1 plaid magenta bag.
mirrored green bags contain 5 striped magenta bags, 1 light lime bag, 2 dim cyan bags.
wavy aqua bags contain 4 dull tan bags, 5 vibrant beige bags.
posh lavender bags contain 4 muted black bags.
dull lime bags contain 2 plaid black bags.
dim chartreuse bags contain 4 bright red bags.
muted lavender bags contain 5 faded red bags, 5 drab brown bags, 5 clear bronze bags.
muted coral bags contain 4 clear red bags, 3 vibrant maroon bags.
bright lavender bags contain 4 striped blue bags.

View File

@@ -0,0 +1,138 @@
use std::fmt;
use multimap::MultiMap;
fn main() {
let input = include_str!("../data/input");
let rules = parse_rules(input);
print!("{}", FmtRules(rules.clone()));
let mut reverted_rules: Rules = Default::default();
rules.iter_all().for_each(|(container, contained)| {
for c in contained {
reverted_rules.insert(c.1, (1, *container));
}
});
// dbg!(reverted_rules.clone());
let shiny_gold_spec = ("shiny", "gold");
let mut shiny_gold_containers = find_containers(
&reverted_rules,
&shiny_gold_spec
);
shiny_gold_containers.0.sort();
shiny_gold_containers.0.dedup();
// shiny_gold_containers also contain shiny_gold sadly...
dbg!(&shiny_gold_containers);
println!("Number of bags that can contain shiny gold ones : {}", shiny_gold_containers.0.len()-1);
//////// PART 2 /////////
let shiny_gold_contained = find_containers(&rules, &shiny_gold_spec);
// Remove 1 because the shiny gold bag actually doesn't contain itself ;)
println!("Number of bags contained by shiny gold bags : {}", shiny_gold_contained.1 - 1);
}
type BagSpec<'a> = (&'a str, &'a str);
type Rules<'a> = MultiMap<BagSpec<'a>, (usize, BagSpec<'a>)>;
// Needed as you cannot implement a trait for an abstract type if not in current mod...
struct FmtRules<'a>(Rules<'a>);
impl<'a> fmt::Display for FmtRules<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for ((adjective,colour), rules) in self.0.iter_all() {
write!(f, "{} {} bags contain ", adjective, colour)?;
if rules.is_empty() {
write!(f, "no other bags.")?;
} else {
for (idx, (nb, (adj, colour))) in rules.iter().enumerate() {
if idx > 0 { write!(f, ", ")? }
write!(f, "{} {} {} {}", nb, adj, colour, if *nb > 1 { "bags" } else { "bag" })?;
}
writeln!(f, ".")?;
}
}
Ok(())
}
}
fn parse_rules(input: &str) -> Rules<'_> {
let mut rules: Rules = Default::default();
peg::parser! {
pub(crate) grammar parser() for str {
pub(crate) rule root(r: &mut Rules<'input>)
= (line(r) "." whitespace()*)* ![_]
rule line(r: &mut Rules<'input>)
= bag:bag_spec() " contain " rules:rules() {
if let Some(rules) = rules {
for rule in rules {
r.insert(bag, rule);
}
}
}
rule bag_spec() -> BagSpec<'input>
= adjective:name() " " colour:name() " bag" "s"? {
(adjective, colour)
}
rule rules() -> Option<Vec<(usize, BagSpec<'input>)>>
= rules:rules1()+ {Some(rules)}
/ "no other bags" { None }
rule rules1() -> (usize, BagSpec<'input>)
= n:number() " " bag:bag_spec() ", "? {
(n, bag)
}
rule name() -> &'input str
= $((!whitespace()[_])+)
rule number() -> usize
= n:$(['0'..='9']+) { n.parse().unwrap() }
rule whitespace() = quiet!{[' ' | '\n' | '\t']+}
}
}
parser::root(input, &mut rules).unwrap();
rules
}
fn find_containers<'a>(rr: &'a Rules, start: &'a BagSpec)
-> (Vec<BagSpec<'a>>, usize) {
let mut res = vec![*start];
let mut count = 0;
let containers = rr.get_vec(start);
// for c in containers.iter().flat_map(|&v|v) {
for c in containers.into_iter().flatten().collect::<Vec<&(usize, (&str, &str))>>() {
let mut b = find_containers(rr, &(c.1));
res.append(&mut b.0);
count += c.0 * b.1;
}
(res, count + 1)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_phase2() {
let input = r"shiny gold bags contain 2 dark red bags.
dark red bags contain 2 dark orange bags.
dark orange bags contain 2 dark yellow bags.
dark yellow bags contain 2 dark green bags.
dark green bags contain 2 dark blue bags.
dark blue bags contain 2 dark violet bags.
dark violet bags contain no other bags.";
let rules = parse_rules(input);
let shiny_gold_spec = ("shiny", "gold");
let shiny_gold_contained = find_containers(&rules, &shiny_gold_spec);
assert_eq!(shiny_gold_contained.1 - 1, 126);
}
}

1
8-handheld_halting/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

70
8-handheld_halting/Cargo.lock generated Normal file
View File

@@ -0,0 +1,70 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "anyhow"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86"
[[package]]
name = "handheld_halting"
version = "0.1.0"
dependencies = [
"anyhow",
"thiserror",
]
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4211ce9909eb971f111059df92c45640aad50a619cf55cd76476be803c4c68e6"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "thiserror"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"

View File

@@ -0,0 +1,11 @@
[package]
name = "handheld_halting"
version = "0.1.0"
authors = ["Guilhem MARION <gmarion@netc.fr>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.37"
thiserror = "1.0.23"

View File

@@ -0,0 +1,623 @@
acc -17
nop +318
jmp +1
acc -10
jmp +394
acc +43
acc +47
nop +570
jmp +176
acc -9
jmp +322
jmp +73
acc +4
acc -4
jmp +460
jmp +228
acc +25
acc +39
jmp +50
acc -12
acc -14
nop +275
jmp +489
acc -11
jmp +338
acc +21
acc +10
jmp +1
acc +20
jmp +445
acc +7
jmp +419
acc -8
acc +32
jmp +181
acc +19
acc +5
acc +46
jmp +417
acc +28
acc +23
acc +16
jmp +225
jmp +317
jmp +309
jmp +69
acc -6
acc -6
jmp +127
acc +49
nop -38
jmp +467
acc +0
acc -12
acc -14
jmp -46
acc +14
acc +2
acc +2
jmp +311
acc +33
jmp +364
nop +234
acc +24
acc +37
acc +18
jmp +22
jmp +303
jmp +414
jmp +318
acc +22
acc +27
jmp +1
jmp +150
acc +34
acc +15
nop +200
acc +6
jmp +320
nop +534
acc +29
jmp +147
nop -20
jmp +255
jmp +10
acc -15
acc +3
jmp +338
nop +362
acc -4
jmp +1
jmp +286
acc -1
jmp +497
acc -4
acc +23
acc +4
jmp +400
acc +35
acc +50
jmp +133
acc -17
jmp -90
jmp +7
acc -17
jmp +472
acc +20
jmp +280
jmp +133
jmp -15
jmp +16
acc -19
acc -2
jmp -64
acc -17
jmp +1
jmp +385
acc -5
acc +34
jmp +382
acc +24
acc -17
acc +0
acc +15
jmp +466
jmp +300
acc +16
jmp +302
nop +479
acc +16
jmp +71
acc +23
jmp +1
acc +8
jmp +154
jmp +410
acc -8
jmp +402
acc +48
acc +42
acc +22
acc +35
jmp +50
jmp -7
acc -13
acc +37
acc +24
jmp +243
jmp +410
acc -3
acc +45
jmp +416
acc +2
acc +25
jmp -109
jmp -41
jmp +318
acc -8
acc -12
jmp +169
nop +393
acc +7
acc -12
acc +35
jmp +381
acc +41
nop -98
acc +15
acc -19
jmp +218
acc +24
acc +47
jmp +65
acc +29
jmp -129
acc +23
acc -13
nop +60
jmp -26
nop -4
acc -5
acc +13
nop -12
jmp -13
jmp -53
acc +21
jmp +276
nop -27
jmp +165
acc +42
nop +43
jmp +1
acc +26
acc +22
acc -3
jmp +405
acc +29
nop -118
acc +21
nop -190
jmp +217
acc -1
nop +223
acc -8
acc +45
jmp +49
acc +8
acc +22
jmp +209
acc +44
jmp +66
acc +7
acc -7
acc +48
jmp +318
nop +398
acc +2
jmp +16
nop +207
nop +358
acc +45
acc +48
jmp +267
nop +248
acc +26
jmp +307
acc +27
jmp -197
jmp -68
acc +34
acc +25
acc -13
jmp +133
jmp -77
acc -13
acc +10
jmp -193
jmp -62
acc +4
acc -14
jmp +261
jmp +151
jmp +208
acc -10
jmp +40
acc +31
jmp -216
acc +23
acc +34
jmp +364
nop +205
acc -3
acc +14
jmp +59
nop +359
acc -4
jmp +1
jmp -248
acc +47
acc +35
jmp +184
acc +16
nop -92
acc -12
jmp +354
acc +27
jmp -152
acc -14
acc -16
acc +43
jmp +147
acc +45
acc +24
acc +6
nop -46
jmp +21
acc +26
jmp +1
jmp +293
acc -8
acc +12
acc -19
acc -9
jmp +94
jmp +299
acc +10
acc -2
jmp +75
acc -7
acc +3
acc +47
jmp +171
acc +16
acc +44
acc -3
jmp +14
acc +30
acc +34
jmp -178
acc +35
nop -238
acc +39
jmp +1
jmp -133
acc +34
acc -6
jmp -276
acc +1
jmp -207
acc +10
jmp -43
jmp -302
acc -1
nop -29
jmp +1
acc +17
jmp -281
acc +17
jmp -109
jmp +1
acc +13
nop -9
jmp +245
acc +5
nop -15
acc +3
acc +7
jmp +65
acc -11
jmp -313
acc +47
jmp +29
jmp -289
acc +18
acc -17
nop +73
acc -12
jmp +80
acc +32
acc -4
acc +3
jmp -126
acc +16
jmp -275
nop -188
acc -3
acc +14
jmp -155
acc +33
acc -19
nop -166
acc +20
jmp +30
nop -169
acc +49
nop +168
jmp -24
nop -345
acc +34
jmp -40
jmp -56
jmp +29
jmp +191
acc +24
jmp +219
acc +34
acc +27
acc +11
jmp -260
jmp -339
acc +15
nop +16
jmp +1
jmp +138
jmp +1
jmp +1
jmp +14
acc -11
acc +45
jmp -19
acc +0
jmp +27
acc +0
nop +128
jmp -65
nop -23
jmp -318
jmp -325
jmp +1
jmp -229
jmp -270
jmp -137
acc +34
acc +7
jmp +1
jmp -346
acc +18
jmp +37
acc +40
acc -16
nop -146
acc +35
jmp -12
acc +1
acc +27
acc +44
acc +8
jmp -276
acc +16
acc +42
nop -342
acc +13
jmp -165
acc -11
acc -17
acc -10
jmp -26
acc +10
acc +43
jmp -276
acc +5
acc +34
acc +17
acc -9
jmp +99
acc +29
jmp -370
acc -11
jmp -412
acc +47
acc +21
acc -12
jmp -136
jmp -124
acc +12
acc +0
acc +25
acc +27
jmp -290
acc +5
acc +49
acc +32
nop +29
jmp -202
nop -296
acc -12
acc +9
acc +21
jmp +23
jmp -345
acc +26
nop -123
jmp -373
nop +118
jmp +43
acc -15
jmp -386
jmp +1
nop -370
acc +47
nop -141
jmp -426
acc +42
acc +12
acc +4
nop -103
jmp -122
acc +23
acc -4
acc +11
jmp -314
jmp -73
nop -1
jmp -411
acc +13
acc +9
nop -372
jmp -293
acc +46
acc +3
acc -1
jmp +86
acc +36
jmp +100
acc +27
acc +49
nop -4
acc +47
jmp -445
acc +31
acc +47
acc -11
acc +14
jmp -181
nop -438
acc +31
jmp -428
nop -115
nop -244
jmp -464
jmp -29
nop -240
jmp -241
acc -12
jmp -329
nop +78
acc +6
jmp +1
acc +49
jmp -322
jmp -133
acc +20
nop -83
acc +35
acc +29
jmp -41
acc +15
jmp -46
jmp -29
acc +45
acc -14
acc +21
jmp -366
nop +84
acc -6
acc +25
acc -17
jmp -326
acc -5
nop -159
acc +5
jmp -171
acc +42
jmp -28
acc +42
acc -11
acc +45
acc +19
jmp -305
acc +38
acc -13
acc -16
jmp -134
acc +45
jmp -256
acc -15
acc -18
acc +28
jmp -114
acc -11
acc +47
nop -420
jmp -90
nop -330
jmp +13
acc -15
acc +9
jmp -159
acc -12
acc +0
acc +0
jmp -538
acc +31
acc +24
acc +32
acc -16
jmp -95
jmp -466
acc +19
acc +2
jmp -172
acc -12
jmp -207
acc +39
acc +18
acc +5
jmp -211
nop -507
jmp +1
jmp -197
nop -227
acc +28
jmp -494
acc +22
acc +2
acc -14
jmp -377
acc +8
acc +29
jmp -573
acc -17
acc +14
acc +29
acc +11
jmp -351
acc +9
nop -540
acc +30
nop -344
jmp -564
acc -4
nop -465
jmp -293
acc -18
acc +5
acc +29
jmp -302
acc -17
acc +14
acc +2
acc -11
jmp -527
jmp -563
acc +14
acc +10
jmp -505
acc +43
jmp -188
nop -448
acc +44
acc +3
acc +16
jmp +1

View File

@@ -0,0 +1,246 @@
use std::str::FromStr;
use anyhow::Result;
#[derive(Debug, Clone, PartialEq)]
enum ISet {
Acc,
Jmp,
Nop,
}
#[derive(Debug, Clone)]
struct Instruction {
execd: bool,
instr: ISet,
arg: i64
}
#[derive(Debug, thiserror::Error)]
enum ParseError {
#[error("Expected {0}")]
Expected(&'static str)
}
impl FromStr for Instruction {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut tokens = s.lines()
.next()
.ok_or(ParseError::Expected("one line"))?
.split_whitespace();
match tokens.next().ok_or(ParseError::Expected("instruction"))? {
"acc" => {
let arg = tokens
.next()
.ok_or(ParseError::Expected("acc argument"))?
.parse()
.unwrap();
Ok(Instruction {
execd: false,
instr: ISet::Acc,
arg,
})
},
"nop" => {
let arg = tokens
.next()
.ok_or(ParseError::Expected("acc argument"))?
.parse()
.unwrap();
Ok(Instruction {
execd: false,
instr: ISet::Nop,
arg, // For part 1 at least NOP args are useless
})
},
"jmp" => {
let arg = tokens
.next()
.ok_or(ParseError::Expected("acc argument"))?
.parse()
.unwrap();
Ok(Instruction {
execd: false,
instr: ISet::Jmp,
arg,
})
},
_ => Err(ParseError::Expected("acc, nop or jmp instruction"))
}
}
}
impl Instruction {
fn exec(&mut self, pc: &mut usize, acc: &mut i64) {
self.execd = true;
match self.instr {
ISet::Acc => {
*acc += self.arg;
*pc += 1;
}
ISet::Jmp => {
// Expect this to panic hard if you underflow :3
*pc = ((*pc as i64) + self.arg) as usize;
}
ISet::Nop => {
*pc += 1;
}
}
}
}
#[derive(Debug, Clone)]
struct Program {
prog: Vec<Instruction>,
pc: usize,
acc: i64,
}
impl Program {
fn load(s: &str) -> Result<Program, ParseError> {
let loaded_program: Vec<Instruction> = s
.lines()
.map(|l| Instruction::from_str(l))
.collect::<Result<Vec<Instruction>, ParseError>>()?;
Ok(
Self {
prog: loaded_program,
pc: 0,
acc: 0,
}
)
}
fn reset(&mut self) {
self.pc = 0;
self.acc = 0;
for mut i in self.prog.iter_mut() {
i.execd = false;
}
}
/// Returns whether execution finished :
/// Normally (true) - executing one instruction after the last one
/// Or abnormalaly (false) - looping forever or executing random
/// instructions
fn exec_until_loop(&mut self) -> bool {
let pc_stop = self.prog.len();
loop {
// Terminate on infinite loop
if self.prog[self.pc].execd {
println!("Infinite loop !");
return false;
}
self.prog[self.pc].exec(&mut self.pc, &mut self.acc);
// Terminate on success
if self.pc == pc_stop {
println!("Good pc !");
return true;
}
// Terminate on corrupted pc
else if !(0..=pc_stop).contains(&(self.pc)) {
println!("Corrupted pc !");
return false;
}
}
}
fn find_corrupted_instruction(&mut self) -> Option<i64> {
// Test jmps -> nops
self.reset();
for j in (0..self.prog.len())
.filter(|&i| self.prog[i].instr == ISet::Jmp)
{
println!("Switch jmp-nop at pos {}", j);
let mut pclone = self.clone();
pclone.prog[j].instr = ISet::Nop;
if pclone.exec_until_loop() {
return Some(pclone.acc);
}
}
// Test nops -> jmps
for n in (0..self.prog.len())
.filter(|&i| self.prog[i].instr == ISet::Nop)
{
println!("Switch nop-jmp at pos {}", n);
let mut pclone = self.clone();
pclone.prog[n].instr = ISet::Jmp;
if pclone.exec_until_loop() {
return Some(pclone.acc);
}
}
None
}
}
fn main() {
let input = include_str!("../data/input");
let mut prog = Program::load(input).unwrap();
prog.exec_until_loop();
println!("Acc before program gets into second loop : {}", prog.acc);
println!("Acc after the program is set to terminate : {}", prog.find_corrupted_instruction().unwrap());
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_nop() {
let input = r"nop +0";
let mut prog = Program::load(input).unwrap();
prog.exec_until_loop();
assert_eq!(prog.acc, 0)
}
#[test]
fn test_acc() {
let input = r"acc +5";
let mut prog = Program::load(input).unwrap();
prog.exec_until_loop();
assert_eq!(prog.acc, 5)
}
#[test]
fn test_jmp() {
let input = r"jmp +2
acc +1
acc +1";
let mut prog = Program::load(input).unwrap();
prog.exec_until_loop();
assert_eq!(prog.acc, 1)
}
#[test]
fn test_short_loop() {
let input = r"acc +1
jmp +2
acc +1
acc +1
jmp -4";
let mut prog = Program::load(input).unwrap();
prog.exec_until_loop();
assert_eq!(prog.acc, 2)
}
#[test]
fn test_exec() {
let input = r"nop +0
acc +1
jmp +4
acc +3
jmp -3
acc -99
acc +1
jmp -4
acc +6";
let mut prog = Program::load(input).unwrap();
prog.exec_until_loop();
assert_eq!(prog.acc, 5)
}
}

1
9-encoding_error/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

View File

@@ -0,0 +1,9 @@
[package]
name = "encoding_error"
version = "0.1.0"
authors = ["Guilhem MARION <gmarion@netc.fr>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

1000
9-encoding_error/data/input Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}