Compare commits

...

11 Commits

38 changed files with 2231 additions and 16 deletions

4
Cargo.lock generated
View File

@ -2,6 +2,10 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 4 version = 4
[[package]]
name = "genaoc"
version = "0.1.0"
[[package]] [[package]]
name = "md5" name = "md5"
version = "0.7.0" version = "0.7.0"

View File

@ -1,3 +1,8 @@
[package]
name = "genaoc"
version = "0.1.0"
edition = "2021"
[workspace] [workspace]
resolver = "2" resolver = "2"
members = [ members = [

8
justfile Normal file
View File

@ -0,0 +1,8 @@
gen year day:
cargo run -- {{year}} {{day}}
run year day:
cargo run --package y{{year}} --bin d{{day}}
test year day *part='1':
cargo test --package y{{year}} days::d{{day}}::tests::part{{part}} -- --nocapture

64
src/main.rs Normal file
View File

@ -0,0 +1,64 @@
use std::{env, fs, path::Path, process::Command};
fn main() -> Result<(), std::io::Error> {
let args: Vec<String> = env::args().collect();
if args.len() == 1 {
println!("Too few arguments");
println!("Please enter a year, or a year and day");
return Err(std::io::ErrorKind::InvalidInput.into());
} else if args.len() > 3 {
println!("Too many arguments");
println!("Please enter a year, or a year and day");
return Err(std::io::ErrorKind::InvalidInput.into());
} else if args.len() == 2 {
prepare_year(&args[1])?;
} else if args.len() == 3 {
prepare_day(&args[1], &args[2])?;
}
match Command::new("cargo").arg("fmt").status() {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}
fn prepare_year(year: &str) -> Result<(), std::io::Error> {
let root = env!("CARGO_MANIFEST_DIR");
if Path::new(&format!("{root}/y{year}")).exists() {
panic!("Folder y{year} already exists")
}
// create workspace
match Command::new("cargo")
.arg("new")
.arg(format!("y{year}"))
.status()
{
Ok(_status) => Ok(()),
Err(e) => Err(e),
}?;
// remove main.rs
fs::remove_file(format!("{root}/y{year}/src/main.rs"))?;
fs::create_dir(format!("{root}/y{year}/src/bin"))?;
fs::create_dir(format!("{root}/y{year}/src/days"))?;
fs::write(format!("{root}/y{year}/src/lib.rs"), "pub mod days;")?;
fs::write(format!("{root}/y{year}/src/days/mod.rs"), "")?;
prepare_day(year, "1")
}
fn prepare_day(year: &str, day: &str) -> Result<(), std::io::Error> {
let root = env!("CARGO_MANIFEST_DIR");
if Path::new(&format!("{root}/y{year}/src/bin/d{day}.rs")).exists() {
panic!("Day y{year}d{day} already exists")
}
let bin = fs::read_to_string(format!("{root}/template/bin/d.rs.tmpl"))?
.replace("{{YEAR}}", year)
.replace("{{DAY}}", day);
let dayfile = fs::read_to_string(format!("{root}/template/days/d.rs.tmpl"))?;
let mut modfile = fs::read_to_string(format!("{root}/y{year}/src/days/mod.rs"))?;
modfile.push_str(format!("\npub mod d{day};").as_str());
let bin_path = format!("{root}/y{year}/src/bin/d{day}.rs");
fs::write(bin_path, bin)?;
fs::write(format!("{root}/y{year}/src/days/d{day}.rs"), dayfile)?;
fs::write(format!("{root}/y{year}/src/days/mod.rs"), modfile)?;
Ok(())
}

20
template/bin/d.rs.tmpl Normal file
View File

@ -0,0 +1,20 @@
use std::fs;
use y{{YEAR}}::days::d{{DAY}};
fn main() {
part1();
part2();
}
fn part1() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/{{DAY}}_input.txt")).unwrap();
println!("{}", d{{DAY}}::process_part1(&content));
}
fn part2() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/{{DAY}}_input.txt")).unwrap();
println!("{}", d{{DAY}}::process_part2(&content));
}

26
template/days/d.rs.tmpl Normal file
View File

@ -0,0 +1,26 @@
pub fn process_part1(input: &str) -> i32 {
0
}
pub fn process_part2(input: &str) -> i32 {
0
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &str = "{{EXAMPLE}}";
#[test]
fn part1() {
let result = process_part1(INPUT);
assert_eq!(result, 0);
}
#[test]
fn part2() {
let result = process_part2(INPUT);
assert_eq!(result, 0);
}
}

View File

@ -0,0 +1,500 @@
Sue 1: goldfish: 9, cars: 0, samoyeds: 9
Sue 2: perfumes: 5, trees: 8, goldfish: 8
Sue 3: pomeranians: 2, akitas: 1, trees: 5
Sue 4: goldfish: 10, akitas: 2, perfumes: 9
Sue 5: cars: 5, perfumes: 6, akitas: 9
Sue 6: goldfish: 10, cats: 9, cars: 8
Sue 7: trees: 2, samoyeds: 7, goldfish: 10
Sue 8: cars: 8, perfumes: 6, goldfish: 1
Sue 9: cats: 4, pomeranians: 0, trees: 0
Sue 10: trees: 2, children: 10, samoyeds: 10
Sue 11: akitas: 10, perfumes: 4, vizslas: 1
Sue 12: akitas: 1, trees: 0, goldfish: 3
Sue 13: perfumes: 6, goldfish: 10, cars: 8
Sue 14: cats: 8, akitas: 5, vizslas: 0
Sue 15: cars: 8, trees: 3, samoyeds: 5
Sue 16: vizslas: 6, cats: 6, pomeranians: 10
Sue 17: akitas: 6, cats: 2, perfumes: 9
Sue 18: children: 9, goldfish: 2, akitas: 10
Sue 19: trees: 3, perfumes: 0, goldfish: 6
Sue 20: vizslas: 3, akitas: 0, trees: 1
Sue 21: vizslas: 3, cars: 7, akitas: 3
Sue 22: perfumes: 7, children: 1, pomeranians: 7
Sue 23: trees: 10, cars: 9, akitas: 10
Sue 24: akitas: 5, goldfish: 6, vizslas: 6
Sue 25: samoyeds: 3, trees: 8, vizslas: 5
Sue 26: vizslas: 4, pomeranians: 2, trees: 1
Sue 27: cars: 9, goldfish: 2, trees: 4
Sue 28: vizslas: 6, goldfish: 10, perfumes: 7
Sue 29: vizslas: 6, pomeranians: 3, akitas: 6
Sue 30: trees: 0, samoyeds: 5, akitas: 9
Sue 31: vizslas: 1, perfumes: 0, trees: 6
Sue 32: cars: 7, vizslas: 1, children: 10
Sue 33: vizslas: 1, cars: 1, perfumes: 7
Sue 34: vizslas: 9, trees: 10, akitas: 9
Sue 35: akitas: 3, vizslas: 5, cars: 10
Sue 36: cats: 3, children: 9, samoyeds: 3
Sue 37: vizslas: 5, pomeranians: 7, cars: 6
Sue 38: cars: 10, akitas: 5, vizslas: 8
Sue 39: akitas: 5, trees: 9, children: 2
Sue 40: vizslas: 0, cats: 7, akitas: 0
Sue 41: cars: 9, trees: 10, perfumes: 8
Sue 42: akitas: 4, trees: 2, goldfish: 3
Sue 43: goldfish: 1, cats: 1, akitas: 8
Sue 44: goldfish: 8, akitas: 9, vizslas: 4
Sue 45: perfumes: 3, goldfish: 4, trees: 0
Sue 46: trees: 7, perfumes: 1, goldfish: 8
Sue 47: pomeranians: 10, cars: 7, trees: 2
Sue 48: trees: 2, akitas: 1, cars: 4
Sue 49: goldfish: 5, perfumes: 7, akitas: 8
Sue 50: akitas: 9, vizslas: 9, trees: 2
Sue 51: cars: 0, samoyeds: 0, vizslas: 8
Sue 52: trees: 0, perfumes: 6, pomeranians: 4
Sue 53: vizslas: 1, cats: 6, akitas: 3
Sue 54: samoyeds: 8, akitas: 1, vizslas: 4
Sue 55: goldfish: 10, perfumes: 2, pomeranians: 10
Sue 56: trees: 9, perfumes: 3, goldfish: 5
Sue 57: akitas: 3, perfumes: 0, cats: 2
Sue 58: perfumes: 4, vizslas: 4, cars: 8
Sue 59: goldfish: 7, children: 5, pomeranians: 8
Sue 60: cars: 1, trees: 1, perfumes: 10
Sue 61: trees: 4, samoyeds: 4, cars: 6
Sue 62: akitas: 10, trees: 2, vizslas: 6
Sue 63: goldfish: 3, perfumes: 7, vizslas: 10
Sue 64: pomeranians: 5, children: 10, cars: 0
Sue 65: vizslas: 10, cars: 8, perfumes: 3
Sue 66: children: 5, vizslas: 4, akitas: 10
Sue 67: children: 6, perfumes: 7, cars: 3
Sue 68: goldfish: 8, cars: 6, children: 1
Sue 69: vizslas: 5, perfumes: 3, cars: 9
Sue 70: goldfish: 0, cats: 6, perfumes: 0
Sue 71: trees: 2, samoyeds: 3, cars: 1
Sue 72: cats: 3, akitas: 8, vizslas: 7
Sue 73: akitas: 3, vizslas: 2, goldfish: 6
Sue 74: pomeranians: 10, samoyeds: 9, cats: 8
Sue 75: vizslas: 7, cars: 7, akitas: 10
Sue 76: children: 3, cats: 6, vizslas: 3
Sue 77: goldfish: 7, pomeranians: 10, trees: 0
Sue 78: vizslas: 9, children: 7, trees: 10
Sue 79: trees: 6, pomeranians: 8, samoyeds: 1
Sue 80: vizslas: 5, children: 6, pomeranians: 5
Sue 81: cars: 9, vizslas: 9, akitas: 9
Sue 82: vizslas: 3, cars: 8, akitas: 1
Sue 83: vizslas: 4, trees: 2, cats: 1
Sue 84: children: 3, akitas: 0, vizslas: 1
Sue 85: cats: 6, vizslas: 5, akitas: 2
Sue 86: cars: 3, akitas: 7, goldfish: 8
Sue 87: samoyeds: 8, vizslas: 3, goldfish: 8
Sue 88: vizslas: 4, children: 0, cats: 7
Sue 89: goldfish: 9, pomeranians: 10, samoyeds: 0
Sue 90: trees: 6, akitas: 3, cars: 7
Sue 91: samoyeds: 3, akitas: 7, perfumes: 10
Sue 92: cars: 7, pomeranians: 10, trees: 2
Sue 93: samoyeds: 1, children: 3, cars: 3
Sue 94: samoyeds: 8, akitas: 7, vizslas: 0
Sue 95: goldfish: 7, children: 2, cars: 6
Sue 96: cars: 3, perfumes: 9, akitas: 10
Sue 97: akitas: 9, cars: 10, vizslas: 10
Sue 98: trees: 4, goldfish: 8, pomeranians: 7
Sue 99: samoyeds: 6, pomeranians: 0, vizslas: 7
Sue 100: akitas: 7, perfumes: 8, vizslas: 3
Sue 101: cars: 5, perfumes: 1, trees: 0
Sue 102: akitas: 6, pomeranians: 10, trees: 0
Sue 103: trees: 3, perfumes: 5, cats: 9
Sue 104: goldfish: 10, perfumes: 8, akitas: 0
Sue 105: goldfish: 6, vizslas: 5, trees: 2
Sue 106: pomeranians: 9, samoyeds: 10, perfumes: 10
Sue 107: cars: 8, vizslas: 4, akitas: 2
Sue 108: cats: 0, goldfish: 7, trees: 0
Sue 109: cars: 3, pomeranians: 6, trees: 2
Sue 110: perfumes: 4, goldfish: 5, akitas: 10
Sue 111: cars: 3, perfumes: 4, pomeranians: 4
Sue 112: cats: 2, goldfish: 10, akitas: 0
Sue 113: cats: 10, children: 0, trees: 1
Sue 114: akitas: 10, vizslas: 3, goldfish: 0
Sue 115: samoyeds: 3, goldfish: 6, vizslas: 1
Sue 116: cars: 3, perfumes: 5, trees: 6
Sue 117: akitas: 9, samoyeds: 8, goldfish: 8
Sue 118: pomeranians: 5, perfumes: 10, trees: 1
Sue 119: goldfish: 6, perfumes: 3, children: 1
Sue 120: trees: 1, children: 3, pomeranians: 6
Sue 121: akitas: 7, cars: 10, vizslas: 9
Sue 122: trees: 4, akitas: 8, samoyeds: 10
Sue 123: cats: 4, cars: 8, vizslas: 9
Sue 124: cars: 10, children: 1, trees: 0
Sue 125: goldfish: 5, pomeranians: 5, trees: 2
Sue 126: goldfish: 1, vizslas: 8, akitas: 10
Sue 127: vizslas: 4, cars: 9, akitas: 1
Sue 128: goldfish: 8, perfumes: 3, cars: 9
Sue 129: goldfish: 9, pomeranians: 9, perfumes: 1
Sue 130: trees: 1, vizslas: 9, perfumes: 3
Sue 131: children: 6, trees: 8, vizslas: 8
Sue 132: cars: 1, vizslas: 3, children: 7
Sue 133: cars: 7, children: 1, perfumes: 6
Sue 134: trees: 8, vizslas: 3, samoyeds: 2
Sue 135: cats: 9, perfumes: 4, pomeranians: 7
Sue 136: perfumes: 0, akitas: 8, vizslas: 6
Sue 137: goldfish: 5, trees: 0, vizslas: 7
Sue 138: trees: 1, perfumes: 2, cars: 10
Sue 139: samoyeds: 8, goldfish: 8, trees: 0
Sue 140: vizslas: 10, perfumes: 9, goldfish: 0
Sue 141: perfumes: 7, cars: 9, cats: 5
Sue 142: trees: 2, samoyeds: 2, cars: 0
Sue 143: cars: 1, perfumes: 1, akitas: 1
Sue 144: vizslas: 9, cars: 7, pomeranians: 10
Sue 145: pomeranians: 2, samoyeds: 7, children: 7
Sue 146: vizslas: 6, cars: 9, goldfish: 7
Sue 147: trees: 2, vizslas: 1, cats: 9
Sue 148: perfumes: 9, trees: 4, pomeranians: 5
Sue 149: samoyeds: 8, children: 1, vizslas: 9
Sue 150: cats: 3, trees: 2, vizslas: 4
Sue 151: goldfish: 7, akitas: 10, trees: 3
Sue 152: perfumes: 4, vizslas: 7, cars: 4
Sue 153: pomeranians: 4, akitas: 0, vizslas: 3
Sue 154: samoyeds: 8, trees: 2, vizslas: 10
Sue 155: vizslas: 7, cats: 7, pomeranians: 5
Sue 156: goldfish: 10, pomeranians: 1, vizslas: 1
Sue 157: cars: 6, perfumes: 7, trees: 9
Sue 158: trees: 5, samoyeds: 9, goldfish: 3
Sue 159: pomeranians: 4, akitas: 6, vizslas: 8
Sue 160: goldfish: 7, children: 0, cats: 0
Sue 161: vizslas: 5, akitas: 0, samoyeds: 2
Sue 162: akitas: 4, children: 0, vizslas: 3
Sue 163: samoyeds: 2, perfumes: 0, goldfish: 9
Sue 164: cars: 9, vizslas: 8, akitas: 6
Sue 165: samoyeds: 9, vizslas: 9, perfumes: 5
Sue 166: cars: 5, pomeranians: 4, samoyeds: 8
Sue 167: cars: 10, perfumes: 3, samoyeds: 6
Sue 168: pomeranians: 8, goldfish: 9, trees: 9
Sue 169: vizslas: 7, akitas: 3, samoyeds: 4
Sue 170: cats: 2, goldfish: 0, vizslas: 4
Sue 171: perfumes: 3, goldfish: 10, cats: 3
Sue 172: goldfish: 7, akitas: 6, cars: 0
Sue 173: cars: 9, goldfish: 7, akitas: 5
Sue 174: goldfish: 6, cats: 0, vizslas: 8
Sue 175: perfumes: 7, cats: 10, cars: 10
Sue 176: samoyeds: 9, vizslas: 4, pomeranians: 10
Sue 177: perfumes: 0, trees: 0, cars: 10
Sue 178: vizslas: 6, children: 7, samoyeds: 1
Sue 179: vizslas: 8, children: 6, trees: 0
Sue 180: cars: 1, vizslas: 6, trees: 1
Sue 181: vizslas: 10, perfumes: 3, cars: 1
Sue 182: trees: 8, samoyeds: 9, cars: 7
Sue 183: cars: 6, vizslas: 2, perfumes: 7
Sue 184: trees: 5, samoyeds: 9, akitas: 0
Sue 185: cars: 8, goldfish: 8, trees: 4
Sue 186: samoyeds: 6, goldfish: 1, trees: 2
Sue 187: perfumes: 1, trees: 2, akitas: 7
Sue 188: samoyeds: 5, cars: 6, perfumes: 2
Sue 189: samoyeds: 8, goldfish: 3, perfumes: 5
Sue 190: akitas: 2, cats: 1, samoyeds: 1
Sue 191: trees: 5, akitas: 1, goldfish: 7
Sue 192: vizslas: 3, trees: 0, perfumes: 4
Sue 193: cars: 3, perfumes: 4, akitas: 3
Sue 194: perfumes: 4, vizslas: 8, children: 4
Sue 195: vizslas: 1, samoyeds: 3, cars: 6
Sue 196: cars: 5, perfumes: 6, vizslas: 2
Sue 197: vizslas: 8, akitas: 8, cats: 6
Sue 198: cars: 9, akitas: 2, pomeranians: 7
Sue 199: cats: 9, akitas: 6, cars: 10
Sue 200: vizslas: 10, pomeranians: 2, goldfish: 9
Sue 201: vizslas: 9, samoyeds: 4, akitas: 3
Sue 202: akitas: 5, cats: 2, vizslas: 0
Sue 203: perfumes: 1, children: 3, akitas: 10
Sue 204: trees: 4, vizslas: 7, akitas: 9
Sue 205: trees: 8, perfumes: 9, cars: 1
Sue 206: goldfish: 6, trees: 5, cars: 8
Sue 207: akitas: 3, vizslas: 8, trees: 8
Sue 208: vizslas: 4, perfumes: 7, akitas: 10
Sue 209: cars: 9, perfumes: 7, goldfish: 9
Sue 210: vizslas: 2, cats: 2, akitas: 10
Sue 211: akitas: 1, trees: 3, cars: 2
Sue 212: goldfish: 5, trees: 0, vizslas: 7
Sue 213: akitas: 3, perfumes: 1, vizslas: 5
Sue 214: perfumes: 3, pomeranians: 6, cars: 0
Sue 215: goldfish: 1, cats: 9, cars: 3
Sue 216: goldfish: 9, pomeranians: 6, samoyeds: 0
Sue 217: cars: 6, trees: 2, perfumes: 2
Sue 218: vizslas: 3, goldfish: 8, akitas: 5
Sue 219: cats: 9, perfumes: 7, cars: 5
Sue 220: pomeranians: 5, vizslas: 4, cats: 5
Sue 221: trees: 0, akitas: 7, goldfish: 10
Sue 222: akitas: 2, cars: 3, vizslas: 5
Sue 223: goldfish: 3, perfumes: 7, akitas: 4
Sue 224: samoyeds: 2, cars: 4, vizslas: 7
Sue 225: trees: 5, cars: 0, perfumes: 0
Sue 226: trees: 2, goldfish: 10, perfumes: 6
Sue 227: cars: 8, trees: 9, akitas: 6
Sue 228: goldfish: 10, trees: 10, perfumes: 0
Sue 229: children: 7, samoyeds: 4, goldfish: 6
Sue 230: vizslas: 9, perfumes: 1, children: 10
Sue 231: vizslas: 8, trees: 5, akitas: 9
Sue 232: akitas: 5, goldfish: 9, trees: 1
Sue 233: vizslas: 3, trees: 2, children: 9
Sue 234: samoyeds: 8, perfumes: 0, cats: 0
Sue 235: perfumes: 4, vizslas: 3, akitas: 5
Sue 236: pomeranians: 5, vizslas: 3, akitas: 9
Sue 237: cats: 1, trees: 7, vizslas: 5
Sue 238: children: 5, cats: 4, samoyeds: 5
Sue 239: trees: 3, akitas: 2, goldfish: 6
Sue 240: goldfish: 9, trees: 1, perfumes: 1
Sue 241: cars: 2, pomeranians: 1, samoyeds: 2
Sue 242: akitas: 2, trees: 3, cars: 4
Sue 243: vizslas: 6, akitas: 2, samoyeds: 7
Sue 244: trees: 0, perfumes: 5, cars: 7
Sue 245: goldfish: 10, perfumes: 5, vizslas: 8
Sue 246: akitas: 0, perfumes: 0, cars: 1
Sue 247: samoyeds: 8, goldfish: 0, cars: 6
Sue 248: perfumes: 0, children: 10, trees: 10
Sue 249: perfumes: 6, akitas: 5, cats: 5
Sue 250: vizslas: 7, akitas: 4, cats: 5
Sue 251: samoyeds: 4, akitas: 1, trees: 8
Sue 252: perfumes: 8, pomeranians: 5, cars: 1
Sue 253: akitas: 10, trees: 4, cats: 3
Sue 254: perfumes: 2, cats: 2, goldfish: 9
Sue 255: cars: 4, trees: 1, akitas: 4
Sue 256: samoyeds: 9, goldfish: 0, akitas: 9
Sue 257: vizslas: 9, perfumes: 2, goldfish: 2
Sue 258: perfumes: 1, cars: 9, samoyeds: 1
Sue 259: trees: 0, goldfish: 0, samoyeds: 3
Sue 260: perfumes: 7, cars: 1, goldfish: 0
Sue 261: cars: 0, trees: 5, goldfish: 6
Sue 262: akitas: 7, vizslas: 3, pomeranians: 5
Sue 263: trees: 1, vizslas: 3, goldfish: 3
Sue 264: akitas: 7, vizslas: 4, children: 0
Sue 265: samoyeds: 5, trees: 0, akitas: 4
Sue 266: perfumes: 9, goldfish: 9, cars: 8
Sue 267: cars: 7, perfumes: 10, pomeranians: 8
Sue 268: cars: 0, akitas: 7, perfumes: 4
Sue 269: pomeranians: 0, cars: 9, perfumes: 10
Sue 270: samoyeds: 10, perfumes: 10, cars: 9
Sue 271: akitas: 2, vizslas: 8, cats: 5
Sue 272: akitas: 3, children: 9, samoyeds: 10
Sue 273: perfumes: 2, cars: 10, goldfish: 8
Sue 274: cars: 3, children: 10, perfumes: 10
Sue 275: cats: 9, akitas: 5, trees: 0
Sue 276: akitas: 6, children: 2, vizslas: 1
Sue 277: pomeranians: 6, trees: 10, samoyeds: 3
Sue 278: cars: 7, perfumes: 10, trees: 1
Sue 279: cars: 6, pomeranians: 8, trees: 2
Sue 280: pomeranians: 9, cats: 0, perfumes: 7
Sue 281: vizslas: 10, goldfish: 9, pomeranians: 5
Sue 282: perfumes: 4, samoyeds: 7, cars: 9
Sue 283: cars: 9, vizslas: 6, trees: 5
Sue 284: cars: 7, trees: 1, vizslas: 4
Sue 285: samoyeds: 4, goldfish: 10, cats: 4
Sue 286: samoyeds: 0, akitas: 4, children: 5
Sue 287: trees: 1, perfumes: 3, goldfish: 10
Sue 288: pomeranians: 10, akitas: 3, cars: 2
Sue 289: trees: 7, pomeranians: 4, goldfish: 10
Sue 290: samoyeds: 10, perfumes: 0, cars: 9
Sue 291: akitas: 0, pomeranians: 7, vizslas: 4
Sue 292: cats: 2, vizslas: 8, goldfish: 5
Sue 293: vizslas: 6, pomeranians: 9, perfumes: 0
Sue 294: akitas: 6, cars: 7, vizslas: 5
Sue 295: goldfish: 0, akitas: 9, cats: 0
Sue 296: goldfish: 1, trees: 0, cars: 6
Sue 297: perfumes: 6, cats: 8, pomeranians: 6
Sue 298: cats: 0, goldfish: 6, perfumes: 2
Sue 299: cars: 4, akitas: 1, samoyeds: 10
Sue 300: goldfish: 9, samoyeds: 6, cats: 5
Sue 301: cars: 0, vizslas: 7, trees: 0
Sue 302: goldfish: 9, samoyeds: 1, children: 6
Sue 303: cars: 6, perfumes: 7, samoyeds: 8
Sue 304: trees: 8, goldfish: 9, children: 9
Sue 305: perfumes: 0, cars: 5, goldfish: 4
Sue 306: cats: 3, cars: 7, vizslas: 7
Sue 307: pomeranians: 4, perfumes: 6, cars: 2
Sue 308: cars: 9, akitas: 6, goldfish: 4
Sue 309: pomeranians: 2, vizslas: 10, goldfish: 10
Sue 310: children: 0, cats: 4, akitas: 7
Sue 311: children: 10, akitas: 8, vizslas: 2
Sue 312: children: 5, cars: 0, vizslas: 4
Sue 313: perfumes: 10, trees: 3, pomeranians: 9
Sue 314: samoyeds: 3, goldfish: 2, trees: 9
Sue 315: cars: 2, cats: 5, pomeranians: 10
Sue 316: cats: 6, pomeranians: 6, children: 9
Sue 317: cats: 2, vizslas: 3, perfumes: 1
Sue 318: akitas: 1, perfumes: 3, vizslas: 10
Sue 319: cars: 7, perfumes: 0, trees: 0
Sue 320: goldfish: 6, samoyeds: 6, pomeranians: 4
Sue 321: trees: 2, goldfish: 6, children: 0
Sue 322: goldfish: 0, trees: 2, akitas: 8
Sue 323: pomeranians: 2, samoyeds: 9, vizslas: 1
Sue 324: trees: 4, goldfish: 6, pomeranians: 6
Sue 325: trees: 2, pomeranians: 3, goldfish: 1
Sue 326: perfumes: 4, goldfish: 6, trees: 5
Sue 327: akitas: 3, cars: 8, cats: 2
Sue 328: cats: 6, vizslas: 0, akitas: 2
Sue 329: perfumes: 3, goldfish: 10, akitas: 3
Sue 330: goldfish: 3, vizslas: 1, akitas: 6
Sue 331: perfumes: 4, trees: 1, goldfish: 5
Sue 332: goldfish: 7, vizslas: 9, akitas: 1
Sue 333: children: 8, cars: 8, trees: 4
Sue 334: cars: 1, vizslas: 6, trees: 0
Sue 335: goldfish: 2, cars: 2, akitas: 1
Sue 336: goldfish: 5, akitas: 5, trees: 9
Sue 337: cars: 5, vizslas: 6, goldfish: 6
Sue 338: cats: 9, akitas: 3, goldfish: 9
Sue 339: akitas: 3, cats: 2, children: 7
Sue 340: goldfish: 0, pomeranians: 8, perfumes: 9
Sue 341: trees: 0, pomeranians: 1, goldfish: 5
Sue 342: goldfish: 10, trees: 3, vizslas: 4
Sue 343: cats: 3, samoyeds: 1, children: 6
Sue 344: perfumes: 3, children: 4, samoyeds: 2
Sue 345: children: 6, trees: 2, goldfish: 1
Sue 346: trees: 2, pomeranians: 3, goldfish: 5
Sue 347: akitas: 10, vizslas: 7, trees: 1
Sue 348: perfumes: 4, akitas: 2, vizslas: 7
Sue 349: perfumes: 8, goldfish: 3, vizslas: 5
Sue 350: trees: 4, pomeranians: 5, akitas: 10
Sue 351: perfumes: 5, cars: 9, trees: 0
Sue 352: akitas: 6, children: 8, trees: 10
Sue 353: samoyeds: 7, akitas: 6, vizslas: 4
Sue 354: children: 9, goldfish: 7, perfumes: 5
Sue 355: trees: 1, perfumes: 4, cars: 1
Sue 356: samoyeds: 1, perfumes: 4, pomeranians: 8
Sue 357: trees: 7, goldfish: 10, akitas: 0
Sue 358: akitas: 1, vizslas: 6, cars: 7
Sue 359: vizslas: 3, goldfish: 8, trees: 4
Sue 360: akitas: 10, vizslas: 2, trees: 3
Sue 361: samoyeds: 6, pomeranians: 1, perfumes: 0
Sue 362: samoyeds: 3, cars: 1, trees: 0
Sue 363: vizslas: 0, pomeranians: 9, akitas: 4
Sue 364: perfumes: 9, pomeranians: 8, vizslas: 9
Sue 365: vizslas: 7, cars: 4, perfumes: 10
Sue 366: cars: 0, samoyeds: 5, goldfish: 10
Sue 367: children: 4, vizslas: 5, akitas: 4
Sue 368: samoyeds: 9, perfumes: 4, vizslas: 6
Sue 369: perfumes: 5, cars: 4, samoyeds: 5
Sue 370: akitas: 3, vizslas: 2, perfumes: 1
Sue 371: cars: 8, cats: 7, children: 5
Sue 372: vizslas: 9, perfumes: 2, akitas: 10
Sue 373: trees: 10, pomeranians: 9, goldfish: 3
Sue 374: children: 4, cars: 10, perfumes: 2
Sue 375: children: 7, samoyeds: 5, cats: 0
Sue 376: akitas: 10, samoyeds: 5, vizslas: 5
Sue 377: goldfish: 8, trees: 3, perfumes: 3
Sue 378: goldfish: 10, vizslas: 0, perfumes: 2
Sue 379: trees: 1, vizslas: 7, pomeranians: 4
Sue 380: samoyeds: 8, vizslas: 3, trees: 2
Sue 381: goldfish: 2, perfumes: 5, samoyeds: 9
Sue 382: cats: 3, vizslas: 10, akitas: 5
Sue 383: cars: 7, goldfish: 5, akitas: 8
Sue 384: children: 6, goldfish: 10, trees: 1
Sue 385: cats: 2, akitas: 6, samoyeds: 7
Sue 386: cars: 10, children: 4, goldfish: 2
Sue 387: cats: 0, perfumes: 5, akitas: 9
Sue 388: pomeranians: 7, akitas: 0, samoyeds: 9
Sue 389: trees: 0, akitas: 9, vizslas: 8
Sue 390: cars: 0, trees: 10, perfumes: 9
Sue 391: cats: 9, goldfish: 10, perfumes: 10
Sue 392: cars: 3, vizslas: 6, cats: 3
Sue 393: vizslas: 10, perfumes: 4, goldfish: 5
Sue 394: perfumes: 4, akitas: 10, trees: 2
Sue 395: pomeranians: 5, cars: 4, perfumes: 3
Sue 396: pomeranians: 9, vizslas: 5, akitas: 2
Sue 397: cars: 10, goldfish: 8, trees: 2
Sue 398: perfumes: 7, children: 9, goldfish: 9
Sue 399: akitas: 6, cats: 2, goldfish: 7
Sue 400: goldfish: 9, perfumes: 0, cars: 2
Sue 401: children: 4, vizslas: 0, trees: 2
Sue 402: akitas: 4, cars: 8, pomeranians: 4
Sue 403: vizslas: 8, perfumes: 7, goldfish: 1
Sue 404: goldfish: 10, samoyeds: 7, vizslas: 3
Sue 405: akitas: 1, vizslas: 6, perfumes: 6
Sue 406: pomeranians: 8, goldfish: 6, cats: 3
Sue 407: goldfish: 2, vizslas: 4, akitas: 7
Sue 408: cars: 10, perfumes: 10, vizslas: 3
Sue 409: vizslas: 7, pomeranians: 4, perfumes: 4
Sue 410: goldfish: 4, vizslas: 7, trees: 5
Sue 411: cars: 8, trees: 0, goldfish: 4
Sue 412: cars: 8, perfumes: 5, vizslas: 4
Sue 413: vizslas: 3, akitas: 7, samoyeds: 6
Sue 414: trees: 0, perfumes: 6, cars: 10
Sue 415: pomeranians: 4, trees: 1, perfumes: 6
Sue 416: cars: 10, perfumes: 6, akitas: 2
Sue 417: perfumes: 6, samoyeds: 0, akitas: 0
Sue 418: children: 1, perfumes: 9, vizslas: 3
Sue 419: goldfish: 9, samoyeds: 3, perfumes: 8
Sue 420: goldfish: 4, cars: 10, vizslas: 7
Sue 421: samoyeds: 7, vizslas: 7, cats: 2
Sue 422: trees: 1, goldfish: 8, perfumes: 0
Sue 423: cars: 3, perfumes: 2, trees: 3
Sue 424: samoyeds: 6, vizslas: 0, akitas: 6
Sue 425: trees: 3, akitas: 7, goldfish: 1
Sue 426: cars: 9, trees: 1, perfumes: 0
Sue 427: pomeranians: 0, children: 5, perfumes: 8
Sue 428: cars: 0, perfumes: 6, children: 4
Sue 429: akitas: 7, pomeranians: 9, cats: 6
Sue 430: cats: 6, trees: 1, cars: 0
Sue 431: children: 8, akitas: 5, perfumes: 9
Sue 432: perfumes: 5, akitas: 10, trees: 9
Sue 433: akitas: 4, perfumes: 10, vizslas: 7
Sue 434: trees: 3, children: 10, samoyeds: 4
Sue 435: vizslas: 5, goldfish: 2, akitas: 2
Sue 436: samoyeds: 3, trees: 2, cars: 6
Sue 437: children: 9, akitas: 0, pomeranians: 3
Sue 438: perfumes: 10, akitas: 2, cars: 7
Sue 439: perfumes: 10, samoyeds: 6, akitas: 10
Sue 440: vizslas: 10, trees: 2, akitas: 8
Sue 441: perfumes: 8, akitas: 2, pomeranians: 7
Sue 442: cars: 8, trees: 3, goldfish: 6
Sue 443: cars: 1, goldfish: 5, vizslas: 5
Sue 444: vizslas: 2, akitas: 10, samoyeds: 4
Sue 445: vizslas: 2, akitas: 10, perfumes: 9
Sue 446: akitas: 3, vizslas: 8, goldfish: 1
Sue 447: vizslas: 7, pomeranians: 5, trees: 10
Sue 448: cats: 6, perfumes: 10, children: 6
Sue 449: trees: 2, cars: 5, goldfish: 8
Sue 450: trees: 0, goldfish: 6, samoyeds: 3
Sue 451: perfumes: 0, cars: 8, trees: 1
Sue 452: akitas: 4, trees: 8, perfumes: 9
Sue 453: goldfish: 1, perfumes: 7, akitas: 6
Sue 454: vizslas: 3, cars: 1, perfumes: 6
Sue 455: trees: 1, akitas: 7, goldfish: 10
Sue 456: samoyeds: 4, vizslas: 2, cars: 9
Sue 457: perfumes: 10, children: 1, trees: 8
Sue 458: perfumes: 0, vizslas: 9, cars: 8
Sue 459: cats: 0, children: 7, trees: 3
Sue 460: vizslas: 4, cats: 6, perfumes: 2
Sue 461: trees: 3, children: 5, cars: 8
Sue 462: goldfish: 7, vizslas: 7, children: 5
Sue 463: cars: 5, akitas: 3, goldfish: 5
Sue 464: vizslas: 0, pomeranians: 5, cars: 0
Sue 465: goldfish: 4, akitas: 0, cats: 5
Sue 466: cars: 5, trees: 1, goldfish: 6
Sue 467: perfumes: 10, trees: 8, cars: 1
Sue 468: perfumes: 4, akitas: 3, cars: 0
Sue 469: vizslas: 3, cars: 7, pomeranians: 1
Sue 470: perfumes: 1, vizslas: 7, akitas: 8
Sue 471: goldfish: 10, samoyeds: 10, pomeranians: 5
Sue 472: goldfish: 6, trees: 0, perfumes: 0
Sue 473: goldfish: 5, vizslas: 0, children: 5
Sue 474: cars: 3, vizslas: 7, perfumes: 10
Sue 475: vizslas: 5, trees: 9, goldfish: 8
Sue 476: akitas: 2, goldfish: 6, children: 7
Sue 477: samoyeds: 0, perfumes: 1, pomeranians: 5
Sue 478: trees: 2, goldfish: 9, vizslas: 0
Sue 479: perfumes: 1, cars: 6, goldfish: 9
Sue 480: pomeranians: 3, perfumes: 5, trees: 9
Sue 481: cats: 3, akitas: 0, vizslas: 8
Sue 482: pomeranians: 10, akitas: 8, trees: 5
Sue 483: goldfish: 6, akitas: 10, perfumes: 2
Sue 484: cats: 0, goldfish: 0, children: 9
Sue 485: children: 4, akitas: 10, vizslas: 8
Sue 486: vizslas: 3, goldfish: 9, children: 10
Sue 487: children: 8, cats: 6, vizslas: 10
Sue 488: cars: 7, akitas: 10, samoyeds: 5
Sue 489: vizslas: 9, akitas: 6, trees: 2
Sue 490: vizslas: 5, akitas: 1, children: 5
Sue 491: vizslas: 8, goldfish: 3, perfumes: 6
Sue 492: trees: 3, samoyeds: 1, pomeranians: 6
Sue 493: akitas: 1, vizslas: 5, cars: 8
Sue 494: akitas: 4, cars: 4, vizslas: 9
Sue 495: vizslas: 1, akitas: 2, cats: 2
Sue 496: trees: 7, vizslas: 5, akitas: 6
Sue 497: akitas: 8, trees: 2, perfumes: 6
Sue 498: akitas: 1, trees: 1, samoyeds: 4
Sue 499: cars: 0, akitas: 5, vizslas: 3
Sue 500: cats: 2, goldfish: 9, children: 8

View File

@ -0,0 +1,20 @@
11
30
47
31
32
36
3
1
5
3
32
36
15
11
46
26
28
1
19
3

View File

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

View File

@ -0,0 +1,45 @@
Al => ThF
Al => ThRnFAr
B => BCa
B => TiB
B => TiRnFAr
Ca => CaCa
Ca => PB
Ca => PRnFAr
Ca => SiRnFYFAr
Ca => SiRnMgAr
Ca => SiTh
F => CaF
F => PMg
F => SiAl
H => CRnAlAr
H => CRnFYFYFAr
H => CRnFYMgAr
H => CRnMgYFAr
H => HCa
H => NRnFYFAr
H => NRnMgAr
H => NTh
H => OB
H => ORnFAr
Mg => BF
Mg => TiMg
N => CRnFAr
N => HSi
O => CRnFYFAr
O => CRnMgAr
O => HP
O => NRnFAr
O => OTi
P => CaP
P => PTi
P => SiRnFAr
Si => CaSi
Th => ThCa
Ti => BP
Ti => TiTi
e => HF
e => NAl
e => OMg
CRnCaSiRnBSiRnFArTiBPTiTiBFArPBCaSiThSiRnTiBPBPMgArCaSiRnTiMgArCaSiThCaSiRnFArRnSiRnFArTiTiBFArCaCaSiRnSiThCaCaSiRnMgArFYSiRnFYCaFArSiThCaSiThPBPTiMgArCaPRnSiAlArPBCaCaSiRnFYSiThCaRnFArArCaCaSiRnPBSiRnFArMgYCaCaCaCaSiThCaCaSiAlArCaCaSiRnPBSiAlArBCaCaCaCaSiThCaPBSiThPBPBCaSiRnFYFArSiThCaSiRnFArBCaCaSiRnFYFArSiThCaPBSiThCaSiRnPMgArRnFArPTiBCaPRnFArCaCaCaCaSiRnCaCaSiRnFYFArFArBCaSiThFArThSiThSiRnTiRnPMgArFArCaSiThCaPBCaSiRnBFArCaCaPRnCaCaPMgArSiRnFYFArCaSiThRnPBPMgAr

View File

@ -0,0 +1,3 @@
Hit Points: 103
Damage: 9
Armor: 2

View File

@ -0,0 +1,2 @@
Hit Points: 71
Damage: 10

View File

@ -14,7 +14,8 @@ fn part1() {
} }
fn part2() { fn part2() {
let root = env!("CARGO_MANIFEST_DIR"); //let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/15_input.txt")).unwrap(); //let content = fs::read_to_string(format!("{root}/resources/15_input.txt")).unwrap();
println!("{}", d15::process_part2(&content)); // change comments in part1
//println!("{}", d15::process_part2(&content));
} }

20
y2015/src/bin/d16.rs Normal file
View File

@ -0,0 +1,20 @@
use std::fs;
use y2015::days::d16;
fn main() {
part1();
part2();
}
fn part1() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/16_input.txt")).unwrap();
println!("{}", d16::process_part1(&content));
}
fn part2() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/16_input.txt")).unwrap();
println!("{}", d16::process_part2(&content));
}

20
y2015/src/bin/d17.rs Normal file
View File

@ -0,0 +1,20 @@
use std::fs;
use y2015::days::d17;
fn main() {
part1();
part2();
}
fn part1() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/17_input.txt")).unwrap();
println!("{}", d17::process_part1(&content, 150));
}
fn part2() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/17_input.txt")).unwrap();
println!("{}", d17::process_part2(&content, 150));
}

20
y2015/src/bin/d18.rs Normal file
View File

@ -0,0 +1,20 @@
use std::fs;
use y2015::days::d18;
fn main() {
part1();
part2();
}
fn part1() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/18_input.txt")).unwrap();
println!("{}", d18::process_part1(&content, 100));
}
fn part2() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/18_input.txt")).unwrap();
println!("{}", d18::process_part2(&content, 100));
}

20
y2015/src/bin/d19.rs Normal file
View File

@ -0,0 +1,20 @@
use std::fs;
use y2015::days::d19;
fn main() {
part1();
part2();
}
fn part1() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/19_input.txt")).unwrap();
println!("{}", d19::process_part1(&content));
}
fn part2() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/19_input.txt")).unwrap();
println!("{}", d19::process_part2(&content));
}

14
y2015/src/bin/d20.rs Normal file
View File

@ -0,0 +1,14 @@
use y2015::days::d20;
fn main() {
part1();
part2();
}
fn part1() {
println!("{}", d20::process_part1(36000000));
}
fn part2() {
println!("{}", d20::process_part2(36000000));
}

20
y2015/src/bin/d21.rs Normal file
View File

@ -0,0 +1,20 @@
use std::fs;
use y2015::days::d21;
fn main() {
part1();
part2();
}
fn part1() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/21_input.txt")).unwrap();
println!("{}", d21::process_part1(&content));
}
fn part2() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/21_input.txt")).unwrap();
println!("{}", d21::process_part2(&content));
}

20
y2015/src/bin/d22.rs Normal file
View File

@ -0,0 +1,20 @@
use std::fs;
use y2015::days::d22;
fn main() {
part1();
part2();
}
fn part1() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/22_input.txt")).unwrap();
println!("{}", d22::process_part1(&content));
}
fn part2() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/22_input.txt")).unwrap();
println!("{}", d22::process_part2(&content));
}

View File

@ -71,11 +71,11 @@ fn permutation(mut people: Vec<String>, nth: usize) -> Result<Vec<String>, Box<d
return Err(Box::from("Out of bounds")); return Err(Box::from("Out of bounds"));
} }
let mut perm = Vec::new(); let mut perm = Vec::new();
let num_unique_locations = people.len(); let num_unique_people = people.len();
let mut remainder = nth - 1; let mut remainder = nth - 1;
for idx in 1..=people.len() { for idx in 1..=people.len() {
let permutations = remainder / factorial(num_unique_locations - idx); let permutations = remainder / factorial(num_unique_people - idx);
remainder %= factorial(num_unique_locations - idx); remainder %= factorial(num_unique_people - idx);
perm.push(people[permutations].clone()); perm.push(people[permutations].clone());
people.remove(permutations); people.remove(permutations);
} }

View File

@ -173,10 +173,6 @@ pub fn process_part1(input: &str) -> i64 {
biggest_score biggest_score
} }
pub fn process_part2(input: &str) -> u32 {
0
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -189,10 +185,4 @@ Cinnamon: capacity 2, durability 3, flavor -2, texture -1, calories 3";
let result = process_part1(INPUT); let result = process_part1(INPUT);
assert_eq!(result, 62842880); assert_eq!(result, 62842880);
} }
#[test]
fn part2() {
let result = process_part2(INPUT);
assert_eq!(result, 0);
}
} }

61
y2015/src/days/d16.rs Normal file
View File

@ -0,0 +1,61 @@
use std::collections::HashMap;
const TAPE: &str = "children: 3
cats: 7
samoyeds: 2
pomeranians: 3
akitas: 0
vizslas: 0
goldfish: 5
trees: 3
cars: 2
perfumes: 1";
pub fn process_part1(input: &str) -> String {
let mut tape = HashMap::new();
TAPE.lines().for_each(|line| {
let (k, v) = line.split_once(": ").unwrap();
tape.insert(k, v.parse::<u32>().unwrap());
});
for line in input.lines() {
let (sue, params) = line.split_once(": ").unwrap();
let mut is_correct = true;
params.split(", ").for_each(|param| {
let (k, v) = param.split_once(": ").unwrap();
if v.parse::<u32>().unwrap() != *tape.get(k).unwrap() {
is_correct = false;
}
});
if is_correct {
return sue.to_string();
}
}
"".to_string()
}
pub fn process_part2(input: &str) -> String {
let mut tape = HashMap::new();
TAPE.lines().for_each(|line| {
let (k, v) = line.split_once(": ").unwrap();
tape.insert(k, v.parse::<u32>().unwrap());
});
for line in input.lines() {
let (sue, params) = line.split_once(": ").unwrap();
let mut is_correct = true;
params.split(", ").for_each(|param| {
let (k, v) = param.split_once(": ").unwrap();
let v = v.parse::<u32>().unwrap();
let tape_value = *tape.get(k).unwrap();
if (["cats", "trees"].contains(&k) && v <= tape_value)
|| (["pomeranians", "goldfish"].contains(&k) && v >= tape_value)
|| (!["cats", "trees", "pomeranians", "goldfish"].contains(&k) && v != tape_value)
{
is_correct = false;
}
});
if is_correct {
return sue.to_string();
}
}
"".to_string()
}

113
y2015/src/days/d17.rs Normal file
View File

@ -0,0 +1,113 @@
use std::{error::Error, fmt::Debug};
pub fn process_part1(input: &str, litres: u32) -> u32 {
let containers = input
.lines()
.map(|container| container.parse::<u32>().unwrap())
.collect::<Vec<u32>>();
let mut correct_combinations = Vec::new();
for k in 1..=containers.len() {
let num_combinations = binomial(containers.len(), k);
for i in 1..=num_combinations {
let res = combination(containers.clone(), k, i).unwrap();
if res.iter().sum::<u32>() == litres {
correct_combinations.push(res);
}
}
}
correct_combinations.len() as u32
}
pub fn process_part2(input: &str, litres: u32) -> u32 {
let containers = input
.lines()
.map(|container| container.parse::<u32>().unwrap())
.collect::<Vec<u32>>();
let mut correct_combinations = Vec::new();
for k in 1..=containers.len() {
let num_combinations = binomial(containers.len(), k);
for i in 1..=num_combinations {
let res = combination(containers.clone(), k, i).unwrap();
if res.iter().sum::<u32>() == litres {
correct_combinations.push(res);
}
}
if !correct_combinations.is_empty() {
break;
}
}
correct_combinations.len() as u32
}
fn combination<T: Clone + Debug>(
elements: Vec<T>,
k: usize,
nth: usize,
) -> Result<Vec<T>, Box<dyn Error>> {
let num_elements = elements.len();
let num_combinations = binomial(num_elements, k);
if nth > num_combinations || k > num_elements || nth == 0 || k == 0 {
return Err(Box::from("Out of bounds"));
}
let mut i = 0;
let mut remaining_k = k;
let mut comb = Vec::new();
let mut remainder = nth - 1;
while remaining_k > 0 {
// Count the number of combinations that start with elements[i]
// example with n = 5, k = 2
// nth <= 4 select first
// nth <= 7 select second
// nth <= 9 select third
// nth == 10 select fourth
let count = binomial(num_elements - i - 1, remaining_k - 1);
if remainder < count {
// If the nth combination is within the count, pick this element
comb.push(elements[i].clone());
remaining_k -= 1;
} else {
remainder -= count;
}
i += 1;
}
Ok(comb)
}
fn factorial(num: usize) -> usize {
let mut fact = 1;
for n in 1..=num {
fact *= n;
}
fact
}
fn binomial(n: usize, k: usize) -> usize {
if k > n {
0
} else {
factorial(n) / (factorial(k) * factorial(n - k))
}
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &str = "20
15
10
5
5";
#[test]
fn part1() {
let result = process_part1(INPUT, 25);
assert_eq!(result, 4);
}
#[test]
fn part2() {
let result = process_part2(INPUT, 25);
assert_eq!(result, 3);
}
}

179
y2015/src/days/d18.rs Normal file
View File

@ -0,0 +1,179 @@
use core::panic;
pub fn process_part1(input: &str, steps: u32) -> i32 {
let mut grid = input
.lines()
.map(|line| line.chars().map(Light::from).collect::<Vec<Light>>())
.collect::<Vec<Vec<Light>>>();
let height = grid.len();
let width = grid[0].len();
let mut new_grid = vec![vec![Light::Off; width]; height];
for _step in 0..steps {
for (y, grid_line) in grid.iter().enumerate() {
for (x, light) in grid_line.iter().enumerate() {
let neighbors = Light::get_neighbors(grid.clone(), (x, y));
new_grid[y][x] = light.new_state(neighbors);
}
}
grid = new_grid.clone();
}
grid.iter()
.map(|line| {
line.iter()
.map(|&light| if light == Light::On { 1 } else { 0 })
.sum::<i32>()
})
.sum()
}
pub fn process_part2(input: &str, steps: u32) -> i32 {
let mut grid = input
.lines()
.map(|line| line.chars().map(Light::from).collect::<Vec<Light>>())
.collect::<Vec<Vec<Light>>>();
let height = grid.len();
let width = grid[0].len();
let corners = vec![
(0, 0),
(width - 1, 0),
(0, height - 1),
(width - 1, height - 1),
];
for (corner_x, corner_y) in corners.clone() {
grid[corner_y][corner_x] = Light::On;
}
let mut new_grid = vec![vec![Light::Off; width]; height];
for _step in 0..steps {
for (y, grid_line) in grid.iter().enumerate() {
for (x, light) in grid_line.iter().enumerate() {
let neighbors = Light::get_neighbors(grid.clone(), (x, y));
new_grid[y][x] = light.new_state(neighbors);
}
}
grid = new_grid.clone();
for (corner_x, corner_y) in corners.clone() {
grid[corner_y][corner_x] = Light::On;
}
}
grid.iter()
.map(|line| {
line.iter()
.map(|&light| if light == Light::On { 1 } else { 0 })
.sum::<i32>()
})
.sum()
}
#[derive(Clone, Copy, PartialEq, Eq)]
enum Light {
On,
Off,
}
impl Light {
fn new_state(self, neighbors: Vec<Light>) -> Self {
let mut light = self;
match self {
Light::On => {
if ![2, 3].contains(&Self::count_on(neighbors)) {
light = Light::Off;
}
}
Light::Off => {
if Self::count_on(neighbors) == 3 {
light = Light::On;
}
}
};
light
}
fn count_on(neighbors: Vec<Light>) -> u32 {
neighbors
.iter()
.map(|&light| if light == Light::On { 1 } else { 0 })
.sum()
}
fn get_neighbors(grid: Vec<Vec<Light>>, coords: (usize, usize)) -> Vec<Light> {
let relative_coords = vec![
(-1, -1),
(0, -1),
(1, -1),
(-1, 0),
(1, 0),
(-1, 1),
(0, 1),
(1, 1),
];
let height = grid.len();
let width = grid[0].len();
let (x, y) = coords;
let mut neighbors = Vec::new();
for (relative_x, relative_y) in relative_coords {
let neighbor_x = x.checked_add_signed(relative_x);
if neighbor_x.is_none() {
continue;
}
let neighbor_x = neighbor_x.unwrap();
let neighbor_y = y.checked_add_signed(relative_y);
if neighbor_y.is_none() {
continue;
}
let neighbor_y = neighbor_y.unwrap();
if neighbor_x >= width || neighbor_y >= height {
continue;
}
neighbors.push(grid[neighbor_y][neighbor_x]);
}
neighbors
}
}
impl From<char> for Light {
fn from(value: char) -> Self {
match value {
'#' => Light::On,
'.' => Light::Off,
_ => panic!("Wrong character"),
}
}
}
#[allow(unused)]
fn print_grid(grid: Vec<Vec<Light>>) {
grid.iter().for_each(|line| {
line.iter().for_each(|&light| {
if light == Light::On {
print!("#");
} else {
print!(".");
}
});
println!();
});
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &str = ".#.#.#
...##.
#....#
..#...
#.#..#
####..";
#[test]
fn part1() {
let result = process_part1(INPUT, 4);
assert_eq!(result, 4);
}
#[test]
fn part2() {
let result = process_part2(INPUT, 5);
assert_eq!(result, 17);
}
}

110
y2015/src/days/d19.rs Normal file
View File

@ -0,0 +1,110 @@
use std::collections::HashSet;
pub fn process_part1(input: &str) -> u32 {
let (replacements_str, molecule) = input.split_once("\n\n").unwrap();
let mut replacements = Vec::new();
replacements_str.lines().for_each(|line| {
let (from, to) = line.split_once(" => ").unwrap();
replacements.push((from, to));
});
let mut possible = HashSet::new();
for (from, to) in replacements {
molecule.match_indices(from).for_each(|(idx, _)| {
let mut new_possible = molecule.to_string();
new_possible.replace_range(idx..(idx + from.len()), to);
possible.insert(new_possible);
});
}
possible.len() as u32
}
// https://www.reddit.com/r/adventofcode/comments/3xflz8/comment/cy4etju/
// broken test
//First insight
//
//There are only two types of productions:
//
// e => XX and X => XX (X is not Rn, Y, or Ar)
//
// X => X Rn X Ar | X Rn X Y X Ar | X Rn X Y X Y X Ar
//
//Second insight
//
//You can think of Rn Y Ar as the characters ( , ):
//
//X => X(X) | X(X,X) | X(X,X,X)
//
//Whenever there are two adjacent "elements" in your "molecule", you apply the first production. This reduces your molecule length by 1 each time.
//
//And whenever you have T(T) T(T,T) or T(T,T,T) (T is a literal token such as "Mg", i.e. not a nonterminal like "TiTiCaCa"), you apply the second production. This reduces your molecule length by 3, 5, or 7.
//Third insight
//
//Repeatedly applying X => XX until you arrive at a single token takes count(tokens) - 1 steps:
//
//ABCDE => XCDE => XDE => XE => X
//count("ABCDE") = 5
//5 - 1 = 4 steps
//
//Applying X => X(X) is similar to X => XX, except you get the () for free. This can be expressed as count(tokens) - count("(" or ")") - 1.
//
//A(B(C(D(E)))) => A(B(C(X))) => A(B(X)) => A(X) => X
//count("A(B(C(D(E))))") = 13
//count("(((())))") = 8
//13 - 8 - 1 = 4 steps
//
//You can generalize to X => X(X,X) by noting that each , reduces the length by two (,X). The new formula is count(tokens) - count("(" or ")") - 2*count(",") - 1.
//
//A(B(C,D),E(F,G)) => A(B(C,D),X) => A(X,X) => X
//count("A(B(C,D),E(F,G))") = 16
//count("(()())") = 6
//count(",,,") = 3
//16 - 6 - 2*3 - 1 = 3 steps
//
//This final formula works for all of the production types (for X => XX, the (,) counts are zero by definition.)
pub fn process_part2(input: &str) -> u32 {
let (_replacements_str, molecule) = input.split_once("\n\n").unwrap();
// An element is always at least an uppercase character and possibly an additional lowercase
// character
let total_elements = molecule.chars().filter(|char| char.is_uppercase()).count();
let num_rn = molecule.matches("Rn").count();
let num_ar = molecule.matches("Ar").count();
let num_y = molecule.matches("Y").count();
(total_elements - (num_rn + num_ar) - 2 * num_y - 1) as u32
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT1: &str = "H => HO
H => OH
O => HH
e => H
e => O
HOH";
const INPUT2: &str = "H => HO
H => OH
O => HH
e => H
e => O
HOHOHO";
#[test]
fn part1() {
let result = process_part1(INPUT1);
assert_eq!(result, 4);
let result = process_part1(INPUT2);
assert_eq!(result, 7);
}
#[test]
fn part2() {
let result = process_part2(INPUT1);
assert_eq!(result, 3);
let result = process_part2(INPUT2);
assert_eq!(result, 6);
}
}

70
y2015/src/days/d20.rs Normal file
View File

@ -0,0 +1,70 @@
pub fn process_part1(input: u32) -> u32 {
// slow
//let mut house = 1;
//loop {
// let mut presents = 0;
// for elf in 1..=house {
// if house % elf == 0 {
// presents += elf * 10;
// println!("{house} {presents}");
// }
// }
// if presents >= input {
// break;
// }
// house += 1;
//}
//house
let mut house = 0;
loop {
house += 1;
let mut divisors = get_divisors(house);
divisors.push(house);
if divisors.iter().sum::<usize>() * 10 >= input as usize {
break;
}
}
house as u32
}
fn get_divisors(n: usize) -> Vec<usize> {
let mut divisors = vec![1];
let mut potential_divisor = 2;
while (potential_divisor * potential_divisor) < n {
if n % potential_divisor == 0 {
divisors.push(potential_divisor);
divisors.push(n / potential_divisor);
}
potential_divisor += 1;
}
// This almost made me go mad
if potential_divisor * potential_divisor == n {
divisors.push(potential_divisor)
}
divisors
}
pub fn process_part2(input: u32) -> u32 {
let mut house = 0;
loop {
house += 1;
let mut divisors = get_divisors(house);
divisors.push(house);
let sum = divisors.iter().filter(|&&d| house / d <= 50).sum::<usize>();
if sum * 11 >= input as usize {
break;
}
}
house as u32
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1() {
let result = process_part1(100);
assert_eq!(result, 6);
}
}

269
y2015/src/days/d21.rs Normal file
View File

@ -0,0 +1,269 @@
use core::panic;
// 1 Weapon
// 0-1 Armor
// 0-2 Rings
const SHOP: &str = "Weapons: Cost Damage Armor
Dagger 8 4 0
Shortsword 10 5 0
Warhammer 25 6 0
Longsword 40 7 0
Greataxe 74 8 0
Armor: Cost Damage Armor
Leather 13 0 1
Chainmail 31 0 2
Splintmail 53 0 3
Bandedmail 75 0 4
Platemail 102 0 5
Rings: Cost Damage Armor
Damage +1 25 1 0
Damage +2 50 2 0
Damage +3 100 3 0
Defense +1 20 0 1
Defense +2 40 0 2
Defense +3 80 0 3";
pub fn process_part1(input: &str) -> u32 {
let player = Character {
hp: 100,
..Default::default()
};
let mut boss = Character::default();
input.lines().for_each(|line| {
let (attribute, value) = line.split_once(": ").unwrap();
match attribute {
"Hit Points" => {
boss.hp = value.parse::<u32>().unwrap();
}
"Damage" => {
boss.damage = value.parse::<u32>().unwrap();
}
"Armor" => {
boss.armor = value.parse::<u32>().unwrap();
}
_ => panic!("Should not happen"),
}
});
let mut weapons = Vec::new();
let mut armors = Vec::new();
let mut rings = Vec::new();
SHOP.split("\n\n").for_each(|category| {
let mut items = category.lines();
let (category_name, _) = items.next().unwrap().split_once(":").unwrap();
let item_vec = items
.map(|item| {
let item_vec = item.split_whitespace().collect::<Vec<&str>>();
let cols = item_vec.len();
let mut name = item_vec[0].to_string();
if item_vec[1].contains("+") {
name.push_str(item_vec[1]);
}
Item {
name,
cost: item_vec[cols - 3].parse::<u32>().unwrap(),
damage: item_vec[cols - 2].parse::<u32>().unwrap(),
armor: item_vec[cols - 1].parse::<u32>().unwrap(),
}
})
.collect::<Vec<Item>>();
match category_name {
"Weapons" => weapons = item_vec,
"Armor" => armors = item_vec,
"Rings" => rings = item_vec,
_ => panic!("Should not happen"),
}
});
//println!("{weapons:#?}");
//println!("{armors:#?}");
//println!("{rings:#?}");
rings.sort_by(|ring_a, ring_b| ring_a.cost.cmp(&ring_b.cost));
let choices = create_item_choices(weapons, armors, rings);
let mut lowest_cost = u32::MAX;
for (weapon, armor, rings) in choices {
let mut current_player = player;
current_player.equip(weapon);
if let Some(armor) = armor {
current_player.equip(armor);
}
if !rings.is_empty() {
for ring in rings {
current_player.equip(ring);
}
}
if current_player.wins_against(&boss) && current_player.items_value < lowest_cost {
lowest_cost = current_player.items_value;
}
}
lowest_cost
}
pub fn process_part2(input: &str) -> u32 {
let player = Character {
hp: 100,
..Default::default()
};
let mut boss = Character::default();
input.lines().for_each(|line| {
let (attribute, value) = line.split_once(": ").unwrap();
match attribute {
"Hit Points" => {
boss.hp = value.parse::<u32>().unwrap();
}
"Damage" => {
boss.damage = value.parse::<u32>().unwrap();
}
"Armor" => {
boss.armor = value.parse::<u32>().unwrap();
}
_ => panic!("Should not happen"),
}
});
let mut weapons = Vec::new();
let mut armors = Vec::new();
let mut rings = Vec::new();
SHOP.split("\n\n").for_each(|category| {
let mut items = category.lines();
let (category_name, _) = items.next().unwrap().split_once(":").unwrap();
let item_vec = items
.map(|item| {
let item_vec = item.split_whitespace().collect::<Vec<&str>>();
let cols = item_vec.len();
let mut name = item_vec[0].to_string();
if item_vec[1].contains("+") {
name.push_str(item_vec[1]);
}
Item {
name,
cost: item_vec[cols - 3].parse::<u32>().unwrap(),
damage: item_vec[cols - 2].parse::<u32>().unwrap(),
armor: item_vec[cols - 1].parse::<u32>().unwrap(),
}
})
.collect::<Vec<Item>>();
match category_name {
"Weapons" => weapons = item_vec,
"Armor" => armors = item_vec,
"Rings" => rings = item_vec,
_ => panic!("Should not happen"),
}
});
//println!("{weapons:#?}");
//println!("{armors:#?}");
//println!("{rings:#?}");
rings.sort_by(|ring_a, ring_b| ring_a.cost.cmp(&ring_b.cost));
let choices = create_item_choices(weapons, armors, rings);
let mut highest_cost = 0;
for (weapon, armor, rings) in choices {
let mut current_player = player;
current_player.equip(weapon);
if let Some(armor) = armor {
current_player.equip(armor);
}
if !rings.is_empty() {
for ring in rings {
current_player.equip(ring);
}
}
if !current_player.wins_against(&boss) && current_player.items_value > highest_cost {
highest_cost = current_player.items_value;
}
}
highest_cost
}
fn create_item_choices(
weapons: Vec<Item>,
armors: Vec<Item>,
rings: Vec<Item>,
) -> Vec<(Item, Option<Item>, Vec<Item>)> {
let mut choices = Vec::new();
for weapon in &weapons {
choices.push((weapon.clone(), None, vec![]));
for armor in &armors {
choices.push((weapon.clone(), Some(armor.clone()), vec![]));
for ring1 in &rings {
choices.push((weapon.clone(), Some(armor.clone()), vec![ring1.clone()]));
for ring2 in &rings {
if ring2.name == ring1.name {
continue;
}
choices.push((
weapon.clone(),
Some(armor.clone()),
vec![ring1.clone(), ring2.clone()],
));
}
}
}
for ring1 in &rings {
choices.push((weapon.clone(), None, vec![ring1.clone()]));
for ring2 in &rings {
if ring2.name == ring1.name {
continue;
}
choices.push((weapon.clone(), None, vec![ring1.clone(), ring2.clone()]));
}
}
}
choices
}
#[derive(Debug, Clone)]
struct Item {
name: String,
cost: u32,
damage: u32,
armor: u32,
}
#[derive(Debug, Default, Clone, Copy)]
struct Character {
hp: u32,
damage: u32,
armor: u32,
items_value: u32,
}
impl Character {
fn hit_damage(&self, other: &Self) -> u32 {
let damage = self.damage.saturating_sub(other.armor);
if damage > 0 {
damage
} else {
1
}
}
fn wins_against(&self, other: &Self) -> bool {
let damage_to_other = self.hit_damage(other);
let mut turns_to_win = other.hp / damage_to_other;
if other.hp % damage_to_other != 0 {
turns_to_win += 1;
}
let damage_to_self = other.hit_damage(self);
let mut turns_to_lose = self.hp / damage_to_self;
if self.hp % damage_to_self != 0 {
turns_to_lose += 1;
}
turns_to_win <= turns_to_lose
}
fn equip(&mut self, item: Item) {
self.damage += item.damage;
self.armor += item.armor;
self.items_value += item.cost;
}
}

472
y2015/src/days/d22.rs Normal file
View File

@ -0,0 +1,472 @@
use core::panic;
pub fn process_part1(input: &str) -> u32 {
let mut boss = Character::default();
input.lines().for_each(|line| {
let (attribute, value) = line.split_once(": ").unwrap();
if attribute == "Hit Points" {
boss.hp = value.parse::<u32>().unwrap();
} else if attribute == "Damage" {
boss.damage = value.parse::<u32>().unwrap();
}
});
let player = Character {
hp: 50,
mana: 500,
..Default::default()
};
// Initial state, nothing happened yet
let start = RoundNode {
player,
boss,
spent_mana: 0,
state: State::Playing,
};
let mut smallest = u32::MAX;
let mut leafs = vec![start];
let mut test = 0;
println!("start");
loop {
println!("iter: {test},");
let current_leafs = leafs.clone();
println!("leaf count: {}", current_leafs.len());
leafs.clear();
// create potential rounds
for leaf in current_leafs {
if leaf.state == State::Playing {
//println!("try for leaf");
for spell in Spell::get_all() {
leafs.push(leaf.use_spell(spell));
}
}
}
for leaf in &leafs {
if leaf.state == State::Win && leaf.spent_mana < smallest {
smallest = leaf.spent_mana;
}
//println!(
// "player hp: {}, boss hp: {}, spent mana so far: {}",
// leaf.player.hp, leaf.boss.hp, leaf.spent_mana
//);
}
leafs = leafs
.clone()
.iter()
.filter(|&leaf| leaf.state == State::Playing || leaf.spent_mana <= smallest)
.map(|leaf| leaf.to_owned())
.collect();
if leafs.is_empty() {
break;
}
// already know it's higher than this
if smallest <= 2000 {
let mut count_losses = 0;
for leaf in leafs {
if leaf.state == State::Loss {
count_losses += 1;
}
}
println!("Losses: {count_losses}");
break;
}
test += 1;
println!(" smallest: {smallest}");
}
smallest
}
pub fn process_part2(input: &str) -> u32 {
0
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum State {
Playing,
Win,
Loss,
}
#[derive(Debug, Clone)]
struct RoundNode {
player: Character,
boss: Character,
spent_mana: u32,
state: State,
}
impl RoundNode {
fn use_spell(&self, spell: Spell) -> RoundNode {
if self.state != State::Playing {
eprintln!("State: {:#?}", self.state);
eprintln!("spell: {spell:#?}");
panic!("State should be Playing");
}
let mut player = self.player.clone();
let mut boss = self.boss.clone();
// Player turn
for effect in player.status_effects.iter_mut() {
if effect.name == SpellID::Recharge {
player.mana += effect.mana;
}
effect.duration -= 1;
if effect.duration > 0 && effect.name == SpellID::Shield {
player.armor = effect.armor;
} else if effect.name == SpellID::Shield {
player.armor = 0;
}
}
for effect in boss.status_effects.iter_mut() {
boss.hp = boss.hp.saturating_sub(effect.damage);
effect.duration -= 1;
}
boss.status_effects = boss
.status_effects
.into_iter()
.filter(|&effect| effect.duration > 0)
.collect::<Vec<Spell>>();
if boss.hp == 0 {
return RoundNode {
player,
boss,
spent_mana: self.spent_mana,
state: State::Win,
};
}
player.status_effects = player
.status_effects
.into_iter()
.filter(|&effect| effect.duration > 0)
.collect::<Vec<Spell>>();
let used_mana = spell.cost;
let mut dmg = 0;
match spell.name {
SpellID::MagicMissile => {
player.mana = player.mana.saturating_sub(spell.cost);
dmg = spell.damage;
}
SpellID::Drain => {
player.mana = player.mana.saturating_sub(spell.cost);
dmg = spell.damage;
player.hp += spell.hp;
}
SpellID::Shield => {
player.mana = player.mana.saturating_sub(spell.cost);
player.status_effects.push(spell);
player.armor = spell.armor;
}
SpellID::Poison => {
player.mana = player.mana.saturating_sub(spell.cost);
boss.status_effects.push(spell);
}
SpellID::Recharge => {
player.mana = player.mana.saturating_sub(spell.cost);
player.status_effects.push(spell);
}
}
boss.hp = boss.hp.saturating_sub(dmg);
if boss.hp == 0 {
return RoundNode {
player,
boss,
spent_mana: used_mana + self.spent_mana,
state: State::Win,
};
}
if player.mana == 0 {
return RoundNode {
player,
boss,
spent_mana: used_mana + self.spent_mana,
state: State::Loss,
};
}
// Boss turn
for effect in player.status_effects.iter_mut() {
if effect.name == SpellID::Recharge {
player.mana += effect.mana;
}
effect.duration -= 1;
if effect.duration > 0 && effect.name == SpellID::Shield {
player.armor = effect.armor;
} else if effect.name == SpellID::Shield {
player.armor = 0;
}
}
player.status_effects = player
.status_effects
.into_iter()
.filter(|&effect| effect.duration > 0)
.collect::<Vec<Spell>>();
for effect in boss.status_effects.iter_mut() {
boss.hp = boss.hp.saturating_sub(effect.damage);
effect.duration -= 1;
}
if boss.hp == 0 {
return RoundNode {
player,
boss,
spent_mana: used_mana + self.spent_mana,
state: State::Win,
};
}
boss.status_effects = boss
.status_effects
.into_iter()
.filter(|&effect| effect.duration > 0)
.collect::<Vec<Spell>>();
let dmg = boss.hit_damage(&player);
player.hp = player.hp.saturating_sub(dmg);
if player.hp == 0 {
return RoundNode {
player,
boss,
spent_mana: used_mana + self.spent_mana,
state: State::Loss,
};
}
RoundNode {
player,
boss,
spent_mana: used_mana + self.spent_mana,
state: State::Playing,
}
}
//fn get_leafs(&self) -> Vec<RoundNode> {
// let mut leafs = Vec::new();
// match self.state {
// State::Playing => {
// if self.next_rounds.is_empty() {
// return vec![self.clone()];
// }
// let mut round_leafs = Vec::new();
// for round in self.next_rounds.clone() {
// round_leafs = round.get_leafs();
// }
// leafs.append(&mut round_leafs);
// leafs
// }
// State::Win => vec![self.clone()],
// State::Loss => vec![self.clone()],
// }
//}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum SpellID {
MagicMissile,
Drain,
Shield,
Poison,
Recharge,
}
#[derive(Debug, Clone, Copy)]
struct Spell {
name: SpellID,
hp: u32,
damage: u32,
mana: u32,
armor: u32,
duration: u32,
cost: u32,
}
impl Spell {
fn get_all() -> Vec<Spell> {
vec![
Spell {
name: SpellID::MagicMissile,
hp: 0,
damage: 4,
mana: 0,
armor: 0,
duration: 0,
cost: 53,
},
Spell {
name: SpellID::Drain,
hp: 2,
damage: 2,
mana: 0,
armor: 0,
duration: 0,
cost: 73,
},
Spell {
name: SpellID::Shield,
hp: 0,
damage: 0,
mana: 0,
armor: 7,
duration: 6,
cost: 113,
},
Spell {
name: SpellID::Poison,
hp: 0,
damage: 3,
mana: 0,
armor: 0,
duration: 6,
cost: 173,
},
Spell {
name: SpellID::Recharge,
hp: 0,
damage: 0,
mana: 101,
armor: 0,
duration: 5,
cost: 229,
},
]
}
}
#[derive(Debug, Default, Clone)]
struct Character {
hp: u32,
damage: u32,
armor: u32,
mana: u32,
status_effects: Vec<Spell>,
}
impl Character {
fn hit_damage(&self, other: &Self) -> u32 {
let damage = self.damage.saturating_sub(other.armor);
if damage > 0 {
damage
} else {
1
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_1() {
let boss = Character {
hp: 13,
damage: 8,
..Default::default()
};
let player = Character {
hp: 10,
mana: 250,
..Default::default()
};
// Initial state, nothing happened yet
let start = RoundNode {
player,
boss,
spent_mana: 0,
state: State::Playing,
};
let mut smallest = u32::MAX;
let mut leafs = vec![start];
let mut test = 0;
println!("start");
loop {
println!("iter: {test},");
let current_leafs = leafs.clone();
leafs.clear();
// create potential rounds
for leaf in current_leafs {
if leaf.state == State::Playing {
for spell in Spell::get_all() {
leafs.push(leaf.use_spell(spell));
}
}
}
let mut all_done = true;
for leaf in &leafs {
if leaf.state == State::Win && leaf.spent_mana < smallest {
smallest = leaf.spent_mana;
}
if leaf.state == State::Playing {
all_done = false;
}
println!(
"player hp: {}, boss hp: {}, spent mana so far: {}",
leaf.player.hp, leaf.boss.hp, leaf.spent_mana
);
}
if all_done {
break;
}
test += 1;
println!(" smallest: {smallest}");
}
assert_eq!(smallest, 226);
}
#[test]
fn part1_2() {
let boss = Character {
hp: 14,
damage: 8,
..Default::default()
};
let player = Character {
hp: 10,
mana: 250,
..Default::default()
};
// Initial state, nothing happened yet
let start = RoundNode {
player,
boss,
spent_mana: 0,
state: State::Playing,
};
let mut smallest = u32::MAX;
let mut leafs = vec![start];
let mut test = 0;
println!("start");
loop {
println!("iter: {test},");
let current_leafs = leafs.clone();
leafs.clear();
// create potential rounds
for leaf in current_leafs {
if leaf.state == State::Playing {
for spell in Spell::get_all() {
leafs.push(leaf.use_spell(spell));
}
}
}
let mut all_done = true;
for leaf in &leafs {
if leaf.state == State::Win && leaf.spent_mana < smallest {
smallest = leaf.spent_mana;
}
if leaf.state == State::Playing {
all_done = false;
}
println!(
"player hp: {}, boss hp: {}, spent mana so far: {}",
leaf.player.hp, leaf.boss.hp, leaf.spent_mana
);
}
if all_done {
break;
}
test += 1;
println!(" smallest: {smallest}");
}
assert_eq!(smallest, 641);
}
#[test]
fn part2() {
let result = process_part2("");
assert_eq!(result, 0);
}
}

View File

@ -5,6 +5,9 @@ pub mod d12;
pub mod d13; pub mod d13;
pub mod d14; pub mod d14;
pub mod d15; pub mod d15;
pub mod d16;
pub mod d17;
pub mod d18;
pub mod d2; pub mod d2;
pub mod d3; pub mod d3;
pub mod d4; pub mod d4;
@ -13,3 +16,11 @@ pub mod d6;
pub mod d7; pub mod d7;
pub mod d8; pub mod d8;
pub mod d9; pub mod d9;
pub mod d19;
pub mod d20;
pub mod d21;
pub mod d22;

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@