Compare commits
	
		
			23 Commits
		
	
	
		
			main
			...
			9b2497f31e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9b2497f31e | |||
| ada97e5ad6 | |||
| b457e10a35 | |||
| 961bc666d6 | |||
| f61f1567cf | |||
| 49633b8504 | |||
| 8fd9bcd63a | |||
| a09f89896d | |||
| d12175371e | |||
| 3da784f97d | |||
| b39f312e9f | |||
| f663a57db8 | |||
| 33ba8d72f4 | |||
| 29a122c3ff | |||
| dafe576fc9 | |||
| 900f01913f | |||
| f952db1e0f | |||
| 1ec3c9c939 | |||
| 27e9e60089 | |||
| d06a694543 | |||
| d655185336 | |||
| f468af10f4 | |||
| 4d1477d7c1 | 
							
								
								
									
										51
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										51
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -11,31 +11,6 @@ dependencies = [ | |||||||
|  "memchr", |  "memchr", | ||||||
| ] | ] | ||||||
|  |  | ||||||
| [[package]] |  | ||||||
| name = "crossbeam-deque" |  | ||||||
| version = "0.8.6" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" |  | ||||||
| dependencies = [ |  | ||||||
|  "crossbeam-epoch", |  | ||||||
|  "crossbeam-utils", |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| [[package]] |  | ||||||
| name = "crossbeam-epoch" |  | ||||||
| version = "0.9.18" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" |  | ||||||
| dependencies = [ |  | ||||||
|  "crossbeam-utils", |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| [[package]] |  | ||||||
| name = "crossbeam-utils" |  | ||||||
| version = "0.8.21" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" |  | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "either" | name = "either" | ||||||
| version = "1.13.0" | version = "1.13.0" | ||||||
| @@ -67,26 +42,6 @@ version = "2.7.4" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" | ||||||
|  |  | ||||||
| [[package]] |  | ||||||
| name = "rayon" |  | ||||||
| version = "1.10.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" |  | ||||||
| dependencies = [ |  | ||||||
|  "either", |  | ||||||
|  "rayon-core", |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| [[package]] |  | ||||||
| name = "rayon-core" |  | ||||||
| version = "1.12.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" |  | ||||||
| dependencies = [ |  | ||||||
|  "crossbeam-deque", |  | ||||||
|  "crossbeam-utils", |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "regex" | name = "regex" | ||||||
| version = "1.11.1" | version = "1.11.1" | ||||||
| @@ -133,9 +88,7 @@ dependencies = [ | |||||||
| name = "y2016" | name = "y2016" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "itertools", |  | ||||||
|  "md5", |  "md5", | ||||||
|  "utils", |  | ||||||
| ] | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| @@ -161,9 +114,6 @@ version = "0.1.0" | |||||||
| [[package]] | [[package]] | ||||||
| name = "y2022" | name = "y2022" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| dependencies = [ |  | ||||||
|  "utils", |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "y2023" | name = "y2023" | ||||||
| @@ -174,7 +124,6 @@ name = "y2024" | |||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "itertools", |  "itertools", | ||||||
|  "rayon", |  | ||||||
|  "regex", |  "regex", | ||||||
|  "utils", |  "utils", | ||||||
| ] | ] | ||||||
|   | |||||||
| @@ -23,4 +23,3 @@ utils = { path = "../utils" } | |||||||
| itertools = "0.13.0" | itertools = "0.13.0" | ||||||
| regex = "1.11.1" | regex = "1.11.1" | ||||||
| md5 = "0.7.0" | md5 = "0.7.0" | ||||||
| rayon = "1.10" |  | ||||||
|   | |||||||
							
								
								
									
										179
									
								
								day22.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								day22.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | |||||||
|  | 'use strict'; | ||||||
|  |  | ||||||
|  | var bossStats = { | ||||||
|  | 	hp: 71, | ||||||
|  | 	damageAmt: 10, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class Player { | ||||||
|  | 	constructor(initial, isWizard) { | ||||||
|  | 		this.history = []; | ||||||
|  | 		this.initial = initial; | ||||||
|  | 		this.isWizard = !!isWizard; | ||||||
|  |  | ||||||
|  | 		if (this.isWizard) { | ||||||
|  | 			this.spells = [ | ||||||
|  | 				{ | ||||||
|  | 					cost: 53, | ||||||
|  | 					effect: (m, o) => o.damage(4), | ||||||
|  | 				}, | ||||||
|  | 				{ | ||||||
|  | 					cost: 73, | ||||||
|  | 					effect: (m, o) => { o.damage(2); m.hp += 2; }, | ||||||
|  | 				}, | ||||||
|  | 				{ | ||||||
|  | 					cost: 113, | ||||||
|  | 					start: (m, o) => m.armor += 7, | ||||||
|  | 					effect: (m, o) => { }, | ||||||
|  | 					end: (m, o) => m.armor -= 7, | ||||||
|  | 					duration: 6, | ||||||
|  | 				}, | ||||||
|  | 				{ | ||||||
|  | 					cost: 173, | ||||||
|  | 					effect: (m, o) => o.damage(3), | ||||||
|  | 					duration: 6, | ||||||
|  | 				}, | ||||||
|  | 				{ | ||||||
|  | 					cost: 229, | ||||||
|  | 					effect: (m, o) => m.mana += 101, | ||||||
|  | 					duration: 5, | ||||||
|  | 				}, | ||||||
|  | 			]; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		this.start(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	attack(opponent, spellIdx) { | ||||||
|  | 		if (!this.isWizard) { | ||||||
|  | 			opponent.damage(this.damageAmt); | ||||||
|  | 		} else { | ||||||
|  | 			this.history.push(spellIdx); | ||||||
|  | 			var spell = this.spells[spellIdx]; | ||||||
|  | 			this.spent += spell.cost; | ||||||
|  | 			this.mana -= spell.cost; | ||||||
|  |  | ||||||
|  | 			if (spell.duration) { | ||||||
|  | 				var newSpell = { | ||||||
|  | 					idx: spellIdx, | ||||||
|  | 					effect: spell.effect, | ||||||
|  | 					duration: spell.duration, | ||||||
|  | 				}; | ||||||
|  | 				if (spell.start) { | ||||||
|  | 					spell.start(this, opponent); | ||||||
|  | 				} | ||||||
|  | 				if (spell.end) { | ||||||
|  | 					newSpell.end = spell.end; | ||||||
|  | 				} | ||||||
|  | 				this.activeSpells.push(newSpell); | ||||||
|  | 			} else { | ||||||
|  | 				spell.effect(this, opponent); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	damage(n) { | ||||||
|  | 		this.hp -= Math.max(1, n - this.armor); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	duplicate() { | ||||||
|  | 		var newPlayer = new Player(this.initial, this.isWizard); | ||||||
|  | 		newPlayer.hp = this.hp; | ||||||
|  | 		newPlayer.spent = this.spent; | ||||||
|  | 		newPlayer.armor = this.armor; | ||||||
|  | 		newPlayer.turn = this.turn; | ||||||
|  | 		for (var i = 0; i < this.activeSpells.length; i++) { | ||||||
|  | 			newPlayer.activeSpells.push(Object.assign({}, this.activeSpells[i])); | ||||||
|  | 		} | ||||||
|  | 		for (var i = 0; i < this.history.length; i++) { | ||||||
|  | 			newPlayer.history.push(this.history[i]); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (this.isWizard) | ||||||
|  | 			newPlayer.mana = this.mana; | ||||||
|  | 		else | ||||||
|  | 			newPlayer.damageAmt = this.damageAmt; | ||||||
|  |  | ||||||
|  | 		return newPlayer; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	takeTurn(opponent) { | ||||||
|  | 		this.turn++; | ||||||
|  |  | ||||||
|  | 		for (var i = 0; i < this.activeSpells.length; i++) { | ||||||
|  | 			var spell = this.activeSpells[i]; | ||||||
|  |  | ||||||
|  | 			if (spell.duration > 0) { | ||||||
|  | 				spell.effect(this, opponent); | ||||||
|  | 				spell.duration--; | ||||||
|  |  | ||||||
|  | 				if (spell.duration === 0 && spell.end) { | ||||||
|  | 					spell.end(this, opponent); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	start() { | ||||||
|  | 		this.hp = this.initial.hp; | ||||||
|  | 		this.spent = 0; | ||||||
|  | 		this.armor = 0; | ||||||
|  | 		this.turn = 0; | ||||||
|  | 		this.activeSpells = []; | ||||||
|  | 		if (this.isWizard) | ||||||
|  | 			this.mana = this.initial.mana; | ||||||
|  | 		else | ||||||
|  | 			this.damageAmt = this.initial.damageAmt; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | var me = new Player({ hp: 50, mana: 500 }, true); | ||||||
|  | var boss = new Player(bossStats); | ||||||
|  |  | ||||||
|  | var cheapestSpent = Infinity; | ||||||
|  |  | ||||||
|  | function playAllGames(me, boss, partTwo, depth) { | ||||||
|  | 	depth = depth || 0; | ||||||
|  | 	for (var i = 0; i < me.spells.length; i++) { | ||||||
|  | 		var spellMatch = false; | ||||||
|  | 		for (var j = 0; j < me.activeSpells.length; j++) { | ||||||
|  | 			if (me.activeSpells[j].duration > 1 && i === me.activeSpells[j].idx) { | ||||||
|  | 				spellMatch = true;; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if (spellMatch) | ||||||
|  | 			continue; | ||||||
|  | 		if (me.spells[i].cost > me.mana) { | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		var newMe = me.duplicate(); | ||||||
|  | 		var newBoss = boss.duplicate(); | ||||||
|  |  | ||||||
|  | 		if (partTwo) | ||||||
|  | 			newMe.hp--; | ||||||
|  |  | ||||||
|  | 		newMe.takeTurn(newBoss); | ||||||
|  | 		newBoss.takeTurn(newMe); | ||||||
|  | 		newMe.attack(newBoss, i); | ||||||
|  |  | ||||||
|  | 		newMe.takeTurn(newBoss); | ||||||
|  | 		newBoss.takeTurn(newMe); | ||||||
|  | 		newBoss.attack(newMe); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		if (newBoss.hp <= 0) { | ||||||
|  | 			cheapestSpent = Math.min(cheapestSpent, newMe.spent); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (newMe.hp > (partTwo ? 1 : 0) && newBoss.hp > 0 && newMe.spent < cheapestSpent) | ||||||
|  | 			playAllGames(newMe, newBoss, partTwo, depth + 1); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | playAllGames(me, boss); | ||||||
|  | console.log('Part One:', cheapestSpent); | ||||||
|  | cheapestSpent = Infinity; | ||||||
|  | playAllGames(me, boss, true); | ||||||
|  | console.log('Part Two:', cheapestSpent); | ||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y{{YEAR}}::days::d{{DAY}}; | use y{{YEAR}}::days::d{{DAY}}; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,27 +1,20 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d1; | use y2015::days::d1; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |     let root = env!("CARGO_MANIFEST_DIR"); | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/1_input.txt")).unwrap(); |     let content = fs::read_to_string(format!("{root}/resources/1_input.txt")).unwrap(); | ||||||
|     println!("Answer: {}", d1::process_part1(&content)); |     println!("{}", d1::process_part1(&content)); | ||||||
| } | } | ||||||
|  |  | ||||||
| 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/1_input.txt")).unwrap(); |     let content = fs::read_to_string(format!("{root}/resources/1_input.txt")).unwrap(); | ||||||
|     println!("Answer: {}", d1::process_part2(&content)); |     println!("{}", d1::process_part2(&content)); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,17 +1,8 @@ | |||||||
| use std::time::Instant; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d10; | use y2015::days::d10; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,8 @@ | |||||||
| use std::time::Instant; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d11; | use y2015::days::d11; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d12; | use y2015::days::d12; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d13; | use y2015::days::d13; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d14; | use y2015::days::d14; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d15; | use y2015::days::d15; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d16; | use y2015::days::d16; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d17; | use y2015::days::d17; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d18; | use y2015::days::d18; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d19; | use y2015::days::d19; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d2; | use y2015::days::d2; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,8 @@ | |||||||
| use std::time::Instant; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d20; | use y2015::days::d20; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d21; | use y2015::days::d21; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d22; | use y2015::days::d22; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d23; | use y2015::days::d23; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d24; | use y2015::days::d24; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,13 +1,7 @@ | |||||||
| use std::time::Instant; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d25; | use y2015::days::d25; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d3; | use y2015::days::d3; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::time::Instant; | use std::time::Instant; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d4; | use y2015::days::d4; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d5; | use y2015::days::d5; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d6; | use y2015::days::d6; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d7; | use y2015::days::d7; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d8; | use y2015::days::d8; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2015::days::d9; | use y2015::days::d9; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -5,5 +5,3 @@ edition = "2021" | |||||||
|  |  | ||||||
| [dependencies] | [dependencies] | ||||||
| md5 = { workspace = true } | md5 = { workspace = true } | ||||||
| utils = { workspace = true } |  | ||||||
| itertools = { workspace = true } |  | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,162 +0,0 @@ | |||||||
| rect 1x1 |  | ||||||
| rotate row y=0 by 6 |  | ||||||
| rect 1x1 |  | ||||||
| rotate row y=0 by 3 |  | ||||||
| rect 1x1 |  | ||||||
| rotate row y=0 by 5 |  | ||||||
| rect 1x1 |  | ||||||
| rotate row y=0 by 4 |  | ||||||
| rect 2x1 |  | ||||||
| rotate row y=0 by 5 |  | ||||||
| rect 2x1 |  | ||||||
| rotate row y=0 by 2 |  | ||||||
| rect 1x1 |  | ||||||
| rotate row y=0 by 5 |  | ||||||
| rect 4x1 |  | ||||||
| rotate row y=0 by 2 |  | ||||||
| rect 1x1 |  | ||||||
| rotate row y=0 by 3 |  | ||||||
| rect 1x1 |  | ||||||
| rotate row y=0 by 3 |  | ||||||
| rect 1x1 |  | ||||||
| rotate row y=0 by 2 |  | ||||||
| rect 1x1 |  | ||||||
| rotate row y=0 by 6 |  | ||||||
| rect 4x1 |  | ||||||
| rotate row y=0 by 4 |  | ||||||
| rotate column x=0 by 1 |  | ||||||
| rect 3x1 |  | ||||||
| rotate row y=0 by 6 |  | ||||||
| rotate column x=0 by 1 |  | ||||||
| rect 4x1 |  | ||||||
| rotate column x=10 by 1 |  | ||||||
| rotate row y=2 by 16 |  | ||||||
| rotate row y=0 by 8 |  | ||||||
| rotate column x=5 by 1 |  | ||||||
| rotate column x=0 by 1 |  | ||||||
| rect 7x1 |  | ||||||
| rotate column x=37 by 1 |  | ||||||
| rotate column x=21 by 2 |  | ||||||
| rotate column x=15 by 1 |  | ||||||
| rotate column x=11 by 2 |  | ||||||
| rotate row y=2 by 39 |  | ||||||
| rotate row y=0 by 36 |  | ||||||
| rotate column x=33 by 2 |  | ||||||
| rotate column x=32 by 1 |  | ||||||
| rotate column x=28 by 2 |  | ||||||
| rotate column x=27 by 1 |  | ||||||
| rotate column x=25 by 1 |  | ||||||
| rotate column x=22 by 1 |  | ||||||
| rotate column x=21 by 2 |  | ||||||
| rotate column x=20 by 3 |  | ||||||
| rotate column x=18 by 1 |  | ||||||
| rotate column x=15 by 2 |  | ||||||
| rotate column x=12 by 1 |  | ||||||
| rotate column x=10 by 1 |  | ||||||
| rotate column x=6 by 2 |  | ||||||
| rotate column x=5 by 1 |  | ||||||
| rotate column x=2 by 1 |  | ||||||
| rotate column x=0 by 1 |  | ||||||
| rect 35x1 |  | ||||||
| rotate column x=45 by 1 |  | ||||||
| rotate row y=1 by 28 |  | ||||||
| rotate column x=38 by 2 |  | ||||||
| rotate column x=33 by 1 |  | ||||||
| rotate column x=28 by 1 |  | ||||||
| rotate column x=23 by 1 |  | ||||||
| rotate column x=18 by 1 |  | ||||||
| rotate column x=13 by 2 |  | ||||||
| rotate column x=8 by 1 |  | ||||||
| rotate column x=3 by 1 |  | ||||||
| rotate row y=3 by 2 |  | ||||||
| rotate row y=2 by 2 |  | ||||||
| rotate row y=1 by 5 |  | ||||||
| rotate row y=0 by 1 |  | ||||||
| rect 1x5 |  | ||||||
| rotate column x=43 by 1 |  | ||||||
| rotate column x=31 by 1 |  | ||||||
| rotate row y=4 by 35 |  | ||||||
| rotate row y=3 by 20 |  | ||||||
| rotate row y=1 by 27 |  | ||||||
| rotate row y=0 by 20 |  | ||||||
| rotate column x=17 by 1 |  | ||||||
| rotate column x=15 by 1 |  | ||||||
| rotate column x=12 by 1 |  | ||||||
| rotate column x=11 by 2 |  | ||||||
| rotate column x=10 by 1 |  | ||||||
| rotate column x=8 by 1 |  | ||||||
| rotate column x=7 by 1 |  | ||||||
| rotate column x=5 by 1 |  | ||||||
| rotate column x=3 by 2 |  | ||||||
| rotate column x=2 by 1 |  | ||||||
| rotate column x=0 by 1 |  | ||||||
| rect 19x1 |  | ||||||
| rotate column x=20 by 3 |  | ||||||
| rotate column x=14 by 1 |  | ||||||
| rotate column x=9 by 1 |  | ||||||
| rotate row y=4 by 15 |  | ||||||
| rotate row y=3 by 13 |  | ||||||
| rotate row y=2 by 15 |  | ||||||
| rotate row y=1 by 18 |  | ||||||
| rotate row y=0 by 15 |  | ||||||
| rotate column x=13 by 1 |  | ||||||
| rotate column x=12 by 1 |  | ||||||
| rotate column x=11 by 3 |  | ||||||
| rotate column x=10 by 1 |  | ||||||
| rotate column x=8 by 1 |  | ||||||
| rotate column x=7 by 1 |  | ||||||
| rotate column x=6 by 1 |  | ||||||
| rotate column x=5 by 1 |  | ||||||
| rotate column x=3 by 2 |  | ||||||
| rotate column x=2 by 1 |  | ||||||
| rotate column x=1 by 1 |  | ||||||
| rotate column x=0 by 1 |  | ||||||
| rect 14x1 |  | ||||||
| rotate row y=3 by 47 |  | ||||||
| rotate column x=19 by 3 |  | ||||||
| rotate column x=9 by 3 |  | ||||||
| rotate column x=4 by 3 |  | ||||||
| rotate row y=5 by 5 |  | ||||||
| rotate row y=4 by 5 |  | ||||||
| rotate row y=3 by 8 |  | ||||||
| rotate row y=1 by 5 |  | ||||||
| rotate column x=3 by 2 |  | ||||||
| rotate column x=2 by 3 |  | ||||||
| rotate column x=1 by 2 |  | ||||||
| rotate column x=0 by 2 |  | ||||||
| rect 4x2 |  | ||||||
| rotate column x=35 by 5 |  | ||||||
| rotate column x=20 by 3 |  | ||||||
| rotate column x=10 by 5 |  | ||||||
| rotate column x=3 by 2 |  | ||||||
| rotate row y=5 by 20 |  | ||||||
| rotate row y=3 by 30 |  | ||||||
| rotate row y=2 by 45 |  | ||||||
| rotate row y=1 by 30 |  | ||||||
| rotate column x=48 by 5 |  | ||||||
| rotate column x=47 by 5 |  | ||||||
| rotate column x=46 by 3 |  | ||||||
| rotate column x=45 by 4 |  | ||||||
| rotate column x=43 by 5 |  | ||||||
| rotate column x=42 by 5 |  | ||||||
| rotate column x=41 by 5 |  | ||||||
| rotate column x=38 by 1 |  | ||||||
| rotate column x=37 by 5 |  | ||||||
| rotate column x=36 by 5 |  | ||||||
| rotate column x=35 by 1 |  | ||||||
| rotate column x=33 by 1 |  | ||||||
| rotate column x=32 by 5 |  | ||||||
| rotate column x=31 by 5 |  | ||||||
| rotate column x=28 by 5 |  | ||||||
| rotate column x=27 by 5 |  | ||||||
| rotate column x=26 by 5 |  | ||||||
| rotate column x=17 by 5 |  | ||||||
| rotate column x=16 by 5 |  | ||||||
| rotate column x=15 by 4 |  | ||||||
| rotate column x=13 by 1 |  | ||||||
| rotate column x=12 by 5 |  | ||||||
| rotate column x=11 by 5 |  | ||||||
| rotate column x=10 by 1 |  | ||||||
| rotate column x=8 by 1 |  | ||||||
| rotate column x=2 by 5 |  | ||||||
| rotate column x=1 by 5 |  | ||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2016::days::d1; | use y2016::days::d1; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2016::days::d2; | use y2016::days::d2; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2016::days::d3; | use y2016::days::d3; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2016::days::d4; | use y2016::days::d4; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,8 @@ | |||||||
| use std::time::Instant; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2016::days::d5; | use y2016::days::d5; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2016::days::d6; | use y2016::days::d6; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2016::days::d7; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part1() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/7_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d7::process_part1(&content)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part2() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/7_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d7::process_part2(&content)); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2016::days::d8; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part1() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/8_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d8::process_part1(&content, (50, 6))); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part2() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/8_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d8::process_part2(&content)); |  | ||||||
| } |  | ||||||
| @@ -1,163 +0,0 @@ | |||||||
| pub fn process_part1(input: &str) -> u32 { |  | ||||||
|     input |  | ||||||
|         .lines() |  | ||||||
|         .map(|line| if is_tls(line) { 1 } else { 0 }) |  | ||||||
|         .sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str) -> u32 { |  | ||||||
|     input |  | ||||||
|         .lines() |  | ||||||
|         .map(|line| if is_ssl(line) { 1 } else { 0 }) |  | ||||||
|         .sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn is_tls(ipv7: &str) -> bool { |  | ||||||
|     let mut abba = false; |  | ||||||
|     let mut part = String::new(); |  | ||||||
|     for chara in ipv7.chars() { |  | ||||||
|         if chara == '[' { |  | ||||||
|             if contains_abba(&part) { |  | ||||||
|                 abba = true; |  | ||||||
|             } |  | ||||||
|             part.clear(); |  | ||||||
|         } else if chara == ']' { |  | ||||||
|             if contains_abba(&part) { |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|             part.clear(); |  | ||||||
|         } else { |  | ||||||
|             part.push(chara); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     if contains_abba(&part) { |  | ||||||
|         abba = true; |  | ||||||
|     } |  | ||||||
|     abba |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn contains_abba(part: &str) -> bool { |  | ||||||
|     if part.len() < 4 { |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|     for window in part.chars().collect::<Vec<char>>().windows(4) { |  | ||||||
|         if window[0] == window[3] && window[1] == window[2] && window[0] != window[1] { |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn is_ssl(ipv7: &str) -> bool { |  | ||||||
|     let mut abas = Vec::new(); |  | ||||||
|     let mut babs = Vec::new(); |  | ||||||
|     let mut part = String::new(); |  | ||||||
|     for chara in ipv7.chars() { |  | ||||||
|         if chara == '[' { |  | ||||||
|             if let Some(additional_aba) = get_aba_or_bab(&part) { |  | ||||||
|                 abas.extend_from_slice(&additional_aba); |  | ||||||
|             } |  | ||||||
|             part.clear(); |  | ||||||
|         } else if chara == ']' { |  | ||||||
|             if let Some(additional_bab) = get_aba_or_bab(&part) { |  | ||||||
|                 babs.extend_from_slice(&additional_bab); |  | ||||||
|             } |  | ||||||
|             part.clear(); |  | ||||||
|         } else { |  | ||||||
|             part.push(chara); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     if let Some(additional_aba) = get_aba_or_bab(&part) { |  | ||||||
|         abas.extend_from_slice(&additional_aba); |  | ||||||
|     } |  | ||||||
|     for aba in abas { |  | ||||||
|         for bab in babs.iter() { |  | ||||||
|             let aba = aba.chars().collect::<Vec<char>>(); |  | ||||||
|             let bab = bab.chars().collect::<Vec<char>>(); |  | ||||||
|             if aba[0] == bab[1] && aba[1] == bab[0] { |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn get_aba_or_bab(part: &str) -> Option<Vec<String>> { |  | ||||||
|     if part.len() < 3 { |  | ||||||
|         return None; |  | ||||||
|     } |  | ||||||
|     let mut aba_bab: Vec<String> = Vec::new(); |  | ||||||
|     for window in part.chars().collect::<Vec<char>>().windows(3) { |  | ||||||
|         if window[0] == window[2] { |  | ||||||
|             aba_bab.push(window.iter().collect()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     if aba_bab.is_empty() { |  | ||||||
|         None |  | ||||||
|     } else { |  | ||||||
|         Some(aba_bab) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT_1: &str = "abba[mnop]qrst"; |  | ||||||
|     const INPUT_2: &str = "abcd[bddb]xyyx"; |  | ||||||
|     const INPUT_3: &str = "aaaa[qwer]tyui"; |  | ||||||
|     const INPUT_4: &str = "ioxxoj[asdfgh]zxcvbn"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_1() { |  | ||||||
|         let result = is_tls(INPUT_1); |  | ||||||
|         assert!(result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_2() { |  | ||||||
|         let result = is_tls(INPUT_2); |  | ||||||
|         assert!(!result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_3() { |  | ||||||
|         let result = is_tls(INPUT_3); |  | ||||||
|         assert!(!result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_4() { |  | ||||||
|         let result = is_tls(INPUT_4); |  | ||||||
|         assert!(result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     const INPUT_5: &str = "aba[bab]xyz"; |  | ||||||
|     const INPUT_6: &str = "xyx[xyx]xyx"; |  | ||||||
|     const INPUT_7: &str = "aaa[kek]eke"; |  | ||||||
|     const INPUT_8: &str = "zazbz[bzb]cdb"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_1() { |  | ||||||
|         let result = is_ssl(INPUT_5); |  | ||||||
|         assert!(result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_2() { |  | ||||||
|         let result = is_ssl(INPUT_6); |  | ||||||
|         assert!(!result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_3() { |  | ||||||
|         let result = is_ssl(INPUT_7); |  | ||||||
|         assert!(result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_4() { |  | ||||||
|         let result = is_ssl(INPUT_8); |  | ||||||
|         assert!(result); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,100 +0,0 @@ | |||||||
| use itertools::Itertools; |  | ||||||
|  |  | ||||||
| enum Instruction { |  | ||||||
|     Rect(u32, u32), |  | ||||||
|     ShiftRight(u32, u32), |  | ||||||
|     ShiftDown(u32, u32), |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str, grid_size: (usize, usize)) -> i32 { |  | ||||||
|     let instructions = input |  | ||||||
|         .lines() |  | ||||||
|         .map(parse_instruction) |  | ||||||
|         .map(|option| option.unwrap()) |  | ||||||
|         .collect_vec(); |  | ||||||
|     let mut grid = vec![vec!['.'; grid_size.0]; grid_size.1]; |  | ||||||
|     for instrution in instructions { |  | ||||||
|         match instrution { |  | ||||||
|             Instruction::Rect(width, height) => { |  | ||||||
|                 for row in 0..=height { |  | ||||||
|                     for col in 0..=width { |  | ||||||
|                         grid[row as usize][col as usize] = '#'; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             Instruction::ShiftRight(row, by) => grid[row as usize].rotate_right(by as usize), |  | ||||||
|             Instruction::ShiftDown(col, by) => { |  | ||||||
|                 let mut col_items = grid.iter().map(|row| row[col as usize]).collect_vec(); |  | ||||||
|                 col_items.rotate_right(by as usize); |  | ||||||
|                 for (row, pixel) in col_items.iter().enumerate() { |  | ||||||
|                     grid[row][col as usize] = *pixel; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         for row in grid.clone() { |  | ||||||
|             println!("{}", row.iter().join("")); |  | ||||||
|         } |  | ||||||
|         println!(); |  | ||||||
|     } |  | ||||||
|     grid.iter() |  | ||||||
|         .map(|row| { |  | ||||||
|             row.iter() |  | ||||||
|                 .map(|pixel| if *pixel == '#' { 1 } else { 0 }) |  | ||||||
|                 .sum::<i32>() |  | ||||||
|         }) |  | ||||||
|         .sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(_input: &str) -> i32 { |  | ||||||
|     0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn parse_instruction(inst: &str) -> Option<Instruction> { |  | ||||||
|     if inst.contains("rect") { |  | ||||||
|         let (_, axb) = inst.split_once(" ").unwrap(); |  | ||||||
|         let (a, b) = axb.split_once("x").unwrap(); |  | ||||||
|         return Some(Instruction::Rect( |  | ||||||
|             a.parse::<u32>().unwrap() - 1, |  | ||||||
|             b.parse::<u32>().unwrap() - 1, |  | ||||||
|         )); |  | ||||||
|     } |  | ||||||
|     if inst.contains("rotate row y") { |  | ||||||
|         let (_, abyb) = inst.split_once("=").unwrap(); |  | ||||||
|         let (a, b) = abyb.split_once(" by ").unwrap(); |  | ||||||
|         return Some(Instruction::ShiftRight( |  | ||||||
|             a.parse().unwrap(), |  | ||||||
|             b.parse().unwrap(), |  | ||||||
|         )); |  | ||||||
|     } |  | ||||||
|     if inst.contains("rotate column x") { |  | ||||||
|         let (_, abyb) = inst.split_once("=").unwrap(); |  | ||||||
|         let (a, b) = abyb.split_once(" by ").unwrap(); |  | ||||||
|         return Some(Instruction::ShiftDown( |  | ||||||
|             a.parse().unwrap(), |  | ||||||
|             b.parse().unwrap(), |  | ||||||
|         )); |  | ||||||
|     } |  | ||||||
|     None |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT: &str = "rect 3x2 |  | ||||||
| rotate column x=1 by 1 |  | ||||||
| rotate row y=0 by 4 |  | ||||||
| rotate column x=1 by 1"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1() { |  | ||||||
|         let result = process_part1(INPUT, (7, 3)); |  | ||||||
|         assert_eq!(result, 6); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2() { |  | ||||||
|         let result = process_part2(INPUT); |  | ||||||
|         assert_eq!(result, 0); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -9,7 +9,3 @@ pub mod d4; | |||||||
| pub mod d5; | pub mod d5; | ||||||
|  |  | ||||||
| pub mod d6; | pub mod d6; | ||||||
|  |  | ||||||
| pub mod d7; |  | ||||||
|  |  | ||||||
| pub mod d8; |  | ||||||
|   | |||||||
| @@ -4,4 +4,3 @@ version = "0.1.0" | |||||||
| edition = "2021" | edition = "2021" | ||||||
|  |  | ||||||
| [dependencies] | [dependencies] | ||||||
| utils = { workspace = true } |  | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2022::days::d1; | use y2022::days::d1; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2022::days::d2::{process_part1, process_part2}; | use y2022::days::d2::{process_part1, process_part2}; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2022::days::d3; | use y2022::days::d3; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2022::days::d4; | use y2022::days::d4; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2022::days::d5; | use y2022::days::d5; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2022::days::d6; | use y2022::days::d6; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2022::days::d7; | use y2022::days::d7; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2022::days::d8; | use y2022::days::d8; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2022::days::d9; | use y2022::days::d9; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -7,4 +7,3 @@ edition = "2021" | |||||||
| regex = "1.11.1" | regex = "1.11.1" | ||||||
| utils = { workspace = true } | utils = { workspace = true } | ||||||
| itertools = { workspace = true } | itertools = { workspace = true } | ||||||
| rayon = { workspace = true } |  | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| 5 62914 65 972 0 805922 6521 1639064 |  | ||||||
| @@ -1,140 +0,0 @@ | |||||||
| CCCCCCCCCBBBMMGGGGGGGGGGGGGYWWWWWWWWWWWWOOOOOOOOOOOOOOOOHLLHHHHHHHHHHTHUUUULBBBBBBBBBBBBPPPPPPPPPPPKKWWWWCCCWWWWWWWWWWWWWWWWWWWWEEEEYNNNYYLL |  | ||||||
| CCCCCCCCCBBBBBBGGGGGGGGGGGGGWWWWWWWWWWWWOOOOOOOOOOOOOOOOHHHHHHHHHHHHHHHHUUULBBBBBBBBBBBPPPPPPPPPPPPPPPWWWCCCWWWWWWWWWWWWWWWWWWWBEEEYYYNYYLLL |  | ||||||
| CCCCCCCBBBBBBBBGGGGGGGGGGGGWWWWWWWWWWWWWOAOOOOOOOOOOOOOOHHHHHHHHHHHHHHHHUUULLLLLBBBBBBBBPSPPPPPPPPPPPMMWWCCCCCCCWWWWWWWWWWWBWWWBBBBYYYYYYYLL |  | ||||||
| CCCCCCCCBBBBBBBGGGGGGGGAAGWWWWWWWWWWWWWWWWOOOOOOOOOOOIOOHHHHHHHHHHHHHHHHUUULLLLLLLBBBJBJSSPPPPPPPPPPMMMMMCCCCCCCWWWWWWWWWBBBBBWBBBBYYYYYYYYY |  | ||||||
| CCCCCCCCCBBBBBBGGGGGGGGGAAWPPWWWWWWWWWWWWWOOOOOOOOOIIIOHHHHHHHHHHHHHHHHUULLLLLLLLBBBBJJJSSPPPPPGGGGPEEMCCCCCCCCCCCCCCCBBWWBBBBBBBBBBYYYYYYYY |  | ||||||
| CCCCCCCCCBBBBBBBGGGGGGGGAAASSWWWWWWWWWWWWWOOOUOOOIIIIIIIYHHHHHHHHHHHHHHHHHNLLLLLLLBBBBJJJJVPPPPGGGGPEEMCCCCCCCCCCCCCCCBBBBBBBBBBBBBYYYYYYYYY |  | ||||||
| CCCNNNCCBBBBBBBBGEGGGGGAAAAASWWWWWWWWWWWWWXOOOOIIIIIIIYYYHHHHHHHHHHHHHHHGGLLLLLLLLLBBJJJJJJPPPPGGGGPMEMCCCCCCCCCCCCCCCBBBBBBBBBBBBBYYYYYYYYY |  | ||||||
| CCNNNNNBBBBBBBBBBEBSGGGGGGSSSWWWWWWWWUWXXXXXXOOIVVVIIIIIYHHHYYHHHYYYYHHHGLLLLLLLLLLLLJJJJJPPPPPGGGGPMMMMMMMCCCCCCCCCCBBBBBBBBBBBBYYYYYYYYYYM |  | ||||||
| NNNNNNNVVVBBBBBBBBBSGGSSSSSSSSWWWWWWWUWWXXXXXXOVVVIIIIIIYYYYYYYYHYYYYYHHGGLLLLLLLLLLLJJJJJJJPPPGGGGPMMMMMMMCCCCCCCCCCBBBBBBBBBBBBBBYYYYYYMMM |  | ||||||
| NNNNNNNVVVBBBBBBBBBSGGSSSSSSSDDWWWWWWWWXXXXXXXOOIIIIISIIYYYYYYYYYYYYDYYGGGLLLLLLLLLLLJJJJJJJPGGGGGGPPPMMMMMCCCCCCCCCCBBBBBBBBBBBBBBYYYYYYMMM |  | ||||||
| NNNNFNNNNBNBBBBBBBSSSSSSSSSSSSSSWDWWUUNXXXXXXXXXIIIIISSSSYYYYYYYYYYYYYYGGGLLLLLLLLJJJJJJJJJJGGGGGGGPDMMMMMMCCCCCXWWWWWBBBBBBBBBBBBBYYYYYMMMM |  | ||||||
| NNNNNNNNBBBBBBBBBBSSSSSSSSSSSSSSSDDDNUNNNXXXXXXXIIXIISSSYYYYYYYYYYYYYYYGGGGGLLLLLLLJJJJJJJJJGGGGGGGPDDMDMMMXXXXXXXXXWWWWWWBBBBBBBBBYYYYMMMMM |  | ||||||
| NNNNNNNBBBBBBBBBBBSSSSSSSSSSSSSSSSNNNNNNNNXXXXXXXXXXXXSSSQQNYYYYYYYYYYGGGGGGLLLLLLLLJJJJJJJDGGGGGGGDDDDDMMDXXXXXXWWWWWWWWBBBBBBBBBHYYYMMMMMM |  | ||||||
| NNNNNNAAXXXBBBBXXBBBSSSSSSSSSSSSSENNNNNNNNNNXXXXXXXQXXQQQQQNYYYYYYYYYYYGGGGGGLLLLLLLJJJJJJJDGGGGGGGDDDDDDDDXXXXXWWWWWWWWWWWBBBBBBHHYYYMMMMMM |  | ||||||
| NNNNNNNNXXXXXXXXBBBSSSYSSSSSSSSSSNNNNNNNNNNZXXXXXXEQQQQQQQQYYYYYYYYYYYYGGGGGLLLLLLLGJJJJJJJJGGGGGGGDDDDDDXXXXXXXXWWWWWWWWWWBBBBBBHHHYYMMMMMM |  | ||||||
| NNNXXNNNXXXXXXXXXXXYYYYYSSSSSSSSIIINNNNNNNNXXCXXXXEQQQQQQQQQYYYYYYYYYYYGGGGGGGGLGLGGJJJJJJJDGGGGGGGDGDDDGGXXXXXXCWWWWWWWWWWWWABOOHHHYMMMMMMM |  | ||||||
| SNNSXNNNRXXXXXXXXXXXYYYYYSSSSSSIIIINNNNNNNNXXCCXEEEQQQQQQQQYYYYYYYYYYYYGGGGGGGGGGGGJJJJJJJJUGGGGGGGGGGGGGGGGGGXCCCWCCWWWWWAAAAAOOHHHHMMMMMMM |  | ||||||
| SSSSXSNNRXXXXXXXYYYYYEYNYSSSMHSIIIIINNNNNNNNCCCCTTEQYYQQQQQQYYYYYUYYYYYGGGGGGGGGGGJJJJJJJJJJGGGGGGGGGGGGGGGGGGXGCCCCCWWWWWAAAAAHOHHHHMMMMMMM |  | ||||||
| SSSSSSNNSJJJXXXYYYYYYYYYMSMMMMGMIMIINNNNNNNCCCCCTTEYYYQYQQQQQQMYUUYUYYGGGGGGGGIIIJJJJJJJJJJUGGGGGGGGGGGGGGGGGGDGCCCCWWWWWWAAAAAHHHHNMMMMMMMM |  | ||||||
| SSSSSSSSSSSJXXXYYYYYYYYYMSMMMMMMMMIIINNNNNNCCCCCTTEYYYYYYQQQQBBBUUYYYYYOOOOGGGIIIPJJJJJJJJUUGGGGGGUGGGGGGGGGGGGGCCCCCCAAAAAAAAAHHHHNMMMMMMMM |  | ||||||
| SSSSSSSSSSSJJJJYYYYYYYYYYMMMMMMMMMIIIINNNCCCCCCTTTTCYYYYQQQBBBBBBUUYYYYOGOOOOGIIIIIIIJJJJUUUGGGGGGGGGGGGGGGGGGGGCCCHHHAAAAAAAAAHHHHNNMMMMMMM |  | ||||||
| SSSSSSSSSSSSSJJJYYYYYYYMMMMMMMMMMMIIIINNNCSCCTTTTTYYYYYYPPQBBBBBBUUUYGYGGOGGGGIIIIIIIJJIIUUUGGGGGGGGGGGGGGGGGGCGGCCCCCAAAAAAAAAHHHNNAAAMMQMM |  | ||||||
| SSSSSSSSSSSJJJJJYYYYYYYYMMMMMMMMMIIISISSSSSCCTTTTTYYYYYYPPPPBBBBUUUUUGGGGGGGGGIIIIIIIIJIIUUUGGGGGGGGGGGGGGGGGGCCGCCCCCAAAAAAAAAKKKAKAHAMMQMY |  | ||||||
| SSSSSSSSSSSSJJDJJJYYYYYMMMMMMMMMMOOSSSSSSSSSCTETTTTYYYPYPPPPPPBBBBUGUGGGGGGGYYIIIIIIIIIIIUUUGGGGGGGGGMMMGGGGGGCCCCCCCAAAAAAAAAAKKKKKHHAAMQMY |  | ||||||
| SSSSSSSSSSSSJJDJJJYYOOMMMMMMMMMOQOFFFFSSSSSCCCCOOYYYYYPSPPPPBPBBBBGGGGGGGYGGYYIIIIIIIIIIUUUUUUUUUUUUUUMMGGGGGCCCCCCCBAAAAAAAAAAAAKKKHHHHHHYY |  | ||||||
| SWSSSSSSSSSSJJDJDDYYMOOMMMMMOMOOOOOOSSSSSSSSCCYYYYYYYYPPPPPBBBBBBBIIIIGGGYYYYYYIIIIIIIIIIIIUUUUUUUUUUMMMMMMGKCCKKCCCCAAAAAAAAAAAAKKKHHHHHHYY |  | ||||||
| SSSSSSSSSSSSJDDDDDDYMMMMMMMMOOOOMOOOOOSSSSSNCCZZZZYYYYPPPPPBBBBBBBBBBBWYGAAAAAAAIIIIIIIIIIUUUUUUUUUUUMMMMMKKKKCKKCCCBAAAAAAAAAAAAKKHHHHHHYYY |  | ||||||
| SSSSSSSJSSSSJDDDDDDMMMMMMMMMMGGOOLOCSSSSSSSSCCZZZZZYYYEEPPPBBBBBBBBBBBBYWAAAAAAAIIIIIIIIIIUUUUUUUUUUUMMMMKKKKKKKCCBBBAAAAAAAAAAAAKHHHHHHPHHY |  | ||||||
| SSSSSSSSSYYSDDDDDDDDDDMMMMMMMMMMLLSCCSSSSSSZZZZZZZZZYSPPPPPPBBBBBBBBBBBYYAAAAAAAIIIIIIIIIIUUUUUUUUUUUUUKKKKKKKKKKCCBBAAAAAAAAAAAAHHHHHHHHHHY |  | ||||||
| YYSYSSYYYYYDJDDDDDDDDDMMMMMMMMLLLLSSSSSSSSSZZZZZZZZVSSPPPMPBBBBBBBBBBBBYYAAAAAAAIIIIIIIIIIUUUUUUUUUUUKKKKKKKKKKKKBBBBAAAAAAAAAAAAHHHHHHHHHHH |  | ||||||
| YYYYSSYYYYYDDDDDDDDDDMMMMMMMMLLLLLSSSSSSSSSSZZZZZVVVSSPPPPBBBBBBBBBBBBYYYAAAAAAABIIIIJJIIIUUUUUURVKKKKKKKKKKKKKKKBBBBAAAAAAAAAAAAHHHHHHHHHHF |  | ||||||
| YYYYYYYYYYYDDDDDDDDDMMLMMMMLLLGGLLLLSSSSSSSSZZZZZVVVVSVBPBBBBBBBBAAAAAAAAAAAAAAABIIIIJJJIRRRRRRRRRRRKKKKKKKKKKEKKBBBBAAAAAAAAAAAAHHHHHHHHHHF |  | ||||||
| YYSSSYYYYYYDDDDDDDDDDMLLLLLLLLGGGGLLSSLLSSSZZZZZZVVVVVVBBBBBBAAAAAAAAAAAAAAAAAAABBIIRRRRRRRRRLRRRRRRKKKKKKKKKKKKWWWBBAAAAAAAAAAAAHHHHHHHHFFF |  | ||||||
| SSSSSSYAAYYYYDDDDDDDDDDLLLLLGGGGGGGLLLLLLSSZZZZZZVVVVVBBBBBBBAAAAAAAAAAAAAABBYYBBRIIRRRRRRRRRRRRRRRKKKKKKKKKKKKKWWWWWAAAABBBBBBBCHHHHHHAAFFF |  | ||||||
| SSSSSAAAAYAYYYYDDDDDDDDDDZZZGGGGGGGGGGLLLSSZZZZZZVVVFVBBBBBBBAAAAAAAAAAAAAABBBBBBRRRRRRRRRRRRRRRRRRKKKKKKKKKKKKKWWWWAAAAABAABIBHHHHHHHHAAAFF |  | ||||||
| SSSSSAAAAAAAYYYYDDDDDDDDZZZZGGGGGGGGGGGLLSZZZZZZVVVVVBBBBBBBBAAAAAAAAAAAAAABBBBBBBNRRRRRRRRRRRVRRRRRKKKKKKKKKKKWWWWWAAAAAAABBIIIHHHHHAAAAAAA |  | ||||||
| SSSAAAAAAAAAAAAZDDDDDDDDZZZZGGGGGGGGGGGLLZZZZZZZZVVVVVBBBBBBBAAAAAAAAAAAAAABBBBBBBBRRRRRRRRRRRVRRRRRRKKRKKKRKKWWWWWWWAAAAAAAIIIIHHHHHMAAAAAA |  | ||||||
| SSSAAAAAAAAAAADZKKKDDDDZZZZZGGGGGGGGGGGGLZYKKZKUVVVVVVBBBBBBBAAAAAAAAAAAAAABBBBBBRRRRRRRRRRRRVVVRRRRRRRRRRRRRWWWWWWWAAAAAAAAAIIIIISSAAAAAAAA |  | ||||||
| SSSAAAAAAAAAAKKKKKKKDDZZZZZZZGGGGGGGGGGGGGKKKKKUUVVOODOOBBBBBBBBBJJJJJJBBBBBBBBBBBRRRRRRRRRRRVVVRRRRRRRRRRRRWWWWWWWAAAAAAAAAAIIIISSSSAAAAAAA |  | ||||||
| SSSAAAAAAAAAAKKKKKKKZZZZZZZZZVGGGGGGGGGGXKKKKKKUVVOOOOOOBBBBBBBJJJJJJJJJJBBBBBBBBBCCRRRRRRRRRVVRRRRRRRRRRRRRWWWWWWWAAAAAAAAAAIIIIIIAAAAAAAAA |  | ||||||
| SSSAAAAAHHHHHHHHHHHHHHHHHHZZZVGGGGGGGGGKKKKKKKKUVVOOOOOOCBBBBBBBJJJJJJJJJBBBBBBBBCCRRRRRRRRIRRRRRRRRRRRRRRWWWWWWWWWAAAAAAAAAAIIIIIIAAAAAAAAA |  | ||||||
| SSSSAAAAHHHHHHHHHHHHHHHHHHZZZZQQGQQGGGQKKKKKKKKVVVOOOOOOCCBBBBBBJJJJJJJJJJJJJJBCCCCRRRCCCCCIIIRRRRRRRRRRRRWWWWWWWWAAAAAAAAVVIIIIIIIOAAAAAAAA |  | ||||||
| SSSSSSAAHHHHHHHHHHHHHHHHHHZZZZZQQQQQQQQQQKKKKKKKOOOOOOOOCCBBBBBJJJJJJJJJJJJJJJBCCCCCCCCCCCIIKKKRRRYRRRRWWWWWWKWWWKKAAAAAAAAIIIIIIIIIHAAAAAAA |  | ||||||
| SSSSSSSAABBBBKKKHHHHHHHHHHZZZZZQQQQQQQQQQQKKKKKKOOOOOOOOCCCBBBBJJJJJJJJJJJJJJCBCCCCCCCCCCCCCKKKKKRKRRRRWWWWWWKKKKKKWAAAAAAAIIIIIIIIIHAAAAAAA |  | ||||||
| SSSSSSSSABBBBBZZHHHHHHHHHHZCCEECCCCQQQQQQQKKKKKKOOOOOOOOOCBBBBBJJJJJJJJJJJJSCCCCCCCCCCCCCCCCKKKKKKKKKKKKWWWGGKKKKKKWWWAATTIIIIIIIYHHHHAAAAAA |  | ||||||
| SSSSSSSSSSSBBBBHHHHHHHHHHHZZCCCCCCCQQCQQQQNKKNOOOOOOOOOOOBBBBBBBBJJJJJJJJJJSSCCCCCCCCCCCCCCCCKKKKKKKKKKMMMGGYYKKKKKWWWWATTIIIINIIYYHYYAAAAAA |  | ||||||
| SSSSSSSSSSSSBBBHHHHHHHHHHHKKKCCCCCCCCCQQQNNKKNNOOOOOOOOFFBBBBBBBBJJJJJJJJJJJCCCCCCCCCCCCCKCCKKKKKKKKMMMMMMMGGKKKKKKWWWWTTTTITIIIKYYYYYAAAAJA |  | ||||||
| SSSSSSSSSSSSSSBHHHHHHHHHHHHHKCCCCCCCCCNNNNNNNNNNOOOOOOOFFFFBUBHHHHHJJJJAJQQJQCCCDCCCJCKKCKKKKKKKKKKMMMMMMMGGGKKKKKKTTTTTTTTTTTTIKYYYYYAYAAAU |  | ||||||
| SSSSSSSSSFFFFBBHHHHHHHHHHHHHHCCCCCCCYCYNNNNNNNNNNNNOOOORRRRRRTZHZZZJJJJJJQQQQCBCCCCCCCKKKKKKKKKKKKKKMMMMKMGGGKKKKKKTTTTTTTTTTTTTTTYYYYYYYAAU |  | ||||||
| SSSSSSSSFFFFFBBHHHHHHHHHHHHHHCCCCCYCYYYYYNNNNNNNNNNOONARRRRRZZZZZZZJJJJQQQQQQQCCCCCCCDKKKKKKKMMKKKKKKMMMKMGGGKKKKKKTTTTTTTTTTTTTXTYYYYYYYYYY |  | ||||||
| SMSSSSSSJFFFFFBHHHHHHHHHHHHHHHCCCCYYYYYYYYYNNNNNNNNNNNRRRZZZZZZZZZZZZJJQQQQQQQQQCCCCDDKBKKBKMMMKKKKKKMMKKKJGGGGGKKKTTTTTTTTTTTTTTTTTTYYYYYYY |  | ||||||
| YJJSSSSJJFGFFFBHHHHHHHHHHHHHHHCCCYYYYYYYYYNNJNNNNNNNNNVRRRRZZZZZZZZZZQQQQQQQQQQQCCCCCGBBBBBBBMAMKKKKKKKKKCGGGGGKKKKTTTTTTTTTTTTTTTTYYYYYYYYW |  | ||||||
| YGJJSSSJJJFFJJJHHHHHHHHHHHDLHHHCYYYYYYYYYYYYNNNNNNNNNVVVVRRRZZZZZZZZZQQQQQQQQQQQQQCCCGBBBBGBBMMMKKKKKKKKKCCGGGGKKKKKTTTTTTTTTTTTTTTTYYYYYYYY |  | ||||||
| YGJSSJJJJJJJJJJHHHHHHHHHHHLLLLLLYYYYYYYYYYYYNNNNNNNNNNVVVRRRRRZZZZZZZQQQQQRQQQQQQQQCGGGGGBGMMMMMMMKKCKKCCCCCZGGKKKKKTTTTTTTTTTTXTTTTYMMYYYYY |  | ||||||
| GGJJJJJJJJJJJJJJJHHHHHHHLLLLLLLLLYYYYYYYYYYYYNNNNNNNNNVVVRRRRRZZZZZZRQQRRQRRQKKQQQQCQGGGGGGMMMMMMKKCCCKCCCCCCGKKKKKKTTTXXXXXTTTXTTMTMMMMMYYY |  | ||||||
| GGGGJJJJJJJJJJJJJHHHFHHLLLLLLLLLLYYYYYYYYYYYYNNNNNNNNNNVRRRRRZZZZZZZRRRRRRRRRKKKQQQQQQGGGGGGMMMCMCCCCCCCCCCCCCKKKKKKTTTXXXXXXXXXXXMMMMMMAYYY |  | ||||||
| GGGGGJJJJJJJJJJJJHHHHHHLLLLLLLLLLYYYYYYWYYWYYYNNNNNNNNSSSRRRRAAZZZZRRRRRRRRRRKEKKQQQQGGGGGGOOOMCCCCCCCCCCCCCCNNNNNNNNNNNNNNNNNNMMMMMMMMMMYYA |  | ||||||
| GGGGGJJGTTTTJJJJJLLLLLLLLLLLLLLLLLLYWYWWWWWYYNNNNNNNNNSSSSRKAAAZZZRRRRRRRRRKKKKKKQQQQQGFGGGOOOICCCCCCCCCCCCCCNNNNNNNNNNNNNNNNNNXMMMMMMMMMMYA |  | ||||||
| GGGPPGJGTTTTJTJJJLLLLLLLLLLLLLLLLLYYWWWWWWWWYYYNSNNNNSSSSABAAAAZZRRRRRRRRRRKKKKKNNNNQQFFFFGOOOCCCCCCCCCCCCCCCNNNNNNNNNNNNNNNNNNMMMMMMMMMMMAA |  | ||||||
| GGGGGGGGTTTTTTTLLLLHLLLLLLLLLLDLLLLWWWWWWWWWYYYSSNNSSSSSSAAAAAAAAARRRRRRRRRRKKKKKNNNNQQFFOOOOOOCCCCCCCCCCCCJGNNNNNNNNNNNNNNNNNNMMMMMMMMMMMAN |  | ||||||
| GGGGGGGGGTTTTTTTTTTHLSLLLLLLLLDLLLXXWWWWWWWWYYYSNNNSSSSSSAAAAAAALLRRRRRRRRRRRKKRNNNNQQRFFOOOOOOCCCCCCCCCCCCJJNNNNNNNNNNNNNNNNNNMMMMMMMMMNDNN |  | ||||||
| GGGGGWGGGTTTTTTTFFSSSSSSLLLLLLLLLBWWWWWWWWWWYYYSSSSSSSSSSAAAAAAAAARRRRRRRRRRRRRRNNSSRRRRRRROOOOOOCCCCCCCCJJJJNNNNNNNNNNNNNNNNNNXXXMMMNNNNNNN |  | ||||||
| GGGGWWWGGTTTTTTFFSSSSSSSLLLLLLLLKBWWWWWWWWWWYYYYSSSSSSSSBJJAAAAAAARRRRRRRRRRRRNNNNNNOORRRRRROOOOOCCCCCCCJJJJJNNNNNNNNNNQQQQXXXXXXXXXXNNLNNNN |  | ||||||
| GGGWWWWTTTTTTTTTTOSSSSSSBLSSHLLLKKJWWWWWWWWWWYYRRSRSRSBBBJJJAAAAAAARRRRRRRRRRRNNNNNNOOOORRRRRRROOOOOOJJJVJJJJJJJNNNQQQQQQQQQXXXXXXXXXNNNNNNQ |  | ||||||
| GGGWWWTTTTTTTTKSSSSSSSSSSSSSHLLLKKKWMWWWWWWWWWYRRRRRRBBBBBAAAAEEEAARRRRRRRRRRNNNOOOOOOORRRRRRROOOOOGJJJJJJJJJJJJNNNQQQQQQQQQXXXXXXXNNNNNNNNN |  | ||||||
| WWWWWWTTTTTTTTTJSSSSSSSSSSSSSKKKKKKWMWWWWWWWWWYRRRRRBBBBBBAAAAEEEEEEERRRRRRRRRRROOOOORRRRRRRRRROOOGGJHJJJJJJJJJJNNNQQQQQQQQQXXXXXXXNXNNNNNNN |  | ||||||
| WWWWWTTTTTTTTTTTSSSSSSSSSSHKKKKKKKUKMWWWWWWWWKKKKRRBBBBBEEEEEEEEEEEEETRRDDRRRRROOOOOORRRRRRRRRROOGGGGJJJJJJJJJJJJJQQQQQQQQQQQQQQXXXXXNNNNNNN |  | ||||||
| WWWWWWWTTTTTTTTSSSSSSSSSSSKKKKKKKKKKKWWWWWWWKKKKKRRBBBBBBBBEEEEEEEEETTRRDDRRRRRROOOLOORRRRRRROOOGGGGGJJJJJJJJJJJJCQQQQQQQQQQQQQXXXXNNNNNNNNN |  | ||||||
| WWWIWWWTTTTTTTSSSSSSSSSSSSKKKKKKKKKYYWWWWWWWWKKKKLRBEBEEEEEEEEEEEEETFTTTDDDTTTRBLLLLLLRRRRRRROOHGGGGGGJJJJJJJJJJJJWQQQQQQQQQQQQQXXXNNNRNNNNN |  | ||||||
| WWIIIWWWTTLTTTSSSSSSSSSSKKKKKKKKKPPYYWWWWWWWWKKKKLLEEEEEEEEVVVVVEEETTTTDDTTTTTTLLLLLLLLRRRRRRHHHGGGGMJJJJJJJJJJJQQQQQQQQQQQQQQQQQQNNNRRNNNNN |  | ||||||
| WWIIWWWTTKGTTTSSSSSSSSSKKKKKKKKKPPPPMMMMWWWKKKKLLLLEEEEEEVVVVVVEEEETTTTTTTTTTTTLLLLLLLLRRRIRHHHHGGGGGJJJJJJJJJJQQQQQQQQQQQQQQQQQQQQRRRDDDNNN |  | ||||||
| IIIIIWWWWGGGVVSSSSSSSSSSKKKKKKKKPPPPMMMMWWKKKKKKLLLLELEEEVVVVVVEEEEEETTTTTTTXLLLLLLLLLLLLLLHHHHHGGGGGGJJJJJJJJQQQQQLLLQQQQQQQQQQQQQQRRDDMMDD |  | ||||||
| IIIIIIWWGGGGGVVVSSSSSSSSKKKKKKKFEPPMMMMMMMKKKKKLLLLLLLEVVVVVVVVEEEEETTTTTTTTLLLLLLLLLLLLLLLHHHHHHHGGGGJJJJJJJJNQQQQQLLQQLLQQQQQQQQQQDDDDDDDD |  | ||||||
| IIIIIIGGGGGGGGGVSSSSSSSSSSKKKKKFFPPMMMMMMMKKKSSLLLLLLVVVVVVVVVEEEETETTTTTTTTTLLLLLLLLLLLLLLHHHHHHHGGGGGAJJJJJDQQQQQLLLQLLLLQQQQQQQQQDDDDDDDD |  | ||||||
| IIIIIGGGGGGGGZZZGSSSSSSSSSKKKFFFFHPMMMMMMMKSSSSLLLLLLVVTVVVVVVEEEETTTTTTTTTLLLFFFFFFFFFFLLHHHHHHHHGEEGDDDJDDDDQQQQQLLLQQLQQQQQQQQQQQDDDDDDDD |  | ||||||
| IIIIIGGGGGGGGZZZTTSSSSSSSSKKKKFFFFPMMMMMMMKKSSSLLLLLLLVVVVVVVEEEEEETTTTTTTTLLLFFFFFFFFFFHHHHHHHHHHGEDDDDDDDDDDQQIQQQQLLLLQQQQQQQQDQQDDDDDDDD |  | ||||||
| IIIIIICGGGGGGZZZTTNSSSKKKKKKKFFFFFFMMMMMMMKSSSSSLZLLLLVVVVVVVEEEEEETTTTTTTTLLLFFFFFFFFFFHHHHHIIIHHEEDDDDDDDDDDDTDDQLLLLLTTQQQQQQDDDQDDDDDDDD |  | ||||||
| IIIIIIGGGGGGGZZZNNNNKKKKKKKKKKFFFFFMMMMMMMKSSSSSFZLLLLLVVVVPVLLEETTTTTTTTTTQLLFFFFFFFFFFHHHIIIHHHHEEDDDDDDDDDDDDDDLLLLLTTTTTQQQQQDDDDDDDDDDD |  | ||||||
| ZZIIIIUGWGGGGZZZNNNNNKKKKKKKKKFFFFBKKKKKKKKSKSSSFZLLLLLLVZVPPLLLETTTTTTTTTTTOOLLLLLLLILIHIIITTTHHHEEDDDDDDDDDDDDDLLLLLLLTTTTTTDQDDDDDDDDDDDX |  | ||||||
| ZZIIIUUGWWZZZZZZNNNNNKKKKKKFFFFFFFFKKKKKKKKKKKKZZZZLLLLLVVLLLLLLEETTTTTTTTTOOONNNNNLIIIIIIIIIIIHHEEEEEDDDKKDDDDDDDLLLIIIIIIIIIIQDDDDDDDDDDDD |  | ||||||
| ZIIIIUZGGGZZZZZZNNNNKKLKLFFFFFFFFFFKKKKKKKKKKKKKZZZLLLLLLLLLLLLLEETTTSTTTTSSFNNNNNNNIIIIIIIIIIIHEEEEEEEDDKKDDDDDDLLLLIIIIIIIIIIDDDDDHHHHHHNN |  | ||||||
| ZIIIZZZZZNZZZZZZNNNNNNLLLLFFFFFFFFFKKKKKKKKKKKKKZZLLLLLLLLLLLLLEEEEETSSTTSSLFNNNNNNNIIIIIIIIIIIHHEEEEEEKKKKDDDDDDLLLLIIIIIIIIIIDDDDDHHHHHHNN |  | ||||||
| ZZIZZZZZZNZZZZZZNNNNNNLLLLFFFFFFFFFKKKKKKKKKKHKKGGSLLSLLLLLLLLLLEEESSSSSSSLLFFNNNNNNNPIIIIIIIIIIIEEEEEEEKKLLDLLLDLLLLIIIIIIIIIIDDDDDHHHHHHHN |  | ||||||
| ZZZZZZZZNNZZZZZZNNNNNLLLLLLFDFFFFQQKKKKUKKKKKKKKSGSLLSLSSSSLLLLEEEESSSSSLSLLFFFNNNNKQQQIIIIIIIIJIEEEEELLLLLLLLLLLLLKKIIIIIIIIIIDDDDDHHHHHHHH |  | ||||||
| ZZZZZZZZZZZZZZZNNNNNNNLLLLLQQQQQQQGKAKKEKKKKEEESSGSSSSSSSSSTLLLJJJESSSSLLLLLLQQQQNNNQQQIIIIIIIIIIEEEEELLLLLLLLLLKKKKKIIIIIIIIIIDDDHHHHHHHHHH |  | ||||||
| ZZZZCZZZNNZZZZZNNNNNNNLLLLLQQQQQQQQKAAKEEEEEEEESSSSSSSSSSGZTTTLJJJJSSSSSLLLLLQQQQQNNQQQIIIIIIIIIEEEEEELYLLLLLLLLKKKKIIIIIIIIIIIDHHHHHHHHHHHH |  | ||||||
| CCCCCCZZNNZZZZZNNNNNUNNLLLLQOQQQQQQQQAKEEEEEEEEESSSSSSSSEZZTTTJJJJJFSJNNLLLLLQQQQQQQQQQIIIIIIIEEEEEEEELYYLLFFLLLLPPKIIIIIIIIIIIHHHHHHHHHHHHH |  | ||||||
| CCCCCCZZNNNNNNNNNNNNLLLLLLLOOOOQQQQQQQKEEEEEEEEESSSSSSSSEZZTTTJJJJJJJJLLLLLLLQQQQQQQQQQIIIIIIIEEEEEEEEYYYLYLLLLLLLLKIIIIIIIIKKHHHHHHHHHHHHHH |  | ||||||
| LCCCZZZZZZNNNNNNNNNNNLJRRLLLOOOOOQQQQTTEETEEEEEEESSSSSSEEEZZTTJJJJJJJJJJLLLQQQQQQQQQQQQQIIIHIEEEEEEEEEEEYYYYLLLLLKMKIIIIIIIIKKHHHHHHHHHHHHHH |  | ||||||
| LCLLLZLZLNNNNNNNNNRNNRRROOLOOOOOOQQQQTEEETTTTTEEEESSSEEEEZZTTTTJJJJJJJJJLLLLQQQQQQQQQQQQIIIHHHEEEEEEEYYYYYYYYLLZLKKKIIIIIIIISSHHHHHHHHHHHHHH |  | ||||||
| LLLLLLLZLNNNNNNNRRRFRRRROOLOOOOQQQQQQTTTTTTTTTEEEEEEEEEEEZZTTTZZJJJJJJJJLLQQQQQQQQQQQQQQQQIHHHHEEYYYYYYYYYJJJJJJJKKKIIIIIIIISSSSHHHHHHHHHHHH |  | ||||||
| LLLLLLLLLNLLLLLLRRFFRRRROOLOOOOQQQQDQRTTTTTTTTEEEEEEEZZZZZZTZZZJJJJJJJJLLLQQQQQQQQQQQQQQQQHHHHHNNYYNNNNNNNCJJJJJFKKKIIIIIIIISSSGHHHHHHHHHHHH |  | ||||||
| LLLLLLLLNNLLLLLRRFFFFFRRROOOOOOYFQQQQTTTTTTTTEEEEEEEZZZZZZZZZZZZZJJJJJLLKLQQQQQQQMQQQQQQQNHHHHNNNYYYNNNNNNCJJJJJFKKKIIIIIIIISSSGGHHHHHHHHHHM |  | ||||||
| LLLLLLLLLLLLLLLFFFFFFFFFFFOOOOOYYAAAATTTTTTTTTEEEEZZOZZZZZZZZZZUZJJJJLLLQQQQQQQQMMQQQNNNNNNNNNNNNYNNNNNNNNCCOCCCFFKKIIIIIIIISSSSSSSSSPXXHMHH |  | ||||||
| LLLLLLLLLLLLLLLFFFFFFFOFOOOOOOYYYYYAAATTQTTTQTTQEEZZZZZZZZZZZZZZZJJJJJICCCCCCQQQOMQQQDDNNNNNNNNNNNNNNANNNNCCCCCCFFFFKKKKKKSSSSSSSSSSSPGGHHXX |  | ||||||
| LLLLLLLLLLLLLLLFFFFFFFOOOOOOOOOYYYYAAATTQQTTQQQQEEEEEZZZZZZZZZZZZJJJJJJCCCCCCYQQOMDDDDDNNNNNNNNNNNNNNNNNNCCCCCCFFFFFKKKKKKSSSSSSSSRSPPGGXXXX |  | ||||||
| SSSLLLLLLLLLLLLFFFFFFFFYOOYYYYYYYYYYAATTQQQQQQQQEEEEEZZZZZZZZZZZZJJJJJCCCCCCCCCCODDBDDDDDNNNNNNNNNNNNNNNNCCCCCCCFFFFFFKKKKKSSSSSSSPPPPGGGNNX |  | ||||||
| SSLLLLLLLLLLXXLFXFFFXXXYYYYYYYYYYYYAAAQQQQQQQOQQQEEEEZZZZZZZZZZZYJJYGGCCCCCCCCCCOODDVDDDDINNNNNNNNNNNNNNCCCCZQFFFFFSSFFFFKSSSSSSSSAPPPPGPNNN |  | ||||||
| LLLLLLLLLLLLXXLXXXXXXXXYYYYYYYYYYYYYYQQQQQQQQQQQQQEEEEZZZZZZZZBYYYYYGGCCCCCCCCCDDDDDDDDDDNNNNNNNNNNNNNNNNCCCZQFFFFFSSFFFFKSSSSSSSSSPPPPPPNNN |  | ||||||
| LLLLLLLLLLLLLXXXXXXXXXXYYYYYYYYYYYYQQQQQQQQQQQQPQQEEEEEFZZLZZZBYYYYYYGCCCCCCCCDDDDDDDDDDDNDNNNNNNNNNNNNNNNCCZQFFFFFSSFFFFSSSSSSSSSSSPPNNPPNN |  | ||||||
| QQQYLYYYYLLLJXXXXJXXXXYYYYYYYYYYYYYYQQQQQQQQQQQPPPPPPFFFFFLZZZZYYYYYYYCCCCCCCCCAADADDDDDDDDDNNNNNLNNJJJJCCCCZQQFFFSSSFFFSSSSSSSSSSLLPNNNNNNN |  | ||||||
| QQYYYYYWWLLLJJJJJJJXXXYYYXXXXXXXXXYYQQQQQQQQQQQPPPPNFFFFFFLLZZZYYYYYYYCCCCCCCCZAAAADDDDDDDDDDNNNLLLLJJJJJCCCQQQFQSSSSFKFSSSSSSSSSSSPPPNNNNNN |  | ||||||
| QQQQYYYYWLLLJJJJJJJJJJSNBXXXNXXXUYYYYIIJJJQQBBBPPPPPFFFFFFFZZDYYYYYYYYZCCZCCZZZAAAADDDDLLLDDDDNLLLLJJJJJJQQQQQQQQSSSSKKKKSSSSSSSHSSHHHNDDNNN |  | ||||||
| QQQQYYYYWLLLJJJJJJJJJZNNNNNNNJXXUUUYYYJJJJQQQBPPPPPFFFFFFFFKKYYYYYYKYYZZZZTTTTZZAAAAALLLKLLDLDLLLLJJJJJJJQQQQQQQQSSSSKKKKSSSSSSSHHHHHDDDDNNN |  | ||||||
| QQQYYYYYYYJJJJJJJJZZZZNNNNNNNNUUUUUUYJJJJJJJJBBPPPFFFFFFFFFKKKKKYYYKKZZZZZZZZZZZZAAAAALLLLLLLLLLLLLLLJJJQQQQQQQQQSSSSSKKKKKSSSSSSHHHHDDDDNNN |  | ||||||
| YYYYYYYYYYYJJJJJJJJZZNNNNNNNNUUJJJJJJJJJJJJJJJJBFFFFFFFFFFFFKKKKKKKKKZZZZZZZZZZZAAAAAAAGLLLLLLLLLLLJJJJJJQQQQQQQQSSSSSSKKKKKSSSSTTTTTTTDNNNN |  | ||||||
| SYYYYYYYYYYJJJJJJJJZNNNNNNNNNUUUJJJJJJJJJJJJJBBBBBFFFFFGFFFKKKKKKKKKKZZZZZZZZZAAAGGGAGGGLLLLLLLLLLLLJJJQQTQQQQQQQQQSSSKKKKKKKESTTTTTTNNDNNNN |  | ||||||
| SCYYYYYYYYYJJJJJJUZZZNNNNNNNNNUUUUJJJJJJJJJJJJBBBBFFFFGGFKKKKKKKKKKZZZZZZZZZZZAAAGYGAGGGGLLLLLLLLLLJJJJQQQQQQQQQQQQSSSSSKKKTTTTTTTTTTNNNNNNN |  | ||||||
| SCCYYYYYYJYJJJJJJUUUZNNNNNNNNUUJUUJJJJJJJJJJJLBBBBBGGGGGGKKKKKKKKKKZZZZZZZZZZZAAAGGGAGGGGLLLLLLLLLLLLLJQQQQQQQQQQQQSSSSSKKKTTTTTTTTTTTNNNNNN |  | ||||||
| CCCYYYYYJJJJJJJJUUUNZNNNNNNNNNUJJJJJJJJJJJLJJLLLBBBGGGGGGKKKKKKKKKKZZZZZZZZZZAABAGGGGGGGGGGLLLLLLLLLLLQQQQQQQQQQQQQQSSSSKKTTTTTTTTTTTTNNNMNN |  | ||||||
| CCCYYYYJJJJJJJUUUUUNNNNNNNNJJJJJJJJJJJJJJJLLLLLLLLBBGGGGGKGKKKKKKKKZZZZZZZZZZZABBBBGGGGGGGGLLLLLLLLLLLQQQQQQQQQQQQQQSSSSKKTTTTTTTTTTTTTMMMNN |  | ||||||
| CCCCCYYCJJJJJUUUUUUUNUUNNNNJJJJJJJJJJJJJJLLLLLLLLLLLGGGGGGGKKKKKKKKZZZZZZZZZZZBBBBGGGGGGGGGGGOOLLLLGGGGQQQQQQQQQQQQQSSSKKTTTTTTTTTMMTTTMMMMM |  | ||||||
| CCCCZZCCJJJJJUUUUUUUUUUUUUUJJJJJJJJJJJJJZZLLLLLLLLLLFGGGGGGGGGKKKKKZZZZZZZZZZZBBBGGGGGGGGGGGGGLLLGGGGEEEQQQQQQQQQQSQSSSSSTTTTTTTTMMMTTMMMMMM |  | ||||||
| CCCCZZZCCCJJUUUUUUUUUUUUUUUJJJJUUJJJJDDJJZZLLLLLLLZZGGGGGGGGGGKKKKKZZZZZZZZZZZBBBBGGGGGGGGGGGGLLGGGGETEEEEQQQQSSSSSSSSSXTTTTTTTMTMMMTTTMMMMM |  | ||||||
| CCCCCCCCCCJUUUUUUUUUUUUUUUUUJJJUUUDDDDDJJZZFFLLLFLZZZGGGGGGGGGGKKKKZZZZZZZZZBBBBBBGGGGGGGGGGGGLLLGGEEEEEEEQQJQSSSSUSSSSMMTMMMTTMMMMMTTTMMMMM |  | ||||||
| CCCCCCCCCCCUUUUUUUUUUUUUUUUUUJJUUUDDDDDZZZZFFLLLLLLZGGGGGGGGGGGKKKKZZKKKKZZZZBBBBBJBGGGCGGGGGGGLLGGGEEEEEEQQQSSUUUUSSSMMMMMMMMMMMMMMTTMMMMMM |  | ||||||
| CCCCCCCCCCCUUUUUUUUUUUUUUUUUUUUUUDDDDDDDZZFFFFLPWWLEGGGGGGGGGGKKKKKKKKKLZZZZZZBBBBJBGCCCCGGGGGGGLGGGEBBEEEEQSSUUUUUSUSSMMMMMMMMMMMMMMMMMMMMM |  | ||||||
| CCCCCCCCCCCCUUUUUUUUUUUUUUUUUUUUUUDDDDDZZFFFFPLPWWWEGGGGGGESSSSSSSSSSSLLLLZZBBBBBBBBGGGCCCGGGGGGGGGGGGEEEEEESSUUUUUUUMMMMMNNNNNNNMMMMMMMMMMM |  | ||||||
| CCCCCCCCCCCCUUUUUUUUUUUUUUUUUUUUUUDZDDDDZZZZZPPPWWPEEEEEEEESSSSSSSSSSSLLLLLZBBBBBBBBGGCCCXGGGGNNKNGGGAAEEEEEEBBUUUUUMMUMNNNNNNNNNNMMMMMMMMMM |  | ||||||
| CCCCCCCCCLLUUUUUUUUUUUUUUUUUUUUUUUUZZZZZZZZPPPPPPPPPEEEEEEESSSSSSSSSSSLLLLLLBBBBBIBBGGCCXXGGNNNNNNGGAAAEAAAENBBUUBUUUUUMMNUNNNNNNMMNMMMBMBBS |  | ||||||
| CCYYCCCCCLLLUUUUUUUUUUUUUUUUUUUUUUUZZZZZZZZPPPPPEPPPPEEEEEESSSSSSSSSSSLLLLLBBBBBBBBIIGCCXCCWWWNNZNVGAAAAAAABBBBCBBBUUUUUUNUNNKNNNNNNNMMBBBBB |  | ||||||
| YCYYYYYCCLLLUUULUUUUUUUUUUUUUUUUUUUUZZZZZZZPPPPPPPPPPEEEEEKKKSSSSSSSSSLLLLLLBBBBBBIIIIICCCCWWNNNNVVVFAFAAAABBBBBBBBBBBBUUUUUNNNNNNNNNMBBBBBB |  | ||||||
| YYYYYYYCLLLLLLLLLUWUUUUUUUUUUUUUUUUUZZZZZZZZPPPPPPPPPEEEEEKKKSSSSSSSSSLLLLLLBBBBBIIIIIIUCFCWWNNNVVVVFFFFAAAABBBBBBBBBBUUUUUUNNNNNNNNABBBBBBB |  | ||||||
| YYYYYYCCLLLLLLLCLCCRUUUUUUUUUUXXUUUUZZZZZZPPPPPPPPPPPEEEKKKKKSSSSSSSSSLLLLLLLBBBBBYIIIIIIFFNNNNNVVVFFFFFFFFABBBBBBBBBBBUUUUUNUUNNNNNANNNBBBN |  | ||||||
| YYYYYYYYYYPPLLCCCCCCCCUUUUUUUUXXNDNZZZZZZZPPPPPPPPPRREEEEEERASSSSSSSSSLLLLLLLBYBBYYYYYYYIFFNNNNNNVVFFFFFFFFABBBBBBBBBBBBUUUUUUUNNNNNNNNNNNNN |  | ||||||
| QYYYYYYYYYPLLLLCCCCCCCCCTTUUUUNNNNNZZZZZZZZPPPPPPPPRNNEEEEEESAAAABBBLLLLLLLLLLYBYYYYYYYYFFKKKKKKKKZFFFFFFFFFBBBBBBBBBBBBUUUUUUUUNNNNNNNNNNNN |  | ||||||
| YYYYYYYYPPPPPLLCCCCCCCCCCCAAUUNNNNNZZNNNZPPPPPPPPPPRRREREMESSQAAALLLLLLLLLALAYYYYYYYYYYYFFKKKKKKKKZZFFFFFFFRRRRBBBBBBBBUUUUUUUUUNNNNNNNNNNNN |  | ||||||
| EEYYYYYYPPPPPPPCCCCCCCCCCAAAUUNNNNNZZNNNZPPPPPPPPRRRRRRRORRSSQQAAALALLLLLLAAAAYYYYYYYYYNNNKKKKKKKKZZFFFFFFFFRRRBBBBBBBUUUUUUUUUUNNNNNNNNNNNN |  | ||||||
| EEYMMPPPPPPPPPPCCCCCCCCCCCCNNNNNNNNNNNNXPPPPPPPPPRRRRRRRRRRRQQQAAAAAALLLLLAAAAYYYYYYYYNNNNKKKKKKKKZZFFFFFFFFRRBBBBBBBBUUUUUUUUUUNNNNNNNNNNNN |  | ||||||
| EEYYPPPPPPPPPPGCCCCCCCCCCCDNNNNNNNNNNNNNPPPPPPPPRRRRRRRRRRRYQQQQQQQQALLLAAAAAAAYYYYYNNNNNNKKKKKKKKFFFFFFFFFFFRRRBBBBBRRRUUUUUUUUNNNNNNNNNNNN |  | ||||||
| EEENNPPPPPPPPGGCMCCCCCCNNNNNNNNNNNNNNNNNPPPPPPPPRVRVRRRRRRYYYFQQQQQEQQQVAAAAAAAYYYYYYNNNNNKKKKKKKKKKKKFFFFFFFFFBBBCCBRRRRRUUUUUUNNNNNNNNNNNN |  | ||||||
| EEEPPPPPPPPPPPPCMCCCCCCNNNNNNNNNNNNNNNNNKPPPPPPPPVRVRRRRRYYYYFQQQQQQQQQQQAAAAAAYYYYYYNNNNNKKKKKKKKKKKKFFFFFFFFFFFFFCRRORRRRUUUUUNANNNNNNNNNN |  | ||||||
| EEEPPPPPPPPPPPMMMMCCCICMMNNNNNNNNNNNZNNNTTPTTPPPVVVVRRRRRYYYYQQQQQQQQQQQQQAAAAAYYYYYNNNNNNNNNKKKKKKKKKFFFFFFTCCCCCCCRRRRRRRUUIUNINNNNNNNNNNN |  | ||||||
| EEELPPPWWPPPMMMMMMCCCCCCMMMNNNNNNNNNZNNZTTTTTPPTVVVVVRRRYYYYQQQQQQQQQQQQAAAAAAYYYNNNNNNNNNNNNKKKKKKKKKCCCTTTTTCTTRRRRRRRRRTIIIINNNNNNNNNNNNN |  | ||||||
| UUEEEPPWMPPPPMMMMMCCCCCMMMMNNNNNNNZZZNNZTTTTTYTTVVPPVVRRRYYYYQQQQQQQQQQASAAYYAYNNNNNNNNNNNNNNNYCKKKKKKCSSTTTTTCTTTTRRRRRRTTTIITTNNNNNNNNNNNN |  | ||||||
| UUUUMMMMMPPPMMMMMMCMMMMMMMMNNNNNNNZZZZZZCTTTTTTTPPPPVVVRRRRYYQQQQQQQQQQAAAYYYYYYNNNNNNNNNNNNCYYCCCCCCCCCCTTTTTTTTTTERRRRRRRTTITTNNNNNNNNNNNN |  | ||||||
| UUUMMMMMPPMMMMMMMMMMMUUMMNNNNNNNNNZZZZZCTTTTTTTQPPPPVPPPYYYYYYQQQQQQQQQQEAAYYYYYYNNNNNNNNNNCCCCCCCCCCCCCTTTTTTTTTTTRRRRRRRRTTTTTNTNNNNNNNNNN |  | ||||||
| UUMMMMMMMMMMMMMUMMMMMMUUMMMNNNNNNNZZZZOTTFTTTTTQPPPPPPPPBYYYYQQQQQQQQQQQQYYYYYYYYYNNNNNNNANCCJCCCCCCCCCCTSTTTTTTTTTTTTRRRTTTTTTTNTNTTNNNNNNN |  | ||||||
| UMMMMMMMMMMMMMMUUUUUMUUUMMMNBNNNNZZZZZZZFFFFTTTTPPPPFPPPBYYYQQQQQQQQQQQQCQYYYYYYYYYNNNNNNCCCCCCCCCCCCCCCCCTTTTTTTTTTTTRRTTTTTTTTTTTTTNNNNNNN |  | ||||||
| UUMMMMMMMMMMMMMUUUUUUUUUUMMMBNNNZZZZZZZZFFFFUUTPPPPPPPPBBYYYQWQQQQQQQQQQQQQYYYYYYYYNNNNNNCCCCCCCCCCCCCCCCCTTTTTTTTTTTTTTTTTTTTTTTTTNNNNNNNNN |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,500 +0,0 @@ | |||||||
| p=44,70 v=-47,36 |  | ||||||
| p=56,4 v=69,91 |  | ||||||
| p=6,30 v=-52,-60 |  | ||||||
| p=64,4 v=35,44 |  | ||||||
| p=57,22 v=-56,48 |  | ||||||
| p=5,22 v=18,37 |  | ||||||
| p=2,48 v=88,-65 |  | ||||||
| p=80,54 v=28,-40 |  | ||||||
| p=76,0 v=98,4 |  | ||||||
| p=7,89 v=33,-33 |  | ||||||
| p=25,30 v=-15,70 |  | ||||||
| p=92,41 v=35,80 |  | ||||||
| p=39,6 v=-47,-20 |  | ||||||
| p=30,82 v=97,8 |  | ||||||
| p=8,67 v=-44,-59 |  | ||||||
| p=87,24 v=-51,83 |  | ||||||
| p=83,33 v=43,73 |  | ||||||
| p=95,59 v=50,90 |  | ||||||
| p=10,69 v=-47,-44 |  | ||||||
| p=15,15 v=91,98 |  | ||||||
| p=73,21 v=-24,77 |  | ||||||
| p=11,22 v=2,-82 |  | ||||||
| p=87,95 v=65,-42 |  | ||||||
| p=26,47 v=33,-20 |  | ||||||
| p=50,58 v=69,-62 |  | ||||||
| p=88,60 v=12,68 |  | ||||||
| p=82,15 v=-97,10 |  | ||||||
| p=47,83 v=81,-93 |  | ||||||
| p=96,92 v=47,-61 |  | ||||||
| p=1,30 v=18,84 |  | ||||||
| p=21,51 v=49,50 |  | ||||||
| p=49,18 v=-70,-88 |  | ||||||
| p=52,0 v=54,39 |  | ||||||
| p=46,30 v=61,97 |  | ||||||
| p=13,17 v=10,-51 |  | ||||||
| p=72,85 v=21,-45 |  | ||||||
| p=99,57 v=42,49 |  | ||||||
| p=96,26 v=74,8 |  | ||||||
| p=79,31 v=-66,55 |  | ||||||
| p=0,80 v=-3,29 |  | ||||||
| p=19,89 v=56,-45 |  | ||||||
| p=13,85 v=-58,-59 |  | ||||||
| p=34,51 v=-84,-38 |  | ||||||
| p=67,96 v=-10,-42 |  | ||||||
| p=75,1 v=-11,23 |  | ||||||
| p=30,54 v=85,25 |  | ||||||
| p=95,66 v=81,79 |  | ||||||
| p=19,77 v=87,82 |  | ||||||
| p=32,29 v=-85,-22 |  | ||||||
| p=52,73 v=14,52 |  | ||||||
| p=82,84 v=43,93 |  | ||||||
| p=74,88 v=66,-99 |  | ||||||
| p=47,18 v=-71,-31 |  | ||||||
| p=98,71 v=2,36 |  | ||||||
| p=28,70 v=24,-83 |  | ||||||
| p=91,42 v=-90,46 |  | ||||||
| p=54,101 v=69,-53 |  | ||||||
| p=33,77 v=-34,70 |  | ||||||
| p=0,64 v=95,98 |  | ||||||
| p=56,63 v=-17,-37 |  | ||||||
| p=43,88 v=-94,47 |  | ||||||
| p=31,67 v=43,72 |  | ||||||
| p=72,26 v=-96,-14 |  | ||||||
| p=52,6 v=-56,-96 |  | ||||||
| p=41,67 v=39,6 |  | ||||||
| p=15,18 v=-14,-63 |  | ||||||
| p=73,60 v=23,-79 |  | ||||||
| p=20,54 v=95,97 |  | ||||||
| p=66,41 v=96,-36 |  | ||||||
| p=80,0 v=56,-71 |  | ||||||
| p=83,41 v=-11,43 |  | ||||||
| p=59,0 v=44,-64 |  | ||||||
| p=92,20 v=-35,-6 |  | ||||||
| p=85,102 v=44,-73 |  | ||||||
| p=24,20 v=-87,-6 |  | ||||||
| p=99,52 v=24,-66 |  | ||||||
| p=40,54 v=-32,84 |  | ||||||
| p=86,53 v=-10,-5 |  | ||||||
| p=69,43 v=-80,32 |  | ||||||
| p=81,95 v=98,15 |  | ||||||
| p=55,76 v=-76,36 |  | ||||||
| p=93,68 v=28,85 |  | ||||||
| p=52,6 v=38,-96 |  | ||||||
| p=76,22 v=-74,-17 |  | ||||||
| p=7,93 v=63,67 |  | ||||||
| p=83,12 v=18,51 |  | ||||||
| p=42,100 v=-38,37 |  | ||||||
| p=47,22 v=-39,10 |  | ||||||
| p=85,7 v=-19,-12 |  | ||||||
| p=39,5 v=26,-67 |  | ||||||
| p=26,38 v=-38,-63 |  | ||||||
| p=95,34 v=35,-33 |  | ||||||
| p=67,78 v=-96,-17 |  | ||||||
| p=51,52 v=92,-19 |  | ||||||
| p=14,91 v=-6,-83 |  | ||||||
| p=22,83 v=17,-42 |  | ||||||
| p=26,38 v=-55,-73 |  | ||||||
| p=84,76 v=-50,-48 |  | ||||||
| p=15,42 v=72,3 |  | ||||||
| p=68,32 v=-19,-63 |  | ||||||
| p=40,39 v=32,49 |  | ||||||
| p=35,87 v=48,17 |  | ||||||
| p=32,81 v=43,5 |  | ||||||
| p=66,71 v=93,40 |  | ||||||
| p=1,59 v=80,68 |  | ||||||
| p=99,60 v=38,71 |  | ||||||
| p=66,29 v=44,32 |  | ||||||
| p=13,18 v=-29,59 |  | ||||||
| p=27,39 v=-84,5 |  | ||||||
| p=21,96 v=-53,-64 |  | ||||||
| p=49,30 v=-55,-79 |  | ||||||
| p=36,51 v=-81,53 |  | ||||||
| p=38,6 v=-31,-4 |  | ||||||
| p=4,79 v=-84,-34 |  | ||||||
| p=1,1 v=25,-85 |  | ||||||
| p=28,46 v=-89,62 |  | ||||||
| p=79,38 v=-8,-8 |  | ||||||
| p=24,84 v=-45,-75 |  | ||||||
| p=55,23 v=-71,-69 |  | ||||||
| p=55,7 v=90,69 |  | ||||||
| p=37,34 v=39,16 |  | ||||||
| p=62,70 v=83,-32 |  | ||||||
| p=99,84 v=-84,45 |  | ||||||
| p=75,83 v=28,9 |  | ||||||
| p=15,41 v=55,92 |  | ||||||
| p=73,99 v=-64,56 |  | ||||||
| p=65,3 v=4,16 |  | ||||||
| p=17,30 v=-15,-9 |  | ||||||
| p=4,73 v=81,-51 |  | ||||||
| p=13,41 v=-91,54 |  | ||||||
| p=49,47 v=-32,38 |  | ||||||
| p=92,82 v=98,63 |  | ||||||
| p=67,27 v=40,-39 |  | ||||||
| p=49,52 v=-1,19 |  | ||||||
| p=73,83 v=-62,-56 |  | ||||||
| p=8,89 v=92,9 |  | ||||||
| p=97,43 v=18,-81 |  | ||||||
| p=59,30 v=60,78 |  | ||||||
| p=4,43 v=-99,-81 |  | ||||||
| p=36,78 v=47,-14 |  | ||||||
| p=9,79 v=-52,-15 |  | ||||||
| p=36,97 v=39,-83 |  | ||||||
| p=62,15 v=-41,-47 |  | ||||||
| p=50,2 v=-93,-4 |  | ||||||
| p=95,10 v=-65,-87 |  | ||||||
| p=63,69 v=68,71 |  | ||||||
| p=0,96 v=65,80 |  | ||||||
| p=44,74 v=29,46 |  | ||||||
| p=100,77 v=-63,44 |  | ||||||
| p=29,0 v=-46,53 |  | ||||||
| p=58,63 v=-18,93 |  | ||||||
| p=48,7 v=-55,-85 |  | ||||||
| p=2,71 v=-45,-29 |  | ||||||
| p=67,26 v=97,73 |  | ||||||
| p=76,50 v=84,-31 |  | ||||||
| p=68,0 v=-18,-58 |  | ||||||
| p=4,45 v=57,38 |  | ||||||
| p=23,94 v=-30,31 |  | ||||||
| p=41,26 v=-68,5 |  | ||||||
| p=36,52 v=-55,-3 |  | ||||||
| p=33,96 v=7,96 |  | ||||||
| p=61,25 v=99,-1 |  | ||||||
| p=86,52 v=-68,23 |  | ||||||
| p=7,43 v=59,-71 |  | ||||||
| p=52,17 v=53,75 |  | ||||||
| p=27,84 v=-75,-16 |  | ||||||
| p=12,54 v=64,89 |  | ||||||
| p=5,37 v=88,89 |  | ||||||
| p=8,51 v=84,-82 |  | ||||||
| p=97,30 v=-4,84 |  | ||||||
| p=68,8 v=-81,78 |  | ||||||
| p=93,79 v=-36,88 |  | ||||||
| p=55,14 v=-17,58 |  | ||||||
| p=9,65 v=-29,22 |  | ||||||
| p=4,81 v=97,-21 |  | ||||||
| p=99,81 v=89,55 |  | ||||||
| p=18,30 v=-61,-60 |  | ||||||
| p=34,102 v=-15,-88 |  | ||||||
| p=96,42 v=-20,-76 |  | ||||||
| p=25,46 v=-79,41 |  | ||||||
| p=56,44 v=-96,56 |  | ||||||
| p=66,8 v=-57,72 |  | ||||||
| p=36,87 v=79,82 |  | ||||||
| p=64,9 v=59,-23 |  | ||||||
| p=1,49 v=21,6 |  | ||||||
| p=38,59 v=-40,-73 |  | ||||||
| p=41,102 v=5,94 |  | ||||||
| p=19,87 v=57,-83 |  | ||||||
| p=30,75 v=24,85 |  | ||||||
| p=67,83 v=-18,58 |  | ||||||
| p=68,3 v=61,-7 |  | ||||||
| p=43,49 v=48,-16 |  | ||||||
| p=8,99 v=-67,-46 |  | ||||||
| p=42,58 v=68,-62 |  | ||||||
| p=70,35 v=-10,24 |  | ||||||
| p=34,32 v=39,29 |  | ||||||
| p=19,9 v=46,78 |  | ||||||
| p=1,52 v=4,-49 |  | ||||||
| p=41,57 v=77,82 |  | ||||||
| p=32,97 v=-70,-26 |  | ||||||
| p=57,19 v=61,75 |  | ||||||
| p=83,15 v=97,5 |  | ||||||
| p=1,9 v=87,65 |  | ||||||
| p=18,31 v=-61,51 |  | ||||||
| p=76,27 v=85,-29 |  | ||||||
| p=68,29 v=21,21 |  | ||||||
| p=93,29 v=89,-30 |  | ||||||
| p=37,10 v=70,34 |  | ||||||
| p=75,1 v=-96,47 |  | ||||||
| p=92,40 v=-42,-35 |  | ||||||
| p=21,20 v=-61,2 |  | ||||||
| p=84,13 v=16,42 |  | ||||||
| p=60,16 v=68,78 |  | ||||||
| p=33,87 v=94,34 |  | ||||||
| p=53,51 v=45,27 |  | ||||||
| p=24,90 v=71,91 |  | ||||||
| p=30,36 v=68,-46 |  | ||||||
| p=59,32 v=68,-79 |  | ||||||
| p=95,54 v=-90,25 |  | ||||||
| p=51,71 v=-40,14 |  | ||||||
| p=57,100 v=-40,-82 |  | ||||||
| p=31,4 v=-69,80 |  | ||||||
| p=84,38 v=8,41 |  | ||||||
| p=76,5 v=-49,15 |  | ||||||
| p=29,95 v=-7,23 |  | ||||||
| p=31,48 v=46,41 |  | ||||||
| p=71,46 v=-41,27 |  | ||||||
| p=8,54 v=-25,-37 |  | ||||||
| p=12,65 v=-22,-65 |  | ||||||
| p=28,54 v=29,-27 |  | ||||||
| p=81,26 v=-76,-75 |  | ||||||
| p=62,4 v=-17,15 |  | ||||||
| p=54,12 v=-96,56 |  | ||||||
| p=80,42 v=-96,17 |  | ||||||
| p=3,44 v=-13,11 |  | ||||||
| p=35,95 v=69,26 |  | ||||||
| p=30,32 v=-8,29 |  | ||||||
| p=76,85 v=49,-84 |  | ||||||
| p=77,102 v=67,-88 |  | ||||||
| p=1,37 v=-28,-32 |  | ||||||
| p=25,88 v=-77,39 |  | ||||||
| p=83,3 v=-58,-20 |  | ||||||
| p=96,10 v=-20,45 |  | ||||||
| p=61,7 v=94,6 |  | ||||||
| p=84,100 v=-58,-23 |  | ||||||
| p=26,76 v=55,-33 |  | ||||||
| p=20,91 v=-37,20 |  | ||||||
| p=51,22 v=14,-93 |  | ||||||
| p=53,84 v=23,90 |  | ||||||
| p=75,68 v=-25,82 |  | ||||||
| p=45,57 v=-25,46 |  | ||||||
| p=20,97 v=-43,26 |  | ||||||
| p=11,70 v=58,-57 |  | ||||||
| p=11,5 v=-27,57 |  | ||||||
| p=25,81 v=9,-56 |  | ||||||
| p=94,87 v=42,34 |  | ||||||
| p=18,3 v=-45,18 |  | ||||||
| p=59,87 v=84,12 |  | ||||||
| p=88,64 v=75,11 |  | ||||||
| p=12,83 v=-9,-68 |  | ||||||
| p=33,52 v=72,-71 |  | ||||||
| p=29,17 v=-38,53 |  | ||||||
| p=95,5 v=19,-64 |  | ||||||
| p=32,32 v=-11,-9 |  | ||||||
| p=87,96 v=-62,59 |  | ||||||
| p=57,3 v=-78,-91 |  | ||||||
| p=60,88 v=29,39 |  | ||||||
| p=98,27 v=43,-66 |  | ||||||
| p=74,8 v=-77,-14 |  | ||||||
| p=72,98 v=91,-72 |  | ||||||
| p=63,64 v=26,1 |  | ||||||
| p=11,49 v=-90,11 |  | ||||||
| p=24,72 v=-22,44 |  | ||||||
| p=69,72 v=-51,-25 |  | ||||||
| p=61,12 v=52,26 |  | ||||||
| p=24,82 v=-70,71 |  | ||||||
| p=42,16 v=-93,27 |  | ||||||
| p=63,95 v=45,93 |  | ||||||
| p=10,88 v=64,20 |  | ||||||
| p=90,32 v=-89,13 |  | ||||||
| p=69,81 v=44,-57 |  | ||||||
| p=33,37 v=-94,-52 |  | ||||||
| p=27,50 v=49,53 |  | ||||||
| p=80,32 v=28,13 |  | ||||||
| p=76,68 v=5,-86 |  | ||||||
| p=23,51 v=-21,-19 |  | ||||||
| p=22,41 v=-14,73 |  | ||||||
| p=73,54 v=91,68 |  | ||||||
| p=22,46 v=94,89 |  | ||||||
| p=7,73 v=95,71 |  | ||||||
| p=12,63 v=-37,14 |  | ||||||
| p=33,12 v=-56,-13 |  | ||||||
| p=88,67 v=89,79 |  | ||||||
| p=29,44 v=-85,-27 |  | ||||||
| p=63,16 v=91,18 |  | ||||||
| p=25,49 v=-24,33 |  | ||||||
| p=70,76 v=-93,45 |  | ||||||
| p=66,47 v=-96,-49 |  | ||||||
| p=52,33 v=-73,7 |  | ||||||
| p=5,39 v=10,84 |  | ||||||
| p=89,65 v=58,-16 |  | ||||||
| p=5,16 v=-91,34 |  | ||||||
| p=27,95 v=16,12 |  | ||||||
| p=27,0 v=-12,23 |  | ||||||
| p=4,20 v=-6,-3 |  | ||||||
| p=91,25 v=20,17 |  | ||||||
| p=51,99 v=46,12 |  | ||||||
| p=34,73 v=-15,55 |  | ||||||
| p=100,23 v=-82,-49 |  | ||||||
| p=19,80 v=-53,96 |  | ||||||
| p=80,5 v=-19,64 |  | ||||||
| p=50,100 v=-16,-80 |  | ||||||
| p=69,44 v=22,51 |  | ||||||
| p=26,76 v=91,93 |  | ||||||
| p=48,88 v=-24,55 |  | ||||||
| p=68,26 v=86,-23 |  | ||||||
| p=49,95 v=31,-64 |  | ||||||
| p=53,16 v=93,24 |  | ||||||
| p=0,45 v=-36,-8 |  | ||||||
| p=19,71 v=-78,-8 |  | ||||||
| p=62,98 v=42,7 |  | ||||||
| p=22,85 v=-99,6 |  | ||||||
| p=48,48 v=-54,57 |  | ||||||
| p=81,34 v=81,32 |  | ||||||
| p=23,73 v=71,-89 |  | ||||||
| p=57,64 v=-4,-47 |  | ||||||
| p=89,17 v=26,-60 |  | ||||||
| p=49,60 v=-45,47 |  | ||||||
| p=25,16 v=13,-46 |  | ||||||
| p=16,62 v=17,49 |  | ||||||
| p=70,83 v=44,47 |  | ||||||
| p=52,3 v=69,56 |  | ||||||
| p=53,3 v=7,-58 |  | ||||||
| p=59,28 v=-24,-4 |  | ||||||
| p=39,67 v=15,14 |  | ||||||
| p=59,71 v=-79,52 |  | ||||||
| p=81,90 v=-58,47 |  | ||||||
| p=87,6 v=51,50 |  | ||||||
| p=32,58 v=16,-5 |  | ||||||
| p=99,3 v=12,53 |  | ||||||
| p=71,13 v=-49,86 |  | ||||||
| p=93,25 v=4,59 |  | ||||||
| p=54,95 v=25,12 |  | ||||||
| p=66,76 v=45,-2 |  | ||||||
| p=78,102 v=-42,61 |  | ||||||
| p=47,54 v=37,-35 |  | ||||||
| p=91,76 v=74,-2 |  | ||||||
| p=98,87 v=73,-72 |  | ||||||
| p=62,99 v=-3,-58 |  | ||||||
| p=44,85 v=-24,-45 |  | ||||||
| p=2,57 v=-13,-16 |  | ||||||
| p=10,19 v=10,-1 |  | ||||||
| p=87,40 v=51,73 |  | ||||||
| p=77,27 v=67,81 |  | ||||||
| p=35,96 v=-32,61 |  | ||||||
| p=84,83 v=52,-2 |  | ||||||
| p=10,63 v=18,14 |  | ||||||
| p=57,101 v=-17,26 |  | ||||||
| p=100,54 v=-59,-24 |  | ||||||
| p=96,44 v=-20,54 |  | ||||||
| p=11,83 v=2,17 |  | ||||||
| p=17,87 v=9,-35 |  | ||||||
| p=35,54 v=-93,76 |  | ||||||
| p=66,2 v=36,23 |  | ||||||
| p=37,59 v=-31,-81 |  | ||||||
| p=67,36 v=-2,27 |  | ||||||
| p=100,34 v=40,-86 |  | ||||||
| p=52,81 v=-94,-2 |  | ||||||
| p=30,10 v=39,45 |  | ||||||
| p=7,74 v=80,90 |  | ||||||
| p=77,79 v=59,28 |  | ||||||
| p=40,33 v=96,98 |  | ||||||
| p=60,70 v=99,-59 |  | ||||||
| p=25,66 v=48,33 |  | ||||||
| p=87,50 v=97,-19 |  | ||||||
| p=86,6 v=35,99 |  | ||||||
| p=16,51 v=95,60 |  | ||||||
| p=72,31 v=84,27 |  | ||||||
| p=99,18 v=-28,-55 |  | ||||||
| p=95,38 v=-51,84 |  | ||||||
| p=71,40 v=-19,-25 |  | ||||||
| p=63,2 v=-2,37 |  | ||||||
| p=65,80 v=68,-48 |  | ||||||
| p=58,82 v=-40,3 |  | ||||||
| p=79,27 v=59,-36 |  | ||||||
| p=8,60 v=44,-30 |  | ||||||
| p=53,49 v=-40,27 |  | ||||||
| p=64,81 v=38,-91 |  | ||||||
| p=62,55 v=-87,-8 |  | ||||||
| p=46,43 v=7,-11 |  | ||||||
| p=69,37 v=-65,-79 |  | ||||||
| p=31,58 v=46,30 |  | ||||||
| p=61,17 v=-87,37 |  | ||||||
| p=56,98 v=-8,-15 |  | ||||||
| p=62,102 v=-24,-9 |  | ||||||
| p=46,28 v=54,59 |  | ||||||
| p=21,29 v=-69,-71 |  | ||||||
| p=83,65 v=67,38 |  | ||||||
| p=94,52 v=59,65 |  | ||||||
| p=32,47 v=31,5 |  | ||||||
| p=95,34 v=-80,-3 |  | ||||||
| p=32,37 v=-54,-76 |  | ||||||
| p=89,18 v=82,-66 |  | ||||||
| p=28,88 v=-47,9 |  | ||||||
| p=62,20 v=98,-90 |  | ||||||
| p=83,83 v=51,36 |  | ||||||
| p=21,89 v=-83,-7 |  | ||||||
| p=58,31 v=84,-79 |  | ||||||
| p=75,49 v=-11,92 |  | ||||||
| p=44,91 v=-39,12 |  | ||||||
| p=17,82 v=-93,-80 |  | ||||||
| p=94,56 v=-54,-82 |  | ||||||
| p=56,43 v=69,-42 |  | ||||||
| p=9,27 v=50,-41 |  | ||||||
| p=6,49 v=-29,76 |  | ||||||
| p=64,39 v=3,52 |  | ||||||
| p=8,73 v=26,6 |  | ||||||
| p=58,83 v=-64,-64 |  | ||||||
| p=26,94 v=-8,-15 |  | ||||||
| p=20,69 v=88,9 |  | ||||||
| p=7,82 v=-12,96 |  | ||||||
| p=33,25 v=-89,68 |  | ||||||
| p=61,40 v=-34,78 |  | ||||||
| p=25,39 v=56,49 |  | ||||||
| p=60,18 v=-20,-42 |  | ||||||
| p=91,30 v=-65,56 |  | ||||||
| p=80,21 v=44,-77 |  | ||||||
| p=74,102 v=67,-31 |  | ||||||
| p=98,76 v=-53,76 |  | ||||||
| p=21,23 v=87,29 |  | ||||||
| p=75,57 v=-25,-78 |  | ||||||
| p=13,11 v=-6,86 |  | ||||||
| p=84,1 v=-19,-61 |  | ||||||
| p=80,23 v=28,-93 |  | ||||||
| p=24,17 v=-92,-85 |  | ||||||
| p=4,55 v=70,61 |  | ||||||
| p=33,84 v=-29,-69 |  | ||||||
| p=30,82 v=24,-61 |  | ||||||
| p=58,30 v=6,-52 |  | ||||||
| p=1,71 v=3,-51 |  | ||||||
| p=53,69 v=-64,-24 |  | ||||||
| p=68,11 v=61,2 |  | ||||||
| p=22,8 v=-69,-12 |  | ||||||
| p=82,93 v=75,1 |  | ||||||
| p=45,21 v=44,-89 |  | ||||||
| p=11,81 v=-75,-29 |  | ||||||
| p=59,77 v=42,44 |  | ||||||
| p=11,34 v=10,-3 |  | ||||||
| p=25,98 v=-69,58 |  | ||||||
| p=37,55 v=30,-51 |  | ||||||
| p=0,69 v=55,-90 |  | ||||||
| p=89,12 v=35,82 |  | ||||||
| p=58,65 v=-25,-24 |  | ||||||
| p=29,102 v=-69,64 |  | ||||||
| p=36,0 v=12,17 |  | ||||||
| p=94,54 v=70,-56 |  | ||||||
| p=48,95 v=90,-68 |  | ||||||
| p=39,59 v=-94,34 |  | ||||||
| p=23,18 v=-21,21 |  | ||||||
| p=84,91 v=-81,-34 |  | ||||||
| p=70,44 v=21,-95 |  | ||||||
| p=87,73 v=4,-16 |  | ||||||
| p=66,40 v=86,35 |  | ||||||
| p=97,30 v=-82,-90 |  | ||||||
| p=86,46 v=-61,33 |  | ||||||
| p=90,73 v=-65,82 |  | ||||||
| p=49,24 v=7,-44 |  | ||||||
| p=76,77 v=-74,17 |  | ||||||
| p=89,3 v=-56,-59 |  | ||||||
| p=57,99 v=-25,42 |  | ||||||
| p=72,101 v=-65,94 |  | ||||||
| p=77,27 v=-81,-14 |  | ||||||
| p=18,57 v=-84,-70 |  | ||||||
| p=18,68 v=95,95 |  | ||||||
| p=47,4 v=-70,-23 |  | ||||||
| p=52,66 v=91,9 |  | ||||||
| p=40,89 v=-23,-21 |  | ||||||
| p=80,19 v=85,49 |  | ||||||
| p=75,8 v=5,56 |  | ||||||
| p=35,20 v=-32,-58 |  | ||||||
| p=47,100 v=35,-63 |  | ||||||
| p=66,60 v=60,25 |  | ||||||
| p=36,81 v=-7,-86 |  | ||||||
| p=17,55 v=-22,-84 |  | ||||||
| p=47,94 v=54,4 |  | ||||||
| p=75,22 v=-59,-96 |  | ||||||
| p=0,48 v=-51,73 |  | ||||||
| p=22,2 v=-22,64 |  | ||||||
| p=100,29 v=53,59 |  | ||||||
| p=68,5 v=-10,-31 |  | ||||||
| p=42,3 v=-54,-17 |  | ||||||
| p=97,31 v=58,-1 |  | ||||||
| p=79,34 v=99,-30 |  | ||||||
| p=95,66 v=-19,57 |  | ||||||
| p=40,52 v=47,46 |  | ||||||
| p=36,102 v=-67,-58 |  | ||||||
| p=75,98 v=-4,39 |  | ||||||
| p=89,90 v=-52,50 |  | ||||||
| p=54,50 v=30,57 |  | ||||||
| p=20,72 v=-84,-32 |  | ||||||
| @@ -1,71 +0,0 @@ | |||||||
| ################################################## |  | ||||||
| #OOO#..O.O#O#...#.O.OO...............OO.....O....# |  | ||||||
| #O#O...#...#...O............OO.#...OO..O..OO...O.# |  | ||||||
| #..O....O#.O..O.O..O#O##.OO..O..........#O....OO.# |  | ||||||
| #...O#.OOO.O.O.O......O.OO.O..#.O.OO#O.#OO.O.O#..# |  | ||||||
| #OO..O....O....#....OO#OO..O..OO..O.....#O.O..O.O# |  | ||||||
| #O.....#.O.O...#..OO.......OO....O.#O.O..#..O..O.# |  | ||||||
| #..OO.O.#O.O.O..##O..O#OO....#.O..O...O.OO..#OOO## |  | ||||||
| #....OO...OO..O..O.#.OOO..O..#O....OO#O..O..#.O..# |  | ||||||
| #....OO.#...O#..O...#.....O......#.....#.....#.O.# |  | ||||||
| #..O.....O.O.O..O....OO#.O.#.O......#..#O.O..OO..# |  | ||||||
| #.#..OO....O........O.#....OO...#.O.OO...O.......# |  | ||||||
| #OO...OO.OO...#.OOO........O#...O.#.OO....OO...OO# |  | ||||||
| #.O..O..OO.OOOO....#..O.#OO.O..O#.......O.#....### |  | ||||||
| #O...O.......OO....#......OO.O.#O.O..O.O.O.#..O.O# |  | ||||||
| #OO#OO....#O...O#....#...OOO.O.O..O..#...O.O#O..O# |  | ||||||
| #....OOO#OO.......#.OO....#...O..#.O...#.O.......# |  | ||||||
| #OOOO....O...O.OOOO.....OO.......O#..O.OO.....O.O# |  | ||||||
| #..#..O.#.O..OO.OOOO...OO#...OOO...O.##.O#.O..OOO# |  | ||||||
| #O......O..O#...#....O...O.OO....O.O....OO..#....# |  | ||||||
| #.....OOO..O.O......O...#...O...........#.OO..#O.# |  | ||||||
| #...#.....O.O..#O#....O.#O#..O#....O..O....#OOO### |  | ||||||
| ####O.....O...O.#.......O.O.O...O.....O.O...O...O# |  | ||||||
| #O...O...O.OO.O.....O.O......O.##.#O#.O.....O..OO# |  | ||||||
| #...#..#...#...OO..#OO.O@.O......O............OO.# |  | ||||||
| #O........OOO.O.O.O..#..#O...O.O..#.OO...#.OO..#.# |  | ||||||
| #.O.#..O...O...OO...#..OOO......OO.#O#......O.OO.# |  | ||||||
| #.O...OO#O...O..O......O..#O....O.....O..O..O.O..# |  | ||||||
| #.O..O...O..#..OO.....O..O.........O#...#O#..OO.## |  | ||||||
| #.....O..#..##........O.#..#...O..##..OO.....O...# |  | ||||||
| #.O..O#...#.....O.O#....OOO.#..#.OO..O..OO.OOO...# |  | ||||||
| #.#OO..O...O.....O.O#.....##..O.O#.O.O....O....#.# |  | ||||||
| #....#..#.....#O.#..O..#......O..O.....OO#..O#.OO# |  | ||||||
| #....O.O...#OO...#O.O..O..........OO..#O....O..O## |  | ||||||
| #O...#..#.....O.......O.O.O....O.O.O..O.O.#...#### |  | ||||||
| #.OO........#.#..........#..O....OO#..#O.O.....O.# |  | ||||||
| #.#..O.O....OO....#O.......#.O..O.#O.O..OO#......# |  | ||||||
| #O...O.....O.OO#...#O.O.O.....O..OOO..O##.O...O..# |  | ||||||
| #O...OO.#O#.O..O..O...O.O......O..##............## |  | ||||||
| #O.O.#...........OO.....OO...O.O......#O.OO....OO# |  | ||||||
| #...OO...OO#.O..O.O...O..OO......O.......O.O.OO..# |  | ||||||
| #.#....O..O..O...O.......#...O.#O..O..O.O.O......# |  | ||||||
| #O....O......O#.O......##.....#.....O.O.O#O......# |  | ||||||
| #.OO.OO..O......OOOO..O#.O...O.O......#.....OO..O# |  | ||||||
| #.O......O.O.OO.O..#..O....O.....#....O.#.OO#...O# |  | ||||||
| #.O..#....#...O......#.O.....OO.O.....O.....O....# |  | ||||||
| #.#..OO.....#.....#O.O.#O......O......OO....OOO.O# |  | ||||||
| #..OO.O....O...O.O......O.O.OO...#.....O.......O.# |  | ||||||
| #..O..O...#.O.O#........OO....O...O.OO...#.......# |  | ||||||
| ################################################## |  | ||||||
|  |  | ||||||
| ^>v<v><>^<>v^<vvv<v>v<><>^^v>^^<<^<v^v>v<>v^<^<^v^v^>>v<><>^<^^^^<v^><v<^^>v>vv>v^><<vv>>^><v<^<^v^v>v>>^><>^^vv^<<<>v>v>>vvvv^<^><v>^^><>v>^v^^<>>^<^<v<v^^<v><v><<>>>v^<<>>^^^<^>><v>>v>^>>v^^v^^^>>^v<vv^>>vvv<<>vv<^>>>^^^v<<<^^<v^^<><v>v<v<vvv^>><><>>>^v>^vv>^><^>>vv^^<^<v^<>>v^^vv^v^^v<v^<v^<><>>>>v><<vv<><^vv^vv><^^^vv><v^<^>><<<v^v<>v><>>v^^<^^>><>^vvv<<><<^v<<^>^v^^v><^<^vvv>v<^^vv^<><vvv<><>>>>v<^^v^<vv<v>^v>vv^v>><<v^><<><<>^v>>><^<^<vv>^^^v><^>vv>>v<^<<v>vv<<>>^>v<>^^<^<><^<>vvv><>><<v^^>>>v^>^<<^^>v^>>>vv<^v><>v<<^>>><<><v^><<<<>^>^^v^<>^>v>v><<<>><<>>vv>v><<^><<><vv>vv<v^v^>vv<<v>v^v^v^v<<^v^v><>v>v<^v^>><>><^<>v^^^^v>^^<^v><v<>^<<>^><^^^><>vvv>>>><<vv^v^<v^>vvv^<^^v>><<<v^v^<vv>v^^^^>v<<^<>v<^>^^>^<<v<^^^^>v>>^^<>v>v<<^<><v^^v<v>v>^<^>><<>v>>v>v>^v<<^<<^<vv<>>>vv>^<>v<v^^v<<vv^v>>^v^v>^>^>^>vv><^<<^<><<^v<v<v<v^^vv<<v^>v>v<^>v<vvv^<>^><vv>^v<^>>vvv>v><v>^<>^<^^>><<^><v^>>^v>>><v<^v^<<<<vvvv>^<<<>^>>>v<><><v<v^v>><<^>><v>v^<vv^^<>>^>><<<<^^>v>^^<<v^^>vvv^><v>v^<<>^<<<^<>>^<>< |  | ||||||
| <<^^^v<v^>^v^>v<^>vv^v<>^<v^<<>>^vv>v><^>^>^<<vv><>v>>v^<^<v<^vvv>>v^><>>>v<>>v<><v>><^^<^^v<<<<v<^^<v^>^^^vv>^v<v<>v<^><v<^^>>v^>v^><^><<>>^vvv>>v<>v<^<^>>v<^<^^<>^v^<^>^^>^v<><^><<>^>v>v>v^vv^^<^v^^<>><<v>v<^>>>>v^v<^>><v<vvv>v>v<<^vvv>>^>>^^>><^>vvv>><^v>>v<<<>v<>v>^<^>vv^^<<<<<<<vv^^^<><^<<vv<<^v><vv>>>><>v<>^>>^^v><^v>v<<vv<^>v>^><^>^v<v>^<v<v^<^^v<^<>>^v^<^<<<^^<<<vv><<<v<^><vv>^>v^<^<>^^^vv><>^^<^v<>vv^>^^^^^<vv<vvv>^^v>^><><v^<^<<><<^v^vvvv>>^v>>^<vv^v^<>^<v<>v<^v>vvvvv>>>vvv<v<<<>v<<><<^^^^v<<vv><<^^>><>>>vv>v<^<v>>v^><v<>^<<<v<<^<^<<^>>^<><^v^v^>^^^^v>v>^v<>^>><^>v><><^<^v>^><<>^^v^v>><><v<^^^>v^vv^v>^^^<>^v<<<^>v^^v>^vv<<vv^^<>vvv<>v><^v>^<><^^>v<<^<>v^^<<>>^v<^>vv^<v<>^v<^v><v>>v^<^v><v^vv>><<v<<vv>><<v^v^^<^>^>>>>>>^<vv><>vvv<<<^>>v<>vv<><>^><<v<v>^<<>^>>^<<><>v<^<^<vv>><vv<^^>^><<v>>^<>><^<^v><<><vv>^><vvvv<v<v<v>>^<v^<<>>^v<><>v^>^^>^>v>vv<^^^>v>^>^vv<^vv^v<<>>>^v^>>>vv^^v<^v^<>v<^<>>v^<^v^^<vv<^<^>>><><<>v<^<<<>>>>><<<>^v<<^^^^^^^>v^^^^^^<^>^>^<>^<>^^v^^<<>>^<><^<^<>^^< |  | ||||||
| vv^>^><<<<^v^^<>>><^v^vv^^>^<^<v<^>>^><vv><^<><<v>v^>v<v<>>^>v^<><^vv<><>>^^v^<^v<<^>>^^^>v>v>><>>v><<^>v^^v<v^>>v<v><>v<vv<v^^^v^>>>^^<^^<^v<^v>^><^<v^^v>v^^<<<^>^^<v<<^^><v>>^>^<^^^<>^v<v<>^<>>^>vvvv^^^^v>^v<>^<<<<>^>>^^^^>^^v><v>>>v^v>>><^v^vvvv^v>>^^v^^<vv<<^^<^v<<>^<<vv<v^<>^vv>^><<<>v<v>v^<v<>v>^<><v<<^v<^<>v^<v^^^v<<^<<vv<>vv^<v<>^^^<^<>^vv>^v><^<<^^^vvvv^v<^>vv>>^v^vvvv>><^>>^^<v<<^^<vv<v^<>^<><<v>>vv^v<^v<^<v^><>v<<^v<v>v^>>v<v^^<>>>v^vv^<><>vvvv<>v^<^v^>>vv^v^>v<<^vv>^v^^v<<<v><<^vv><<^>>^^v<v>v<>v>^^>>^^><v>>v^<>vvv^>v<^<>v^><><<^<v^^<v^^^^v<v><<v>v>>>v^^<><v^<>^<>>^<>vv>><^><v^^^<v^^>v<^<v<^<v^vv>^<v^v^>>>v<^vvv>><<>^^>^<^v^^>><>v^^>><^><<vv>>v<^>vv>>v>><v<^><vvv^<^^^v>^^<^v><>^v<^vv^^>v><^v>^>><<<<>^v>><><^v^v>><>v>>><>^^^^<^^v^<<v<>v>v<^^^v<^<<>v<><><vv><v><^^>>^>^v>^^><><^v>^<>>^<<v<^v^v^><^^>^><<v^^v<<><^^>vv>vv^<v^<<<vv^<<>^vv<^<<<><vv><<^v^v<<v>>v^v>^<^^>>>>v^^^<>><v^<v^><><<>^v<^<v<^<<<v^v<v<v^v<^<^<v<><^<>^<<>v<<^<v^vvv>><^^^^><<<^^<<vv><^v<^v^^<^>^^<>>>^>><^^>^^>>< |  | ||||||
| <<<<<>v^>^<^vv>^v^>^>^v<v<<<^v^v>vv><>>>><^><>>>^<vvv>v^<>^v^<<v^>>v^v^vvv>^<>v<>>v^<v<^vv><^>>^>v<<v^<^><>^<^>>v<^^vvv^<<<<^vv^vv^>>^><^>v^>><v><v^^>>><v<^<^v^<v^>v>><v>v^<^>vv<<^^^^^<<>vv><^<^<><^<>^<^>^v^^<v<<>vv<^v>vv<<<vvv^<^>vv><v>>><v<>>v>^^v^^<>>^v<>><>v<>^v^>>>>^^^v^^^><v^v>^^<<<^<<^>^><^><<^vv^^v>v><>^<><^>^<<>>^<v^vv^^vv<^<^^>v>v>^vv<^v>>^>>v>><vv><^<<<<vv>vv>>^^^><<v<<<>v<<<>>v^<<^vv>>>^>><<>^^<<<v^<<><<><<<v^^^>><^v<<<v>v^v^<<v<<v<v^vv<<^vv<v><^>^<v<<v^<v<>^^<^^v><>^v<v<^^v^<><^<v<v^<^v>>v<vv<^^^<^^>v>v^^vv<<<^<vv>^<<^<<^<^^v^v>^v^>v<>>>^v^v<<v<^vv>>^^^>>^<<><^^><v^^^<vv^^^v<<<v<^v<>^^>v<^v<^vv<v<>^vv>^^^>^v^^<>v>^^>v^vv^v><<<^<>v>vvvvvv>vv<>^>^^>>^>^<<>^v>v^<^vvv>^^^^^v<>><v><vv<<<^v>>^v<>>>v><>v>^>v<>^>>vvvv<><><v<^>>vv^^<>>><v>^^v<v<<^^^^v<<><v^<^<vv<<<^<v>><<<>v<v<<<<<>^<>><v>^^><v>^>^^^><>v^v<^v^vvvvv<^^<v>v^v>>>>v^^^<>v<>><<><^<^v^v^<v^v<>v>>v>>^vvv>>>^^>>><^v<<<^>^vv>>v>>>^><v<^>>^<<v>>v<<<^vv>^v<>^v<^><^vv>v^v^vv><vv>v<^^>v>v><><><^><v^v^<v<>>^^><<^<v>v^>v^>^v<^v<> |  | ||||||
| >v>>><>^<^v<<<>^v>v^^v>>^<<^v>><^<v^^^<<<<>^^v<v^>><^^<<<<<v^vv^v<v^^>^>vv^v^<<<^<>v^>^<<<vv^<<<<vv><^v^<^<><v<v^v^<^vv><>^>v<>v>v<<vv<^>^>>v^v<^>v>^^v>v<^^v<<<<^^^<<^<v^<>^>v<vv>><vv<^^<>^>v>v^vv<>^<v^^>vv^>>v^^<>>>><v<>vv^>vv><^^>vv^v^^>^^^^v^v^<v<><^v>v<^^<><>vvvv>>v<v><<<v<<<>^v<^v^v^^>vv^^<v><<^<^vv^^<<<<><^<<>>vv<v>^<^^^<<v^^v^^>><>v^>^>>><<<v>>>>^vv>v>vv>^<<^v^^^^>>^>v<^^>>^v>>^v<>>v<v<>>>v^><>^v<<v>>>^v<>>v>>><<>vvvv^>><><^v>^>>vv<vv^>>^<><^v><^^v><<<<>vv<<^^v<^>vv<^^v<<^><<vv^^<^vv>v<<^v^<^v<<vvv>v<><><^<<>>v^><>^^^vv^>><<vv>^v^^<>v<<vv<^^^^><vv^v>>^^v<v<^<^<v>v<<<v<v<v>>vv^>>>^>v<<vv>>>v^v^v^^v^v>vv>><>vv<<^<^<>vvvv>^^>^<v^<<v<<v^^<^>v<<^^^><^v<^<>^>><^<>vv^>^<<^>>v^<<>v<>^v^v^^<^<>>^><>>^>>^><>v>vv^><^<<^>>><vvv^<^>^^><^^vv^<v<<>v^<^>>v>^<v>v^<v^^<<<v^>>^<<>>>^>v<vv<^vvv>><<><>^v><<^^>^>v^v>vv^vv^<>vvv^<^>^<v^><>v>^>>>v^><<v^>>vv^<v^v<<v<v>v^>^>^v^v^^vv>^v^<v^><<^>v^>v<><vv^^>v<^>^v>^v<><<>^>v^<^vvv><^^>v><^><^>>v>><<v><^^><<<<^^^<^>vv^v>v^<<<>>^v^v<>^<^<v^^^<^>><v^<<v^<^^^< |  | ||||||
| v>v><>^^^><<^v^>v<<>^<<<<v>><<^>^vvv^><v<^<^<<v^v^vv^v^><>v>^^v^<^<^<v>v^><<>^>><^vvvv^^^^v^vvv^^>>^<vv^<^<v^<>^^<^<<^v>>>>v<vv^>^^>v<^><^v^^><^^^v>><>><vvv>v^<<v^vv>v<^><vv>v>v^<><>>v<^>^^v>v<v>><>v<v^^<>v>v>^v>^>^<<<^^vv<<<v^v<vv<><v>>>>v>v<>v<>>v><<><>^^>v<^v>v<^v<^^^^>^^^^v<>v^v^vv<^^^^>^^<^<<v<v>>>><^^>v<<^^^v^^^v^v>^><vv>^><<<v>^<<>v>v>v<^<>>^<<<v><^^<^^v><>^v>v^>v<v>v<v^><><<^v^v<<>^>v^v^<^v^v>v^v>>^v<^vv<^<v<v>>^vv^^^>^<^^^v^>^>>^vvv^^<vvv>vv^>^v<<<<v<v<v>v^^^vvv>^>^^^>v><vv<<<>>><><v>^>^vv>vv>^<v^>>^^<>v>v<<>^>^^v>><><>^>vv>>v>>v^<<>>^v<>vv<><><<>^v>>>^v><^<^>vv>^>><<>v>^^v>v>^>v>>v<<<^^><^v>v>><<^<<^v^>^>>v>^v>v<<><<^^v>><v<<^>v^^<v^^^^^>>>^v^<v^vvv^<<<>>>v<vv^v<^v^<^v^vvv^^<v>><<vv><<^>v<^<^vv<^>v>^v^^<<>v<<>v^<>v<^>>>vv>^vv>vv><<>^>>v<>v<v<>v<^>^<^^^v>>^>v<v^>^^>^^<>><^>^<v^><v>v<>>v^^^^>>v^v^v>v<vv^v><>v<v<^^^<^<v^^v^>vvvv>v^<>^v<v>v<v<v^>>v>v><>^><vvv>v>^^v><<>v^<<^>v><<<><<^>>v^>v>^>^v^<<<>>v^<<><^^vv>v>v^>v<^^v^<v^v>^>>>><<>v>^<>^vv^^>^>v<^v><>v<>>^v><v<>^<><v^>><>><><< |  | ||||||
| ^^v^<v^><><<vv^v^>><^v<<<><>>^vv><v<^^<>><^>^^<^>>^v^>v><<v<^>>vv>>>^>^^^vv><>><^<>v>><>>^^^>><v^v<><v^^>^v><<^vv>>^v<^v>>^vvv^^<>v>>><>>^^<^vv><<<<^v<^v^<<>^<<<<><vvvv^v<<^v^<><^>>v^>>>v<^v^<>^<<v>>v<^<>v><>>v>vv^^<^<<^>>^vvv><<<^<^^v<>>v><<<<>>>v>v<<>>>>^^v>><>^^v>vvvv<><<vv^<^^^v<vv<<v^^^v<v>^<vv^<vv<<<v>><^vv>>><>^<<v>^^^^^v><vvv<<<v^vvv>^<><^v^>>>>^v<^v><><^<<<v<<vvv<^v^^<v^><v^><^>^^^<vv>>>^<>>>><<^<v>v>^>>><^<<>v<^<>>^<^v<v^><v>vvv^^v^vv><vv<>v^>^>vv>^<<^^><v>^vv>v<<>^>v<^v<^v<>^v>v>^>^<^^<v<>vvvv^<<^<<>vv^^>>><^v^v<^v<v>^v<<v<vv^<^vv>v<^>>>>><<<<<<^>><>^^^^^^<>v>v<^<^<<vv>v^^^<^v<>^v<>><^><>^<v<^<<<>><>v><>>v<><^><^^v<>^>>v>^<><vv^><vv><><^<>>^<^^^><^<^v<^<v<>vv<vv<>^v><^vv^<^><>vvv^<v>>^>vvv<^v<^v<^<^v<>^v><vv^<<>><><<>>v>^v<v>v<^>vv><v^>>v>>>^^^^v<vv<>vv^^>^^<>>^<^<^><>^v<<>^v^^v<v<^<<vvv<vvv>v<vv<<<^<<v^<>><><>^^><v<>^>>^^<><v>>^<<>vv<^v^^<<>^>v^><v^>^^>v>v<^^v<^^v><>^v<vv^>^><v<<<v<>^v>>^^v^^<>vvv^v^>^v^<><>vv^<^>^v>>^^<<^<>v>v<^^v<>v^^^<v<<^^>^>>>v<>^v><v>>vv^vv^v<v<v><^<< |  | ||||||
| ^^<>vvv>v<vvv^<^<><vv<vv^>>^<v>>^>>v<^<v^<^>>v^vv^<^>^^>^vv>v>^^<><<<^^<>>><<<<><v^v><^>v>v^v>v<v^vv>^>vvv>>^>v>><<vv<v^<><v>^v<><^<vv<<>>>v<^<^<v^<v><<<v<<<vvv<<v>^<^>vv<^v<<^>><>v>v^>><v<vvv>>^<^v^>><>v^>v>vvv^>>>vv^v><<v<>><v<<^v>>^vv^<><<<<>^><^v<>^v^<^>^vv^vv<^><^<<^^>v<v^><>^>><^^<<^>>>v<>><>^<^^>vv^>^>vvv>v<<>>^v<vv>vv<<<^>v^^vv>>^<>vv^vv<<v^^<<<^<<<<>^>v<<v>>>v<>^<>>>^>v^^<<v^v<^^v^><<<<^vv<^<^<^>^>^>>v<^v^<<>>>^<vv<^>^v^><v^<<>><<><v^<^^<<vvvv>v^v^>>^vvv<<<><<<^<<^<^v^<v<v<>v><<vv^<v<v<<<><>>^^v>^<<^<>v<^<v>>^>v><><^<<<>vvv<v^v><<^<<^^>^<>^>v<<^v<v>v<<^^v<v><v^v>>vv>vv<>>>^v>^v<^^>v^><^<v^<<^<>>^v>>^<v<<>>><<^<>v<^^^>^^^v^^^vv>^<><^v<<<vvv<^>v^v^v^^>v^<>vvv<^<<vv<v<^vv^v<<<vvv^>><>^v<<>>>><<^>vv^v^<><^>><>^>>v<>v>^>>v>><vv^v><^<^>>v<<><>v>^<<>>vvvv>><<^^v<vv>v^<^<>v^v<>^><><<<^vv><v>v>^^><<^<^^>>^vv<^>>v^>>vv<>>>^>>^<<<>v<>v^<>^vv><<^>^^>><<^^v^v^>v>>>>><^v>v^^<vvv^><^>>>>^v>^>^<<^^v^<v<>^^<^v>^vvv<^^<<>^><^<^^^<>v^>^<^^<v><v>^><<v<^>^>>v<<v>>^v^>^<<vv><>^>^vv><<v><<>^<>vvv^>^ |  | ||||||
| vv^^<v><<v>>v<>>^v^v>^^><<<<><>>><>>v^>>>>v^^<<<v>>^v>v^v<>><^v<>^^><>^<<^v>>>^^<^><^<<<<v^^>^<^vv<v<v>v^>>v<v<>v^^vvv<^>>>>vv>^vv>^v>>^^^^v^>^><^^v>v^>v<<<^^><^>v^<^v>>^<^vvv^<><^^v>><v<^<v^<<^vvv^^<>^<>>v^>v^<v^><<<>^^>vv^>>v^v^>^^v^<^^>>v>v><><><<v<^^v<^^<^^^>v<v^v><^><^v<v><^v^^<>^^v<vv^vv<<^>^^^>vvvvvv>^^><v>^v>>>>>v<v^>>vv>^^^<<<<>^><<<v^vv><^>v<^>><<v><>vv>^<v<^<<<><><v^<^<>^<<^>^^^v^vv<v>^^><><>vv>>v<<><>vv^^^>>>^>>>v>>vvv^<^^^<v^>vv>>^>>v^>v<v<>^vv^v>>^<v><vv^>>^<v>^><>><><<v<^v<v^<v><v>^<><><v^v>^<>v^><^^<^vv<v^v^^v><>vv<>v<^^v<<^<v^>^<^<>v^>vvv<<^v<>v^><^<>v^<>^<v<<<<v^>vvv>^v^<^^^^>^v<v^>^v>v>><v^v<><><<<v^<<<v^<>^>><><vv<>v>^vv<vv<^>>><v^vv>^vvv>^^<^v^<>v><vv<v^^v<>v>^v>>^v><vv^v<>><<<<>>v>^<vv>v^<<>><<^><><^v>><<^>v<v<^^vv<<>>v^<^>vv^^<^^>^><^><<v>v>^>>><v>^<>^<v>v^>^^<><v<^<^^^^><>><vv<>^><<<>>v<<v<<v^^v<<<^>vv><<>>>^<<v<<v^<v^<v<^<^^>>v<<<<>vv>^^^><<vv<^^v>^<^v^vv>>^^v>^>^>^^>^v><^><>^v^<<^<v<>vv<<v>v<>^<<^^^<<<v<>>^>^v><>v<^<<<<^>>^<<v<<>^^^^v<vvvvv<<^<<^>>v^<^v^><<^^> |  | ||||||
| <^v^^<<>vvv^<^v<<><v<v^^^v^^>>v^^^^<v<>vv<^^vv>^^<v><<v^^^v^^v^<<>>v^^<<^v^<<^<<>><^>>^^>><^><^>vvvv<^>>>>v<v^^<v<<<vv^><v^^v><<>>vvvvv^v><>>^<^<^vv><v<^vvvv<<v<v^<<^v<^<v^v^><<>vvvv<^>^<^><^v^vv^v<^^>>vvv^v><>^>v^<v<^^<<v<<><^><^>^v^v^<^>>vv<^vv^><v>v>>><v<<>^<^^>^>>^<>^v<>^^v^^>>^^^^><>>^>>vv>^<^^<v<v<^<^^<<<^<^^><v^<>^><v>^v^<<>^^vv<v^^>v^v^^v<<<<<>^>v<<^<<vvv>>v>>v<vvvvvvv<>>v^>>>>v<v>^v^<^^><>v><vv<>v^>v^^<>vvv<v>^>^^^^<^<>^vv><^v<^>v^<v>^v^<<<^v><vv^>><^^>^><<v>>>vvvvvv>vv<>><^<^>^v><<>>v>>v><^>><<<^<v<<<<<v^v>><><^vv^vv<<<vv<<>>v>><^vvv^v>^>^v^^^vv><><^><^<<v<<^<>><>^<><vvv><^^><<<><^vv<<<>v<<^vv>^v^v<<^^^^>>^^>>>v<v>^>v<>^^<^>^>^v^v<^<v><^<v^<<<v<<^^^>>^<>v><^v>><v^>>^<v<vv<v><><<<v><^><v<v<<<<vv^<^><^^^v><v^v>v>^vv>^^v^>v<><vv^>v<v<<v>^<vvv<v^v<<<>v<>^>^>v<<v>v^vv^^^>v^<<v>>^<vv^^<^<^^v><^^vv><vv<<^>>v><><^v^vv<v^>vv><<vv<^>>v>^vv^^<>vv>v<<>v<v>^v^v^v><v><>><<^^<>>^^<v<>v<v<<v<><<><v^>v<^><v<<vv^^v>><v^<>v>>^>>>vv^><><<v<>^v><>^><^>vv^^>>v<v<<^^<<><<><>>><^>>><><v^v>v<vvv<v>v^ |  | ||||||
| v>^<^<>^>>^^>^^v<^>^vv^v>v>v<^v>^<v<v^<v^v>>>^^><vv^<^<>vv<>><v^<<>>^<^^v>>>v^<<<^v^<v^<v><<^^^v>^v^<v^v<^v<vvvvv>^<^v^<<<^>^<<v>^<>><<^^<^vvv>v>^^^>><v<><<<<v^>v^^<<^^<<><>^^>^<vv>^^>^>><<vv^v^<><>^>v><^<^<^^v<>^>v><^^v<v>^<vv^<vv^>^<<<><^<>vv^<^<<v>v<<<<>><<^^^v><>v>^>^<<vv^<<><^>v<<<<vv<v>v><<v<<<>^^v>>><<<vv<<<<v>>vv>><v<>><^<>>v^>^v^v<>v<^<>v><<^<^^v>>><>^^^vvvvvv>v<>><<^v<v>><^v><>v<^v><<>v<^^<<v^^>vv^<v<^>>^^^v><<<^<^^vvv^<><<^v^v^<>^^<<<>v<^vv^^^<vv^v>^^<<v>^v^^^^^vvv<<<v^^<<<v^>>v^><^^^v<v>v^>v<vv><vvvv<>v>^vv^v<<v>v>>^v>^vvv^>>>>^>v>>^^vv>>v^v>v^^<<^<^^><^^v^<<>^vvv<^<><^<v>v^><>>vv><v<<>v^^<>vv^<><<<v<<>vv<><<<><<v<>><^>^<^<>>v<<v>vv<>vvv>>^v^v<<>^<^>^v<<^>>>^^>v^<v^v^v>^^<<v^>v<>^v^vvv<<>>>^vv<v><^<><^<<^<><<^vvv>>><v^v>><>>^<<><^<v>><vv<<^<^>v<>>^><>v<<v^><>^>^^>v<^<vv>^v<<<^<^>v^<<v<>^vv^<^^^v^<v<vv<vv<^>^v<^v>><^>vvv^^<<<^^<<<><>^vv^>^<^^^>v^v<>^>^><v>v^>>>><<>^>>>^<><vv<<^<>v>v^v<<<<<^v<^<<^v<v<>>vvvv<<<<<v<<v^^vv^>^<>v>^v^>^^>^><<v<^^><>><<^^^>vv<<^<^^<<>^<>^v>^v<v^v<< |  | ||||||
| <vv>^<v>>>>><v^^>><<v>v^><^v^><<>^^><vv^^^><^^<^<>>^<v>vvv<>v<<><<^>vv^v^^vvv>v>>v<<<><>>v<<>v^^^<v>v>>v^<^^<>vv^<>v><v><^><><<v<^^<<>v<v^<vv<^v^>^^><^>^<v^^vv><<v<<<^^>^>^v<<v>><>^v>v><<<v>^>v^<><<<>^^><><v^v^v^v<v<^vv<<v<<>^<<v>vv<^<<^>>>v<v^>^^<^<v><^v><^v<<^^>>vvvv^v>>><^>>v^^^<>>>^^>>>>>^<>v>^v>vv><^><^v<<<v^^<<^>v^^v>><v<v^><>>^>^>^^>^vv<<>>>^^^v^^v^<vv^>>vv<vv^<><>v<>^^vv>^<vv^><<><<<<><>v>v>>>>^><>>>>vv><<^^>v^><^>v^^>>v><v^>v<>^<<^>>v<^<>^<><>><<>><vv>^<<^^^>v>^>>v<^v>^vv<<><v<>v><v<vvvv>vv<v>>v>^^>>v<v<v^<v<v>><>^v^<v><>>>^<^<^><v<>v>^<^<^<^^<<^^<^^^^^v>v^>^>^<^><^vv>vv><^<><<<<><><^^^^^><^><<>v><vv^>vv<^^<^vv>><^^v<<v^>^^<v<v<<<v^^v<^^v^v<^vv<v>^^<vv<<vv<vv<v>^<>^<v^v><vv<vvvv>^<<<<<><v>v>^v^v<^^v>v>v<<>>>>v<v<<><<^<>v>><^<^^>>><^v^^v^>>^vv>>^v^v^^<>^><v<><<<^>^>^><>^>>^v^^vv^^^^^<^vv^^^^v>>^<<^^<<^<v<>^v^^vv^^v<v<^<>v^<v<^<><<>>v>vv<><^>^v<<^^^^<<^vv^v^><>^v>v><v><v<<><^<<^<<v>v><>^v>>^><vvv<>vv><<>^>^^<>vv<>vv<><v<^<<^^>vv>vv^^<^v^v><<<<v^>v^>v^^<v^^>^>^>>>^><v^^><<<>^>vv< |  | ||||||
| >><>><<^^v>v<v^><<<<^v><^^vv>^<>v^>>vvv^<^>vv<<^v<v^>v^<>^<v<v^v^<^<>>vvv<<<>v^vv^^><v><^^>^^vv^^^><v^>^>v<<vvvv>v^<<vv^><^v^^<<>^<v^<>>^vv^v^^<^^vv<v>v>^<^>>^^^v<>v^v>>^>^^^^><<<<^>>v<<><><>><^^<vv^v<>^<v<><v^<^^^v<<vvv<^^>>v>v<<v<<<<<v^>v<vv><<<vv><v^^<^<><>v^vv<^<<<^<^>>^>^<^<^vvv^v<<v<^<<<vv^>^^v^^<^^v>>v<^<>>v^^^v^>^<^v>>v^>><>vv^^<<v>>v>>v^vv^<>>^<^>^vv<^v^>v><^^^>^v<>^>>v<^<<>^vv>>>><>^<>>>^^vv>v^^^^<v<v>v^^^>>v^<>^><>v^^<v^>^>>>>^^<v>^^>v^><^>^v<v>^>>>>>v<^><v<^v^>>v<<<^^^>^>^>>^>>v^^>v<><<v<>><<><>v^><v^vv<><^v^><^v<>v^^<>^>>><v>>^><<v>^vv><<^v^vv>^<><^^vv^>><v>>v<v>^<>^v><><<^>v<^<>><^vv<v><v<>>><>v<<<^>>>^v<>><>^><>>^^<>^>^<^><v^<^^<^><>>v>>><<<^^<^<^><^>v>><^<v>><v>^>vvv>^^<>v<<v^>v>^^>v>^vv><<<^^^v^vv<v>>><<>>^v^v^^><>>>>v<v^v><v<v<<v<>>^v^^v^^^v^v^^^^>>^>v^^v>>>>>><<>v^v^>^>>^<^><^<^<>v><<<>^vv^^>^<v^<v^<><v<^<v<<<^v<>v<>^v^<v^><^>>vvv^<^<^v<^>>^>v<^^>>v^^vv>v<<v<>vv^<<<<v>><<>^><<^v<>><>v>v^<v<<<^^v<>><><^^<^v^^^<<^^^>v^>>vv<^^v<<<<<^><^v^<v^>^^vv>v<^v<vv>v>v><^<^^v>>><^ |  | ||||||
| <v^v^v<v^<>>>^v>><><>^><^v>vv<^^^>^vv<v<<>^v>^>>^>>v>^>^^^^^v<<vv>^^^<^<>^>>v^>>^>v<<>^v>^<<v^v<^^v<v>>^v<v^v>v>>^>><><vvv<^^v>^<v>>><<><v^^>^>^>^^^^^><<<>>>vv>v<^v^v^^>v>^><<vvv<^<^><^^v^^^^>^^v<^^>>^v^v^^v<><<^v<^^v^><v>>v<<^^v<<>>^v<>^<>v^>^>^>v>>^v>v^v^<><vvv<>v>v<><>v^^v>>>v<^<<v<<v^^<v>>v><^<<<<<^<<v<^<^>v^v<^^>^v>>^v>vvv>>>>^^v<v^v<>><<>vv>^<><^vv^^>>>v^<v^>^v^^v<<v^<v^<v>^v^<<^vvvv<^v^<^>^<>vv>^^>vvvvvv^>><v><^v^^<v<<^<vvv<><^>^^<^<^<vvvv<^^vv>vv^>v^><<vv<<v^v^>v<v<<v>v>v^vv^v^<^^>v^<<<>v^>^><><<^v<<>v>>^<><^<^v^^>v^^^v^<<^<>>^^>^<<<^>v<>^^^vv>^>^vv^>^vv^><<^>^v^^v^>>^v<^v<>v<>^>v^<^<v><<<v>>v>^^v<^v<^^v^>v^>v<<^^<<^^vv^>>^<^v>^>>v^^v^v^^<<v>^vvv>^<vvv^^^>><v^>>>>v^^>v<v>vv^^v<v^^><^>>v<<<v^v>^v><^>>v^^^vvvv^<^><<^^<>^>>v<vv><^vv>>><v>^<>^v^^v<^>>v<><><>>v>v<^^<vv<<v^>>vv^<<^v>^v>^^v<>>><<vv><^<v<<vv<<>><><<>vvvvvv^<^v<vv<<<v><>vv<<<>^v<^<v<v^^>>vv>^<<v^<^vv<^>v^^^>^vv><<<v^^>^<>^vv^>^<v<<^>>^>^><^>v^v<<^<v<^v>>^<<>v<^^^^>^>^^>v>v<<v>^vv<vv<^^>^<>v<v<<<^<<<v>^><>><<<>>v>^v^v>v> |  | ||||||
| >>>^vv<<^^>^>v>>>v>v>>^^><>v^><<>^<v^<^>^<><^vv^<>^<^^v>^<>^^^<><v^<^v^v>>v^v^<<<v<v<vvv^<>>^^^vv>>><<^<><<<^^^^<><v<<>>>^>^v^^^<>^>>^^>v>v>^<>><^^^<^^>v^v<^<>>><<v^vv^>^<>v^^<v^v^^^^><vv^<v<^<>v^><>vv<v>v<>^^><v>^^v^v^v><>>v>v<^>^><v<>^>>^v>>>>>v^^v>^>>v<<^vvv<^v>^^v<^>v>^v><<vv><v<<<^>^<>^v<v^<vvvv^^^^^^v>v<>>^v^^^^^^<^v^>^^^><><<<<v^^>v^^^<>>vvv<<<>v<>^^v<^<<>^^>^^v^<><^^<<v<>vv^>>^>>^>v^>>><v^vv<^^><>v>><<^<<v<>>^v^><^>v>>v^v<>>><v^>>v<><^>^^v><^^<>>>v<v<><>^^<>^><^>><v<<v<<v>^v<>^vv^>^<<><>>^v<>v<v^<>>v^v><^^<>^>v<>>><^>vv<^>vv<v^^<<^v^<v^v>^><v^^v><^v^<<<>^>v>><>v^v<^<>v<^^><>v><v>vv<v<<v<v^>v^<vv^>v^vv<><>^>^v^^<v<v<^v^<^<<^v^<><vv><>v>v^^<<>vv>><v><<vv<<^^>^<^^<>^^><>>v>>v<v<^>^<<<v<^<vv^<<vv^v<>v^><^><v^<vvv><vvvv<>>><v>>><<^v<^vv>v^<v>^<<<<^^>^>vv>^>>^<vv><>>^<v<vv^><<<<<^v<<^v^^v<^<^vv>^><^<<^><^^>><<>v<>v>^>v>>^<v^>v<<<>v<>>v<v<^><^^^^v<v><>v^v<<v>><^<><^<>^>^^>>>><>^<<>>^<v><>><^^<^^<<vvv^<<<<v>>^^v<<>^v>^<^^>v^vv>vv>><^<^>^^<<>>>v<<<>^>>^v<>^>v><vv^^v^<^>^<v>v><>^v^><<v^< |  | ||||||
| ^>v>>>>>vv^^>^^^v>^^v<>v>v><^^v><><v<>v>><<v>>^>^>^^>><^>^>v><v>>v^>^>>>>v>^v>>^<<^<<>>><>><^^^>^v<v>>^>>>>vv>^><>>vv^<<<>^>^^><v><>^><<<<^v>>><v>v^<v^^>>vv<>>^v^<v^vv>v^<vv<>^>^<><>^<^<>v>>vv^v<^v^>v<>>v>><v^>^^>^^^v<><^>><vv^<<^>^^^^^>>^<<^v^^<>><^>^v<<^^>v<>^<^vvv<^^vv^v>vv>v>v<>v>^<v>>^vv<^>>^<><^^<>v^><^v<^^<^v>vv^v^>^^v><v^^v<^<v<^^^<>v^<><v<<<><^vv><^vvvv>v>>>^v>^<>^^^v^^>v^>v>>vv<<v<^v^v<vv><^^>><^v^>^>^<^><v^v>^^>^v^v<>>vv<vvv>><>^v>vvv><v<<>>vv<>>v>^<>vv>^v^^>>>>>><<v^^><><v^>><^>v>^^vv<<v<^<><>^v^>^<v>^vv^<^v^^>v^<vv^<v><>^>><>><vv^<v>>v^<>^>^v^v<>v>v<v^<^vv><<^v>>><>>^<^>>v^v^v^<^^<<^v<^<>^^>>^^vv<<<>^vvv<v^^<<v<>^^^<vvv<vv>vv>v<v><v^<<<vvv^<v^><>>v^>vv><<>>v^vv><^^>v^>v>v<^vvv<^v^>>>>>^>>>><v>><vv><v>^>>^v><^v^>><v><<^>>><>>vv<^>>^v^<>>^<<^<<v^<^<vv>vv<<vvvvv><^^<^>>v>vvv>^v>^<<v<^>^>>^>v<<vv<^<^>vv>>vvv^>v>><^>v^v>^vvv^v>><<<v^^^>^><>^><<^<^<><v^<v^>v^^<v^v>v>v^v<>><v<vv>^^<<><>v>v<<^>><v^<vvvvv<^>><v><vv><<<>^v^vv<>^<><<^^v<>><>>^<<>v<<<v^<>>v^>v<><^^v^<^v<v^v^<><<>^v>v> |  | ||||||
| ^<vv><>^>vv^>vv^><^<<>^v<<v^v>v^^^v<>>v>>>><<<<v^<<v<^>^>v>v^>><<<v<<>^><v^<<<vv^<^^><><^^>^^><v<^v>^^v^>^<>vv<<<>>>^v^v>>v<^^>v^vv><^v>v><v^v<><^><^^v><^^>^>>^^>>^<<^^>v^<<<^<vvv^^vvv<>v^v^v>>>^><v>^<v^>^v>^v>v<><v^^<<^v^^<v<<<>>^<>^^^>>^^>vvv><>>^<><<<<v>v^^<^<<>v^v<^^><<^^<>^>v^<<<v>>>^>>^^>^<<<>vv^>^v<vv^<vv^<>vv<^>v^v^v>>^^^v<^>>v<>><>v><v<v>^v>^v<>^^<>>vvv><<<^^<>>v<<^v^<>^^v^^>^vv>^v^<<vvv^<<<>>^vv^^^v<<^^vv>^^v><^^^<v><<^^v>^<^<^^>v^v<^>v>><v>><>><v>>><^><vvv<v^v>v<v>^^v^^^v^^v>vv>^<><>^^<<^<vv><><v^<^<vvv^^<vv>^>vvv<v>>>>>>^>>>>><><<v^^^<^^^>><v^^>>^<^^<>vvvv><>^vv<><>><<>>v^<><>v^>>^<^>v<^><v^<>^>>v><<>><>>^^vvv><>vv>>^>^>>>v^^<<<>>v^v>^^v<>^v^<vvv><<<^^v<>>>>^v<v>^>^^v^v<>v>^v<><>v<v<>>vv<>^^^>^<v<vvv>^v<>^v^<<>v<<^v^^v><^>v>>>>v>^<<vvv><<^<v<<v^v^vv^v<<>><^v^v>>>v>^^^^v^^>^v^<<<^vv^<v<^v^>><^>v<<v><><>><vvvv<<vv^^<v<^v>^<>><v><v^>v<^v^v^^v^>^vvv^^<v<>>v^^vv<v^>><^<^>^<><<^<>>vv><>^><^v<<<<^^^v>><^>>^>><>v<>^v<vv^^><<><<v>v>^><vvv><vv><^>v>><vv>v<<<>>>>v<>vv><v<^<v<>>vvv^<vv |  | ||||||
| <<^<<<^>^>>^^^>><^<^^<>v^>^<^vv<^<>vv<><><v^<>^>vvv^<<<v>^<><^<>><v<>^>^v^>v^^<<<<>^<<^v^<>vv^^v<>>v^<>^v^^^<^v^vvvv>vvvvv<^^^^v><>>^>^v^vv>>>^^<><^<>^v<<<>v<^v^v>><>><><>vv^>v^^^<v<v>^<^v^<>^<v<>vv>^^<^v><v<^<v>v<^^^>^><vv^<<v><<^>>v^^>><>v^vv><^<<><^><<^v><><v^<><v<>v>v>^>v<vvv>>>v<<><^^>^v<v>^<><>^>vv<<^>v>v^>v><^<v<<<<^^v>^v>^>>v^<v^<<<^<<^^^>^v<<v<^vv>>^><<>>><<<v>>>vv>>v><v>v>^^>>^>><>v>>^v<>>><><<<<>^>^>v<^<v>>v<v>v^<^<><<^<>>^^<^^v^vvv>>^v>v<^^>^v><<^v>^^^^^<v<>>v<v^^><^vvv^<>v>>^^>v^^v>v^^<<>vv^v>^^v<vvvv<>vvv>>vv>v>>^>>^^>v<>v^<<^>v^^><>v<><^>>^^v>^<^<>^<<v><>^^^^^v^>^<^^vv^v>>>>vvv^>v>vv^^^vv><v>vv<^^>v<>^v>>^^^v>^^^<>>v<^>^<<^>^>><>><^<>^^^vv^<^<^<<^>^<>><^vv<^<<><<<><^<>><^v^>>^v<^^><>v<^^^v^^>>^^vv>^<<vv>>>v>>>v^vvv>^^v^^>^>^^<>>>^<><>^^>^^v>^><^><v<>^>>^>>^<^>^<^<^vv>^>v><v^^>^>v<>>vv><<>><<><<>v<>>v><v>^v<^<<><^v<^^^><>v>>vv<^<<<^v^<vvvv^v<^<>^^^^vvv^<^^<>v<^^^>><^<v^><v^v<<^^><>^^^>^>^vv^^>>v>>^vv<<<v^v<vv><>vv^><<^v<v>^<v<>^^^<v<v^v<^>v^vv>v^vv><vv^v>>^^vvvvv>^<^vv><^ |  | ||||||
| >^<v^v>v>>vv^^>v>^^^^<>v><<vv><<^^v<><<v^^^^>vv>>^>v^v<<^>vvv<<^v<>v><>^v<^vv>>^^>>v<>v>^^^<v<^>>><<^v^^<v^vv<<<^^>>>vv<vv<v>><>^>^<v<<><<vv<vv>vvv><v>^<vv<><^v><>v>^^v>v<vv><v^^v^<^<v<>vv>><<<><<^v><>^>^v>v^^>vv>vv<>v<<^<v^^^>^>>^^v<^^^><v><<v^<>><><vvvv^v^^v^^<^v^>><^>v^><^^<>v<^v<<>>><^<<<^^<^v>v^^<><v<^^<>vvv^><v^v<<><v><v>^<^<^<v<^><<<>>vv<^<vv<<v>vv^^<v^^<<>v^vvv><>v>>^<^v<v><<v<<v<^^vvv>>^<^<^>>^vv>^<>^^<^>v<v>^>v^><><>vv<<>v<^^<>^^><^^^v^vv><v^^^^><^>vv<^><^^v^>>>vv^^>>v>^vv<<<<v^<v^>>>vv^v>^><><>>>^^vv^v^>v<^v>^<<^>>vvvv<<v<^v<^<>^<^>><>>^>^>^>^<<v>v^>>v>^<v>^vv<^><^^v^<<><^v^^^>v^<<>v<vv<vv>v>><>v<^<v^>v<^v>^<<vv^>vvv<><<<^<>>v>^vv<^v>^v><>^<v^v<vvvv^<<^v^v<<^^v^^^>^<v^><^^<>^^<vvv^^^^>><^>>v<>^>v>^v^v^<^^^v<vv<v<><vv<<<vv>v>^><<>vv<<>v>^vv<><^<^^^>^>v^v>^v^<v>^v>^^<^^<>>^<>>><><<<^<<<vvv>^<^<<<^vvv^v<<>><v^v<>^>>^v<^v^v^vvv<v<><v>^<^v<<<^<>>^^>^>>^^>^>v^^<<vv<vv>><^vvv^<<<v>^<><v><<v><<^^<<>><<v^vvv>vv><>><<^<v><<^>>^^vv<vvvv>^>>>>vv<^<<<>v<<<>>>>vv>^^^>^<>>^^<v>v><><^><^>>> |  | ||||||
| v><vv^><>>v<v^>^^vv<vv^^<vvvv^^^v^^^vv^><>>^^vv^>v^<>vvv>vv<>^v>>v<^<>>^v><^<<v<v>>v>v^<<>^<v>v>^^><^^>>vv<v>^v^<><^<>v<^><^v>vv<^vv^<<vv<<<<v<>v<>v^v^>>^>^<^>>^v<^v<v^<<<<>vv>><>vv>^<vvvv<<<<<^<^v<>v<^v<^><^^^>v^^>>><<<>><<v<<>>^vv^<>^<><v<^<v>^^v^^<<>^<^><v>v^^>v<v^vvv>v<<><<^<<<v<<^^><<v<>v<^v^<>v<>vvv<^^vv><<>><>v><>>^>>v<^vv^v<<^v^^>v>v><v^v>vv^^v>><<<^vvvv>^^^<v<<<<>^<<<><^<^>^v^<^v<<vv<<v<<>^<v^^>v^^><^<<^<v>^>v^vv<><^>^vv^v<<<>^vvv<<>>^vv^vvv<vv<^<^v>^^>><>v^^<^v^^^>^>v^<><><>>><v>^v>v^<>>>vv<><^>v>^v<<<^>v^<>><^v<>^><^^v><v^<vv><^^><>^^>vv^vv<<^<v^v<<v<>^v<^<v>^><>v^>v^<^^<^v>^^^>v^vv>^>v^<^^><^<<<>v>^><^>>vvv^^>>>>^>^<^><>^^v<<><v>v^>^<v^>^^<><vv>><>vv^^^v>>v^^v<v<v^<<><^v<<^^<<>v>v>>v<><>^>^^<v>^>vvv<><<>><<v<<<^>^<^v<<<^<>^^>>v^><v<<<<><<>>^^^^^^vvv<><<v<vvv>^^>^v>>>^^>>>^<<<>^vv<^><<<<>^v^>>>v<>>v>><<^<vv><^^<><><v><>^^<vv^<<vvvvvv>vv^^v^v<>>^v<<^v^^>^vv^v>vv<><vv^<v^^>v^^<<<>>vvv^><>v^<v>^<^><><>>v>^><v><^<^^>v>vv<^v^^>^>^v^^>v<vv>v><v^v>>>>vvv^^v^>v>>^^<<<v><<v>v>v<<>^^v |  | ||||||
| @@ -1,141 +0,0 @@ | |||||||
| ############################################################################################################################################# |  | ||||||
| #.#...................#.........#...............#...#...........#...........#.....#.............#...............................#.#........E# |  | ||||||
| #.#.#.###############.###.#####.###.###.#######.#.#.#####.#####.#######.#.#.#.###.#############.#.#####.#.#####.#####.#.#######.#.#.#.####### |  | ||||||
| #...#.........#...#...#...#...#...#.#...#...#...#.#.....#.#...#...#.......#.#...#...#.........#.....#.#...#.....#...#.#...#.#...#...#...#...# |  | ||||||
| #.###########.###.#.###.###.#####.###.###.#.#.###.###.#.#.#.#####.#.###.###.###.###.#.#######.#####.#.#####.#######.#.###.#.#.#########.#.#.# |  | ||||||
| #...#.#.....#...#...#...#.#...........#...#.#.#...#.......#.....#.#.#.......#...#.....#.#...#...#.#...#...#.......#.#...#.#...#...#...#.#.#.# |  | ||||||
| ###.#.#.#.#####.#.#####.#.#.#########.#.###.#.###.#.#.#####.#.###.#.#######.#.#########.#.#.###.#.###.#.#.#######.#.###.#.#.###.#.#.#.#.#.#.# |  | ||||||
| #.#.#.#.#.......................#.....#...#.#.#...#.#...#.#.#.....#.#.....#...#...#.......#.....#.....#.#...............#.#...#.#.#.#...#.#.# |  | ||||||
| #.#.#.#.#.#.#.#.###.#.###.###.#.###.#.###.#.#.#.###.#.#.#.#.#######.#.###.#####.#.#####.###########.#####.#.#####.###.#.#.###.#.#.#.#####.#.# |  | ||||||
| #.#.#...#...#.#...#...#...#...#...#.#.....#.#.#...#.#...............#.#.#.......#.....#.#.#.......#.......#.#.....#...#.#...#...#.#.......#.# |  | ||||||
| #.#.#########.###.#####.###.#####.###.#####.#.###.#.#.#.#####.#.###.#.#.#############.#.#.#.###.#.###########.#####.#.#.#.#.#####.#######.#.# |  | ||||||
| #.#.......#.....#...#...#...#...#.....#.#...#...#.#.#.#.....#.#...#.#...#...#.......#.#.#...#...#.............#.....#.#.#.#.#...#...#...#.#.# |  | ||||||
| #.#######.#.###.###.###.#.#####.#####.#.#.#####.#.###.#####.#.###.#####.#.#.#.#####.#.#.#####.#.#####.#########.#######.###.#.#.###.#.#.###.# |  | ||||||
| #.....#.#...#.#...#...#.#.#.......#.....#.#.#...#...............................#...............#...#.#...#.....#.......#...#.#.....#.#.....# |  | ||||||
| #.#.#.#.#####.###.###.###.###.###.#.#.###.#.#.#######.###.#.###.#.#.#.###.#.#####.###.#####.#.###.#.###.#.#.#.###.###.###.#######.###.#####.# |  | ||||||
| #.#.#...........#...#.....#...#.....#.....#...#.............#.#.#...#.#.....#...#.#...#.......#...#.....#.#.#.#...#...#...#.....#.....#...#.# |  | ||||||
| ###.#############.#.#######.#.#####.#.#######.#.#############.#.#.###.#.#####.#.#.#.###########.#########.#.###.###.#.###.#.###.#######.###.# |  | ||||||
| #...#.......#.....#.#.......#.#...#.#.......#.#.#.......#.....#...#...#.......#.#.#.#.....#.....#.........#.#...#...#...#.....#...#.....#...# |  | ||||||
| #.###.#####.#.#.###.#.###.#####.#.#########.#.#.###.#.###.#.#.###.#############.#.#.#.#.#.#.#####.#########.#.#####.###.#.#######.#.#####.### |  | ||||||
| #...#...#.#...#.......#...#.....#.#...#.....#.#...#.#.#...#.......#...........#.#.#...#...#.....#.#.........#...#...#.#.#.#.....#.#.........# |  | ||||||
| #.#.###.#.###############.#.#####.#.#.#.#####.###.###.#.###########.###.#####.#.#.#####.#.#####.#.#######.#.###.#.###.#.#.#.###.#.#.###.#.#.# |  | ||||||
| #.#...#...........#.....#.#.#...#.#.#...#...#...#...#.#.#.....#...#.#.#.#.....#.....#...#.#.#...#...#...#.....#...#.#...#.#.#.#...#.#...#.#.# |  | ||||||
| #.#.#.#.#######.###.###.###.#.#.#.#.#####.#####.#.#.#.#.#.###.###.#.#.#.#####.#####.#.###.#.#.#####.#.#.#####.#####.#.#####.#.#####.#.###.#.# |  | ||||||
| #.#.#.........#.#...#.#.....#.....#...#.#.......#.#.#.#.#...#...#.#...#.....#.#.....#.#...#.#.#...#.....#.......#...#.#.....#...#...#.....#.# |  | ||||||
| #.#.#.#########.#.###.#######.#######.#.#.#.#######.#.#.#.#.###.#.#.#.#####.###.#####.#.###.#.#.#.#####.#.#####.###.#.#.#######.#.#########.# |  | ||||||
| #.#...#.........#.#...#.....#.........#.#...#.......#.#...#...#.#...#.#...#.....#...#.#.#...#.#.#...#...#.#.........#...#.......#...#.....#.# |  | ||||||
| #.###.#.###.#####.#.#.#.#.#####.#.#####.###.#.#######.#####.#.#.#.###.#.#########.#.#.#.###.#.#.#####.###.#########.#######.#######.###.#.#.# |  | ||||||
| #...#...#...#...#.#.#.#.#...#...#.#.#.....#.#.#...........#.#...#.#...#.....#...#.#.#.#.....#.#...#.....#...#.....#.#.......#.....#...#.#...# |  | ||||||
| ###.#.###.#.#.#.#.###.#.###.#.###.#.#.#.###.#.###.#.#####.#.#####.#.###.#.#.#.#.#.###.#####.#.###.#.###.#.#.#.###.#.###.###.#.###.###.#.###.# |  | ||||||
| #...#.....#...#.#...#.......#.....#...#.#.....#...#.#...#.#.#...#.#...#.#.#...#.#...#.....#.#.#.....#.....#...#...#...#.#...#.............#.# |  | ||||||
| #.###.#####.###.###.#.#.###.#.#######.#.#.#####.#.###.#.#.#.#.#.#.###.#.#.#####.###.#####.#.#.#.###.#.#.#######.#####.#.#.#####.#.#.###.#.#.# |  | ||||||
| #...#.....#...#.#...#...#...#.#.......#...#...#.#.#...#.#.#...#.....#.#.#.#.#...#...#...#.#.#.#...#.#.........#.#...#...#.#.#...#...#...#...# |  | ||||||
| ###.#.###.#.#.###.#######.###.#.#####.#####.#.#.###.###.###.#.#####.#.###.#.#.#.#.#.#.#.#.#.#.#.#.#.#########.#.#.#.#####.#.#.#######.#.###.# |  | ||||||
| #.#.......#.#.....#.....#.#...#.....#.......#.#...#.#.#.......#.....#.....#.#...#.#...#.#.#.#.#.#.#...#.#...#.#...#.........#.....#...#.....# |  | ||||||
| #.###.#.###.#####.#.###.#.#.###.###.#########.#.#.#.#.#########.###########.###.#.#####.#.#.#.#.#.#.#.#.#.#.#.#######.#####.#####.###.#.#.#.# |  | ||||||
| #.......#...#...#.#.#.#.#.#.#.#...#.....#.....#.#.#.#.......#.......#...........#.....#.#.#.#.#.#.#...#.#.#...#...#...#...#.....#...#.......# |  | ||||||
| #.#.#.#.#.#.#.#.###.#.#.#.#.#.###.#.###.#.#######.#.#.#.###.#########.#########.#####.###.#.#.###.#.###.#.#######.#.###.#.#####.###.###.###.# |  | ||||||
| #...#.#.#.....#.#...#.#.#.....#...#.#...#.#.#.........#.#.#.......#...#.......#.....#.#...#.#.....#...#...#.......#...#.#.........#.........# |  | ||||||
| #.###.#.###.#.#.#.###.#.#.###.#.#####.#.#.#.#.#.#####.#.#.#.#.###.#.###.#####.#####.#.#.#######.#####.#.#.###.###.###.#.#####.###.#####.###.# |  | ||||||
| #.#...#.#.....#...#...#.#.....#.#.....#.#.#...#.#.....#...#...#.#...#.#...#.#...#.....#.#.....#.......#.......#.....#.......#.#.......#.....# |  | ||||||
| #.#.###.###.#.#####.#.#.#####.#.#.#####.#.###.#.#.#######.#####.#####.###.#.###.#####.#.#.###.#.#.###########.#####.#######.#.#########.###.# |  | ||||||
| #.#...#.....#.....#.#.#.........#.#...#.#...#.#.#.......#.#.....#...........#.#.....#.#...#.#...#.......#...#.#.......#.....#...............# |  | ||||||
| #####.###.#.#.###.###.#####.#.###.#.#.#.###.###.###.#####.#.###.#####.#.###.#.#####.#.#####.#.#######.#.#.#.###.#####.#################.##### |  | ||||||
| #.......#...#.....#.....#.#.#...#.#.#.#...#...#.....#.....#...........#...#.#.....#.#...#...#.......#.#...#.#.......#.......#.......#.......# |  | ||||||
| #.#######.#.#.#####.###.#.#.###.#.#.#####.###.#.#####.#####.#############.#.#.###.#.###.###.#.#####.#######.#.#########.#.#.#.#####.#.#.###.# |  | ||||||
| #.........#...#.....#...#.#...#...#.....#.#.#.#...#.#.#.......#.....#.....#.#...#...........#...#...#.......#...#.......#.#.#...#.#.......#.# |  | ||||||
| #.#######.###.#.#####.###.###.#######.###.#.#.###.#.#.###.###.#.###.###.#.#.###.#.#.#.#######.###.###.###.#####.#.#.#####.#.###.#.#########.# |  | ||||||
| #.......#.#.....#...#.....#.#.........#...#.#...#...#...#...#.#...#...#...#.#...#.#.#.#.....#.#...#...#...#.....#.#.#.....#...#.#.....#...#.# |  | ||||||
| #.###.#.#.#.#.#.#.#.#.###.#.#####.#.###.###.###.#######.#.#.#.#.#####.#####.###.#.#.###.###.#.#.#####.###.#.#####.###.#####.###.#.###.#.#.#.# |  | ||||||
| #.....#.#.#.#.#.#.#.....#.#...#...#.#...#.....#...........#...#.#...#.#...#...#.#.......#.#...#.#...#...#...#...#.....#...#.......#...#.#...# |  | ||||||
| #######.#.#.#.#.#.#####.#.#.#.#.#####.###.#.#############.#####.#.#.#.#.#.###.#.#.#######.#####.#.#.###.###.#.#.#########.#############.###.# |  | ||||||
| #.#.....#.....#.#.#...#.#...#.#.......#...#.#.......#...........#.#...#.#.....................#...#...#...#...#.......#.....#...#...#...#.#.# |  | ||||||
| #.#.#####.#####.#.###.#.#####.#########.#####.#####.#.###########.###.#.#########.#############.#####.###.###########.#.#.#.#.###.#.#.###.#.# |  | ||||||
| #...#...........#.#...#.#.....#.#.....#.......#...#...#...#.....#.#.#.#...#...#...#...........#...#...#.....#.......#.#.#...#.#...#...#.....# |  | ||||||
| #.###.###########.#.#.#.#.#####.#.#.###.#.#.###.#.#####.#.#.###.#.#.#.###.#.#.#.###.#########.#####.###.#####.#.#####.#.#.###.#.############# |  | ||||||
| #.....#.......#.....#.#.#...#...#.#...#.#.......#.#.....#.#.....#.#...#...#.#.#...#.#.#.....#.....#.#.........#...#.....#...#.#.....#.......# |  | ||||||
| #######.#######.#####.#.###.#.#.#.###.#.#######.#.#.#####.#.#.#.#.#####.###.#.###.#.#.#.###.#####.#.#.#.#########.#.#.#.###.#.#####.#.#####.# |  | ||||||
| #.......#...#...#...#.#...#.#.#.#...#.....#.....#.#...#.#.#.#.#...#.....#.#.#...#.#.#...#...#.....#.#.........#...#.#...#.........#.....#...# |  | ||||||
| ###.#.#.#.#.#.###.#.###.#.#.###.#.#########.#####.###.#.#.###.#.###.#####.#.###.#.#.#.###.#.#.#####.#########.#.###.#.###.###.#####.#####.### |  | ||||||
| #...#.#...#.....#.#.....#.#...#...#...#.....#...#.#...#.......#.#...#.....#.#.#.#.#.#.#...#.#.#.......#...#...#...#...#.#.#...#...#...#...#.# |  | ||||||
| #.###.#########.#.#######.###.#####.#.#.#####.#.#.#.#############.###.#.#.#.#.#.###.###.###.#.#.#####.#.###.#####.#####.#.###.#.#.###.#.###.# |  | ||||||
| #.....#.#...#...#.....#.....#.......#...#.....#.....#.............#.....#.#.#...#...#...#...#.#...#.#.#.....#...#.#...#...#...#.#...#.#...#.# |  | ||||||
| #.#####.#.#.#####.###.#.###.#############.#.###.###.#.#############.#.#.###.#.###.###.#####.#.###.#.#.#.#####.###.#.#.#.###.#.#.###.#.#.#.#.# |  | ||||||
| #.......#.#.....#...#.#.....#.....#.....#.#.#...#...#...#...............#...#.....#.........#.#.....#.#.......#...#.#...#...#.#.#.#.#...#.#.# |  | ||||||
| #########.#####.###.#.###.#####.#.###.#.#.#.#.###.#.###.###.###.#######.#.#########.#######.#.###.###.#######.#.###.#####.###.#.#.#.#.###.#.# |  | ||||||
| #.....#...#.....#...#...#...#...#.....#.#.#.#...#.....#.....#.#.....#...#...#.#.......#.....#.......#.....#...........#...#...#.#.#.#.#...#.# |  | ||||||
| #.###.#.#.#####.#.#.###.###.#.#.#####.###.#.#.#.#####.#######.#####.#.#####.#.#.#####.#.###########.#####.###########.###.#.###.#.#.###.###.# |  | ||||||
| #.#.....#.#...#...#...#.......#.#.....#...#.#.#.....#.#.......#.....#.#...#.#.........#...........#.....#...........#.#...#...#.#.......#...# |  | ||||||
| #.#######.#.#.#######.#.#####.###.#.###.###.###.#.###.###.###.#.#####.#.#.#.###.#####.#####.###########.#######.###.#.#.#.###.#.#########.#.# |  | ||||||
| #...#.#...#.#.#.....#.#...#...#...#...#...#.....#.........#...#.#.....#.#...#...#.....#.....#.........#.....#...#...#.#.#.#...#.....#...#.#.# |  | ||||||
| ###.#.#.###.#.#.###.#.###.###.#.#####.#.#.#.#######.#####.#####.#.#.###.###.#.#.#######.#####.#####.#######.#.#.#.###.#.#.#.#######.###.#.#.# |  | ||||||
| #...#...#...#.#...#.#...#...#.#.....#.#...#...#...#.#...#.#.....#.#...#.#.#...#.......#...#...#...#.......#...#...#.#...#...#...#...#...#.#.# |  | ||||||
| #.###.###.###.###.#.###.###.#.#####.#.#.###.###.#.###.#.###.#########.###.#.#.#######.###.#.###.#####.#.#.#########.#.#######.#.#.###.###.#.# |  | ||||||
| #...#.#...#.#...#.#...#.#...#.#.#...#.#.#...#...#...........#.........#.....#...#.........#.#.......#...#.........#.#.#.......#.............# |  | ||||||
| ###.#.#.###.###.###.###.#.###.#.#.###.#.###.#.###############.###.#####.#######.#.#####.#.#.#####.#.#.#.#.#######.#.#.#.###########.###.###.# |  | ||||||
| #...#.#...........#.....#.#.....#...#...#...#.....#.....#...........#...#...#...#.....#.#.#.....#.#.#.#.#.#...#...#...#...........#...#...#.# |  | ||||||
| #.#####.#.###.###.#.#####.#####.###.#####.#.#.#.#.###.#.#####.#####.#.###.#.#.#######.#.#######.#.#.#.#.###.#.###.###.###.#######.#.#.###.#.# |  | ||||||
| #...#...#...#.#...#.#...........#.#.#.....#.#...#.#...#.....#.#...#...#...#.#.#.....#.#.......#.#.#.#.#.....#...#...#.....................#.# |  | ||||||
| ###.#.###.###.#.###.#####.###.#.#.#.#####.#####.#.#.#######.###.#.#.###.###.#.#####.#.#######.#.#.#.#.#########.###.#######.#.#.###.#######.# |  | ||||||
| #...#.#.#.#.......#.....#.........#.....#.......#...#.....#.....#.#.#...#.#...#.....#.#.....#...#.#.........#...#...#.....#.#.#...#.....#...# |  | ||||||
| #.###.#.#.#.#####.#####.#.#######.#####.#.#.###.#####.#.#.#######.###.###.#####.###.#.#.#.#.###.#.#####.#####.###.###.###.#.#.###.#.#.###.### |  | ||||||
| #.#...#...#.#...#.#.....#.#.#.........#.#.#.#...#.....#.#...#...#.....#.......#...#.#...#.#...#...#.....#...#.#.......#.#.#...#...#.#...#...# |  | ||||||
| #.#.#######.#.#.#.#####.#.#.#.#########.#.#.#####.#####.#####.#.#######.#####.#.#.#######.###.###.#######.#.#.#.#######.#.#####.#####.#.#.#.# |  | ||||||
| #...#.......#.#.#.#...#...#.....#.......#.#.........#.#.....#.#.......#.#...#...#.#.........#.#...#.....#.#...#.........#.......#.....#.....# |  | ||||||
| #.###.#.#####.#.#.#.#.###.#####.#.#.#.###.#########.#.#.#.#.#.#.#####.#.#.#.###.#.#.#######.#.#####.###.#.#####.#.###############.###.#.#.### |  | ||||||
| #.#...#.#...#.#.#...#.#...#...#...#.......#.......#...#...#.#.#.#...#...#.#.....#.......#.#.#...#...#.#.#.#.#...#.............#.......#.#...# |  | ||||||
| #.#.#.#.#.#.#.#.#.###.#.###.#.#.#########.#.#####.#######.#.#.#.#.#.#######.#.#########.#.#.###.#.###.#.#.#.#.#########.#######.#####.#.#.#.# |  | ||||||
| #.#.#.#.#.#.#.#...#...#.#.#.#...#.......#.#.#...#.#.....#.#.#.#.#.#.........#.......#.....#...#...#...#...#...#.......#...........#...#.#.#.# |  | ||||||
| #.###.#.#.#.#.###.#.###.#.#.#####.#.###.#.#.#.###.#.###.###.#.#.#.#####.#.###.#####.#.#####.#.#####.#.#########.#####.###.#########.#.###.#.# |  | ||||||
| #.....#.#.#...#.....#.#.#.#.#...#.#.#...#.#.#.....#.#.....#...#.#.....#.#.#.........#.#...#.#.........#.....#...#...#...#.#.#...#...#.....#.# |  | ||||||
| #######.#.###########.#.#.#.#.###.#.#.#####.#.#####.#####.#####.#######.#.#.###########.#.#####.#####.###.#.#.#####.###.#.#.#.#.#.###.#.#.#.# |  | ||||||
| #...#...#.......#.....#...#.#.....#.#.#.....#.....#...#.....#...#.......#.#.#...#.......#.......#...#.#...#...#.....#.#.#.#.#.#...#.....#...# |  | ||||||
| #.#.#.#########.###.#.###.#.#####.#.#.###.#######.#.#.###.#.#.###.#########.#.###.#.#.#############.#.#.#.#######.#.#.#.#.#.#.#####.#.#.#.#.# |  | ||||||
| #.#.#.....#...#...#.#...#.#.....#.#.#.....#.......#.#.....#...#.#.......#...#.....#.#.....#.#.......#...#...#.....#.#.#.#...#.....#.#.#...#.# |  | ||||||
| #.#.#####.###.###.#.#.###.#####.###.#########.###########.#####.#.#####.#.#####.###.#.###.#.#.###.#########.#.#.###.#.#.###.#####.#.#.#.#.#.# |  | ||||||
| #.#.....#.........#.#...#.....#...#.........#.#...........#.....#.#.#...#.#...#.#.#.#.#.....#...#...........#.#.#.#...#.#.#.#...#.....#...#.# |  | ||||||
| #.#####.#####.#.#######.#####.###.#.#######.#.#.###.###########.#.#.#.###.#.#.#.#.#.#.#####.###.#####.#######.#.#.#.###.#.#.#.#.###.#.#.#.#.# |  | ||||||
| #.#...#.....#.#.#.......#.....#...#.....#.#.#.#.#...#.#.......#.....#...#...#.....#.#...#.#.#.#.#...#...#.....#.#...#...#...#.#.#...#.....#.# |  | ||||||
| #.#.#.#####.#.#.###.#####.#####.#######.#.#.#.###.###.#.###.#.#####.###.#####.#####.#.#.#.#.#.#.#.#.###.#.#####.#####.###.###.#.#.#.#.#.###.# |  | ||||||
| #.#.#.....#.#.#...#.......#...#...#.....#.#.#.....#...#...#.#.......#.......#...#...#.#.#.....#...#...#.#...#...#...#.#.........#.#.........# |  | ||||||
| #.#####.#.#.#.###.#########.#.###.#.#.###.#.#######.#.###.#.#######.#.###.#.###.#.###.#.#########.#####.#.###.###.#.#.###########.#.#.#.#.### |  | ||||||
| #...#...#.#.#.#.#...#.....#.#...#...#.....#.#.......#.#...#...#.......#...#...#.#...#.#.#...#.....#.....#.#...#...#.#...........#.#...#.....# |  | ||||||
| ###.#.#####.#.#.###.#.###.#.###.###.#####.#.###.###.###.#####.#########.#####.#.###.#.#.#.#.#.#####.###.#.#.###.###.###########.#.#########.# |  | ||||||
| #...#.......#.....#...#.#...#.#...#.#.....#...#...#.....#...#.#.......#.#.....#.......#.....#.#...#.#...#.#...#.#.#.....#.....#.#...........# |  | ||||||
| #.#####.#########.#####.#####.###.#.#########.###.#.#####.###.#.#####.#.#.#.#.#########.#.#.#.#.###.###.#.###.#.#.#####.#.#.###.#.#.###.#.### |  | ||||||
| #.....#.....#...#...#.........#...#...........#.#.....#.....#...#.....#.#.#.............#.#...#...#...#.#.#.#.#.......#.#.#.....#...#...#.#.# |  | ||||||
| #.###.#.#.###.#.###.#.#.###.#.#.###.#.#########.#####.#.###.#####.#####.#.#.#############.#######.###.#.#.#.#.###.#####.#.#########.#.###.#.# |  | ||||||
| #.#...#...#...#.....#.#...#...#.#...#...#.........#...#...#.....#.......#.#.#.....#.....#...#.....#.#.....#.#...#.#.....#.........#...#.#.#.# |  | ||||||
| #.#.###.###.#############.#.#.#.#.#####.#.#.#####.#.###########.###.#####.###.###.#.###.###.###.#.#.#.###.#.###.#.#.###.#########.###.#.#.#.# |  | ||||||
| #.#.......#...#...........#...#.#.......#.#...#...#.#.........#.........#...#...#.#...#.....#...#...#.#...#...#...#.#.......#.....#...#.....# |  | ||||||
| #.#####.#.###.#.#######.###.#.#.#######.#.###.###.#.#.#######.#.#######.#.#.#.#.#.###.#######.#####.#.#.###.#.#####.#######.#.#####.###.###.# |  | ||||||
| #.#.....#...#.......#...#...#.#.....#...#.........#.#.#.....#.#.......#.#...#...#.#...#...#.......#.#.#.#.......#.........#.#...#...#.....#.# |  | ||||||
| #.#.###.###.#####.#.#.###.#.#.#####.#.#.###.###.###.#.#.###.#.#.#####.#.#.#####.#.#.#####.#.#####.#.#.#.###.###.#.#######.#.###.#.###.#.#.### |  | ||||||
| #.#.#.#...#.......#.#.#...#.#.......#.#...#.#.#.....#.#...#...#.....#.#.#...#...#.#.#...#.....#.#.#.#.#.....#.#.#.......#.#.#.#.#.#.....#...# |  | ||||||
| #.#.#.#.#.###.###.###.#.###.###.#.#.#.###.#.#.###.###.###.###.#####.#.#####.#.###.#.#.#.#####.#.#.#.#.#######.#.#####.#.#.#.#.#.#.#.###.#.#.# |  | ||||||
| #.#...#.....#.#...#...#.#.#.#.#.#.#.#.#.#...#.....#...#.#.....#.....#.....#...#.#...#.#.....#...#.#...........#.......#.#.#...#.#.#.#.#.....# |  | ||||||
| #.#####.#.###.#####.#.#.#.#.#.#.#.#.#.#.#####.###.#.###.#####.#####.#####.#####.#####.#####.#####.#.###########.#######.#.###.#.#.#.#.#.#.#.# |  | ||||||
| #.#.....#.#...#...#...#.#.#.#...#.#.#...#.....#...#.#.....#.#.....#.....#...#.........#...#...#...#.......#.........#...#.#...#.#.....#.#.#.# |  | ||||||
| #.#.#####.#.###.#.#.#.#.#.#.###.#.#####.###.###.###.###.#.#.###.#.#.#####.#.#.#.#####.#.#.###.#.#.#######.#.#.#.#####.###.###.#.#######.#.#.# |  | ||||||
| #...#.....#.....#...#...#.....#.#.#...#.....#.#.....#...#.#.#.....#.#...#.#...#.........#...#.#.#...#...#...#.#.#...#...#...#.#.#.......#...# |  | ||||||
| #######.###########.#.#######.###.#.#.#######.#######.###.#.#.#######.#.#.#.###.#.###########.#.###.#.#.#####.###.#.###.###.#.#.#.#####.#.### |  | ||||||
| #.....#.......#...#.#...#...#.....#.#...........#.....#.....#.........#...#.....#.........#...#...#.#.#.....#.....#.........#.#.#.#...#.....# |  | ||||||
| #.###.#####.#.#.#.#.###.#.#.#####.#.#.#######.#.#.###.#.###.#############.###############.#.###.#.#.#####.#.#############.#.###.#.#.#.#.#.#.# |  | ||||||
| #...#.#.....#.#.#.#...#...#.#.....#.#...............#.#.............#.....................#...#.#.....#...#.........#...#.#.#...#...#...#.#.# |  | ||||||
| #.#.#.#.#.#.#.#.#.#######.#.#######.###############.#.#.###########.#######.#.###########.###.#.#.###.#.#.#####.###.###.#.###.###.#####.#.#.# |  | ||||||
| #.#.#.#.#.....#.#...........#.......#.#.....#.....#.#.#.......#...........#.#.#.....#.......#.#.#.#...#.#...#...#.......#.#...#...........#.# |  | ||||||
| ###.#.#.###.###.###.#.#######.#######.#.###.#.###.###.#.#.#.#.###.#######.#.#.#.###.#######.#.#.#.#.###.###.#.#.#.#######.#.###.#####.#####.# |  | ||||||
| #...#.#.#.......#...#.........#.......#.#...#...#...#...#.#.#...#.#...#...#.#.#...#.......#...................#.#.#.......#...#.#...#.#...#.# |  | ||||||
| #.###.###.#.###.#####.###########.#.###.#.###.#.###.###.#.#.###.###.#.#.###.#####.#######.###.###.#.#####.#####.#.#.#####.#.#.###.#.###.#.#.# |  | ||||||
| #...#...#.....#.#.....#.........#.#.#...#.#...#...#.......#...#.....#.#...#.....#.....#.#...#...#.#...#...........#.....#.#.#...#.#.....#.#.# |  | ||||||
| #.#.###.#.#.#.###.###.#.#######.#.###.###.#.#####.#####.#####.#######.###.###.#.#####.#.###.###.#.#.#.#############.###.#.#.###.#.#######.#.# |  | ||||||
| #.#...#.#...#...#.#.#.........#.#.#...#...#.#.....#...#.#.....#...#...#...#...#...#...#...#.#...#...#.#...........#.#...#.....#.#.#.........# |  | ||||||
| #.###.#.###.###.#.#.#.#####.#.#.#.#.###.#####.#####.#.###.#####.#.#.###.###.###.#.#.###.#.#.#.#####.#.#.#########.###.###.#.###.#.########### |  | ||||||
| #...#.#.#.......#.#.#...#...#.#.#.#...#.......#...#.#...#.......#.#.#.......#...#.....................#...#.....#.#...#...#.....#...........# |  | ||||||
| ###.#.#.#.#.#####.#.#.#.#.###.#.#.###.###.#####.#.#.###.#####.#####.#.#######.#.#.###.#.#.#.#.###.#.#.###.#####.#.#.#######.###########.###.# |  | ||||||
| #.#.#.#...#.......#.....#.#...#.#...#...#.#.....#.#.#...#.....#.....#...#.......#.#...#.#.#.#...#.#...#.#.#...#.....#.....#...#.......#.#...# |  | ||||||
| #.#.#.#####.#########.###.#.#.#.#.#####.###.#####.#.#.###.#####.#########.#####.#.#.###.#.#.###.#.#.###.#.#.#.#######.###.#.#.#.#####.###.### |  | ||||||
| #...#.#.....#...#...#.#.....................#...#.#.#.#...#.......................................#.#...#...#.#...#...#.#.....#.#...#...#...# |  | ||||||
| #.###.#.#####.#.#.#.#.#.###.#######.#.###.#.#.#.#.#.#.#.###.#####.#####.#.#.#.#.###.#.###.#######.#.#.#.#####.#.#.#.###.#####.#.#.#####.###.# |  | ||||||
| #S..#.........#...#.....#...........#...#.....#.#...#.....#...........#.....#.#.......#...........#...#.....#...#...............#...........# |  | ||||||
| ############################################################################################################################################# |  | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| Register A: 55593699 |  | ||||||
| Register B: 0 |  | ||||||
| Register C: 0 |  | ||||||
|  |  | ||||||
| Program: 2,4,1,3,7,5,0,3,1,5,4,4,5,5,3,0 |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,402 +0,0 @@ | |||||||
| rbrr, gbgrgrg, rgurwgb, grb, ggg, grbugw, brwggrw, rbbrub, grguuu, uuub, uw, urug, bru, wwrrb, rbwbb, urw, uwuw, ubg, uugug, wbub, guubr, rru, gwb, wggrg, gubbwww, wrr, wbw, grug, brrr, rgw, urg, gugg, rugwuwb, rwu, rgu, bbu, ubb, gr, wwwggw, ub, uggrb, bbwrru, wuwrww, gbrbwru, uubu, bub, uguub, b, uwgu, brggrr, rruuggrr, buuu, brbgw, wbugb, rbwru, wrgu, bbg, uwbg, ruwg, bgugub, urwrrb, bggugw, bg, rgrrb, guwwu, gbbr, rwb, urrgu, brw, gbrwg, gbgwwrb, grgb, ggug, ugw, wbwwbug, wrbru, uwww, wwuw, wubg, burubw, gwr, wwubu, ubggrr, uru, www, wwr, uwbw, ww, rbbrwbr, rrwgru, gwuwgug, wubwww, gwbbwwb, bwu, ubr, rrguwr, bu, g, wrwbr, ggwb, wbr, uubwbrrg, gubrurwu, ugbg, wrurwbwr, buu, wuwbgrbw, ruw, wwgrw, bbbr, wbg, grrrrbu, wguuggwb, wrrwr, rbrru, bur, wurgwbgw, wgr, burggw, grugug, uugbrg, bgurgrr, urbw, gurur, wggb, rrub, uwgwg, grrug, uuu, gurg, ugugg, rurb, bbb, rrggwwb, brwbb, rrbub, ugb, wwbgg, gbguw, wgwgbb, wgw, brrw, ugbwrg, wgub, uub, bwgrugwb, guwgg, gurw, rrruwr, wgg, bgw, wrub, bubrw, uwrbb, uubugbwg, bwr, ugg, gwrbg, gbg, rbuwr, gububbu, bbw, wggw, rwrww, bbggbr, urgburg, rwbgr, rgr, wbugu, uug, uwg, ubgruurb, r, uu, rrw, uuwgu, gbu, urb, ugwg, bgrgrrg, rub, wubgwbg, brgubr, uuuburb, rbrwgr, wgwur, wbu, buurrgw, uwu, wbgb, rgru, wgggg, gubbr, uubwwg, uurbbggg, bgrwg, wggburr, ubwrg, wu, urbu, wbwrur, urgu, bggub, gbuwbb, uruu, gwwggwu, wugubrbr, bgrb, rgrbrb, guw, brr, rbguu, bgb, rug, gbur, gbb, rbrwbbb, ruuw, wrug, bbrwbgu, wwuwwbr, bgugur, rgg, brbw, wru, burrg, gu, ggwuww, wuw, uurg, wuwwbrwr, bbgbr, wb, ug, rrru, gwbg, ubwrug, rgur, rwg, ggrr, rgbub, uwubub, rwugg, wgbw, wburr, rgbu, ugr, ggwwb, gg, bbrbwgrw, gwu, brgwrwb, bguw, bbwwurr, ruu, ggbbu, ggr, bgwbgr, gru, gguuw, rbg, urbb, grw, wrwubbg, wbuu, ubwuw, gug, rbbr, wwb, buw, gw, buuw, wurgbuu, u, uuw, rwbw, wbbguw, bww, urguuwr, buwb, rugguggb, wwub, wrgubb, wrbr, gubbrw, guugr, ubbu, rwwbrb, bw, uwur, uugugw, bb, grr, wwuu, grrggg, rur, burugrr, ggb, rr, grg, brgw, wbwgu, uruwb, wuu, bwwgwrb, urgg, rrwuru, wurbur, uwb, bwrb, wur, ruwbwug, gb, bbr, uuwguu, ggwgwggw, bgurbb, wrw, rrbu, ubu, wbrgr, ruug, rbrg, rbr, bubwb, wbwgbwb, urugww, wrgbw, wgb, grub, gwrbuu, rbb, rrb, wbb, gguw, ggurrwg, bgwg, uuurw, wrwuww, brg, gbuub, uuur, rwrwu, wgu, rrrw, rbw, bwrbr, gwrgwu, ubbruu, rurrbrg, wwbwb, ubrg, wbbb, brb, rgwgr, gwg, brrgb, rwub, guwburb, buwgbru, ugbug, bwb, wgbwuu, wrbg, rrwugb, guuub, burw, brgwbwb, ubrub, ggbb, wggww, buwwwwuw, gur, ugu, guu, gwrbbrug, wbggu, gbgbuu, gbr, ggub, bbwg, ugwuur, grgr, ubguu, urgw, ru, bgg, wwu, buggg, gbuu, uuwu, rrww, ugrw, urr, rbu, bbugb, rgb, uwrbbu, wrwguu, rw, wwwu, gbbbuguw, wbrwwg, gbbrwrwr, wugw, rrbb, wurg, wgbubg, wug, wwwwg, br, rwbg, ur, rrrggg, gbw, ggu, bwrwb, rrr, rguuww, wuwbgww, bug, wgwru, wgbggw, uww, bwg, ggw, ubw, rrg, wg, uur, uwr, wrb, bwurbg, ugur, rb, gww, ubuu, burr, ggwg, rwr, gwuww, bgbwu, gub, bgu, wwgr, wwgb, bbrug |  | ||||||
|  |  | ||||||
| wwugguwgrwwbrwubrwrwburubgrwubbbrugbggwrbwrwwrgggg |  | ||||||
| brwwgggrrubuwubbgbgruwgwguguwgwwugrgbwbgrbbwwuwwruug |  | ||||||
| gruurgurbugwgwbwuwubrggrgbgguurgrugbuubwgwrguwggwburrrgu |  | ||||||
| ugbrrgrwgbuggrrwuwwwbwugwwgbbrbuugbwbwbrrggwgruurrguuguw |  | ||||||
| grgggbwuuggwbbugrburbbbbbbbgwubbruuggubbgrggurg |  | ||||||
| wrggrurwbubuwwbrbrrurgrrrbuggwgbbgbbwgbwbbrgugruug |  | ||||||
| ugrrrrwggbbuuubrbggrgurggruurgrburbrgubrwrwgbwwwuugbwwuw |  | ||||||
| ggwrrwwrbbrrbwrgrwuurrbbwubgugruurbrggrrbr |  | ||||||
| rrurruguurburuwubwugurrrwgwgubbbwuurbggrwruuwg |  | ||||||
| gwbgrrggwbgbwrgwurbubgrwubwrgbugurbrbbrbrb |  | ||||||
| rwburrrbrwggbgwbruuwrwrrurwwuwwbugguwwrurwbwrrbu |  | ||||||
| uwruuuuwrwrwrrgurrubuwgwgrwbwuubgrwrbugubbbbuwbr |  | ||||||
| rwwggwwurwwrrrbwrwwwugbrggruwgruggwbwwgguuuuwurbrgbu |  | ||||||
| rwgbgwbgburuwubrbgrwrwubrrbrgubbwrgwbrbrugbbubbwurgu |  | ||||||
| ugbbbubgbbuwbwrwgbgbggurbggrwbgubbwuwbbrwgrubbg |  | ||||||
| wwbwbrggbrburubwgrwgbgrgwuruwrwwrgubwgurrbwrrwurwuurgggwgg |  | ||||||
| wuwgbwrbbgguwgwurgwbrgbwguwrbwuugubuubuuwgbwrr |  | ||||||
| ruuwuugwuuggbbwbuurguuwwgbwbgbgwbwwgwwuugugbbwwwruwuubrrgw |  | ||||||
| wwbgrburbbwurgruwugbrgggrgwwggbbgwgurbbgubugbgwubwg |  | ||||||
| wrggbbruuwrrbgrbwbuuubrruwgrwrrrgrwgwbbw |  | ||||||
| rgbugwrgwwurbgwubwruwwbrwggbwruubwbbrrwubrgwurrrrugbgg |  | ||||||
| buurwgrwgwbbugwgbuwbwurbwbggrugbbbwwbwrbwgrwurwubrgbrbbgu |  | ||||||
| rwwururugbgubrwubrrggbwwbgbrgrrbbuurbugwbgwuurgbuubrgu |  | ||||||
| bwgwruwwrbwgrgggrgwbruguwrubbrrgugbrbruwbug |  | ||||||
| bwwrurburbbwbuubrrwwuwubwrburrwuggrbbuwwggb |  | ||||||
| gbwuuuruuwguuwwbuwguuuuwgwuuugubbggrbuuuwb |  | ||||||
| uuwrwrwwbrubgbrrwbrbuuuwrrggbrrgwuugbuurrbbu |  | ||||||
| wubggwugrugbubgrbwwgbburbuuuwwbbwuuguggruugbuwwwbwrwbww |  | ||||||
| gggwbuwrugwruurgubrugrrrubbwwguwurbwbrgbwgwwgug |  | ||||||
| wrgguwwbbgbggubbuugbgrrbrurwuguwguuggwbwwrggww |  | ||||||
| ubrruwrbuuggwuuwbrwgbguurbwbbgrrwurbbbgrwbubgwubgbrwgbbrb |  | ||||||
| ugrgrwbrgwgwrrwbrwwugrruwrgrgwrurbbgurrbwwrruruwbbbrbrugu |  | ||||||
| wbrgrubuugggruwwrwbuwgwgurugurbbgwwuggbwgrugwubr |  | ||||||
| uugwugbububwrrgwwrrguruwwgwgbgugwgbrrwgrubbrwrrrbgwr |  | ||||||
| rgwuugbwbwurggurrbrbuwggwwbbgwrbbrugwbggwggwuurg |  | ||||||
| wgrrrurwgrgbwuwrggrbbgwgurugruwwugbuuruurub |  | ||||||
| buwgubbgbwwgbwwrrggwwrrbwgwwgrugbbguwwwwgbwuwuuuururgur |  | ||||||
| rburrbgwwwwgrrurbruwwbwbbwrwgubguwbbubwbgguruggruuugubbwu |  | ||||||
| grbgurbbgguubrrwbrwwgrwrwwubbubbbugwwgurwgwgrbwww |  | ||||||
| wrgbggrgrwggwuuwbrgwurgurrbwbbwrbgwuurwgrgw |  | ||||||
| gbwwubwgrwuguwggbgrgrwwgugbuuwbuuwruwwgbbb |  | ||||||
| ugrwwrrgwrguwgbbrbguugbbgbgbbbggbrubbbbrbguwwgu |  | ||||||
| guggrgugguuubwwgruwwuggbugwbwwwururgbwwwrggrgbugubgubg |  | ||||||
| rrgwrbggggbgwgggubrugrrbgrwwwuggbwwrgurwwuubgwrww |  | ||||||
| bgbuuwgwgrgwwggrggrbwurguuururwrbbwuuwbwgugbbgwr |  | ||||||
| bgbbrbgbrugrggrbwgurbgwwbbrurguwrbrwwwwwbbggrwbgrwwwbw |  | ||||||
| ruwbbgburgrbrbwrrbwwwuwggguruubbbrugbgbbrurbugrubgwgur |  | ||||||
| ubrgguggrwgrbrgrrbwrrrgrgbrruwgwrurugbgubb |  | ||||||
| wuggrwwgrgwwwbgwwuubrggwuuwbubgbrgbuwurubbwbuwwbw |  | ||||||
| grwbwruuggubgurrbrrwguggbwrubwwuuubbbgggwururw |  | ||||||
| guurbugubbwbgrruggubbgrurgggwugugrrubgbruububgubgubu |  | ||||||
| uubwwbgrurgrrurwbgwgwurguuuwguuwbwbuurbrgrgbuubgwbwbbgbbw |  | ||||||
| wrggguwwwwrgbbgrwrbwbgbbuguurrgbbubwbbwrbgwuwwruubrwrrgbgu |  | ||||||
| wgwugwwrrurbgwwrgbggbgbwgbbgrgrbuwgwrwrrurw |  | ||||||
| bbbwbbgwgurrgbuugwbbrubrgrrggurwgguwruwruggrwwrgrrgbugrub |  | ||||||
| bbwbrbrwrwbgurgrrwrrwbbrwrwgruugwbwrwurbwbwug |  | ||||||
| wwgwrrrgbbgguwguuggwbrruubgwrwuuuwrgbrburbu |  | ||||||
| urgwwgwbwbgrguwguubggwuwrbuugggbwuburubbuburrgbuwb |  | ||||||
| wrgbbwuruubwuuguubwuguwwgbuurgrgwguwbrbwwrgrggugbbbb |  | ||||||
| uuuubuuguubugbruwwwbrbrbgrrwwurwrruwwbuuwwrbbgrurbubbubrb |  | ||||||
| bgwurgbwrbwurgwbgwburgubuuubbbwbwwwuuwrgwugg |  | ||||||
| wrggwubugrugugubbguwgwbrwruurrggwuwwrbbgbbbrgbb |  | ||||||
| wruwwgbbrrgwrgrggbrugrwwwbrbwubuggugwbwuggbrwgburbwbbwubbg |  | ||||||
| ugwuuugbwwwrurrgubbbwguurbwgwbrgrwbwugugubbug |  | ||||||
| wrgrubuuwrgrbwbuuubgrbubbrbgrurbuuwggbgrwwgwwbwr |  | ||||||
| uururwwbrgwwrwggwbwrrrrgbbbuugbguwuwwggrgug |  | ||||||
| ugrwbwwrgbrbwwuuwuuurbgruwgrugbrrrbguuwubbub |  | ||||||
| wwwbrruggbuwwgbubwggrrgugruuurrurrwgwrguwwwrrgubugww |  | ||||||
| wrgrrgbrbggbwbubrwbrwrwbbgbwuwgbbwggwrrubgurbugguwuwuw |  | ||||||
| grrwbggrwbuugrggwubrbguuwrurbuuwbggbgugburbrrbuwwrrggggwwu |  | ||||||
| uubrruwgwuwbggbbuurwubwgburbuuwugbwuwurrwbrbgrbbr |  | ||||||
| rubuubuwuuburbbbwgbrrguwgrbbrwwgbugrubbruwgrgbgrbw |  | ||||||
| rwwwbwwguwrurbubwrurrbuurbwrubuwruggbguubgwrbugguuubrgrg |  | ||||||
| buwuwruubbrrrwbbuwbbugrwbguuwrubwrbwwrrgugwuur |  | ||||||
| wrrbuwuwwgwrgwgrruwrwbbwbwwruuwwuugbgrggubbbwwgb |  | ||||||
| guwbwrwuruwrgwuguguwbuwurruwbuggwuwrwwubugb |  | ||||||
| bgbuwwgrrwwuwrbgrgbwbrggubwwbggwwbbwwurgbuubrrwwrburwgrbb |  | ||||||
| wwwgbrbwrwrurrgrbgwbbgrbuwwbbugwwwuwwrurbu |  | ||||||
| wrgbrurguwgrruuggrrugurwuurrubuuguwgugurwgbrruburuu |  | ||||||
| wuwurubwugubrbrbwgrwbuugwbbbrwggrbwwguwwrbrbr |  | ||||||
| wrgwrggbwbwbwubrbgruurbbgggububbbgbburgurrgruwb |  | ||||||
| bggwbbrwbgugbgrwwgbbrruuguuuruuuwgrrrrgwbr |  | ||||||
| wrgwwrgrgbwugbgwgbgbbgrgbuwwwwuwwbubbbwg |  | ||||||
| gggbrrgwbwbuwbrbbbrbbwuubrrwuuggurwggwrwbwbu |  | ||||||
| rbugwwuwrbwbguwbgbgrwbwbbggwruwbuwrwwubrgbbrwurwwwb |  | ||||||
| bwwwbuggbuurbbuwrwwrbgubwbuurbrbubwgwgugrwuwgburwbbwwbrg |  | ||||||
| wrggrgwgbgrwubgbwgrugwbuggggurrrwbrgwwwgwwggwgu |  | ||||||
| ggburrrgubrrgwgwgbrwugwgwgrwbbbuguwbgbrwbuuurwrbr |  | ||||||
| urrgbwwuubwwubuurrbwwgubuuggrguwwwgbwwuguwgbugb |  | ||||||
| buugbwgwrurbbugbrugggwrbrwwruurgurwrburgrguur |  | ||||||
| bwugruuggubrbuuwurbbwbbruggrwwbrruugrwrguw |  | ||||||
| wrgwubgubbuwubwruuruuuwwrurrbgrrbruuurgrbrwugbbuggww |  | ||||||
| ugubburbrggubgrwgwguburwwburbubbrubrwrbuwb |  | ||||||
| wrgguwubbrrwbrwuwwbrwruubwgwwwrwwgbrrwguubbwwwugugwr |  | ||||||
| wgwuwwgrwrubrgwrgubrggggwuwrgrwwbwwbggrgbuwu |  | ||||||
| grwbwgubgwrggwrbgrwbuugrgrburbuubbgrwwwbwgb |  | ||||||
| bwwwbbrbwwurruuwwggrwbggrgguwrubbwbgbbgugubwbbuug |  | ||||||
| bbggwubbgwwrbburwwwgwrbwrbgrbubbwrrrgbgbruu |  | ||||||
| wrgwurrubgguggwgrrbugbbwbrbuurgbbrwrwrwgugwubbbubu |  | ||||||
| wrggggwrbbrugbrubguwuggubwggugrbuurwubgbuwubwgwgugugwubwbrwu |  | ||||||
| bwwugbwbgrrbgrrbbrbgggbwwwwggbbrbwwbbbuwgguugubrububgwwu |  | ||||||
| ugurgbgruurwbwgrruuwwbgbrrbbbggggurruruwrubbbuu |  | ||||||
| uwrugrrgrwbrgubrwwuwwgwgrbbgrbgbrwwuwubuwr |  | ||||||
| ggbgwbrwuwgruwrwgrrrrwugwgbrbbuwuwwbuubwgw |  | ||||||
| wrrrgguurbgubbgbguwruugwrbrgwbgwrrbbuwugbbrwgrbbugrgbbgwuu |  | ||||||
| urguruuggubbwurrubuurgbgbrbgugwwrrggwwwugugg |  | ||||||
| gugbggubuwubrgubwuwrwbgbrgbguggwrbrrgwguugu |  | ||||||
| buwurubbbwurgrubgwgggrruwrrbbrbugggggwbwwgwwb |  | ||||||
| wrwbbuburwrrwwururbrwgbbrbgwbbrrrbubbgrgbuggwrw |  | ||||||
| ugubruguuwrgwububrbgrbwgbwburwgurwbuwwubuwu |  | ||||||
| gwrgugrbgbubbwubgbrwbuwggugwurrburgwrwrugubwggwuu |  | ||||||
| rgbrgrbggwbwuubburrurggwggguurwuwwwrwuwurbrggrgbuwrgbgwbgb |  | ||||||
| wrggrwwbrrurbbuuwburubgruurbrgwrwgrrgrbguguuubwug |  | ||||||
| rguwwuuwgwwubwbggbugwgrrwgbrgbgurbwgrgugurrgguggrrbuuu |  | ||||||
| ruwubrwugurgrbruruggwbugbgrurwuuwbwrwugwgrr |  | ||||||
| wrgbrrbgubgbgwrbwgwubuggurguburgwrruruur |  | ||||||
| uburbrrbgbrrruwruwgwrrgrgurgrruugrruwuuugbuwburwubbrbbgw |  | ||||||
| wrbwuggbuuwwwuuwbwuuwgwbuubuwgrggrrbgbuwgubrruuggrrruuuwub |  | ||||||
| rwwgbrrurubuwrgwgrbgbrrbbbwbbbwrugwbubugwuwgwugwwurwgrbr |  | ||||||
| wrrgwrggrbuuruggggwrguwbwgrubgwbguuggbgrwrgubrurwuggrwgwrb |  | ||||||
| wwrggguurbuwbwurwwbbwwbrggwggbrbbrgugurbrbwwwrbrrggbbb |  | ||||||
| ubbrrbbwwrugugwrggwuwwuruwuwbwguwgggwwbwrbgbwuugruw |  | ||||||
| rggbrwgbbgwrwwrrbgwbuwwbrbrbururwgbugwwbrguuruwrbbbbwrwgu |  | ||||||
| rguwbuwgwrrbgwbwwwuwrrbrwwwburrbbwbruwggugubbu |  | ||||||
| rgwbgwwbugbgwruugwwrugwrrbuwgrbbwbuwubguubwbugugrwu |  | ||||||
| ubwwgrurugbrbrgwrbgrbwruwrbwwbugrwgwrwubrgbwwrurb |  | ||||||
| rurugbugrwuwbgrbwgbbrguwgbgugwgurbbrbuuurbwuuwwgbgg |  | ||||||
| rruubwwwuwrrwgwugwrbgwbuugbrbwugrwwuwurguw |  | ||||||
| wrgwwrgugrbrruurwuwgbwguwurrubwbbwurwwrgruwbgbwwrwu |  | ||||||
| bgruuwgwrgwugrrguwugwbrbgbbbgguurwrbubgwrr |  | ||||||
| gwrgrwurbruwgburrruuggbuwbgbwggwgurubwgurrbwuwb |  | ||||||
| bwbugugubgubrwubrbgruwrubbrurggbgrrgubrrbuurwrrubbwurbbb |  | ||||||
| bggwwgrbburbbubbuuburuguwubrubgbrubrrrgwwbgrrggrgggwrrgrg |  | ||||||
| rrrgbgwbgrwuwgubbwbwgubbrgwwbwburbwguuruwwwrbrb |  | ||||||
| wrgwbbugggruwgbwrggbbburbrgbwuuwurbugggbuggrwrbw |  | ||||||
| wgurbubuuwrwubrrgrrbrbwrwurwbrbgrggguggwubgrgbr |  | ||||||
| rubgwgbwbrubrbbrwwbbrrugrbbrrwuugggggwrwugbbbrb |  | ||||||
| wrwwubrbguubrggurwrburgggruwubggwgwbrgrggrggwuubwggubgggww |  | ||||||
| wrgwbgbrgugggburuguuwgrrrbrgrwbgubruwrwugbggubuwbbbbwwwbw |  | ||||||
| wrgrwggbwwrgbwubrubbwbbuuggrbbugrrrbguwbrub |  | ||||||
| grbrwgbugbgwgwbwubbuurgrgbbggwgbgbwwwrurguuubgbrwugb |  | ||||||
| urwbbbuggwugrgggurbuwgrrwwbuubwubugbgburgwgbubwuurwuwbuw |  | ||||||
| wwgubbuwubrgrgwguwbgrurbgwwuwbgwwgbuuuwwwwggwgrrwwwwrbrbuw |  | ||||||
| wurwrbgrubrrbguwwwgrggwwgrgbbbbuburgruwugwrbr |  | ||||||
| gbwgbrbrrrggrurrbrrwwrrbwwgubgwwuruwurgrrbbrwb |  | ||||||
| gubuwgggwgwwwwuwgggwgwwugrwbggbbwbwrrwugrwuurggwbgbgrwruug |  | ||||||
| uwrugrgbburwwbugrbwwwbbgurruwbburgrwwwgrwrwrggg |  | ||||||
| brbgrggwububuugrwgubwubbbwwgggrgurrwwggbburgbuugw |  | ||||||
| ggwwbgugwwggrrububbgrrrrwwbwwuuurbuuubbgwbwu |  | ||||||
| bgruubgwurbuwrrggugwwbwrbwbgwrwugugbrwwwbburugbbguur |  | ||||||
| bbbrggbgrrbrubugbrguwrrrruwbuwbgugwubgrugrwruugwgbuw |  | ||||||
| wuurgrrwurwggwwguguwwurwwugguuguubbuuruwubg |  | ||||||
| bbuuwrbwwwgggrgrrrrbgwwbwurrurubgubwburgbggrwrubgwbrw |  | ||||||
| rwuwwbrguggwuwrruwurubguubgwburrwgugrwubwwbwgwwbbbrgrbb |  | ||||||
| gguuggrrggbwbubgrbrrwbbubuwbrwrwgbuggbbbuuuuuwrgrrgw |  | ||||||
| bubbrwwgbwrwwggubgwwwubgbrwubuuruuwuwgwwgruggbw |  | ||||||
| wubburwgbbgruuubwggwurwrubwuwbrgbuuwbbguwwgrwbugbwrrgubrg |  | ||||||
| rbwrruguuuwwbrwwwbwrwrbubwuggwurrbugwubuggrbubwrubwbwu |  | ||||||
| uggubuwbuurrbgrugwwubwubrrburubbbgbugubrwwbuwrbu |  | ||||||
| ubbgbbgrbuguwwbgrwwwgwubuguubruugbguuuwbrrg |  | ||||||
| rugbbrguuruuruwgbuwrwbbubgrrbrwwbwugrwugbwuuwbwwbbwuwrg |  | ||||||
| gbubbuubburgrbbrgubggrbbwwuwwbbrurguubgwubbubbbuu |  | ||||||
| uggwrwuubrrwrrwurbrwrguurrugwwgruwrgwrrrbbuubgrruruwr |  | ||||||
| wrgrwburgbugwgruburwguurbgggbgubrurwurguwwurwwrbrubbwbwr |  | ||||||
| bbrubwwbubwuwgwgbrbwuurwrrbgguwbwbgbwuwurbbwbrgrrgwbbgw |  | ||||||
| bwurwgwgguubrgwbguugrubbrgwrugubbgwwubruguwbrbwb |  | ||||||
| wrgrwggurrrgwwggbgwrgrrubuubwbwrrrwggbbgbgrbwgwbgb |  | ||||||
| wubrrwbbugrrrrbbgrbwuwwggggrrbbbwurrbuurwbuwrwgrbggu |  | ||||||
| gwgurwruwwbbgbrurrrbrurrrgrrggbgubwbggugrwrrbuw |  | ||||||
| wrgwwwurubgbrgwbuguubwuwurbuurwrruuggrwrrburuuur |  | ||||||
| gubwbwuggbbguwwbgbgrgggbwggbrrrrwubwrrrruuwbgrrwguww |  | ||||||
| wrgguwubgwwwrwwbrbgrruwbrurrrugwrrbbrgbgbw |  | ||||||
| guwwwgrrurrwuwbwrgububgwurrbrrbgbrrwguwrrggguuugbrbbwrgw |  | ||||||
| rwwbggrrugburbbrbguwbgwwrubwrrwwbbgurruurbggruubrgggg |  | ||||||
| uwbgbugwrguuwurgrrgrbrwwubrrbuuwggwwwurgurgwrgrwbr |  | ||||||
| wwgrggwgwbgrugwrggbbruurbgbbwrgruuwbbrurwb |  | ||||||
| urbwbgwbbugbuwwrgwwwwgbbwbruwbwgwwrrrrbubrbbgurbgwuru |  | ||||||
| wgrgrrwububgruwubgwuuwbubbgurruruwrubgrgwg |  | ||||||
| wbbbgbbbguuuubruurugwbruwbbrbwubrgrburrrrwrrb |  | ||||||
| wrggrugrubgrwrwgugugrrgguuwrubwwugrrbuwbw |  | ||||||
| uwbbggrrburubbgwwrwgggwgwggwgbuwbwgburbgrrwr |  | ||||||
| wubbgrggwrrbrbrgwrbubbruugbrwbbbugbrgguubgrgwggu |  | ||||||
| ruuuuurgrrrrrugbbrgburubbwuugwwgbgubgubwubguuururgrwb |  | ||||||
| bwgrugbbwbbrrwuuuruwubgwuwbrwurrrbwgurwbur |  | ||||||
| ubgwubrburgrgrwwrrurrgguwbbwbrbwbuuuuwwwugbrwgrwguubwbrrrg |  | ||||||
| wbrbwruwbbubbgbbgurbuurbwrggbwbgrugugwwgwwwbrburbgbbwr |  | ||||||
| ubgbbbbgwrwgrgrguubrrgugbgugubrwbruguwbwrugwuburwwbb |  | ||||||
| ubrwbuubwuubrrbbrurgbwubuwwbrbrruwwrgrguwrrbwgrugwbubw |  | ||||||
| gwwruuuwurbwrwrubrwwrrbwrrggrburbgwgruwubrrwgubbbuw |  | ||||||
| rwggugubbwgwrwbwrwrwrgwgugugguruwgwbbrwbwrggwurb |  | ||||||
| ugubuwurgrrgugbugrrwrguwwrrurubrbrbrurbrbbwbbuuwugrg |  | ||||||
| uuurwubugubbggwwwurbwgrgruubrwbwgguwrwwrbubbgrgrbbgubb |  | ||||||
| wggruwbwbrwgrwrwbrbuwbrbbwrwwrbubwggrbuwuggbbrgwrgbggwwb |  | ||||||
| wrgbgrbrgwbggbgbrwgrbbwgrgbgrubbwgbrwrwwgbbbwurgwbgwbwbrug |  | ||||||
| urgwwbwbbrwugruuruuubgbwubgwbuwbbggwrbrggwurgrrrgbububwg |  | ||||||
| wguubbbbgwuuuwrrguurgugrrubrguurwggburbgrwbgwuu |  | ||||||
| uurrbwuwwuwugbgrbgwbggwbwgwbwugbbwgurubwgrrbb |  | ||||||
| wrwrbuggbbrrwrgugrububuwggbwrbrrbbruuuggwb |  | ||||||
| wgwwurrwuuuubuuggrgwwuurrugruwbuwgwrrrwrwbwrubugrwwuwurbgw |  | ||||||
| wrgruubububrbwggggbbrrgrbuuuuwrgwggruwurgggwgwggwuwwwgrwgb |  | ||||||
| ruuggwgbrwwbubuggwwugrrubuwurbgrugrwgwubgbggrbbgbwgrurwggg |  | ||||||
| bggbrgwrwruuuuuwbbrgbrgwubbubugbguugggwwrrugrbu |  | ||||||
| wuuwguubwwguubbwggwwwurbgbugbwwwugwwguuugrwgrwrbwbrbubbgbg |  | ||||||
| ggrgwbwrubrwugwrgbrwurwggrguurgurwrwrrgubbbwrwg |  | ||||||
| wrgguwwrbubgrurgwbbuwguwuwgwbwugruruwwuuuwrbrubwrgr |  | ||||||
| bgwrrbwugrbuggrwbuwrrbrrggggruuugbrrguwubur |  | ||||||
| wrgwbgwruwggbwuubrugbgrrwubrgbburwwrbrwrwwrbguwgur |  | ||||||
| buwbrgrbubgubgugwrrbwbgguuwbbwuubrgrrwwgubbbgwgggugbru |  | ||||||
| gurbrrwbbwgubrrwbwuubbuuruubbruwrwwwrrbrwrwwbrbrubb |  | ||||||
| wrgbbwbrrwwrrwggbbwrrurgurbgwgguggubwbbbruurwrwuggg |  | ||||||
| wrggrugrrwwbgwwwwbugbbbbrwwgggrgggwbuguurgu |  | ||||||
| wwugrwwbbggrgwurgrrbbuwgwgurrrbgruwrwugwrr |  | ||||||
| bwrwubrgugguububbuggubbgggugrwuburuwrwrrrgbrwbrgr |  | ||||||
| grgggugwbuburgbggguubwbrrgrguuwwbrgggwwwrgbgugw |  | ||||||
| ubgbbugugbrugrwuguugwbggugbbwrgrbuurwbgrbrbgubbgwuwuwgbgw |  | ||||||
| gurbubbwgwuwwgwbrbuwugguggbgrwgggrwuwwbgbgwbg |  | ||||||
| rbuuugbburuuubgrubrbbrwgggwbbuugrugrrbbwggwr |  | ||||||
| wrgrwrwbwggwrwuguwrurbugwbruwbggbggrrwurruwuuruwru |  | ||||||
| uwguwwgbgggrubggwugwbwrbrbbwbgguuwrbgggwugrbwuwrwwgrur |  | ||||||
| rgrwrgwuwbbbrgwrrwuubgrgbwwrrgburbgbbubbgubwrburbbwuuur |  | ||||||
| wgruurgwubgubgbwbwbgggurbgbrggrbbgwgrrwggrwwgg |  | ||||||
| wgwbwuwwwgwrbubwbuuuwwuuuuubuwbuurrgbgbubbbuuguburwbgru |  | ||||||
| wrgbuurwbwbwguwrrugbrrwuuububbrgwbgugubbwgugrwgwwggwuwgrgrr |  | ||||||
| guggbbgugbwgurrwbuwruggbbubbwguuuruuwwggwrbbgruburgrrbug |  | ||||||
| wrgwuggurgbwgrgrggwwwgbbrwwgguwgguggbbgbbugwbrruwubrrrbrwuu |  | ||||||
| bwgbuubgrwbugwbrwuugurwgbrggbgrwrggwbrgguwbr |  | ||||||
| rbwwgrbgwwuwbrwgurbguwwgwrgwburwbbbwgrrgubugwurrggrwuww |  | ||||||
| ggrwruugwguuwrbgbrgbrggrwugwggbrgwgurbwgbbrbgwubuggbbrgugw |  | ||||||
| uuwwrwrrurgbrwrgbbuguruwwuwrwrugwrgrrbburgu |  | ||||||
| grbbgurubwbwbgrwwgruurwbbuubrwwrrbwubwuwbbbrwu |  | ||||||
| brrwwbbuwbwrbbgrbgbbuwwbbwrwwgubuwruwbgbwrwwwggug |  | ||||||
| wrwbgbgggruurugwbrwwgbuguuwguurbgrgrguuwwwrgu |  | ||||||
| wbwgbubrgbuwwwwbwbuuggugggggrwbwrwgrgguwrggrbwrgrburwbubb |  | ||||||
| ubgwwrbbwbuwrguwrrwrrwggruwbgbrwuwbubububuggbggbrwbu |  | ||||||
| urrbwuwwwrugbugwwgwbbubgrgbburuuwgbgguguugb |  | ||||||
| uwbugbgubgrwgbruubbrrbrwgwuubuwbwbbuwrgbwugbr |  | ||||||
| wrgwrrrbugbgwuwbwrubwgbbbuguwrrgrrwgbbgurwwbrbbggggrrbrruwu |  | ||||||
| rwrrwbwwggubbguuubrwrurgrbwurguuuruuwgubwgbwbrbbgbgb |  | ||||||
| grrbrgwrwbwbbgguwgguugrwurrbwwgwgbuubgrbuwbbbgbbbuw |  | ||||||
| rgwubwwubrrgbrwwubuguugwbbwuwgbgubgruuruubgurrgwguuggwrw |  | ||||||
| ruwuwuwbuwrgggwgrruguwwbrbuwwgugbuuwruwbwrbgwubwu |  | ||||||
| ubgrgrguguwwbwrwwbgwurwurrrbggrrggubgrrbuuggbgg |  | ||||||
| wrggwgrbugwwgruwwubrubgrgggwgubbbwwwwrwurubrwrggrwwbrgwgw |  | ||||||
| gwbggrggwbgwgbrwwuuuwbbwrwgbguwruguuugwrbgrbbrrwrurrggbb |  | ||||||
| brrbuwguwgrbbburrubrbwburbrwbgwbbwgrrgwugrg |  | ||||||
| wgruguruwwgbrurbugrrrwrgwbrwuuruurrwrrgwuuwgwg |  | ||||||
| buuwrbwbubggrwugwwbuwgubbbrbbgbubrrwrbbwwrrrrrwgugurrrbbb |  | ||||||
| rbrrburuubrwurwgguggggubgbbruwwggburwwbwrb |  | ||||||
| ubgruruwbrgbrbugrbburuwugrurugrwbwwguwuuwuwgubgbrgwrbbggbg |  | ||||||
| gguuuwwrgggwgurrrubggubruubbugbbuuwgrruuwguguu |  | ||||||
| uwbwggbrbrrbuggbwwwubwwuuggwrwwrurrwbgbwuwgw |  | ||||||
| rwwwbuurburrrwubguwgrguguubrbgwbggbwurgwug |  | ||||||
| gbgugwbuuwuwguwugwruwwbwurguubuurbbgggbgggrrwgwbgu |  | ||||||
| gbrrbwwbuugurwbgrrwwwwgruurgbbgwwwgrguuuwgbgbgwwrbgwr |  | ||||||
| gbwubwugbgwwugwgguruwubwggwuruwrbbwwbggggrgurwg |  | ||||||
| wrgwbggbrgbuwrgrggwrwbbwwuwruuwuwrgrwwuwg |  | ||||||
| wbrwgrgbrrrwuuuuuugwwrwbrbwbuubgggrrrbwuwruggwbwwubwbrgbwb |  | ||||||
| uurbbgrrwrbwubwwwgbrrrrugbrbrbgbubrgrwbruuwggbbwbrg |  | ||||||
| wrgbrrugrwrugbbrbwgrwbubruuguggwuwugrgbruurbbuubwbwur |  | ||||||
| ggrwgwgwugbggwrbwbrwwrrrbgwrbwuwgwbuuurbwwuwbgubuurwb |  | ||||||
| wrgrrbuwgurbgubwwwwguuwggwbrbwbwwwwuuwggb |  | ||||||
| bbrurwwuwbgggrbgwrbrbgwurrrbbggrguwuwgggbbuuwggruwwgbw |  | ||||||
| ugggggbwgrwubrrwurwgrwwurwrrgbrurbuguwbgwwrrbgwwwwrgwrrw |  | ||||||
| rurbgbbwgrrgwuuwugwgbubwrwruugubgruwbwwrrg |  | ||||||
| wrgrrwggbwruuugrwurbuwwgrgururgugwuwubbgbbgrwururwrgr |  | ||||||
| wgrrbwrwrrbgwgwwrwubgrrurbgrwruguurrruwbwbrwugwr |  | ||||||
| gbrwwbbbuwbwwuwubwggwrrbubuwrrwbrrrbuwbbbbugwbgu |  | ||||||
| gurwruwurbgrurgbuwwgrrrwrbrrgwrbggwwrwruggurg |  | ||||||
| bgururwbrguubbwbwbubbbrrbrbwrbgrubgwbruwbbwwruurruurrgurru |  | ||||||
| bgugrwbbbgrbwuwrbubwbwubggwrwrwgrrbrubggwgwruwwuwwgrbwwb |  | ||||||
| rbguwuwrrbwbbgrrururugbwwruwwrrwbugwguggubruuuuburrguugbu |  | ||||||
| gurbggwbggwwurggbrgbgugrbgubrgrwrrgwguubwrurrrgrbwwbugwrw |  | ||||||
| wrgbuwbugrgwrugguggbrrrgurruuuwgbguwgburb |  | ||||||
| gurburbuuubuwrbwrubwuugwgwbuurrbwuurbrruuburwggw |  | ||||||
| wgguwuuwguubuwrbwwwbbguwuugwrbubwugugrwwgwwwwggurwrbru |  | ||||||
| wggbwgwwrggruuwbrubrrgbggrgwrwrgubbwuugwwuwrggrg |  | ||||||
| bbwbgggubbwwuwrbggwbrgguugbuuwubguuwwrgbwuruwgruwr |  | ||||||
| wuububrwurrgwubbgrbrrgubbbubgwbrbwrwrbwurwgg |  | ||||||
| bgbbrbwwgubwbwbgggrwbrgbbuurgwbrrwgwgruwwrguuggubrbrurwr |  | ||||||
| rbuuwrwbuubwrwrgrggurgwrurrgubbuwuugwbgwrrw |  | ||||||
| wrggbwurgrrubgbgwrrgbruuuuwrruruubbbgrgubbggrwbbuugg |  | ||||||
| buggwggrgbwbgwwbguwuwrbgwrbbwwrguwwuwggurbwgurbggubrrwgg |  | ||||||
| guuggrbbuwbrwgrurrwwwuugwbwugbuwrbgrwguuwbgubgrbbg |  | ||||||
| uuwwwbgugguuwuggrburwwubgurwwbuugrrwgugwuu |  | ||||||
| buurwugwrrrgggubgwwwggwwgwugurbgrgwwuuubwuggurwrrbggbguwgr |  | ||||||
| uuwwbgggubuubgurgwurbwguwrrwgwugubruuugwuguuuwwwgwgb |  | ||||||
| rwbgrbwrwugbbwgwrwrgubbbbwwrrguwwubbugrbbwgbg |  | ||||||
| ugrurggwgbgwgwrruugrwugwrgggbuurwbbubuugrbgbru |  | ||||||
| uuugugurgbwwwwrbrgbrbggrbrurrgbbbrubburbbbbrrrbbbgww |  | ||||||
| brbburruuwuwwbgwugrrrrggbwgrbrgwugrwbwggrr |  | ||||||
| rbbbgburbwbwgbubbrugbgwgugwgrbubggwgwwuwbuurbuurgwrugrrg |  | ||||||
| wuuuubrgwrwwwwugugrgwbrubbbbbgwbbgbubrrbbwgwwrgg |  | ||||||
| ubrwubuurrrwugruubggwuwbbbuuwgbuubwrrrwbrwwwwbubwgwbrwwu |  | ||||||
| brrurgrwwrruwrrubbwuwguuuggurbwgruuurbggggguwurrg |  | ||||||
| uuggbrwgbugguwbgrrwgwwuuwuururwwbgbgrbgbuu |  | ||||||
| grbbbrrgwrurugbwugbwgrgbgbgubugbrurruubgrugguubrwwugwuu |  | ||||||
| ruwbwbugbbbgggbrugrgbbwbbgrguwrwuurrrbugbugbwwgbbugb |  | ||||||
| ruwwrrwugwwbubggrubwbbgwrbgwggbwgguuubgbgubg |  | ||||||
| uuwwugrbbwbbbbwwwwgrbbggurubwrrbbuuubrrggbgb |  | ||||||
| wrgrgwuruwwugubrbrruggwrbbgrrubbggrbrwbruwubgbbrrwwgrgbgubgg |  | ||||||
| urwuuwgugwwubuwrgwbwbgbbrwrwrrrrrbuburwbrurwuuruuugbrbb |  | ||||||
| ggrurrwubwuwbugguuruuwggwwrgrgwwbbrwubgrbggbbur |  | ||||||
| rwuggbgubrwuuwrwrbbbgbrgwwuwrbbuwrubguuugbbgwww |  | ||||||
| wbrwgbrubgrrwbrwrwrwwrgrrbbrwggwbrguwwbrbbwggubbrruuwgrb |  | ||||||
| bruwgrwrrgwrbugruuubwbruuurgbwgguwwruuurwbgr |  | ||||||
| wubrurubrubrrwbuurgrgubgwbgrrurugguggbrguurbugr |  | ||||||
| gbrggggugguugrrrwrgrrurggwwrgubuubwurugrbbrrrgg |  | ||||||
| gwrbugwubbuuwrggubrrubbgggggbgbggwrbrgrwgwruwbwggubug |  | ||||||
| gwrrgubggrurrgbbugruwgbwbrrbwuwuwbggwgrrrwgrggubbgurbg |  | ||||||
| wrggwgwgwuwbrwwbwwgrurubugubgrgubuubbgwgbggwwwg |  | ||||||
| wwrwbbrwwrwubwwwgbwrgguwuwrguwwggurgwgbburuuwwgwrggg |  | ||||||
| wwrbwwbbgbgbuwbwuggrbrggurbugbrwuwugrrurwbruw |  | ||||||
| wrbgrrggbwwgwwwgbwgbbrurwugwgugurguwbrgubr |  | ||||||
| gwrbgbgugubgbgrugbrbgrgguwggwgubugwurwbwrgwbrugwwwb |  | ||||||
| wbgugubwwwrurggwuwuwrrwwrwgbbbuwbbbrgrrgwurw |  | ||||||
| uuuguubwbbwwgbbwwggguubgububgrguguubwwuugwwrwbr |  | ||||||
| rwbgrwwgwrrruwugruuubbwrbrgubgrgwgbbbwwgburbubgrg |  | ||||||
| wgbuugbgwbgwuwwgbwgwwguwrbuwurbuwrbwwrbbrwrrrubwrgbbug |  | ||||||
| ubuwggbwubbgrwbbbwwrrbuwwuwwwwbbubbwrwbubwgrr |  | ||||||
| uurwrurwrbbbgwrbggbwwruguwbwgwururgugrugruggggbgwwrrurggg |  | ||||||
| wrggurbbwgrurggubgbggbrbgbgrwbgwrwbububgrwrwgrwwubuububu |  | ||||||
| wrbwrgggggbuwubugurguuuugbwuwuuruburgwrwuwr |  | ||||||
| bggbgwgrrrbwbwurgwwrggbwrwgbwuwwugwbwgbrrrbgrwwgwrwgbr |  | ||||||
| ubuguruwbrrrgbwwgrgggrruwgggrgrbgrgwubggbrbuubw |  | ||||||
| grurrbguuubuggbbguurbwwbrrurguwurubrbgwggrguwbrrgburruugb |  | ||||||
| wrgbgrugrwwgwbgubbwbbrwubruggruuguuwubwgwurubggrbgwurrrrr |  | ||||||
| wrgrwuguggwwurbwubgwrbrugbruruwuurgurbbgrgr |  | ||||||
| wbbrguggbrbgwgwrugbuwrgbrgbuurrggggbrwgwwwuubbub |  | ||||||
| grrgwbwwbruugggburwbwgrbrggwgwwwwuwwbrwrbwr |  | ||||||
| guuwuuuwrgwwgbruugwwwrwuggrrgwbwwruuuuubububrwrbgurbw |  | ||||||
| rrwrrurggwurggguurrrrurwugwwrruwrruubwrbbguubww |  | ||||||
| grrwgrrrwbubggrrwbbgggbgwbbwubrbwwugugggwbg |  | ||||||
| wrgrrggwurbwbrguwrurwbwrbrbrggggrguwbwgwgwrbggbgrbgrb |  | ||||||
| bwrbwbwurbrugggwbgbrguwrugugrruubrggbwuurrubub |  | ||||||
| wbgwwubuurwwubbwwgurgugbbbgrgwuwbbwrbgwbwguugurubr |  | ||||||
| bbbbruwuwgwbuuugrrbgugrwgrrwwggugrggugbbgrrbw |  | ||||||
| wrggrwwubwruwbugubgurrwrbrrwbgrgbgrruguuubgbbwuwbub |  | ||||||
| wgurrgubgrgbgggurgubbugbbbruruggrbggrgrwwrw |  | ||||||
| rurbwwuuugurguwgwguwurrruubuguwwrbbburrbrwwugrruuw |  | ||||||
| wwubwbggrurbwubbrwbuuruwbgugbwgwgrugubbwbub |  | ||||||
| ruwbrbuguwuuuwwbrbwguuwgrwuruugbrgbbwugubrrrgrgb |  | ||||||
| rwrbrwrbwuwbuubrugwrubwbuuwbubrwbrgurgwgbgrurwrruuwu |  | ||||||
| rugwbruruguuuwgrbwruggggwbgruwrwuggubgruurbubwug |  | ||||||
| wgruguuruwbrrbwubuwgbrwugrgubgrwgggbwwuggbwbb |  | ||||||
| gubuwrgurwrbrbrugrruuwgbbwubwwbgbgguwuuwwgrbrwuwr |  | ||||||
| grrrgwguwrgbrbbwbbrwbgugwbrgggggbbrrurbbgbggwbuugwugb |  | ||||||
| gbrbggrbgrrbbggggubbbwuugubgggbgbrurburugwwwurwwuuw |  | ||||||
| wrgguubrrwbrrugwuuruurwbuuwgwbuugubgbrbbrrbgrbgwrrrwrgguww |  | ||||||
| uwwburbrrururbrwgrwrgrbuwubgugwwwgwgwrrurggu |  | ||||||
| rgubgrwgruwwwgrrruwrububgrrwuubbwrguuwwrrubururguwgbrg |  | ||||||
| gguwbrrrrgwbbgrrbubugrgwwbbgwrgrguwuwwrwbwwgubbgubbuwuwgw |  | ||||||
| rwgrwrbuwbwrrwrrbrrbbbuubgrgbrgugbuuuwbuuw |  | ||||||
| rgguwggrbrurwrrgbruwbguwwwrubwurbrbrwwbwwggrrrwbwg |  | ||||||
| rwruubwuwguwrurrubwuubbburwubbwwguguurggbbwuwb |  | ||||||
| wgwubbbrrbgbwrgubrgguurrrbuurwubbbguubguuuurguwwr |  | ||||||
| grwwbgggrbbrbwgrwbuuuruwwgbbuguurgburbrgugurwb |  | ||||||
| rgugwuuubgubwwwwbbuurwwwburrrgurbwbgbuwwruuugu |  | ||||||
| gurrwwgrgwrbrbbgurbwrrbubrbuwbuurrrguugggrrbwugbb |  | ||||||
| wgwburbwwbubrgurgbbugwrbbrwggwgbwbrbgwburbbugbrrbggbwwwwg |  | ||||||
| uwubgbbubwrbbbubgbbgwbuguububruubbbwuwrububbg |  | ||||||
| ubgbbuwgwrbrggrbrwrgubbubrbbuurrgwbrggbuuwwwrgwubwrbbwb |  | ||||||
| wgrbrwwwgrbgruwbbwgbggwuugggwggbrwrwbburgubgburrwrrwrwbw |  | ||||||
| wrgrbgrbugubrwwwwuubbrbrbrwgwuwbbrgwrbwwrbwbrrubbrr |  | ||||||
| wrgbburuubwbrrggwurbwwbrwuwwugrwrbwwbwgrwwwrbrurubrgrbw |  | ||||||
| rwwbwgwbgggwuuwwbrwgwgrubwwwrrbgruubwrgguwrwr |  | ||||||
| rurbrwwruuuuugwgbbwgwrgrbbwbrwwruuuwwgrbgwbbbuurururwww |  | ||||||
| uwguwbuggubwuubururgbgurrbbugbwuwrgwwrbwwuuwruwuubgb |  | ||||||
| rwubrrrubgwubbgbubrrrrwbbbgbgrbbbuuwrwuggwgugr |  | ||||||
| buwrgbggrburwwrrwrrgbrwbwurwgwubgwbwgrrgwbwrrbrbrgrbgububb |  | ||||||
| wuuurwgbuwwwwuwbbugbrwurrgguwbbbbuuggwbrrwbgrbrgwrgrubug |  | ||||||
| bbuwbrubrwbgurwbwbguugwwgwrwbgbwruurwuwbuuruuggr |  | ||||||
| rbbrwwbbwuuwwuuurburrrgwgrwbbrrbuggwrwrgruugbu |  | ||||||
| gbrgubuurgbgguwwwwubbgrbwrrurburugbwgbubbwruuuuruuwbbgwguw |  | ||||||
| wurwggrggwwrwugbwgrwuuwrugbuuggbgrwrgwggrgugrgrwrrwbb |  | ||||||
| rgwrwuwuwrgubuwbgurwrgurwuuuwgwwrgwgrgruwuwwggwurwrbbuw |  | ||||||
| wrwwrgwbwgbugggrguuurwwuwrbrwrrruwwbrrrgrruubg |  | ||||||
| wbwrrruuurgrrrwrbuwbggbguwugrbwbggbuburgruwgbbruubrwbrgrur |  | ||||||
| uuubuguurruuwwurbuwbgwrrrbrbwrwbuwubugrrruwuggrrwb |  | ||||||
| rrbggbubgrruubbgubuwubbgwuubgbrruwuugggbrbuubgugg |  | ||||||
| buwugbwbbrugbwbgwurguwbwwbbgbbbuguwgrwburrgggbgbguruww |  | ||||||
| wrgbgwurgrbrggrburguuubugbwgugrwbwwwwbbuubw |  | ||||||
| gwruuubuubbbwurbgurrrbwwbburguugbwbrrgbubrwwrrwwgbbgbu |  | ||||||
| wgubuugggrugrwrrggugguwgbwwwruuuwwurwbwgwbbwgr |  | ||||||
| buwwwgrruuuwrwgggbbggbguuwwugwwguuuuuruubrruubbuwubggbgwrg |  | ||||||
| gwrgbgubrwuruwuruguubbuwrbggwwrguugrrgwwbbwgwrbbwbgguuw |  | ||||||
| wrgrbwuburwgwggggrrbrgrbbguuwuwbgrbwbubbbbb |  | ||||||
| wuuurbguuwrurgggrwbgwrbgggrgrggrwuwguwrrugugrugwbuwbrug |  | ||||||
| ugbubbugwbwgugbwuurwbuugbgwbgwgbrurgruuruubgugbwugwubu |  | ||||||
| rgguwubwruubugbrrguruugrrwbrgggurrgbugwbrggu |  | ||||||
| ggwrgrrrrwrggbbwwuwgbrrrugrrubwwwrgrruugurwgrbgwbg |  | ||||||
| gugwrgwbugugrruubbbgugrwuurbruubwrrbbuuubbb |  | ||||||
| gbuuggruguburwbrrbrggrguwguubugbwggbgwuwrwgrgub |  | ||||||
| urbwrguguuwrugrbwgrrgbwrwrwwuuwgbgwbururggwurgrw |  | ||||||
| wuwurrubrwubugbgwgwwuguugbgbuwrwbuwrgbggrurgruwuwuuu |  | ||||||
| grrugwbrrbbwbrgguuwbubbgrugrwbwrurwggbwwwr |  | ||||||
| rwbggurbrwubrbgwuwruwbrgwwgrubuuuurbbggbwrrrwur |  | ||||||
| wwbugrgrgruwrgbugrwrgwgrbruuuuubbubrwbwrgrb |  | ||||||
| wbbbrgwwrrrwwbrrwwwuwugwbrwgrbwuwuggbuwruuugubgbg |  | ||||||
| wrgbuggbbrbrubgubbbuwrubbuwwgbggbbwgrwrruwgguwguwruubw |  | ||||||
| guggwbwbgrrubbrwrrwgugguuuwrgbwgbbguwbbubw |  | ||||||
| @@ -1,141 +0,0 @@ | |||||||
| ############################################################################################################################################# |  | ||||||
| #...###.....#...#...#...#...#...#...###...#.....#.........#...#.......#...#.....#...#.........###...#.....#.............#...#...#.......#...# |  | ||||||
| #.#.###.###.#.#.#.#.#.#.#.#.#.#.#.#.###.#.#.###.#.#######.#.#.#.#####.#.#.#.###.#.#.#.#######.###.#.#.###.#.###########.#.#.#.#.#.#####.#.#.# |  | ||||||
| #.#.#...#...#.#...#...#...#...#...#...#.#...#...#.#.......#.#.#.#.....#.#.#...#...#.#.#.......#...#...#...#.#.....#.....#.#.#.#.#.#.....#.#.# |  | ||||||
| #.#.#.###.###.#######################.#.#####.###.#.#######.#.#.#.#####.#.###.#####.#.#.#######.#######.###.#.###.#.#####.#.#.#.#.#.#####.#.# |  | ||||||
| #.#.#...#.###.....#.............#...#.#.#...#.#...#.#...###.#...#.......#.#...#...#.#.#.###.....#.....#.....#.###...#.....#.#.#...#.......#.# |  | ||||||
| #.#.###.#.#######.#.###########.#.#.#.#.#.#.#.#.###.#.#.###.#############.#.###.#.#.#.#.###.#####.###.#######.#######.#####.#.#############.# |  | ||||||
| #.#.....#.#...#...#...#.....###...#.#.#.#.#...#...#...#...#.#...#.........#.....#.#...#...#.......#...#...#...#...###.....#.#.#.............# |  | ||||||
| #.#######.#.#.#.#####.#.###.#######.#.#.#.#######.#######.#.#.#.#.###############.#######.#########.###.#.#.###.#.#######.#.#.#.############# |  | ||||||
| #.......#.#.#.#.......#...#...#.....#.#.#.#...###.#.......#...#.#.#.......#...#...#.......#.....###.#...#...###.#...#.....#...#...#.........# |  | ||||||
| #######.#.#.#.###########.###.#.#####.#.#.#.#.###.#.###########.#.#.#####.#.#.#.###.#######.###.###.#.#########.###.#.###########.#.#######.# |  | ||||||
| #...#...#.#.#.#...###...#...#.#.....#.#.#...#.#...#.#...###.....#...#.....#.#.#.#...###...#...#.#...#.#...#...#...#...#...........#.#.......# |  | ||||||
| #.#.#.###.#.#.#.#.###.#.###.#.#####.#.#.#####.#.###.#.#.###.#########.#####.#.#.#.#####.#.###.#.#.###.#.#.#.#.###.#####.###########.#.####### |  | ||||||
| #.#.#...#.#.#.#.#...#.#...#.#.#...#.#.#.#.....#.#...#.#...#.....#.....###...#...#.#...#.#.#...#.#...#.#.#...#...#...#...#...#.....#.#.......# |  | ||||||
| #.#.###.#.#.#.#.###.#.###.#.#.#.#.#.#.#.#.#####.#.###.###.#####.#.#######.#######.#.#.#.#.#.###.###.#.#.#######.###.#.###.#.#.###.#.#######.# |  | ||||||
| #.#.....#.#.#.#.#...#...#...#...#...#...#.......#.....#...#...#.#.......#.....#...#.#.#.#.#...#.###.#.#.....#...#...#.....#...#...#.#.......# |  | ||||||
| #.#######.#.#.#.#.#####.###############################.###.#.#.#######.#####.#.###.#.#.#.###.#.###.#.#####.#.###.#############.###.#.####### |  | ||||||
| #.......#...#.#.#...###...#...#.....#...#.............#.#...#.#.#.......#.....#.....#.#.#.#...#...#.#.###...#.###.#.............#...#.......# |  | ||||||
| #######.#####.#.###.#####.#.#.#.###.#.#.#.###########.#.#.###.#.#.#######.###########.#.#.#.#####.#.#.###.###.###.#.#############.#########.# |  | ||||||
| #.....#.....#.#.#...#...#...#.#.#...#.#.#.#.....#...#...#...#...#.....#...#...........#.#.#.....#...#.#...#...#...#.......###...#.#.........# |  | ||||||
| #.###.#####.#.#.#.###.#.#####.#.#.###.#.#.#.###.#.#.#######.#########.#.###.###########.#.#####.#####.#.###.###.#########.###.#.#.#.######### |  | ||||||
| #...#.......#...#...#.#.#...#...#.....#.#.#.#...#.#...###...#.........#...#...#.....#...#.#.....#...#.#...#.#...#...#.....#...#.#.#.#.......# |  | ||||||
| ###.###############.#.#.#.#.###########.#.#.#.###.###.###.###.###########.###.#.###.#.###.#.#####.#.#.###.#.#.###.#.#.#####.###.#.#.#.#####.# |  | ||||||
| ###.#.....#.......#...#.#.#.....#.......#...#.....#...#...#...#.....#...#.#...#...#.#.#...#...#...#...#...#...#...#.#...###...#...#...#...#.# |  | ||||||
| ###.#.###.#.#####.#####.#.#####.#.#################.###.###.###.###.#.#.#.#.#####.#.#.#.#####.#.#######.#######.###.###.#####.#########.#.#.# |  | ||||||
| #...#.###...###...#...#...#.....#.........#...#.....###...#...#.#...#.#.#.#.###...#.#.#...#...#.#...###.....#...###...#...###.#.....#...#.#.# |  | ||||||
| #.###.#########.###.#.#####.#############.#.#.#.#########.###.#.#.###.#.#.#.###.###.#.###.#.###.#.#.#######.#.#######.###.###.#.###.#.###.#.# |  | ||||||
| #...#.#...#.....#...#.....#.#...###.......#.#...###...#...#...#.#.#...#.#.#...#...#.#.#...#.#...#.#...#...#.#.....###...#.....#...#...###...# |  | ||||||
| ###.#.#.#.#.#####.#######.#.#.#.###.#######.#######.#.#.###.###.#.#.###.#.###.###.#.#.#.###.#.###.###.#.#.#.#####.#####.#########.########### |  | ||||||
| ###...#.#.#...#...#.......#...#...#.......#...#...#.#...#...###.#.#...#.#...#.#...#.#.#...#.#.###.#...#.#.#.#.....#...#.#...#...#...#...#...# |  | ||||||
| #######.#.###.#.###.#############.#######.###.#.#.#.#####.#####.#.###.#.###.#.#.###.#.###.#.#.###.#.###.#.#.#.#####.#.#.#.#.#.#.###.#.#.#.#.# |  | ||||||
| #.......#.....#...#.........#...#.#...#...#...#.#.#.....#.#...#.#.#...#.#...#.#.#...#.#...#.#...#.#...#.#.#.#.....#.#.#...#...#.....#.#...#.# |  | ||||||
| #.###############.#########.#.#.#.#.#.#.###.###.#.#####.#.#.#.#.#.#.###.#.###.#.#.###.#.###.###.#.###.#.#.#.#####.#.#.###############.#####.# |  | ||||||
| #.......#...#.....#...#...#...#.#...#.#.#...###.#.#...#.#.#.#.#.#.#...#.#.#...#.#.###.#.###.#...#...#.#.#...#...#...#...###...#...#...#...#.# |  | ||||||
| #######.#.#.#.#####.#.#.#.#####.#####.#.#.#####.#.#.#.#.#.#.#.#.#.###.#.#.#.###.#.###.#.###.#.#####.#.#.#####.#.#######.###.#.#.#.#.###.#.#.# |  | ||||||
| #...###...#...#.....#...#.....#.....#...#.#...#.#.#.#...#...#.#.#...#.#.#.#.#...#...#.#...#.#...#...#.#.#.....#.........#...#...#...#...#...# |  | ||||||
| #.#.###########.#############.#####.#####.#.#.#.#.#.#########.#.###.#.#.#.#.#.#####.#.###.#.###.#.###.#.#.###############.###########.####### |  | ||||||
| #.#.#...###...#.............#.#...#.....#...#.#.#.#...#.......#...#...#.#.#.#.#.....#...#.#.#...#...#.#.#.............###.#.......#...#...### |  | ||||||
| #.#.#.#.###.#.#############.#.#.#.#####.#####.#.#.###.#.#########.#####.#.#.#.#.#######.#.#.#.#####.#.#.#############.###.#.#####.#.###.#.### |  | ||||||
| #.#...#.....#.#...#...#.....#...#.......#.....#.#.#...#.....#...#...#...#.#.#.#.#...#...#...#.#...#.#.#.#.......#...#.....#.....#.#.....#...# |  | ||||||
| #.###########.#.#.#.#.#.#################.#####.#.#.#######.#.#.###.#.###.#.#.#.#.#.#.#######.#.#.#.#.#.#.#####.#.#.###########.#.#########.# |  | ||||||
| #.#.....#...#...#...#...#...#...#...#...#.....#.#.#.......#...#.#...#...#.#...#...#.#.....#...#.#...#...#.....#...#...#...#.....#...........# |  | ||||||
| #.#.###.#.#.#############.#.#.#.#.#.#.#.#####.#.#.#######.#####.#.#####.#.#########.#####.#.###.#############.#######.#.#.#.################# |  | ||||||
| #.#.#...#.#.........#...#.#.#.#.#.#...#.....#...#.#.....#.#.....#...###.#.#.........#...#.#.....#...........#.......#.#.#.#...#...#...#...### |  | ||||||
| #.#.#.###.#########.#.#.#.#.#.#.#.#########.#####.#.###.#.#.#######.###.#.#.#########.#.#.#######.#########.#######.#.#.#.###.#.#.#.#.#.#.### |  | ||||||
| #.#.#.....#.......#.#.#...#.#.#.#.#.......#.#.....#.###.#.#...#...#...#...#.....#...#.#...###...#.........#.#...#...#...#...#...#...#.#.#...# |  | ||||||
| #.#.#######.#####.#.#.#####.#.#.#.#.#####.#.#.#####.###.#.###.#.#.###.#########.#.#.#.#######.#.#########.#.#.#.#.#########.#########.#.###.# |  | ||||||
| #...###...#.....#.#...#.....#.#...#.....#.#.#.....#...#.#...#...#...#...#.......#.#.#...###...#...........#...#...#...#####...........#...#.# |  | ||||||
| #######.#.#####.#.#####.#####.#########.#.#.#####.###.#.###.#######.###.#.#######.#.###.###.#######################.#.###################.#.# |  | ||||||
| #...#...#.#.....#.#...#.......#.........#...###...#...#.#...#.......#...#.#.....#.#...#...#.#...#...#.....#...#...#.#...###...#...#...#...#.# |  | ||||||
| #.#.#.###.#.#####.#.#.#########.###############.###.###.#.###.#######.###.#.###.#.###.###.#.#.#.#.#.#.###.#.#.#.#.#.###.###.#.#.#.#.#.#.###.# |  | ||||||
| #.#.#...#.#.....#.#.#.#...###...#.............#.#...###.#.#...#...#...###.#.#...#...#.#...#...#...#.#.#...#.#.#.#...#...#...#...#...#...#...# |  | ||||||
| #.#.###.#.#####.#.#.#.#.#.###.###.###########.#.#.#####.#.#.###.#.#.#####.#.#.#####.#.#.###########.#.#.###.#.#.#####.###.###############.### |  | ||||||
| #.#.....#.......#...#...#...#...#.#...#.......#...#...#...#...#.#.#.....#...#.#...#.#.#.#...........#.#.....#...#.....#...#...#.....#...#...# |  | ||||||
| #.#########################.###.#.#.#.#.###########.#.#######.#.#.#####.#####.#.#.#.#.#.#.###########.###########.#####.###.#.#.###.#.#.###.# |  | ||||||
| #.....#...#.............#...###...#.#...#...#####...#.......#...#.#.....###...#.#.#.#...#...........#.###.....#...###...#...#...###...#.....# |  | ||||||
| #####.#.#.#.###########.#.#########.#####.#.#####.#########.#####.#.#######.###.#.#.###############.#.###.###.#.#####.###.################### |  | ||||||
| #...#...#.#.#...........#...#.......#...#.#...#...#.........###...#.......#...#.#.#.#.............#.#.#...#...#.......#...#...#...#.........# |  | ||||||
| #.#.#####.#.#.#############.#.#######.#.#.###.#.###.###########.#########.###.#.#.#.#.###########.#.#.#.###.###########.###.#.#.#.#.#######.# |  | ||||||
| #.#.....#...#.............#.#...#.....#...#...#...#.#...###...#...#.......###.#.#...#...........#.#...#...#...........#...#.#.#.#.#.....#...# |  | ||||||
| #.#####.#################.#.###.#.#########.#####.#.#.#.###.#.###.#.#########.#.###############.#.#######.###########.###.#.#.#.#.#####.#.### |  | ||||||
| #.#...#...###...#.........#...#...#...#...#.......#...#.#...#...#.#.....#.....#.....#.....#.....#.#...###...........#.....#.#...#.###...#...# |  | ||||||
| #.#.#.###.###.#.#.###########.#####.#.#.#.#############.#.#####.#.#####.#.#########.#.###.#.#####.#.#.#############.#######.#####.###.#####.# |  | ||||||
| #.#.#...#.....#...#.....#...#...#...#...#.#...#...#...#...#...#.#.#.....#.......#...#...#.#.....#.#.#...............#.......#.....#...#.....# |  | ||||||
| #.#.###.###########.###.#.#.###.#.#######.#.#.#.#.#.#.#####.#.#.#.#.###########.#.#####.#.#####.#.#.#################.#######.#####.###.##### |  | ||||||
| #.#.###.....#...#...###...#...#.#...#...#...#...#...#.#.....#.#.#.#.....#.......#.#.....#.#.....#...#...............#...#.....#...#...#.#...# |  | ||||||
| #.#.#######.#.#.#.###########.#.###.#.#.#############.#.#####.#.#.#####.#.#######.#.#####.#.#########.#############.###.#.#####.#.###.#.#.#.# |  | ||||||
| #.#.#.......#.#.#.#.......###.#.###...#.#...#.......#.#.....#...#.#...#.#...#...#.#.....#.#...........#.........#...###.#.......#.....#...#.# |  | ||||||
| #.#.#.#######.#.#.#.#####.###.#.#######.#.#.#.#####.#.#####.#####.#.#.#.###.#.#.#.#####.#.#############.#######.#.#####.###################.# |  | ||||||
| #...#.#...#...#...#.....#.....#.......#...#...#...#.#...#...#.....#.#.#.###.#.#...#.....#.....#.......#.......#.#.#.....#.........#...#...#.# |  | ||||||
| #####.#.#.#.###########.#############.#########.#.#.###.#.###.#####.#.#.###.#.#####.#########.#.#####.#######.#.#.#.#####.#######.#.#.#.#.#.# |  | ||||||
| #...#...#...#.......###...#.........#.#.....#...#...#...#...#.......#.#.#...#...###...#.....#...#...#.........#...#.#.....#.....#.#.#.#.#...# |  | ||||||
| #.#.#########.#####.#####.#.#######.#.#.###.#.#######.#####.#########.#.#.#####.#####.#.###.#####.#.###############.#.#####.###.#.#.#.#.##### |  | ||||||
| #.#...........#...#.......#...#.....#...###.#.....###.......#...#.....#.#...#...#.....#.###.......#.......#...#...#.#.......#...#...#...#...# |  | ||||||
| #.#############.#.###########.#.###########.#####.###########.#.#.#####.###.#.###.#####.#################.#.#.#.#.#.#########.###########.#.# |  | ||||||
| #.#.............#.........#...#...........#.#...#.............#.#.#.....###.#...#.#.....#...........#...#...#.#.#.#.#.....#...#...........#.# |  | ||||||
| #.#.#####################.#.#############.#.#.#.###############.#.#.#######.###.#.#.#####.#########.#.#.#####.#.#.#.#.###.#.###.###########.# |  | ||||||
| #...#...#.................#.###...#...#...#...#.#.......#.......#...#.......#...#...#.....#.......#...#.......#.#...#...#...###.#.......#...# |  | ||||||
| #####.#.#.#################.###.#.#.#.#.#######.#.#####.#.###########.#######.#######.#####.#####.#############.#######.#######.#.#####.#.### |  | ||||||
| #.....#...#...#.....#.....#.#...#...#...#...###.#.....#.#.....###...#.........#.......#...#.#...#.....#...#.....#.....#.........#.....#...### |  | ||||||
| #.#########.#.#.###.#.###.#.#.###########.#.###.#####.#.#####.###.#.###########.#######.#.#.#.#.#####.#.#.#.#####.###.###############.####### |  | ||||||
| #.#.....#...#...###...###...#.............#...#...#...#.......#...#...#...#...#.........#...#.#.#...#...#...#.....###.#.......#.......#...### |  | ||||||
| #.#.###.#.###################################.###.#.###########.#####.#.#.#.#.###############.#.#.#.#########.#######.#.#####.#.#######.#.### |  | ||||||
| #...###...#.......###...#...#.........#.......###...###...###...#.....#.#.#.#.#############...#...#.#...#...#.......#.#.....#...#.......#...# |  | ||||||
| ###########.#####.###.#.#.#.#.#######.#.###############.#.###.###.#####.#.#.#.#############.#######.#.#.#.#.#######.#.#####.#####.#########.# |  | ||||||
| #...........#...#.#...#...#...#.....#.#...#...#...#...#.#.#...#...#...#.#.#.#S#############.......#...#...#...#...#.#.#...#...###.#.........# |  | ||||||
| #.###########.#.#.#.###########.###.#.###.#.#.#.#.#.#.#.#.#.###.###.#.#.#.#.#####################.###########.#.#.#.#.#.#.###.###.#.######### |  | ||||||
| #.....#.......#.#...#...#.......#...#.#...#.#.#.#...#.#.#.#...#.#...#.#.#.#.........#########...#.#.........#...#...#...#...#.....#.........# |  | ||||||
| #####.#.#######.#####.#.#.#######.###.#.###.#.#.#####.#.#.###.#.#.###.#.#.#########.#########.#.#.#.#######.###############.###############.# |  | ||||||
| #.....#.#.......#.....#...#...###...#...###.#.#.....#...#...#.#.#.#...#.#.#...#...#.#########.#...#.#.......#.............#...#.............# |  | ||||||
| #.#####.#.#######.#########.#.#####.#######.#.#####.#######.#.#.#.#.###.#.#.#.#.#.#.#########.#####.#.#######.###########.###.#.############# |  | ||||||
| #.#...#.#.........#.........#.......#.......#.....#...#.....#.#...#.....#.#.#.#.#.#.#########.....#.#.....#...#.......#...###.#.........#...# |  | ||||||
| #.#.#.#.###########.#################.###########.###.#.#####.###########.#.#.#.#.#.#############.#.#####.#.###.#####.#.#####.#########.#.#.# |  | ||||||
| #...#...#...........#...#...#.........#...........###.#.....#.........#...#.#.#.#...#############...#...#...#...#...#.#.#...#.#...#.....#.#.# |  | ||||||
| #########.###########.#.#.#.#.#########.#############.#####.#########.#.###.#.#.#####################.#.#####.###.#.#.#.#.#.#.#.#.#.#####.#.# |  | ||||||
| #.......#...#...#.....#...#.#.#.......#...........#...#.....#...#...#.#.#...#.#.....#####......E#.....#.......###.#.#...#.#.#.#.#.#.......#.# |  | ||||||
| #.#####.###.#.#.#.#########.#.#.#####.###########.#.###.#####.#.#.#.#.#.#.###.#####.#####.#######.###############.#.#####.#.#.#.#.#########.# |  | ||||||
| #.....#.###...#...#...###...#.#.#...#...#...#...#.#...#.#...#.#...#...#.#...#.#...#.#.....#.....#.................#.....#.#.#.#.#.#.....#...# |  | ||||||
| #####.#.###########.#.###.###.#.#.#.###.#.#.#.#.#.###.#.#.#.#.#########.###.#.#.#.#.#.#####.###.#######################.#.#.#.#.#.#.###.#.### |  | ||||||
| ###...#...#.........#.....#...#...#...#...#...#...#...#...#.#.....#.....#...#.#.#...#.......#...#...#...#...#.....#.....#.#.#...#.#.#...#.### |  | ||||||
| ###.#####.#.###############.#########.#############.#######.#####.#.#####.###.#.#############.###.#.#.#.#.#.#.###.#.#####.#.#####.#.#.###.### |  | ||||||
| #...#.....#.......#.........#.........#.....#.....#.....#...###...#.#...#...#.#.#.............#...#.#.#.#.#...###...#.....#.#...#...#...#...# |  | ||||||
| #.###.###########.#.#########.#########.###.#.###.#####.#.#####.###.#.#.###.#.#.#.#############.###.#.#.#.###########.#####.#.#.#######.###.# |  | ||||||
| #...#...#.........#.###...###.......###.#...#.#...#...#.#.#...#.#...#.#.###.#.#.#.###...###...#.#...#.#.#...#...#...#.#.....#.#.#.....#.#...# |  | ||||||
| ###.###.#.#########.###.#.#########.###.#.###.#.###.#.#.#.#.#.#.#.###.#.###.#.#.#.###.#.###.#.#.#.###.#.###.#.#.#.#.#.#.#####.#.#.###.#.#.### |  | ||||||
| ###...#.#.........#.#...#...#.......#...#.#...#.#...#...#.#.#.#.#...#.#.....#.#.#.....#.#...#.#.#.#...#...#...#...#...#.......#...#...#.#...# |  | ||||||
| #####.#.#########.#.#.#####.#.#######.###.#.###.#.#######.#.#.#.###.#.#######.#.#######.#.###.#.#.#.#####.#########################.###.###.# |  | ||||||
| #.....#.........#...#.....#...#...#...#...#.#...#...#.....#.#.#...#...###.....#.....#...#.###...#.#.###...#...#...#...#.............###...#.# |  | ||||||
| #.#############.#########.#####.#.#.###.###.#.#####.#.#####.#.###.#######.#########.#.###.#######.#.###.###.#.#.#.#.#.#.#################.#.# |  | ||||||
| #.....#...#...#.......###.#.....#.#.###...#.#...#...#.....#.#.#...#.......#...#...#.#...#.....###.#.#...#...#...#.#.#.#.............#.....#.# |  | ||||||
| #####.#.#.#.#.#######.###.#.#####.#.#####.#.###.#.#######.#.#.#.###.#######.#.#.#.#.###.#####.###.#.#.###.#######.#.#.#############.#.#####.# |  | ||||||
| #.....#.#...#.......#.....#.#.....#...###...#...#.......#...#.#.###.#.....#.#.#.#.#.#...#...#...#...#...#.###...#.#.#.#...#...#.....#.#...#.# |  | ||||||
| #.#####.###########.#######.#.#######.#######.#########.#####.#.###.#.###.#.#.#.#.#.#.###.#.###.#######.#.###.#.#.#.#.#.#.#.#.#.#####.#.#.#.# |  | ||||||
| #.....#.#...........#...#...#.....#...#.......#...#.....#.....#...#...#...#.#.#.#.#.#.#...#.#...#.......#.....#.#...#...#...#.#.....#...#.#.# |  | ||||||
| #####.#.#.###########.#.#.#######.#.###.#######.#.#.#####.#######.#####.###.#.#.#.#.#.#.###.#.###.#############.#############.#####.#####.#.# |  | ||||||
| #.....#.#...........#.#.#...###...#...#...#...#.#.#.....#...#...#.###...#...#.#.#.#.#.#.#...#.#...#.....#.....#.............#.#...#.....#.#.# |  | ||||||
| #.#####.###########.#.#.###.###.#####.###.#.#.#.#.#####.###.#.#.#.###.###.###.#.#.#.#.#.#.###.#.###.###.#.###.#############.#.#.#.#####.#.#.# |  | ||||||
| #...#...#...........#.#...#.#...#...#...#...#...#.#.....###.#.#.#.#...#...###.#.#...#...#...#.#.#...###.#...#.#...#.....#...#...#.......#...# |  | ||||||
| ###.#.###.###########.###.#.#.###.#.###.#########.#.#######.#.#.#.#.###.#####.#.###########.#.#.#.#####.###.#.#.#.#.###.#.################### |  | ||||||
| ###.#...#...........#.#...#.#...#.#...#.#.........#.###.....#.#.#.#...#.....#.#...#.......#.#.#.#...#...#...#.#.#.#...#.#...###.............# |  | ||||||
| ###.###.###########.#.#.###.###.#.###.#.#.#########.###.#####.#.#.###.#####.#.###.#.#####.#.#.#.###.#.###.###.#.#.###.#.###.###.###########.# |  | ||||||
| #...#...###.........#.#.....#...#...#...#.........#...#.#.....#.#.###...#...#.....#.....#...#.#.#...#...#...#.#.#.#...#...#.....#...#...#...# |  | ||||||
| #.###.#####.#########.#######.#####.#############.###.#.#.#####.#.#####.#.#############.#####.#.#.#####.###.#.#.#.#.#####.#######.#.#.#.#.### |  | ||||||
| #.....#.....#.....#...#.......#.....#...#.........#...#.#...###.#.#.....#.#...###.......#...#.#.#.#.....#...#...#.#.....#.#.......#.#.#.#...# |  | ||||||
| #######.#####.###.#.###.#######.#####.#.#.#########.###.###.###.#.#.#####.#.#.###.#######.#.#.#.#.#.#####.#######.#####.#.#.#######.#.#.###.# |  | ||||||
| #.......#...#.#...#.###...#...#.....#.#.#.......#...###...#.#...#.#.....#...#...#...#...#.#.#.#.#.#.....#.....#...#.....#.#.......#...#...#.# |  | ||||||
| #.#######.#.#.#.###.#####.#.#.#####.#.#.#######.#.#######.#.#.###.#####.#######.###.#.#.#.#.#.#.#.#####.#####.#.###.#####.#######.#######.#.# |  | ||||||
| #...#...#.#.#.#...#...#...#.#.....#...#.#.......#.....#...#.#.#...#.....#.......###.#.#.#.#...#.#.#...#.#.....#...#.....#...#.....#.....#.#.# |  | ||||||
| ###.#.#.#.#.#.###.###.#.###.#####.#####.#.###########.#.###.#.#.###.#####.#########.#.#.#.#####.#.#.#.#.#.#######.#####.###.#.#####.###.#.#.# |  | ||||||
| #...#.#.#.#.#.#...#...#.....#.....#.....#.#.....#.....#.#...#.#...#.#...#.......#...#.#.#.....#.#.#.#...#...#...#.#.....#...#.......#...#...# |  | ||||||
| #.###.#.#.#.#.#.###.#########.#####.#####.#.###.#.#####.#.###.###.#.#.#.#######.#.###.#.#####.#.#.#.#######.#.#.#.#.#####.###########.####### |  | ||||||
| #...#.#.#.#.#.#...#.#.......#.....#.....#.#.#...#.....#.#.###...#.#.#.#.#.....#.#.#...#...#...#.#.#...#.....#.#...#.....#.#...#.......#...### |  | ||||||
| ###.#.#.#.#.#.###.#.#.#####.#####.#####.#.#.#.#######.#.#.#####.#.#.#.#.#.###.#.#.#.#####.#.###.#.###.#.#####.#########.#.#.#.#.#######.#.### |  | ||||||
| #...#.#.#.#.#.#...#.#.#...#.......#...#.#.#.#...#...#.#.#.#...#...#...#.#.###.#.#.#.....#.#.#...#...#.#.....#.#...#...#.#.#.#.#...#.....#...# |  | ||||||
| #.###.#.#.#.#.#.###.#.#.#.#########.#.#.#.#.###.#.#.#.#.#.#.#.#########.#.###.#.#.#####.#.#.#.#####.#.#####.#.#.#.#.#.#.#.#.#.###.#.#######.# |  | ||||||
| #.#...#...#.#.#.#...#...#...#...#...#.#.#.#...#.#.#.#.#.#...#...#.......#...#.#.#...#...#.#.#.#.....#.#.....#.#.#...#.#.#.#.#...#...#...#...# |  | ||||||
| #.#.#######.#.#.#.#########.#.#.#.###.#.#.###.#.#.#.#.#.#######.#.#########.#.#.###.#.###.#.#.#.#####.#.#####.#.#####.#.#.#.###.#####.#.#.### |  | ||||||
| #.#...#.....#.#.#.#.........#.#.#...#.#.#.#...#.#.#.#.#.#...#...#...#...#...#.#.#...#.#...#.#.#.#.....#.....#.#.....#.#.#.#...#...#...#.#...# |  | ||||||
| #.###.#.#####.#.#.#.#########.#.###.#.#.#.#.###.#.#.#.#.#.#.#.#####.#.#.#.###.#.#.###.#.###.#.#.#.#########.#.#####.#.#.#.###.###.#.###.###.# |  | ||||||
| #.....#.......#...#...........#.....#...#...###...#...#...#...#####...#...###...#.....#.....#...#...........#.......#...#.....###...###.....# |  | ||||||
| ############################################################################################################################################# |  | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| 340A |  | ||||||
| 149A |  | ||||||
| 582A |  | ||||||
| 780A |  | ||||||
| 463A |  | ||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d1; | use y2024::days::d1; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d10; | use y2024::days::d10; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d11; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part1() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/11_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d11::process_part1(&content)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part2() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/11_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d11::process_part2(&content, 75)); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d12; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part1() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/12_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d12::process_part1(&content)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part2() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/12_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d12::process_part2(&content)); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d13; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part1() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/13_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d13::process_part1(&content)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part2() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/13_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d13::process_part2(&content)); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d14; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part1() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/14_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d14::process_part1(&content)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part2() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/14_input.txt")).unwrap(); |  | ||||||
|     d14::process_part2(&content); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d15; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part1() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/15_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d15::process_part1(&content)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part2() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/15_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d15::process_part2(&content)); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d16; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| 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)); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d17; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| 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).0); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| 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)); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d18; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| 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)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| 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)); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d19; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| 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)); |  | ||||||
| } |  | ||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d2; | use y2024::days::d2; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d20; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part1() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/20_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d20::process_part1(&content)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn part2() { |  | ||||||
|     let root = env!("CARGO_MANIFEST_DIR"); |  | ||||||
|     let content = fs::read_to_string(format!("{root}/resources/20_input.txt")).unwrap(); |  | ||||||
|     println!("{}", d20::process_part2(&content)); |  | ||||||
| } |  | ||||||
| @@ -1,27 +0,0 @@ | |||||||
| use std::{fs, time::Instant}; |  | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d21; |  | ||||||
|  |  | ||||||
| fn main() { |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |  | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| 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)); |  | ||||||
| } |  | ||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d3; | use y2024::days::d3; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d4; | use y2024::days::d4; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d5; | use y2024::days::d5; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d6; | use y2024::days::d6; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d7; | use y2024::days::d7; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d8; | use y2024::days::d8; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,17 +1,10 @@ | |||||||
| use std::{fs, time::Instant}; | use std::fs; | ||||||
|  |  | ||||||
| use utils::time::get_elapsed_string; |  | ||||||
| use y2024::days::d9; | use y2024::days::d9; | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 1:"); |  | ||||||
|     part1(); |     part1(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|     let now = Instant::now(); |  | ||||||
|     println!("Part 2:"); |  | ||||||
|     part2(); |     part2(); | ||||||
|     println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn part1() { | fn part1() { | ||||||
|   | |||||||
| @@ -1,155 +0,0 @@ | |||||||
| use std::collections::HashMap; |  | ||||||
|  |  | ||||||
| use itertools::Itertools; |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str) -> u64 { |  | ||||||
|     let stones = input |  | ||||||
|         .split_whitespace() |  | ||||||
|         .map(|stone| stone.parse::<u64>().unwrap()) |  | ||||||
|         .collect_vec(); |  | ||||||
|     let mut result = stones; |  | ||||||
|     for _ in 0..25 { |  | ||||||
|         result = blink(result); |  | ||||||
|     } |  | ||||||
|     let mut test = HashMap::new(); |  | ||||||
|     for stone in result.iter() { |  | ||||||
|         test.entry(stone) |  | ||||||
|             .and_modify(|count| *count += 1) |  | ||||||
|             .or_insert(1); |  | ||||||
|     } |  | ||||||
|     result.len() as u64 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str, blinks: u64) -> u64 { |  | ||||||
|     let mut stones: HashMap<u64, u64> = HashMap::new(); |  | ||||||
|     input.split_whitespace().for_each(|stone| { |  | ||||||
|         let stone = stone.parse::<u64>().unwrap(); |  | ||||||
|         stones |  | ||||||
|             .entry(stone) |  | ||||||
|             .and_modify(|count| *count += 1) |  | ||||||
|             .or_insert(1); |  | ||||||
|     }); |  | ||||||
|     let mut stones_after: HashMap<u64, u64> = HashMap::new(); |  | ||||||
|     for _idx in 0..blinks { |  | ||||||
|         for (stone, count) in stones.iter() { |  | ||||||
|             if *stone == 0 { |  | ||||||
|                 stones_after |  | ||||||
|                     .entry(1) |  | ||||||
|                     .and_modify(|inner_count| *inner_count += count) |  | ||||||
|                     .or_insert(*count); |  | ||||||
|             } else if (((*stone as f64).log10() + 1.0).floor() as u64) % 2 == 0 { |  | ||||||
|                 let num_digits = ((*stone as f64).log10() + 1.0).floor() as u64; |  | ||||||
|                 let digits_per_side = num_digits / 2; |  | ||||||
|                 let left = stone / 10_u64.pow(digits_per_side as u32); |  | ||||||
|                 let right = stone % 10_u64.pow(digits_per_side as u32); |  | ||||||
|                 stones_after |  | ||||||
|                     .entry(left) |  | ||||||
|                     .and_modify(|inner_count| *inner_count += count) |  | ||||||
|                     .or_insert(*count); |  | ||||||
|                 stones_after |  | ||||||
|                     .entry(right) |  | ||||||
|                     .and_modify(|inner_count| *inner_count += count) |  | ||||||
|                     .or_insert(*count); |  | ||||||
|                 //stones_after.push(left); |  | ||||||
|                 //stones_after.push(right); |  | ||||||
|             } else { |  | ||||||
|                 let new_stone = stone * 2024; |  | ||||||
|                 stones_after |  | ||||||
|                     .entry(new_stone) |  | ||||||
|                     .and_modify(|inner_count| *inner_count += count) |  | ||||||
|                     .or_insert(*count); |  | ||||||
|                 //stones_after.push(stone * 2024); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         stones = stones_after.clone(); |  | ||||||
|         stones_after.clear(); |  | ||||||
|     } |  | ||||||
|     stones |  | ||||||
|         .into_values() |  | ||||||
|         .reduce(|acc, count| acc + count) |  | ||||||
|         .unwrap() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn blink(stones: Vec<u64>) -> Vec<u64> { |  | ||||||
|     let mut stones_after = Vec::new(); |  | ||||||
|     for stone in stones { |  | ||||||
|         if stone == 0 { |  | ||||||
|             stones_after.push(1); |  | ||||||
|             continue; |  | ||||||
|         } |  | ||||||
|         let num_digits = ((stone as f64).log10() + 1.0).floor() as u64; |  | ||||||
|         if num_digits % 2 == 0 { |  | ||||||
|             let digits_per_side = num_digits / 2; |  | ||||||
|             let left = stone / 10_u64.pow(digits_per_side as u32); |  | ||||||
|             let right = stone % 10_u64.pow(digits_per_side as u32); |  | ||||||
|             stones_after.push(left); |  | ||||||
|             stones_after.push(right); |  | ||||||
|         } else { |  | ||||||
|             stones_after.push(stone * 2024); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     stones_after |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use itertools::Itertools; |  | ||||||
|  |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT_1: &str = "0 1 10 99 999"; |  | ||||||
|     const INPUT_2: &str = "125 17"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn test_blink_1() { |  | ||||||
|         let stones = INPUT_1 |  | ||||||
|             .split_whitespace() |  | ||||||
|             .map(|stone| stone.parse::<u64>().unwrap()) |  | ||||||
|             .collect_vec(); |  | ||||||
|         let stones = blink(stones); |  | ||||||
|         assert_eq!(stones, vec![1, 2024, 1, 0, 9, 9, 2021976]); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn test_blink_2() { |  | ||||||
|         let stones = INPUT_2 |  | ||||||
|             .split_whitespace() |  | ||||||
|             .map(|stone| stone.parse::<u64>().unwrap()) |  | ||||||
|             .collect_vec(); |  | ||||||
|         let mut result = stones; |  | ||||||
|         for _ in 0..6 { |  | ||||||
|             result = blink(result); |  | ||||||
|         } |  | ||||||
|         assert_eq!( |  | ||||||
|             result, |  | ||||||
|             vec![ |  | ||||||
|                 2097446912, 14168, 4048, 2, 0, 2, 4, 40, 48, 2024, 40, 48, 80, 96, 2, 8, 6, 7, 6, |  | ||||||
|                 0, 3, 2 |  | ||||||
|             ] |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1() { |  | ||||||
|         let result = process_part1(INPUT_2); |  | ||||||
|         assert_eq!(result, 55312); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_1() { |  | ||||||
|         let result = process_part2(INPUT_1, 1); |  | ||||||
|         assert_eq!(result, 7); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_2() { |  | ||||||
|         let result = process_part2(INPUT_2, 6); |  | ||||||
|         assert_eq!(result, 22); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_3() { |  | ||||||
|         let result = process_part2(INPUT_2, 25); |  | ||||||
|         assert_eq!(result, 55312); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,348 +0,0 @@ | |||||||
| use std::{collections::HashMap, fmt::Display}; |  | ||||||
|  |  | ||||||
| use itertools::Itertools; |  | ||||||
|  |  | ||||||
| #[derive(Debug)] |  | ||||||
| enum Reason { |  | ||||||
|     WrongPlotType, |  | ||||||
|     AlreadyInRegion, |  | ||||||
|     PlotNotNeighbor, |  | ||||||
|     WrongRegionType, |  | ||||||
|     MergeImpossible, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl Display for Reason { |  | ||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |  | ||||||
|         let reason_str = match self { |  | ||||||
|             Reason::WrongPlotType => "Could not add plot. Wrong plant type!", |  | ||||||
|             Reason::AlreadyInRegion => "Could not add plot. Already in region!", |  | ||||||
|             Reason::PlotNotNeighbor => "Could not add plot. Not a Neighbor!", |  | ||||||
|             Reason::WrongRegionType => "Could not merge regions. Incompatible plant types!", |  | ||||||
|             Reason::MergeImpossible => "Could not merge Regions!", |  | ||||||
|         }; |  | ||||||
|         write!(f, "{reason_str}") |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Clone)] |  | ||||||
| struct Region { |  | ||||||
|     plant: char, |  | ||||||
|     plots: Vec<(u32, u32)>, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl Region { |  | ||||||
|     fn add(&mut self, new_plot: (char, (u32, u32))) -> Result<(), Reason> { |  | ||||||
|         if new_plot.0 != self.plant { |  | ||||||
|             return Err(Reason::WrongPlotType); |  | ||||||
|         } |  | ||||||
|         let new_plot = new_plot.1; |  | ||||||
|         for plot in self.plots.iter() { |  | ||||||
|             if (plot.0.abs_diff(new_plot.0) == 1 && plot.1 == new_plot.1) |  | ||||||
|                 || (plot.1.abs_diff(new_plot.1) == 1 && plot.0 == new_plot.0) |  | ||||||
|             { |  | ||||||
|                 self.plots.push(new_plot); |  | ||||||
|                 return Ok(()); |  | ||||||
|             } else if *plot == new_plot { |  | ||||||
|                 return Err(Reason::AlreadyInRegion); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         Err(Reason::PlotNotNeighbor) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn merge(mut self, other: Self) -> Result<Self, Reason> { |  | ||||||
|         if self.plant != other.plant { |  | ||||||
|             return Err(Reason::WrongRegionType); |  | ||||||
|         } |  | ||||||
|         for plot in self.plots.clone() { |  | ||||||
|             for other_plot in other.plots.clone().into_iter() { |  | ||||||
|                 if (plot.0.abs_diff(other_plot.0) == 1 && plot.1 == other_plot.1) |  | ||||||
|                     || (plot.1.abs_diff(other_plot.1) == 1 && plot.0 == other_plot.0) |  | ||||||
|                 { |  | ||||||
|                     self.plots = [self.plots, other.plots] |  | ||||||
|                         .concat() |  | ||||||
|                         .into_iter() |  | ||||||
|                         .unique() |  | ||||||
|                         .collect_vec(); |  | ||||||
|                     return Ok(self); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         Err(Reason::MergeImpossible) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn merge_multiple(regions: Vec<Region>) -> Region { |  | ||||||
|         let mut merged_regions = regions[0].clone(); |  | ||||||
|         for region in regions[1..].iter() { |  | ||||||
|             merged_regions = merged_regions.merge(region.clone()).unwrap(); |  | ||||||
|         } |  | ||||||
|         merged_regions |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn area(&self) -> u32 { |  | ||||||
|         self.plots.len() as u32 |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn perimeter(&self) -> u32 { |  | ||||||
|         let mut num_fence_elements = 0; |  | ||||||
|         for plot in self.plots.iter() { |  | ||||||
|             if plot.0 == 0 || !self.plots.contains(&(plot.0 - 1, plot.1)) { |  | ||||||
|                 num_fence_elements += 1; |  | ||||||
|             } |  | ||||||
|             if plot.1 == 0 || !self.plots.contains(&(plot.0, plot.1 - 1)) { |  | ||||||
|                 num_fence_elements += 1; |  | ||||||
|             } |  | ||||||
|             if !self.plots.contains(&(plot.0 + 1, plot.1)) { |  | ||||||
|                 num_fence_elements += 1; |  | ||||||
|             } |  | ||||||
|             if !self.plots.contains(&(plot.0, plot.1 + 1)) { |  | ||||||
|                 num_fence_elements += 1; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         num_fence_elements |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn sides(&self) -> u32 { |  | ||||||
|         let mut top_sides = HashMap::new(); |  | ||||||
|         let mut bottom_sides = HashMap::new(); |  | ||||||
|         let mut left_sides = HashMap::new(); |  | ||||||
|         let mut right_sides = HashMap::new(); |  | ||||||
|         for plot in self.plots.iter() { |  | ||||||
|             if plot.0 == 0 || !self.plots.contains(&(plot.0 - 1, plot.1)) { |  | ||||||
|                 left_sides |  | ||||||
|                     .entry(plot.0) |  | ||||||
|                     .and_modify(|ys: &mut Vec<u32>| ys.push(plot.1)) |  | ||||||
|                     .or_insert(vec![plot.1]); |  | ||||||
|             } |  | ||||||
|             if plot.1 == 0 || !self.plots.contains(&(plot.0, plot.1 - 1)) { |  | ||||||
|                 top_sides |  | ||||||
|                     .entry(plot.1) |  | ||||||
|                     .and_modify(|xs: &mut Vec<u32>| xs.push(plot.0)) |  | ||||||
|                     .or_insert(vec![plot.0]); |  | ||||||
|             } |  | ||||||
|             if !self.plots.contains(&(plot.0, plot.1 + 1)) { |  | ||||||
|                 bottom_sides |  | ||||||
|                     .entry(plot.1) |  | ||||||
|                     .and_modify(|xs: &mut Vec<u32>| xs.push(plot.0)) |  | ||||||
|                     .or_insert(vec![plot.0]); |  | ||||||
|             } |  | ||||||
|             if !self.plots.contains(&(plot.0 + 1, plot.1)) { |  | ||||||
|                 right_sides |  | ||||||
|                     .entry(plot.0) |  | ||||||
|                     .and_modify(|ys: &mut Vec<u32>| ys.push(plot.1)) |  | ||||||
|                     .or_insert(vec![plot.1]); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         let mut num_top_sides = top_sides.len() as u32; |  | ||||||
|         for (_x, ys) in top_sides.iter_mut() { |  | ||||||
|             ys.sort(); |  | ||||||
|             ys.windows(2).for_each(|window| { |  | ||||||
|                 if window[0].abs_diff(window[1]) != 1 { |  | ||||||
|                     num_top_sides += 1; |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
|         let mut num_bottom_sides = bottom_sides.len() as u32; |  | ||||||
|         for (_x, ys) in bottom_sides.iter_mut() { |  | ||||||
|             ys.sort(); |  | ||||||
|             ys.windows(2).for_each(|window| { |  | ||||||
|                 if window[0].abs_diff(window[1]) != 1 { |  | ||||||
|                     num_bottom_sides += 1; |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
|         let mut num_left_sides = left_sides.len() as u32; |  | ||||||
|         for (_y, xs) in left_sides.iter_mut() { |  | ||||||
|             xs.sort(); |  | ||||||
|             xs.windows(2).for_each(|window| { |  | ||||||
|                 if window[0].abs_diff(window[1]) != 1 { |  | ||||||
|                     num_left_sides += 1; |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
|         let mut num_right_sides = right_sides.len() as u32; |  | ||||||
|         for (_y, xs) in right_sides.iter_mut() { |  | ||||||
|             xs.sort(); |  | ||||||
|             xs.windows(2).for_each(|window| { |  | ||||||
|                 if window[0].abs_diff(window[1]) != 1 { |  | ||||||
|                     num_right_sides += 1; |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
|         num_top_sides + num_bottom_sides + num_left_sides + num_right_sides |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str) -> u32 { |  | ||||||
|     let mut regions: Vec<Region> = Vec::new(); |  | ||||||
|  |  | ||||||
|     input.lines().enumerate().for_each(|(y, line)| { |  | ||||||
|         line.chars().enumerate().for_each(|(x, plant)| { |  | ||||||
|             let mut added_regions_idx = Vec::new(); |  | ||||||
|             for (idx, region) in regions.iter_mut().enumerate() { |  | ||||||
|                 match region.add((plant, (x as u32, y as u32))) { |  | ||||||
|                     Ok(_) => added_regions_idx.push(idx), |  | ||||||
|                     Err(_) => continue, |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             if added_regions_idx.is_empty() { |  | ||||||
|                 regions.push(Region { |  | ||||||
|                     plant, |  | ||||||
|                     plots: vec![(x as u32, y as u32)], |  | ||||||
|                 }); |  | ||||||
|             } else if added_regions_idx.len() > 1 { |  | ||||||
|                 let regions_to_merge = regions |  | ||||||
|                     .iter() |  | ||||||
|                     .enumerate() |  | ||||||
|                     .filter(|&(idx, _region)| added_regions_idx.contains(&idx)) |  | ||||||
|                     .map(|(_, region)| region) |  | ||||||
|                     .cloned() |  | ||||||
|                     .collect_vec(); |  | ||||||
|                 let merged_region = Region::merge_multiple(regions_to_merge); |  | ||||||
|                 for idx in added_regions_idx.iter().rev() { |  | ||||||
|                     regions.remove(*idx); |  | ||||||
|                 } |  | ||||||
|                 regions.push(merged_region); |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|     }); |  | ||||||
|     regions |  | ||||||
|         .iter() |  | ||||||
|         .map(|region| region.perimeter() * region.area()) |  | ||||||
|         .sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str) -> u32 { |  | ||||||
|     let mut regions: Vec<Region> = Vec::new(); |  | ||||||
|  |  | ||||||
|     input.lines().enumerate().for_each(|(y, line)| { |  | ||||||
|         line.chars().enumerate().for_each(|(x, plant)| { |  | ||||||
|             let mut added_regions_idx = Vec::new(); |  | ||||||
|             for (idx, region) in regions.iter_mut().enumerate() { |  | ||||||
|                 match region.add((plant, (x as u32, y as u32))) { |  | ||||||
|                     Ok(_) => added_regions_idx.push(idx), |  | ||||||
|                     Err(_) => continue, |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             if added_regions_idx.is_empty() { |  | ||||||
|                 regions.push(Region { |  | ||||||
|                     plant, |  | ||||||
|                     plots: vec![(x as u32, y as u32)], |  | ||||||
|                 }); |  | ||||||
|             } else if added_regions_idx.len() > 1 { |  | ||||||
|                 let regions_to_merge = regions |  | ||||||
|                     .iter() |  | ||||||
|                     .enumerate() |  | ||||||
|                     .filter(|&(idx, _region)| added_regions_idx.contains(&idx)) |  | ||||||
|                     .map(|(_, region)| region) |  | ||||||
|                     .cloned() |  | ||||||
|                     .collect_vec(); |  | ||||||
|                 let merged_region = Region::merge_multiple(regions_to_merge); |  | ||||||
|                 for idx in added_regions_idx.iter().rev() { |  | ||||||
|                     regions.remove(*idx); |  | ||||||
|                 } |  | ||||||
|                 regions.push(merged_region); |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|     }); |  | ||||||
|     regions |  | ||||||
|         .iter() |  | ||||||
|         .map(|region| region.sides() * region.area()) |  | ||||||
|         .sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT_1: &str = "AAAA |  | ||||||
| BBCD |  | ||||||
| BBCC |  | ||||||
| EEEC"; |  | ||||||
|  |  | ||||||
|     const INPUT_2: &str = "OOOOO |  | ||||||
| OXOXO |  | ||||||
| OOOOO |  | ||||||
| OXOXO |  | ||||||
| OOOOO"; |  | ||||||
|  |  | ||||||
|     const INPUT_3: &str = "RRRRIICCFF |  | ||||||
| RRRRIICCCF |  | ||||||
| VVRRRCCFFF |  | ||||||
| VVRCCCJFFF |  | ||||||
| VVVVCJJCFE |  | ||||||
| VVIVCCJJEE |  | ||||||
| VVIIICJJEE |  | ||||||
| MIIIIIJJEE |  | ||||||
| MIIISIJEEE |  | ||||||
| MMMISSJEEE"; |  | ||||||
|  |  | ||||||
|     const INPUT_CUSTOM: &str = "XOX |  | ||||||
| OOO"; |  | ||||||
|  |  | ||||||
|     const INPUT_4: &str = "EEEEE |  | ||||||
| EXXXX |  | ||||||
| EEEEE |  | ||||||
| EXXXX |  | ||||||
| EEEEE"; |  | ||||||
|  |  | ||||||
|     const INPUT_5: &str = "AAAAAA |  | ||||||
| AAABBA |  | ||||||
| AAABBA |  | ||||||
| ABBAAA |  | ||||||
| ABBAAA |  | ||||||
| AAAAAA"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_1() { |  | ||||||
|         let result = process_part1(INPUT_1); |  | ||||||
|         assert_eq!(result, 140); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_2() { |  | ||||||
|         let result = process_part1(INPUT_2); |  | ||||||
|         assert_eq!(result, 772); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_3() { |  | ||||||
|         let result = process_part1(INPUT_3); |  | ||||||
|         assert_eq!(result, 1930); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_custom() { |  | ||||||
|         let result = process_part1(INPUT_CUSTOM); |  | ||||||
|         assert_eq!(result, 48); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_1() { |  | ||||||
|         let result = process_part2(INPUT_1); |  | ||||||
|         assert_eq!(result, 80); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_2() { |  | ||||||
|         let result = process_part2(INPUT_2); |  | ||||||
|         assert_eq!(result, 436); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_3() { |  | ||||||
|         let result = process_part2(INPUT_3); |  | ||||||
|         assert_eq!(result, 1206); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_4() { |  | ||||||
|         let result = process_part2(INPUT_4); |  | ||||||
|         assert_eq!(result, 236); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_5() { |  | ||||||
|         let result = process_part2(INPUT_5); |  | ||||||
|         assert_eq!(result, 368); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,151 +0,0 @@ | |||||||
| use core::panic; |  | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, Copy)] |  | ||||||
| struct ClawMachine { |  | ||||||
|     button_a: (i64, i64), |  | ||||||
|     button_b: (i64, i64), |  | ||||||
|     prize: (i64, i64), |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl ClawMachine { |  | ||||||
|     fn parse(s: &str) -> Self { |  | ||||||
|         let mut button_a = (0, 0); |  | ||||||
|         let mut button_b = (0, 0); |  | ||||||
|         let mut prize = (0, 0); |  | ||||||
|         s.lines().for_each(|line| { |  | ||||||
|             let (field, coords) = line.split_once(": ").unwrap(); |  | ||||||
|             if field == "Button A" { |  | ||||||
|                 let (x, y) = coords.split_once(", ").unwrap(); |  | ||||||
|                 let x: i64 = x.split_once("+").unwrap().1.parse().unwrap(); |  | ||||||
|                 let y: i64 = y.split_once("+").unwrap().1.parse().unwrap(); |  | ||||||
|                 button_a = (x, y); |  | ||||||
|             } else if field == "Button B" { |  | ||||||
|                 let (x, y) = coords.split_once(", ").unwrap(); |  | ||||||
|                 let x: i64 = x.split_once("+").unwrap().1.parse().unwrap(); |  | ||||||
|                 let y: i64 = y.split_once("+").unwrap().1.parse().unwrap(); |  | ||||||
|                 button_b = (x, y); |  | ||||||
|             } else if field == "Prize" { |  | ||||||
|                 let (x, y) = coords.split_once(", ").unwrap(); |  | ||||||
|                 let x: i64 = x.split_once("=").unwrap().1.parse().unwrap(); |  | ||||||
|                 let y: i64 = y.split_once("=").unwrap().1.parse().unwrap(); |  | ||||||
|                 prize = (x, y); |  | ||||||
|             } else { |  | ||||||
|                 panic!("Unknown machine information {line}"); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|         Self { |  | ||||||
|             button_a, |  | ||||||
|             button_b, |  | ||||||
|             prize, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn correct(&mut self) { |  | ||||||
|         self.prize.0 += 10000000000000; |  | ||||||
|         self.prize.1 += 10000000000000; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn parse_all(input: &str) -> Vec<Self> { |  | ||||||
|         input.split("\n\n").map(Self::parse).collect() |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     //fn get_moves(&self) -> Option<(i64, i64)> { |  | ||||||
|     //    if self.prize.0 % self.button_b.0 == 0 |  | ||||||
|     //        && self.prize.1 % self.button_b.1 == 0 |  | ||||||
|     //        && self.prize.0 / self.button_b.0 == self.prize.1 / self.button_b.1 |  | ||||||
|     //    { |  | ||||||
|     //        let b_moves = self.prize.0 / self.button_b.0; |  | ||||||
|     //        return Some((0, b_moves)); |  | ||||||
|     //    } |  | ||||||
|  |  | ||||||
|     //    for b_presses in (1..=100).rev() { |  | ||||||
|     //        let after_b_moves = (self.button_b.0 * b_presses, self.button_b.1 * b_presses); |  | ||||||
|     //        if after_b_moves.0 < self.prize.0 && after_b_moves.1 < self.prize.1 { |  | ||||||
|     //            for a_presses in 1..=100 { |  | ||||||
|     //                let after_a_moves = ( |  | ||||||
|     //                    after_b_moves.0 + a_presses * self.button_a.0, |  | ||||||
|     //                    after_b_moves.1 + a_presses * self.button_a.1, |  | ||||||
|     //                ); |  | ||||||
|     //                if after_a_moves == self.prize { |  | ||||||
|     //                    return Some((a_presses, b_presses)); |  | ||||||
|     //                } |  | ||||||
|     //            } |  | ||||||
|     //        } |  | ||||||
|     //    } |  | ||||||
|     //    None |  | ||||||
|     //} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str) -> i64 { |  | ||||||
|     let machines = ClawMachine::parse_all(input); |  | ||||||
|     machines |  | ||||||
|         .iter() |  | ||||||
|         .map(|machine| { |  | ||||||
|             let p = machine.prize; |  | ||||||
|             let a = machine.button_a; |  | ||||||
|             let b = machine.button_b; |  | ||||||
|             let bm = (p.1 * a.0 - p.0 * a.1) / (b.1 * a.0 - b.0 * a.1); |  | ||||||
|             let am = (p.0 - bm * b.0) / a.0; |  | ||||||
|             if p.0 != am * a.0 + bm * b.0 || p.1 != am * a.1 + bm * b.1 { |  | ||||||
|                 0 |  | ||||||
|             } else { |  | ||||||
|                 am * 3 + bm |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|         .sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str) -> i64 { |  | ||||||
|     let mut machines = ClawMachine::parse_all(input); |  | ||||||
|     for machine in machines.iter_mut() { |  | ||||||
|         machine.correct(); |  | ||||||
|     } |  | ||||||
|     machines |  | ||||||
|         .iter() |  | ||||||
|         .map(|machine| { |  | ||||||
|             let p = machine.prize; |  | ||||||
|             let a = machine.button_a; |  | ||||||
|             let b = machine.button_b; |  | ||||||
|             let bm = (p.1 * a.0 - p.0 * a.1) / (b.1 * a.0 - b.0 * a.1); |  | ||||||
|             let am = (p.0 - bm * b.0) / a.0; |  | ||||||
|             if p.0 != am * a.0 + bm * b.0 || p.1 != am * a.1 + bm * b.1 { |  | ||||||
|                 0 |  | ||||||
|             } else { |  | ||||||
|                 am * 3 + bm |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|         .sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT: &str = "Button A: X+94, Y+34 |  | ||||||
| Button B: X+22, Y+67 |  | ||||||
| Prize: X=8400, Y=5400 |  | ||||||
|  |  | ||||||
| Button A: X+26, Y+66 |  | ||||||
| Button B: X+67, Y+21 |  | ||||||
| Prize: X=12748, Y=12176 |  | ||||||
|  |  | ||||||
| Button A: X+17, Y+86 |  | ||||||
| Button B: X+84, Y+37 |  | ||||||
| Prize: X=7870, Y=6450 |  | ||||||
|  |  | ||||||
| Button A: X+69, Y+23 |  | ||||||
| Button B: X+27, Y+71 |  | ||||||
| Prize: X=18641, Y=10279"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1() { |  | ||||||
|         let result = process_part1(INPUT); |  | ||||||
|         assert_eq!(result, 480); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2() { |  | ||||||
|         let result = process_part2(INPUT); |  | ||||||
|         assert_eq!(result, 0); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,331 +0,0 @@ | |||||||
| use std::{collections::HashMap, thread, time::Duration}; |  | ||||||
|  |  | ||||||
| use itertools::Itertools; |  | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] |  | ||||||
| struct Robot { |  | ||||||
|     position: (i32, i32), |  | ||||||
|     velocity: (i32, i32), |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl Robot { |  | ||||||
|     fn parse(s: &str) -> Self { |  | ||||||
|         let (p, v) = s.split_once(" ").unwrap(); |  | ||||||
|         let (_, p_x_y) = p.split_once("=").unwrap(); |  | ||||||
|         let (px, py) = p_x_y.split_once(",").unwrap(); |  | ||||||
|         let position: (i32, i32) = (px.parse().unwrap(), py.parse().unwrap()); |  | ||||||
|         let (_, v_x_y) = v.split_once("=").unwrap(); |  | ||||||
|         let (vx, vy) = v_x_y.split_once(",").unwrap(); |  | ||||||
|         let velocity: (i32, i32) = (vx.parse().unwrap(), vy.parse().unwrap()); |  | ||||||
|         Robot { position, velocity } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn walk(&mut self, seconds: i32, grid_size: (i32, i32)) { |  | ||||||
|         let movement = ( |  | ||||||
|             self.velocity.0 * seconds + self.position.0, |  | ||||||
|             self.velocity.1 * seconds + self.position.1, |  | ||||||
|         ); |  | ||||||
|         let mut position = (movement.0 % (grid_size.0), movement.1 % (grid_size.1)); |  | ||||||
|         if position.0 < 0 { |  | ||||||
|             position.0 += grid_size.0; |  | ||||||
|         } |  | ||||||
|         if position.1 < 0 { |  | ||||||
|             position.1 += grid_size.1; |  | ||||||
|         } |  | ||||||
|         self.position = position; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn get_quadrant(&self, grid_size: (i32, i32)) -> i32 { |  | ||||||
|         if self.position.0 == (grid_size.0 / 2) || self.position.1 == (grid_size.1 / 2) { |  | ||||||
|             return 0; |  | ||||||
|         } |  | ||||||
|         let top = self.position.1 < grid_size.1 / 2; |  | ||||||
|         let left = self.position.0 < grid_size.0 / 2; |  | ||||||
|         match (top, left) { |  | ||||||
|             (true, true) => 1, |  | ||||||
|             (true, false) => 2, |  | ||||||
|             (false, true) => 3, |  | ||||||
|             (false, false) => 4, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn print_robots(robots: &Vec<Self>, grid_size: (i32, i32)) { |  | ||||||
|         let mut grid = vec![vec![0; grid_size.0 as usize]; grid_size.1 as usize]; |  | ||||||
|         for robot in robots { |  | ||||||
|             let value = grid[robot.position.1 as usize][robot.position.0 as usize]; |  | ||||||
|             grid[robot.position.1 as usize][robot.position.0 as usize] = value + 1; |  | ||||||
|         } |  | ||||||
|         for row in grid { |  | ||||||
|             for tile in row { |  | ||||||
|                 if tile == 0 { |  | ||||||
|                     print!("."); |  | ||||||
|                 } else { |  | ||||||
|                     print!("{tile}"); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             println!(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str) -> i32 { |  | ||||||
|     let robots = input |  | ||||||
|         .lines() |  | ||||||
|         .map(|line| { |  | ||||||
|             let mut robot = Robot::parse(line); |  | ||||||
|             robot.walk(100, (101, 103)); |  | ||||||
|             robot |  | ||||||
|         }) |  | ||||||
|         .collect_vec(); |  | ||||||
|     Robot::print_robots(&robots, (101, 103)); |  | ||||||
|     let mut quadrants = HashMap::new(); |  | ||||||
|     for robot in robots { |  | ||||||
|         let quadrant = robot.get_quadrant((101, 103)); |  | ||||||
|         quadrants |  | ||||||
|             .entry(quadrant) |  | ||||||
|             .and_modify(|count| *count += 1) |  | ||||||
|             .or_insert(1); |  | ||||||
|     } |  | ||||||
|     quadrants |  | ||||||
|         .iter() |  | ||||||
|         .filter(|(quadrant, _)| **quadrant != 0) |  | ||||||
|         .map(|(_, count)| count) |  | ||||||
|         .product() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str) { |  | ||||||
|     let mut robots = input.lines().map(Robot::parse).collect_vec(); |  | ||||||
|     for seconds in 1..=10000 { |  | ||||||
|         for robot in robots.iter_mut() { |  | ||||||
|             robot.walk(1, (101, 103)); |  | ||||||
|         } |  | ||||||
|         let mut quadrants = HashMap::new(); |  | ||||||
|         for robot in robots.iter() { |  | ||||||
|             let quadrant = robot.get_quadrant((101, 103)); |  | ||||||
|             quadrants |  | ||||||
|                 .entry(quadrant) |  | ||||||
|                 .and_modify(|count| *count += 1) |  | ||||||
|                 .or_insert(1); |  | ||||||
|         } |  | ||||||
|         if quadrants.iter().any(|(_, count)| *count > robots.len() / 3) { |  | ||||||
|             Robot::print_robots(&robots, (101, 103)); |  | ||||||
|             println!("{seconds} secs"); |  | ||||||
|             let half_sec = Duration::from_millis(1000); |  | ||||||
|             thread::sleep(half_sec); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT: &str = "p=0,4 v=3,-3 |  | ||||||
| p=6,3 v=-1,-3 |  | ||||||
| p=10,3 v=-1,2 |  | ||||||
| p=2,0 v=2,-1 |  | ||||||
| p=0,0 v=1,3 |  | ||||||
| p=3,0 v=-2,-2 |  | ||||||
| p=7,6 v=-1,-3 |  | ||||||
| p=3,0 v=-1,-2 |  | ||||||
| p=9,3 v=2,3 |  | ||||||
| p=7,3 v=-1,2 |  | ||||||
| p=2,4 v=2,-3 |  | ||||||
| p=9,5 v=-3,-3"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_1() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (0, 4), |  | ||||||
|             velocity: (3, -3), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (3, 5), |  | ||||||
|             velocity: (3, -3), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_2() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (6, 3), |  | ||||||
|             velocity: (-1, -3), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (5, 4), |  | ||||||
|             velocity: (-1, -3), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_3() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (10, 3), |  | ||||||
|             velocity: (-1, 2), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (9, 0), |  | ||||||
|             velocity: (-1, 2), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_4() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (2, 0), |  | ||||||
|             velocity: (2, -1), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (4, 5), |  | ||||||
|             velocity: (2, -1), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_5() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (0, 0), |  | ||||||
|             velocity: (1, 3), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (1, 6), |  | ||||||
|             velocity: (1, 3), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_6() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (3, 0), |  | ||||||
|             velocity: (-2, -2), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (1, 3), |  | ||||||
|             velocity: (-2, -2), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_7() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (7, 6), |  | ||||||
|             velocity: (-1, -3), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (6, 0), |  | ||||||
|             velocity: (-1, -3), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_8() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (3, 0), |  | ||||||
|             velocity: (-1, -2), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (2, 3), |  | ||||||
|             velocity: (-1, -2), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_9() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (9, 3), |  | ||||||
|             velocity: (2, 3), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (0, 2), |  | ||||||
|             velocity: (2, 3), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_10() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (7, 3), |  | ||||||
|             velocity: (-1, 2), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (6, 0), |  | ||||||
|             velocity: (-1, 2), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_11() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (2, 4), |  | ||||||
|             velocity: (2, -3), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (4, 5), |  | ||||||
|             velocity: (2, -3), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_12() { |  | ||||||
|         let mut robot = Robot { |  | ||||||
|             position: (9, 5), |  | ||||||
|             velocity: (-3, -3), |  | ||||||
|         }; |  | ||||||
|         robot.walk(100, (11, 7)); |  | ||||||
|         let result = Robot { |  | ||||||
|             position: (6, 6), |  | ||||||
|             velocity: (-3, -3), |  | ||||||
|         }; |  | ||||||
|         assert_eq!(robot, result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1() { |  | ||||||
|         let robots = INPUT |  | ||||||
|             .lines() |  | ||||||
|             .map(|line| { |  | ||||||
|                 let mut robot = Robot::parse(line); |  | ||||||
|                 robot.walk(100, (11, 7)); |  | ||||||
|                 robot |  | ||||||
|             }) |  | ||||||
|             .collect_vec(); |  | ||||||
|         Robot::print_robots(&robots, (11, 7)); |  | ||||||
|         let mut quadrants = HashMap::new(); |  | ||||||
|         for robot in robots { |  | ||||||
|             let quadrant = robot.get_quadrant((11, 7)); |  | ||||||
|             quadrants |  | ||||||
|                 .entry(quadrant) |  | ||||||
|                 .and_modify(|count| *count += 1) |  | ||||||
|                 .or_insert(1); |  | ||||||
|         } |  | ||||||
|         println!("{quadrants:?}"); |  | ||||||
|         let result: i32 = quadrants |  | ||||||
|             .iter() |  | ||||||
|             .filter(|(quadrant, _)| **quadrant != 0) |  | ||||||
|             .map(|(_, count)| count) |  | ||||||
|             .product(); |  | ||||||
|         assert_eq!(result, 12); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,569 +0,0 @@ | |||||||
| use std::error::Error; |  | ||||||
|  |  | ||||||
| use itertools::Itertools; |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str) -> u32 { |  | ||||||
|     let (grid, movements) = input.split_once("\n\n").unwrap(); |  | ||||||
|     let (mut grid, mut robot) = parse_grid(grid); |  | ||||||
|     let movements = parse_movements(movements); |  | ||||||
|     for movement in movements { |  | ||||||
|         match movement { |  | ||||||
|             Movement::Up => move_up(&mut robot, &mut grid), |  | ||||||
|             Movement::Down => move_down(&mut robot, &mut grid), |  | ||||||
|             Movement::Left => move_left(&mut robot, &mut grid), |  | ||||||
|             Movement::Right => move_right(&mut robot, &mut grid), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     log_grid(grid.clone()); |  | ||||||
|     grid.concat().iter().map(|tile| tile.get_gps()).sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str) -> u32 { |  | ||||||
|     let (grid, movements) = input.split_once("\n\n").unwrap(); |  | ||||||
|     let (mut grid, mut robot) = parse_large_grid(grid); |  | ||||||
|     let movements = parse_movements(movements); |  | ||||||
|     for movement in movements { |  | ||||||
|         match movement { |  | ||||||
|             Movement::Up => move_up_large(&mut robot, &mut grid), |  | ||||||
|             Movement::Down => move_down_large(&mut robot, &mut grid), |  | ||||||
|             Movement::Left => move_left_large(&mut robot, &mut grid), |  | ||||||
|             Movement::Right => move_right_large(&mut robot, &mut grid), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     log_grid(grid.clone()); |  | ||||||
|     grid.concat().iter().map(|tile| tile.get_gps()).sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn log_grid(grid: Vec<Vec<GridTile>>) { |  | ||||||
|     for row in grid { |  | ||||||
|         for tile in row { |  | ||||||
|             match tile.entity { |  | ||||||
|                 GridTileType::Robot => print!("@"), |  | ||||||
|                 GridTileType::Crate => print!("O"), |  | ||||||
|                 GridTileType::Wall => print!("#"), |  | ||||||
|                 GridTileType::Nothing => print!("."), |  | ||||||
|                 GridTileType::BigCrateLeft => print!("["), |  | ||||||
|                 GridTileType::BigCrateRight => print!("]"), |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         println!(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn parse_large_grid(input: &str) -> (Vec<Vec<GridTile>>, GridTile) { |  | ||||||
|     let mut grid_entities = Vec::new(); |  | ||||||
|     let mut robot = GridTile { |  | ||||||
|         entity: GridTileType::Robot, |  | ||||||
|         ..Default::default() |  | ||||||
|     }; |  | ||||||
|     input.lines().enumerate().for_each(|(yidx, line)| { |  | ||||||
|         let mut row_entities = Vec::new(); |  | ||||||
|         line.chars().enumerate().for_each(|(xidx, chara)| { |  | ||||||
|             if let Ok(entity) = GridTileType::from_character(chara) { |  | ||||||
|                 match entity { |  | ||||||
|                     GridTileType::Robot => { |  | ||||||
|                         robot.coords = (xidx as u32 * 2, yidx as u32); |  | ||||||
|                         row_entities.push(robot); |  | ||||||
|                         row_entities.push(GridTile::default()); |  | ||||||
|                     } |  | ||||||
|                     GridTileType::Crate => { |  | ||||||
|                         let entity = GridTile { |  | ||||||
|                             entity: GridTileType::BigCrateLeft, |  | ||||||
|                             coords: (xidx as u32 * 2, yidx as u32), |  | ||||||
|                         }; |  | ||||||
|                         row_entities.push(entity); |  | ||||||
|                         let entity = GridTile { |  | ||||||
|                             entity: GridTileType::BigCrateRight, |  | ||||||
|                             coords: (xidx as u32 * 2 + 1, yidx as u32), |  | ||||||
|                         }; |  | ||||||
|                         row_entities.push(entity); |  | ||||||
|                     } |  | ||||||
|                     GridTileType::Wall => { |  | ||||||
|                         let entity = GridTile { |  | ||||||
|                             entity, |  | ||||||
|                             coords: (xidx as u32 * 2, yidx as u32), |  | ||||||
|                         }; |  | ||||||
|                         row_entities.push(entity); |  | ||||||
|                         let entity = GridTile { |  | ||||||
|                             entity: GridTileType::Wall, |  | ||||||
|                             coords: (xidx as u32 * 2 + 1, yidx as u32), |  | ||||||
|                         }; |  | ||||||
|                         row_entities.push(entity); |  | ||||||
|                     } |  | ||||||
|                     GridTileType::Nothing => { |  | ||||||
|                         row_entities.push(GridTile::default()); |  | ||||||
|                         row_entities.push(GridTile::default()); |  | ||||||
|                     } |  | ||||||
|                     GridTileType::BigCrateLeft | GridTileType::BigCrateRight => (), |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|         grid_entities.push(row_entities); |  | ||||||
|     }); |  | ||||||
|     (grid_entities, robot) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn parse_grid(input: &str) -> (Vec<Vec<GridTile>>, GridTile) { |  | ||||||
|     let mut grid_entities = Vec::new(); |  | ||||||
|     let mut robot = GridTile { |  | ||||||
|         entity: GridTileType::Robot, |  | ||||||
|         ..Default::default() |  | ||||||
|     }; |  | ||||||
|     input.lines().enumerate().for_each(|(yidx, line)| { |  | ||||||
|         let mut row_entities = Vec::new(); |  | ||||||
|         line.chars().enumerate().for_each(|(xidx, chara)| { |  | ||||||
|             if let Ok(entity) = GridTileType::from_character(chara) { |  | ||||||
|                 match entity { |  | ||||||
|                     GridTileType::Robot => { |  | ||||||
|                         robot.coords = (xidx as u32, yidx as u32); |  | ||||||
|                         row_entities.push(robot); |  | ||||||
|                     } |  | ||||||
|                     GridTileType::Crate | GridTileType::Wall => { |  | ||||||
|                         let entity = GridTile { |  | ||||||
|                             entity, |  | ||||||
|                             coords: (xidx as u32, yidx as u32), |  | ||||||
|                         }; |  | ||||||
|                         row_entities.push(entity); |  | ||||||
|                     } |  | ||||||
|                     GridTileType::Nothing => row_entities.push(GridTile::default()), |  | ||||||
|                     GridTileType::BigCrateLeft | GridTileType::BigCrateRight => (), |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|         grid_entities.push(row_entities); |  | ||||||
|     }); |  | ||||||
|     (grid_entities, robot) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn parse_movements(input: &str) -> Vec<Movement> { |  | ||||||
|     input |  | ||||||
|         .lines() |  | ||||||
|         .map(|line| { |  | ||||||
|             line.chars() |  | ||||||
|                 .map(|chara| Movement::try_from(chara).unwrap()) |  | ||||||
|                 .collect_vec() |  | ||||||
|         }) |  | ||||||
|         .concat() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn move_up(robot: &mut GridTile, grid: &mut [Vec<GridTile>]) { |  | ||||||
|     let (robot_x, robot_y) = robot.coords; |  | ||||||
|     let mut moving_tiles = Vec::new(); |  | ||||||
|     for above in (0..robot_y).rev() { |  | ||||||
|         let tile = grid[above as usize][robot_x as usize]; |  | ||||||
|         match tile.entity { |  | ||||||
|             GridTileType::Robot => (), |  | ||||||
|             GridTileType::Crate => moving_tiles.push(tile), |  | ||||||
|             GridTileType::Wall => return, |  | ||||||
|             GridTileType::Nothing => break, |  | ||||||
|             GridTileType::BigCrateLeft | GridTileType::BigCrateRight => (), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     for tile in moving_tiles.iter_mut() { |  | ||||||
|         tile.coords.1 -= 1; |  | ||||||
|         grid[tile.coords.1 as usize][tile.coords.0 as usize] = *tile; |  | ||||||
|     } |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = GridTile::default(); |  | ||||||
|     robot.coords.1 -= 1; |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = *robot; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn move_down(robot: &mut GridTile, grid: &mut [Vec<GridTile>]) { |  | ||||||
|     let (robot_x, robot_y) = robot.coords; |  | ||||||
|     let height = grid.len(); |  | ||||||
|     let mut moving_tiles = Vec::new(); |  | ||||||
|     for below in robot_y..height as u32 { |  | ||||||
|         let tile = grid[below as usize][robot_x as usize]; |  | ||||||
|         match tile.entity { |  | ||||||
|             GridTileType::Robot => (), |  | ||||||
|             GridTileType::Crate => moving_tiles.push(tile), |  | ||||||
|             GridTileType::Wall => return, |  | ||||||
|             GridTileType::Nothing => break, |  | ||||||
|             GridTileType::BigCrateLeft | GridTileType::BigCrateRight => (), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     for tile in moving_tiles.iter_mut() { |  | ||||||
|         tile.coords.1 += 1; |  | ||||||
|         grid[tile.coords.1 as usize][tile.coords.0 as usize] = *tile; |  | ||||||
|     } |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = GridTile::default(); |  | ||||||
|     robot.coords.1 += 1; |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = *robot; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn move_left(robot: &mut GridTile, grid: &mut [Vec<GridTile>]) { |  | ||||||
|     let (robot_x, robot_y) = robot.coords; |  | ||||||
|     let mut moving_tiles = Vec::new(); |  | ||||||
|     for left in (0..robot_x).rev() { |  | ||||||
|         let tile = grid[robot_y as usize][left as usize]; |  | ||||||
|         match tile.entity { |  | ||||||
|             GridTileType::Robot => (), |  | ||||||
|             GridTileType::Crate => moving_tiles.push(tile), |  | ||||||
|             GridTileType::Wall => return, |  | ||||||
|             GridTileType::Nothing => break, |  | ||||||
|             GridTileType::BigCrateLeft | GridTileType::BigCrateRight => (), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     for tile in moving_tiles.iter_mut() { |  | ||||||
|         tile.coords.0 -= 1; |  | ||||||
|         grid[tile.coords.1 as usize][tile.coords.0 as usize] = *tile; |  | ||||||
|     } |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = GridTile::default(); |  | ||||||
|     robot.coords.0 -= 1; |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = *robot; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn move_right(robot: &mut GridTile, grid: &mut [Vec<GridTile>]) { |  | ||||||
|     let (robot_x, robot_y) = robot.coords; |  | ||||||
|     let mut moving_tiles = Vec::new(); |  | ||||||
|     let width = grid[0].len(); |  | ||||||
|     for right in robot_x..width as u32 { |  | ||||||
|         let tile = grid[robot_y as usize][right as usize]; |  | ||||||
|         match tile.entity { |  | ||||||
|             GridTileType::Robot => (), |  | ||||||
|             GridTileType::Crate => moving_tiles.push(tile), |  | ||||||
|             GridTileType::Wall => return, |  | ||||||
|             GridTileType::Nothing => break, |  | ||||||
|             GridTileType::BigCrateLeft | GridTileType::BigCrateRight => (), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     for tile in moving_tiles.iter_mut() { |  | ||||||
|         tile.coords.0 += 1; |  | ||||||
|         grid[tile.coords.1 as usize][tile.coords.0 as usize] = *tile; |  | ||||||
|     } |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = GridTile::default(); |  | ||||||
|     robot.coords.0 += 1; |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = *robot; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn get_above(tile: &GridTile, grid: &[Vec<GridTile>]) -> Vec<GridTile> { |  | ||||||
|     let (tile_x, tile_y) = tile.coords; |  | ||||||
|     let mut above_tiles = Vec::new(); |  | ||||||
|     let above = grid[tile_y as usize - 1][tile_x as usize]; |  | ||||||
|     match above.entity { |  | ||||||
|         GridTileType::Robot => (), |  | ||||||
|         GridTileType::Crate => { |  | ||||||
|             above_tiles.push(above); |  | ||||||
|             above_tiles.extend_from_slice(&get_above(&above, grid)); |  | ||||||
|         } |  | ||||||
|         GridTileType::BigCrateLeft => { |  | ||||||
|             above_tiles.push(above); |  | ||||||
|             let right = grid[above.coords.1 as usize][above.coords.0 as usize + 1]; |  | ||||||
|             above_tiles.push(above); |  | ||||||
|             above_tiles.push(right); |  | ||||||
|             above_tiles.extend_from_slice(&get_above(&above, grid)); |  | ||||||
|             above_tiles.extend_from_slice(&get_above(&right, grid)); |  | ||||||
|         } |  | ||||||
|         GridTileType::BigCrateRight => { |  | ||||||
|             above_tiles.push(above); |  | ||||||
|             let left = grid[above.coords.1 as usize][above.coords.0 as usize - 1]; |  | ||||||
|             above_tiles.push(above); |  | ||||||
|             above_tiles.push(left); |  | ||||||
|             above_tiles.extend_from_slice(&get_above(&above, grid)); |  | ||||||
|             above_tiles.extend_from_slice(&get_above(&left, grid)); |  | ||||||
|         } |  | ||||||
|         GridTileType::Wall => above_tiles.push(above), |  | ||||||
|         GridTileType::Nothing => (), |  | ||||||
|     } |  | ||||||
|     above_tiles |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn get_below(tile: &GridTile, grid: &[Vec<GridTile>]) -> Vec<GridTile> { |  | ||||||
|     let (tile_x, tile_y) = tile.coords; |  | ||||||
|     let mut below_tiles = Vec::new(); |  | ||||||
|     let below = grid[tile_y as usize + 1][tile_x as usize]; |  | ||||||
|     match below.entity { |  | ||||||
|         GridTileType::Robot => (), |  | ||||||
|         GridTileType::Crate => { |  | ||||||
|             below_tiles.push(below); |  | ||||||
|             below_tiles.extend_from_slice(&get_below(&below, grid)); |  | ||||||
|         } |  | ||||||
|         GridTileType::BigCrateLeft => { |  | ||||||
|             below_tiles.push(below); |  | ||||||
|             let right = grid[below.coords.1 as usize][below.coords.0 as usize + 1]; |  | ||||||
|             below_tiles.push(below); |  | ||||||
|             below_tiles.push(right); |  | ||||||
|             below_tiles.extend_from_slice(&get_below(&below, grid)); |  | ||||||
|             below_tiles.extend_from_slice(&get_below(&right, grid)); |  | ||||||
|         } |  | ||||||
|         GridTileType::BigCrateRight => { |  | ||||||
|             below_tiles.push(below); |  | ||||||
|             let left = grid[below.coords.1 as usize][below.coords.0 as usize - 1]; |  | ||||||
|             below_tiles.push(below); |  | ||||||
|             below_tiles.push(left); |  | ||||||
|             below_tiles.extend_from_slice(&get_below(&below, grid)); |  | ||||||
|             below_tiles.extend_from_slice(&get_below(&left, grid)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         GridTileType::Wall => below_tiles.push(below), |  | ||||||
|         GridTileType::Nothing => (), |  | ||||||
|     } |  | ||||||
|     below_tiles |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn get_left(tile: &GridTile, grid: &[Vec<GridTile>]) -> Vec<GridTile> { |  | ||||||
|     let (tile_x, tile_y) = tile.coords; |  | ||||||
|     let mut left_tiles = Vec::new(); |  | ||||||
|     let left = grid[tile_y as usize][tile_x as usize - 1]; |  | ||||||
|     match left.entity { |  | ||||||
|         GridTileType::Robot => (), |  | ||||||
|         GridTileType::Crate | GridTileType::BigCrateLeft | GridTileType::BigCrateRight => { |  | ||||||
|             left_tiles.push(left); |  | ||||||
|             left_tiles.extend_from_slice(&get_left(&left, grid)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         GridTileType::Wall => left_tiles.push(left), |  | ||||||
|         GridTileType::Nothing => (), |  | ||||||
|     } |  | ||||||
|     left_tiles |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn get_right(tile: &GridTile, grid: &[Vec<GridTile>]) -> Vec<GridTile> { |  | ||||||
|     let (tile_x, tile_y) = tile.coords; |  | ||||||
|     let mut right_tiles = Vec::new(); |  | ||||||
|     let right = grid[tile_y as usize][tile_x as usize + 1]; |  | ||||||
|     match right.entity { |  | ||||||
|         GridTileType::Robot => (), |  | ||||||
|         GridTileType::Crate | GridTileType::BigCrateLeft | GridTileType::BigCrateRight => { |  | ||||||
|             right_tiles.push(right); |  | ||||||
|             right_tiles.extend_from_slice(&get_right(&right, grid)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         GridTileType::Wall => right_tiles.push(right), |  | ||||||
|         GridTileType::Nothing => (), |  | ||||||
|     } |  | ||||||
|     right_tiles |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn move_up_large(robot: &mut GridTile, grid: &mut [Vec<GridTile>]) { |  | ||||||
|     let mut moving_tiles = get_above(robot, grid); |  | ||||||
|     if moving_tiles |  | ||||||
|         .iter() |  | ||||||
|         .map(|tile| tile.entity) |  | ||||||
|         .contains(&GridTileType::Wall) |  | ||||||
|     { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|     moving_tiles.sort_by(|tile_a, tile_b| tile_a.coords.1.cmp(&tile_b.coords.1)); |  | ||||||
|     for tile in moving_tiles.iter_mut() { |  | ||||||
|         grid[tile.coords.1 as usize][tile.coords.0 as usize] = GridTile::default(); |  | ||||||
|         tile.coords.1 -= 1; |  | ||||||
|         grid[tile.coords.1 as usize][tile.coords.0 as usize] = *tile; |  | ||||||
|     } |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = GridTile::default(); |  | ||||||
|     robot.coords.1 -= 1; |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = *robot; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn move_down_large(robot: &mut GridTile, grid: &mut [Vec<GridTile>]) { |  | ||||||
|     let mut moving_tiles = get_below(robot, grid); |  | ||||||
|     if moving_tiles |  | ||||||
|         .iter() |  | ||||||
|         .map(|tile| tile.entity) |  | ||||||
|         .contains(&GridTileType::Wall) |  | ||||||
|     { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|     moving_tiles.sort_by(|tile_a, tile_b| tile_b.coords.1.cmp(&tile_a.coords.1)); |  | ||||||
|     for tile in moving_tiles.iter_mut() { |  | ||||||
|         grid[tile.coords.1 as usize][tile.coords.0 as usize] = GridTile::default(); |  | ||||||
|         tile.coords.1 += 1; |  | ||||||
|         grid[tile.coords.1 as usize][tile.coords.0 as usize] = *tile; |  | ||||||
|     } |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = GridTile::default(); |  | ||||||
|     robot.coords.1 += 1; |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = *robot; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn move_left_large(robot: &mut GridTile, grid: &mut [Vec<GridTile>]) { |  | ||||||
|     let mut moving_tiles = get_left(robot, grid); |  | ||||||
|     if moving_tiles |  | ||||||
|         .iter() |  | ||||||
|         .map(|tile| tile.entity) |  | ||||||
|         .contains(&GridTileType::Wall) |  | ||||||
|     { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|     for tile in moving_tiles.iter_mut() { |  | ||||||
|         tile.coords.0 -= 1; |  | ||||||
|         grid[tile.coords.1 as usize][tile.coords.0 as usize] = *tile; |  | ||||||
|     } |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = GridTile::default(); |  | ||||||
|     robot.coords.0 -= 1; |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = *robot; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn move_right_large(robot: &mut GridTile, grid: &mut [Vec<GridTile>]) { |  | ||||||
|     let mut moving_tiles = get_right(robot, grid); |  | ||||||
|     if moving_tiles |  | ||||||
|         .iter() |  | ||||||
|         .map(|tile| tile.entity) |  | ||||||
|         .contains(&GridTileType::Wall) |  | ||||||
|     { |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|     for tile in moving_tiles.iter_mut() { |  | ||||||
|         tile.coords.0 += 1; |  | ||||||
|         grid[tile.coords.1 as usize][tile.coords.0 as usize] = *tile; |  | ||||||
|     } |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = GridTile::default(); |  | ||||||
|     robot.coords.0 += 1; |  | ||||||
|     grid[robot.coords.1 as usize][robot.coords.0 as usize] = *robot; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] |  | ||||||
| enum GridTileType { |  | ||||||
|     Robot, |  | ||||||
|     Crate, |  | ||||||
|     BigCrateLeft, |  | ||||||
|     BigCrateRight, |  | ||||||
|     Wall, |  | ||||||
|     #[default] |  | ||||||
|     Nothing, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl GridTileType { |  | ||||||
|     fn from_character(value: char) -> Result<GridTileType, Box<dyn Error>> { |  | ||||||
|         match value { |  | ||||||
|             '#' => Ok(Self::Wall), |  | ||||||
|             'O' => Ok(Self::Crate), |  | ||||||
|             '@' => Ok(Self::Robot), |  | ||||||
|             '.' => Ok(Self::Nothing), |  | ||||||
|             _ => Err(Box::from(format!("{value} is not a valid entity"))), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] |  | ||||||
| struct GridTile { |  | ||||||
|     entity: GridTileType, |  | ||||||
|     coords: (u32, u32), |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl GridTile { |  | ||||||
|     fn get_gps(&self) -> u32 { |  | ||||||
|         if self.entity == GridTileType::Crate || self.entity == GridTileType::BigCrateLeft { |  | ||||||
|             self.coords.0 + self.coords.1 * 100 |  | ||||||
|         } else { |  | ||||||
|             0 |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |  | ||||||
| enum Movement { |  | ||||||
|     Up, |  | ||||||
|     Down, |  | ||||||
|     Left, |  | ||||||
|     Right, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl TryFrom<char> for Movement { |  | ||||||
|     type Error = Box<dyn Error>; |  | ||||||
|  |  | ||||||
|     fn try_from(value: char) -> std::result::Result<Movement, Box<dyn Error>> { |  | ||||||
|         match value { |  | ||||||
|             '^' => Ok(Self::Up), |  | ||||||
|             'v' => Ok(Self::Down), |  | ||||||
|             '<' => Ok(Self::Left), |  | ||||||
|             '>' => Ok(Self::Right), |  | ||||||
|             _ => Err(Box::from(format!("{value} is not a valid direction"))), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT_SMALL: &str = "####### |  | ||||||
| #...O.. |  | ||||||
| #......"; |  | ||||||
|  |  | ||||||
|     const INPUT_MEDIUM: &str = "######## |  | ||||||
| #..O.O.# |  | ||||||
| ##@.O..# |  | ||||||
| #...O..# |  | ||||||
| #.#.O..# |  | ||||||
| #...O..# |  | ||||||
| #......# |  | ||||||
| ######## |  | ||||||
|  |  | ||||||
| <^^>>>vv<v>>v<<"; |  | ||||||
|  |  | ||||||
|     const INPUT_LARGE: &str = "########## |  | ||||||
| #..O..O.O# |  | ||||||
| #......O.# |  | ||||||
| #.OO..O.O# |  | ||||||
| #..O@..O.# |  | ||||||
| #O#..O...# |  | ||||||
| #O..O..O.# |  | ||||||
| #.OO.O.OO# |  | ||||||
| #....O...# |  | ||||||
| ########## |  | ||||||
|  |  | ||||||
| <vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^ |  | ||||||
| vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v |  | ||||||
| ><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv< |  | ||||||
| <<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^ |  | ||||||
| ^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^>< |  | ||||||
| ^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^ |  | ||||||
| >^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^ |  | ||||||
| <><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<> |  | ||||||
| ^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v> |  | ||||||
| v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^"; |  | ||||||
|  |  | ||||||
|     const INPUT_LARGE_BOX_SIMPLE: &str = "##### |  | ||||||
| #..O. |  | ||||||
| #...."; |  | ||||||
|  |  | ||||||
|     const INPUT_LARGE_BOX_FULL: &str = "####### |  | ||||||
| #...#.# |  | ||||||
| #.....# |  | ||||||
| #..OO@# |  | ||||||
| #..O..# |  | ||||||
| #.....# |  | ||||||
| ####### |  | ||||||
|  |  | ||||||
| <vv<<^^<<^^"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_small() { |  | ||||||
|         let (grid, _) = parse_grid(INPUT_SMALL); |  | ||||||
|         let flat_grid = grid.concat(); |  | ||||||
|         let result: u32 = flat_grid.iter().map(|tile| tile.get_gps()).sum(); |  | ||||||
|         assert_eq!(result, 104); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_medium() { |  | ||||||
|         let result = process_part1(INPUT_MEDIUM); |  | ||||||
|         assert_eq!(result, 2028); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_large() { |  | ||||||
|         let result = process_part1(INPUT_LARGE); |  | ||||||
|         assert_eq!(result, 10092); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_simple() { |  | ||||||
|         let (grid, _) = parse_large_grid(INPUT_LARGE_BOX_SIMPLE); |  | ||||||
|         let flat_grid = grid.concat(); |  | ||||||
|         let result: u32 = flat_grid.iter().map(|tile| tile.get_gps()).sum(); |  | ||||||
|         assert_eq!(result, 106); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_full() { |  | ||||||
|         let result = process_part2(INPUT_LARGE_BOX_FULL); |  | ||||||
|         assert_eq!(result, 618); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_large() { |  | ||||||
|         let result = process_part2(INPUT_LARGE); |  | ||||||
|         assert_eq!(result, 9021); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,448 +0,0 @@ | |||||||
| use std::{collections::HashMap, error::Error}; |  | ||||||
|  |  | ||||||
| use itertools::Itertools; |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str) -> usize { |  | ||||||
|     let mut start = (0, 0); |  | ||||||
|     let mut end = (0, 0); |  | ||||||
|     let grid = input |  | ||||||
|         .lines() |  | ||||||
|         .enumerate() |  | ||||||
|         .map(|(yidx, row)| { |  | ||||||
|             row.chars() |  | ||||||
|                 .enumerate() |  | ||||||
|                 .map(|(xidx, chara)| { |  | ||||||
|                     let tile = GridTile::try_from(chara).unwrap(); |  | ||||||
|                     match tile { |  | ||||||
|                         GridTile::Wall | GridTile::Path => tile, |  | ||||||
|                         GridTile::Start => { |  | ||||||
|                             start = (xidx, yidx); |  | ||||||
|                             tile |  | ||||||
|                         } |  | ||||||
|                         GridTile::End => { |  | ||||||
|                             end = (xidx, yidx); |  | ||||||
|                             tile |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 }) |  | ||||||
|                 .collect_vec() |  | ||||||
|         }) |  | ||||||
|         .collect_vec(); |  | ||||||
|     let mut next_paths = vec![Reindeer { |  | ||||||
|         coords: start, |  | ||||||
|         ..Default::default() |  | ||||||
|     }]; |  | ||||||
|     let mut arrived: Vec<Reindeer> = Vec::new(); |  | ||||||
|     let mut visited = HashMap::new(); |  | ||||||
|     let mut iter = 0; |  | ||||||
|     while !next_paths.is_empty() { |  | ||||||
|         next_paths = next_paths |  | ||||||
|             .iter() |  | ||||||
|             .map(|reindeer| reindeer.get_all_next_paths(&grid)) |  | ||||||
|             .collect_vec() |  | ||||||
|             .concat(); |  | ||||||
|         for (idx, reindeer) in next_paths.clone().iter().enumerate().rev() { |  | ||||||
|             if let Some(score) = visited.get_mut(&reindeer.coords) { |  | ||||||
|                 if *score <= reindeer.score { |  | ||||||
|                     next_paths.remove(idx); |  | ||||||
|                     continue; |  | ||||||
|                 } else { |  | ||||||
|                     *score = reindeer.score; |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
|                 visited.insert(reindeer.coords, reindeer.score); |  | ||||||
|             } |  | ||||||
|             if reindeer.state == ReindeerState::Arrived { |  | ||||||
|                 let arrived_reindeer = next_paths.remove(idx); |  | ||||||
|                 arrived.push(arrived_reindeer); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         iter += 1; |  | ||||||
|     } |  | ||||||
|     println!("Iterations to goal {iter}"); |  | ||||||
|     arrived.iter().map(|reindeer| reindeer.score).min().unwrap() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str) -> usize { |  | ||||||
|     let mut start = (0, 0); |  | ||||||
|     let mut end = (0, 0); |  | ||||||
|     let grid = input |  | ||||||
|         .lines() |  | ||||||
|         .enumerate() |  | ||||||
|         .map(|(yidx, row)| { |  | ||||||
|             row.chars() |  | ||||||
|                 .enumerate() |  | ||||||
|                 .map(|(xidx, chara)| { |  | ||||||
|                     let tile = GridTile::try_from(chara).unwrap(); |  | ||||||
|                     match tile { |  | ||||||
|                         GridTile::Wall | GridTile::Path => tile, |  | ||||||
|                         GridTile::Start => { |  | ||||||
|                             start = (xidx, yidx); |  | ||||||
|                             tile |  | ||||||
|                         } |  | ||||||
|                         GridTile::End => { |  | ||||||
|                             end = (xidx, yidx); |  | ||||||
|                             tile |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 }) |  | ||||||
|                 .collect_vec() |  | ||||||
|         }) |  | ||||||
|         .collect_vec(); |  | ||||||
|     let mut smallest_score = usize::MAX; |  | ||||||
|     let mut visited = HashMap::new(); |  | ||||||
|     visited.insert((start, Orientation::East), 0); |  | ||||||
|     let mut next_paths = vec![Reindeer { |  | ||||||
|         coords: start, |  | ||||||
|         visited: visited.clone(), |  | ||||||
|         ..Default::default() |  | ||||||
|     }]; |  | ||||||
|     let mut arrived: Vec<Reindeer> = Vec::new(); |  | ||||||
|     while !next_paths.is_empty() { |  | ||||||
|         next_paths = next_paths |  | ||||||
|             .iter() |  | ||||||
|             .map(|reindeer| reindeer.get_all_next_paths(&grid)) |  | ||||||
|             .collect_vec() |  | ||||||
|             .concat(); |  | ||||||
|         for (idx, reindeer) in next_paths.clone().iter().enumerate().rev() { |  | ||||||
|             if reindeer.score > smallest_score |  | ||||||
|                 || reindeer |  | ||||||
|                     .visited |  | ||||||
|                     .contains_key(&(reindeer.coords, reindeer.orientation)) |  | ||||||
|             { |  | ||||||
|                 next_paths.remove(idx); |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|             next_paths[idx] |  | ||||||
|                 .visited |  | ||||||
|                 .insert((reindeer.coords, reindeer.orientation), reindeer.score); |  | ||||||
|             if let Some(score) = visited.get_mut(&(reindeer.coords, reindeer.orientation)) { |  | ||||||
|                 if *score < reindeer.score { |  | ||||||
|                     next_paths.remove(idx); |  | ||||||
|                     continue; |  | ||||||
|                 } else { |  | ||||||
|                     *score = reindeer.score; |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
|                 visited.insert((reindeer.coords, reindeer.orientation), reindeer.score); |  | ||||||
|             } |  | ||||||
|             if reindeer.state == ReindeerState::Arrived && reindeer.score <= smallest_score { |  | ||||||
|                 smallest_score = reindeer.score; |  | ||||||
|                 let arrived_reindeer = next_paths.remove(idx); |  | ||||||
|                 arrived.push(arrived_reindeer); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         arrived.retain(|reindeer| reindeer.score == smallest_score); |  | ||||||
|     } |  | ||||||
|     let visited = arrived |  | ||||||
|         .iter() |  | ||||||
|         .map(|reindeer| { |  | ||||||
|             reindeer |  | ||||||
|                 .visited |  | ||||||
|                 .keys() |  | ||||||
|                 .map(|(coords, _)| coords) |  | ||||||
|                 .collect_vec() |  | ||||||
|         }) |  | ||||||
|         .collect_vec() |  | ||||||
|         .concat(); |  | ||||||
|     log_maze(&grid, &arrived); |  | ||||||
|     visited.iter().unique().count() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)] |  | ||||||
| enum Orientation { |  | ||||||
|     #[default] |  | ||||||
|     East, |  | ||||||
|     West, |  | ||||||
|     North, |  | ||||||
|     South, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl Orientation { |  | ||||||
|     fn turn_clockwise(&self) -> Self { |  | ||||||
|         match self { |  | ||||||
|             Orientation::East => Self::South, |  | ||||||
|             Orientation::West => Self::North, |  | ||||||
|             Orientation::North => Self::East, |  | ||||||
|             Orientation::South => Self::West, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn turn_counterclockwise(&self) -> Self { |  | ||||||
|         match self { |  | ||||||
|             Orientation::East => Self::North, |  | ||||||
|             Orientation::West => Self::South, |  | ||||||
|             Orientation::North => Self::West, |  | ||||||
|             Orientation::South => Self::East, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)] |  | ||||||
| enum ReindeerState { |  | ||||||
|     #[default] |  | ||||||
|     Going, |  | ||||||
|     Arrived, |  | ||||||
|     Stuck, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, PartialEq, Eq)] |  | ||||||
| struct Reindeer { |  | ||||||
|     orientation: Orientation, |  | ||||||
|     coords: (usize, usize), |  | ||||||
|     score: usize, |  | ||||||
|     visited: HashMap<((usize, usize), Orientation), usize>, |  | ||||||
|     state: ReindeerState, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl Reindeer { |  | ||||||
|     fn get_next(&self, grid: &[Vec<GridTile>]) -> Reindeer { |  | ||||||
|         let tile = match self.orientation { |  | ||||||
|             Orientation::East => grid[self.coords.1][self.coords.0 + 1], |  | ||||||
|             Orientation::West => grid[self.coords.1][self.coords.0 - 1], |  | ||||||
|             Orientation::North => grid[self.coords.1 - 1][self.coords.0], |  | ||||||
|             Orientation::South => grid[self.coords.1 + 1][self.coords.0], |  | ||||||
|         }; |  | ||||||
|         let coords = match self.orientation { |  | ||||||
|             Orientation::East => (self.coords.0 + 1, self.coords.1), |  | ||||||
|             Orientation::West => (self.coords.0 - 1, self.coords.1), |  | ||||||
|             Orientation::South => (self.coords.0, self.coords.1 + 1), |  | ||||||
|             Orientation::North => (self.coords.0, self.coords.1 - 1), |  | ||||||
|         }; |  | ||||||
|         if tile == GridTile::Wall { |  | ||||||
|             Reindeer { |  | ||||||
|                 state: ReindeerState::Stuck, |  | ||||||
|                 ..self.clone() |  | ||||||
|             } |  | ||||||
|         } else if tile == GridTile::End { |  | ||||||
|             Reindeer { |  | ||||||
|                 score: self.score + 1, |  | ||||||
|                 state: ReindeerState::Arrived, |  | ||||||
|                 coords, |  | ||||||
|                 ..self.clone() |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             Reindeer { |  | ||||||
|                 score: self.score + 1, |  | ||||||
|                 coords, |  | ||||||
|                 ..self.clone() |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn get_right(&self, grid: &[Vec<GridTile>]) -> Reindeer { |  | ||||||
|         let tile = match self.orientation { |  | ||||||
|             Orientation::East => grid[self.coords.1 + 1][self.coords.0], |  | ||||||
|             Orientation::West => grid[self.coords.1 - 1][self.coords.0], |  | ||||||
|             Orientation::North => grid[self.coords.1][self.coords.0 + 1], |  | ||||||
|             Orientation::South => grid[self.coords.1][self.coords.0 - 1], |  | ||||||
|         }; |  | ||||||
|         let coords = match self.orientation { |  | ||||||
|             Orientation::East => (self.coords.0, self.coords.1 + 1), |  | ||||||
|             Orientation::West => (self.coords.0, self.coords.1 - 1), |  | ||||||
|             Orientation::South => (self.coords.0 - 1, self.coords.1), |  | ||||||
|             Orientation::North => (self.coords.0 + 1, self.coords.1), |  | ||||||
|         }; |  | ||||||
|         if tile == GridTile::Wall { |  | ||||||
|             Reindeer { |  | ||||||
|                 state: ReindeerState::Stuck, |  | ||||||
|                 ..self.clone() |  | ||||||
|             } |  | ||||||
|         } else if tile == GridTile::End { |  | ||||||
|             Reindeer { |  | ||||||
|                 score: self.score + 1001, |  | ||||||
|                 state: ReindeerState::Arrived, |  | ||||||
|                 coords, |  | ||||||
|                 orientation: self.orientation.turn_clockwise(), |  | ||||||
|                 ..self.clone() |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             Reindeer { |  | ||||||
|                 score: self.score + 1001, |  | ||||||
|                 orientation: self.orientation.turn_clockwise(), |  | ||||||
|                 coords, |  | ||||||
|                 ..self.clone() |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn get_left(&self, grid: &[Vec<GridTile>]) -> Reindeer { |  | ||||||
|         let tile = match self.orientation { |  | ||||||
|             Orientation::East => grid[self.coords.1 - 1][self.coords.0], |  | ||||||
|             Orientation::West => grid[self.coords.1 + 1][self.coords.0], |  | ||||||
|             Orientation::North => grid[self.coords.1][self.coords.0 - 1], |  | ||||||
|             Orientation::South => grid[self.coords.1][self.coords.0 + 1], |  | ||||||
|         }; |  | ||||||
|         let coords = match self.orientation { |  | ||||||
|             Orientation::East => (self.coords.0, self.coords.1 - 1), |  | ||||||
|             Orientation::West => (self.coords.0, self.coords.1 + 1), |  | ||||||
|             Orientation::South => (self.coords.0 + 1, self.coords.1), |  | ||||||
|             Orientation::North => (self.coords.0 - 1, self.coords.1), |  | ||||||
|         }; |  | ||||||
|         if tile == GridTile::Wall { |  | ||||||
|             Reindeer { |  | ||||||
|                 state: ReindeerState::Stuck, |  | ||||||
|                 ..self.clone() |  | ||||||
|             } |  | ||||||
|         } else if tile == GridTile::End { |  | ||||||
|             Reindeer { |  | ||||||
|                 score: self.score + 1001, |  | ||||||
|                 state: ReindeerState::Arrived, |  | ||||||
|                 coords, |  | ||||||
|                 orientation: self.orientation.turn_counterclockwise(), |  | ||||||
|                 ..self.clone() |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             Reindeer { |  | ||||||
|                 score: self.score + 1001, |  | ||||||
|                 orientation: self.orientation.turn_counterclockwise(), |  | ||||||
|                 coords, |  | ||||||
|                 ..self.clone() |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn get_all_next_paths(&self, grid: &[Vec<GridTile>]) -> Vec<Reindeer> { |  | ||||||
|         let next = self.get_next(grid); |  | ||||||
|         let right = self.get_right(grid); |  | ||||||
|         let left = self.get_left(grid); |  | ||||||
|         let mut paths = Vec::new(); |  | ||||||
|         if next.state != ReindeerState::Stuck { |  | ||||||
|             paths.push(next); |  | ||||||
|         } |  | ||||||
|         if right.state != ReindeerState::Stuck { |  | ||||||
|             paths.push(right); |  | ||||||
|         } |  | ||||||
|         if left.state != ReindeerState::Stuck { |  | ||||||
|             paths.push(left); |  | ||||||
|         } |  | ||||||
|         paths |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)] |  | ||||||
| enum GridTile { |  | ||||||
|     Wall, |  | ||||||
|     #[default] |  | ||||||
|     Path, |  | ||||||
|     Start, |  | ||||||
|     End, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl TryFrom<char> for GridTile { |  | ||||||
|     type Error = Box<dyn Error>; |  | ||||||
|  |  | ||||||
|     fn try_from(value: char) -> std::result::Result<GridTile, Box<dyn Error>> { |  | ||||||
|         match value { |  | ||||||
|             '#' => Ok(Self::Wall), |  | ||||||
|             '.' => Ok(Self::Path), |  | ||||||
|             'S' => Ok(Self::Start), |  | ||||||
|             'E' => Ok(Self::End), |  | ||||||
|             _ => Err(Box::from(format!("{value} is not a valid tile"))), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn log_maze(grid: &[Vec<GridTile>], visited: &Vec<Reindeer>) { |  | ||||||
|     for (yidx, row) in grid.iter().enumerate() { |  | ||||||
|         for (xidx, tile) in row.iter().enumerate() { |  | ||||||
|             let contains = { |  | ||||||
|                 let mut contains = false; |  | ||||||
|                 for reindeer in visited { |  | ||||||
|                     if reindeer |  | ||||||
|                         .visited |  | ||||||
|                         .contains_key(&((xidx, yidx), Orientation::East)) |  | ||||||
|                         || reindeer |  | ||||||
|                             .visited |  | ||||||
|                             .contains_key(&((xidx, yidx), Orientation::West)) |  | ||||||
|                         || reindeer |  | ||||||
|                             .visited |  | ||||||
|                             .contains_key(&((xidx, yidx), Orientation::North)) |  | ||||||
|                         || reindeer |  | ||||||
|                             .visited |  | ||||||
|                             .contains_key(&((xidx, yidx), Orientation::South)) |  | ||||||
|                     { |  | ||||||
|                         contains = true; |  | ||||||
|                         break; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 contains |  | ||||||
|             }; |  | ||||||
|             if contains && !(*tile == GridTile::Start || *tile == GridTile::End) { |  | ||||||
|                 print!("O"); |  | ||||||
|             } else if *tile == GridTile::Wall { |  | ||||||
|                 print!("#"); |  | ||||||
|             } else if *tile == GridTile::Path { |  | ||||||
|                 print!("."); |  | ||||||
|             } else if *tile == GridTile::Start { |  | ||||||
|                 print!("S"); |  | ||||||
|             } else if *tile == GridTile::End { |  | ||||||
|                 print!("E"); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         println!(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT_1: &str = "############### |  | ||||||
| #.......#....E# |  | ||||||
| #.#.###.#.###.# |  | ||||||
| #.....#.#...#.# |  | ||||||
| #.###.#####.#.# |  | ||||||
| #.#.#.......#.# |  | ||||||
| #.#.#####.###.# |  | ||||||
| #...........#.# |  | ||||||
| ###.#.#####.#.# |  | ||||||
| #...#.....#.#.# |  | ||||||
| #.#.#.###.#.#.# |  | ||||||
| #.....#...#.#.# |  | ||||||
| #.###.#.#.#.#.# |  | ||||||
| #S..#.....#...# |  | ||||||
| ###############"; |  | ||||||
|  |  | ||||||
|     const INPUT_2: &str = "################# |  | ||||||
| #...#...#...#..E# |  | ||||||
| #.#.#.#.#.#.#.#.# |  | ||||||
| #.#.#.#...#...#.# |  | ||||||
| #.#.#.#.###.#.#.# |  | ||||||
| #...#.#.#.....#.# |  | ||||||
| #.#.#.#.#.#####.# |  | ||||||
| #.#...#.#.#.....# |  | ||||||
| #.#.#####.#.###.# |  | ||||||
| #.#.#.......#...# |  | ||||||
| #.#.###.#####.### |  | ||||||
| #.#.#...#.....#.# |  | ||||||
| #.#.#.#####.###.# |  | ||||||
| #.#.#.........#.# |  | ||||||
| #.#.#.#########.# |  | ||||||
| #S#.............# |  | ||||||
| #################"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_1() { |  | ||||||
|         let result = process_part1(INPUT_1); |  | ||||||
|         assert_eq!(result, 7036); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_2() { |  | ||||||
|         let result = process_part1(INPUT_2); |  | ||||||
|         assert_eq!(result, 11048); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_1() { |  | ||||||
|         let result = process_part2(INPUT_1); |  | ||||||
|         assert_eq!(result, 45); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2_2() { |  | ||||||
|         let result = process_part2(INPUT_2); |  | ||||||
|         assert_eq!(result, 64); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,308 +0,0 @@ | |||||||
| use std::{collections::HashMap, error::Error}; |  | ||||||
|  |  | ||||||
| use itertools::Itertools; |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str) -> (String, HashMap<&str, u64>) { |  | ||||||
|     let (registers, program) = input.split_once("\n\n").unwrap(); |  | ||||||
|     let mut registers = parse_registers(registers); |  | ||||||
|     let (_, instructions) = program.split_once(": ").unwrap(); |  | ||||||
|     let mut out = Vec::new(); |  | ||||||
|     let instructions = instructions |  | ||||||
|         .lines() |  | ||||||
|         .map(|line| { |  | ||||||
|             line.split(",") |  | ||||||
|                 .collect_vec() |  | ||||||
|                 .chunks(2) |  | ||||||
|                 .map(|chunk| (chunk[0], chunk[1])) |  | ||||||
|                 .collect_vec() |  | ||||||
|         }) |  | ||||||
|         .collect_vec() |  | ||||||
|         .concat(); |  | ||||||
|  |  | ||||||
|     let mut instruction_pointer: u64 = 0; |  | ||||||
|  |  | ||||||
|     while let Some((opcode, operand)) = instructions.get(instruction_pointer as usize) { |  | ||||||
|         let opcode = OpCodes::try_from(*opcode).unwrap(); |  | ||||||
|         if let Some((output, skip)) = opcode.exec(operand, &mut registers) { |  | ||||||
|             if skip { |  | ||||||
|                 instruction_pointer = 0; |  | ||||||
|             } else { |  | ||||||
|                 out.push(output); |  | ||||||
|                 instruction_pointer += 1; |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             instruction_pointer += 1; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     (out.into_iter().join(","), registers) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str) -> u64 { |  | ||||||
|     let (registers, program) = input.split_once("\n\n").unwrap(); |  | ||||||
|     let mut registers = parse_registers(registers); |  | ||||||
|     let (_, instructions) = program.split_once(": ").unwrap(); |  | ||||||
|     let instructions = instructions |  | ||||||
|         .lines() |  | ||||||
|         .map(|line| { |  | ||||||
|             line.split(",") |  | ||||||
|                 .collect_vec() |  | ||||||
|                 .chunks(2) |  | ||||||
|                 .map(|chunk| (chunk[0], chunk[1])) |  | ||||||
|                 .collect_vec() |  | ||||||
|         }) |  | ||||||
|         .collect_vec() |  | ||||||
|         .concat(); |  | ||||||
|     let orig = instructions |  | ||||||
|         .iter() |  | ||||||
|         .map(|(opcode, operand)| { |  | ||||||
|             [ |  | ||||||
|                 opcode.parse::<u64>().unwrap(), |  | ||||||
|                 operand.parse::<u64>().unwrap(), |  | ||||||
|             ] |  | ||||||
|         }) |  | ||||||
|         .collect_vec() |  | ||||||
|         .concat(); |  | ||||||
|     let mut a = 0; |  | ||||||
|     for idx in 1..=orig.len() { |  | ||||||
|         let target = orig[orig.len() - idx..].to_vec(); |  | ||||||
|  |  | ||||||
|         let mut new_a = a << 3; |  | ||||||
|         loop { |  | ||||||
|             registers.insert("A", new_a); |  | ||||||
|             let out = exec_program(instructions.clone(), &mut registers); |  | ||||||
|             //println!("target {target:?}"); |  | ||||||
|             //println!("output {out:?}"); |  | ||||||
|             if out == target { |  | ||||||
|                 a = new_a; |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|             new_a += 1; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     a |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn exec_program(instructions: Vec<(&str, &str)>, registers: &mut HashMap<&str, u64>) -> Vec<u64> { |  | ||||||
|     let mut out = Vec::new(); |  | ||||||
|     let mut instruction_pointer: u64 = 0; |  | ||||||
|  |  | ||||||
|     while let Some((opcode, operand)) = instructions.get(instruction_pointer as usize) { |  | ||||||
|         let opcode = OpCodes::try_from(*opcode).unwrap(); |  | ||||||
|         if let Some((output, skip)) = opcode.exec(operand, registers) { |  | ||||||
|             if skip { |  | ||||||
|                 instruction_pointer = 0; |  | ||||||
|             } else { |  | ||||||
|                 out.push(output); |  | ||||||
|                 instruction_pointer += 1; |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             instruction_pointer += 1; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     out |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn parse_registers(input: &str) -> HashMap<&str, u64> { |  | ||||||
|     let mut registers = HashMap::new(); |  | ||||||
|     input.lines().for_each(|line| { |  | ||||||
|         let (register, value) = line.split_once(": ").unwrap(); |  | ||||||
|         let (_, register) = register.split_once(" ").unwrap(); |  | ||||||
|         let value = value.parse().unwrap(); |  | ||||||
|         registers.insert(register, value); |  | ||||||
|     }); |  | ||||||
|     registers |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug)] |  | ||||||
| enum OpCodes { |  | ||||||
|     Adv, |  | ||||||
|     Bxl, |  | ||||||
|     Bst, |  | ||||||
|     Jnz, |  | ||||||
|     Bxc, |  | ||||||
|     Out, |  | ||||||
|     Bdv, |  | ||||||
|     Cdv, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl OpCodes { |  | ||||||
|     fn exec(&self, operand: &str, registers: &mut HashMap<&str, u64>) -> Option<(u64, bool)> { |  | ||||||
|         let a = *registers.get("A").unwrap(); |  | ||||||
|         let b = *registers.get("B").unwrap(); |  | ||||||
|         let c = *registers.get("C").unwrap(); |  | ||||||
|         let operand: u64 = operand.parse().unwrap(); |  | ||||||
|         let combo = if operand <= 3 { |  | ||||||
|             operand |  | ||||||
|         } else if operand == 4 { |  | ||||||
|             a |  | ||||||
|         } else if operand == 5 { |  | ||||||
|             b |  | ||||||
|         } else if operand == 6 { |  | ||||||
|             c |  | ||||||
|         } else { |  | ||||||
|             0 |  | ||||||
|         }; |  | ||||||
|         match self { |  | ||||||
|             OpCodes::Adv => { |  | ||||||
|                 //println!( |  | ||||||
|                 //    "a = a / 2 ** combo = {a} / 2 ** {combo} = {}", |  | ||||||
|                 //    a / 2_u64.pow(combo) |  | ||||||
|                 //); |  | ||||||
|                 registers.insert("A", a / 2_u64.pow(combo as u32)); |  | ||||||
|                 None |  | ||||||
|             } |  | ||||||
|             OpCodes::Bxl => { |  | ||||||
|                 //println!("b = b xor operand = {b} xor {operand} = {}", b ^ operand); |  | ||||||
|                 registers.insert("B", b ^ operand); |  | ||||||
|                 None |  | ||||||
|             } |  | ||||||
|             OpCodes::Bst => { |  | ||||||
|                 //println!("b = combo mod 8 = {combo} mod 8 = {}", combo % 8); |  | ||||||
|                 registers.insert("B", combo % 8); |  | ||||||
|                 None |  | ||||||
|             } |  | ||||||
|             OpCodes::Jnz => { |  | ||||||
|                 if a != 0 { |  | ||||||
|                     //println!("jump {operand}"); |  | ||||||
|                     Some((operand, true)) |  | ||||||
|                 } else { |  | ||||||
|                     //println!("don't jump"); |  | ||||||
|                     None |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             OpCodes::Bxc => { |  | ||||||
|                 //println!("b = b xor c = {b} xor {c} = {}", b ^ c); |  | ||||||
|                 registers.insert("B", b ^ c); |  | ||||||
|                 None |  | ||||||
|             } |  | ||||||
|             OpCodes::Out => { |  | ||||||
|                 //println!("out {combo} % 8 = {}", combo % 8); |  | ||||||
|                 Some((combo % 8, false)) |  | ||||||
|             } |  | ||||||
|             OpCodes::Bdv => { |  | ||||||
|                 //println!( |  | ||||||
|                 //    "b = a / 2 ** combo = {a} / 2 ** {combo} = {}", |  | ||||||
|                 //    a / 2_u64.pow(combo) |  | ||||||
|                 //); |  | ||||||
|                 registers.insert("B", a / 2_u64.pow(combo as u32)); |  | ||||||
|                 None |  | ||||||
|             } |  | ||||||
|             OpCodes::Cdv => { |  | ||||||
|                 //println!( |  | ||||||
|                 //    "c = a / 2 ** combo = {a} / 2 ** {combo} = {}", |  | ||||||
|                 //    a / 2_u64.pow(combo) |  | ||||||
|                 //); |  | ||||||
|                 registers.insert("C", a / 2_u64.pow(combo as u32)); |  | ||||||
|                 None |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl TryFrom<&str> for OpCodes { |  | ||||||
|     type Error = Box<dyn Error>; |  | ||||||
|  |  | ||||||
|     fn try_from(value: &str) -> std::result::Result<OpCodes, Box<dyn Error>> { |  | ||||||
|         match value { |  | ||||||
|             "0" => Ok(Self::Adv), |  | ||||||
|             "1" => Ok(Self::Bxl), |  | ||||||
|             "2" => Ok(Self::Bst), |  | ||||||
|             "3" => Ok(Self::Jnz), |  | ||||||
|             "4" => Ok(Self::Bxc), |  | ||||||
|             "5" => Ok(Self::Out), |  | ||||||
|             "6" => Ok(Self::Bdv), |  | ||||||
|             "7" => Ok(Self::Cdv), |  | ||||||
|             _ => Err(Box::from(format!("{value} is not a valid OpCode"))), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT_MAIN: &str = "Register A: 729 |  | ||||||
| Register B: 0 |  | ||||||
| Register C: 0 |  | ||||||
|  |  | ||||||
| Program: 0,1,5,4,3,0"; |  | ||||||
|  |  | ||||||
|     const INPUT_SMALL_1: &str = "Register A: 0 |  | ||||||
| Register B: 0 |  | ||||||
| Register C: 9 |  | ||||||
|  |  | ||||||
| Program: 2,6"; |  | ||||||
|  |  | ||||||
|     const INPUT_SMALL_2: &str = "Register A: 10 |  | ||||||
| Register B: 0 |  | ||||||
| Register C: 0 |  | ||||||
|  |  | ||||||
| Program: 5,0,5,1,5,4"; |  | ||||||
|  |  | ||||||
|     const INPUT_SMALL_3: &str = "Register A: 2024 |  | ||||||
| Register B: 0 |  | ||||||
| Register C: 0 |  | ||||||
|  |  | ||||||
| Program: 0,1,5,4,3,0"; |  | ||||||
|  |  | ||||||
|     const INPUT_SMALL_4: &str = "Register A: 0 |  | ||||||
| Register B: 29 |  | ||||||
| Register C: 0 |  | ||||||
|  |  | ||||||
| Program: 1,7"; |  | ||||||
|  |  | ||||||
|     const INPUT_SMALL_5: &str = "Register A: 0 |  | ||||||
| Register B: 2024 |  | ||||||
| Register C: 43690 |  | ||||||
|  |  | ||||||
| Program: 4,0"; |  | ||||||
|  |  | ||||||
|     const INPUT_COPY: &str = "Register A: 2024 |  | ||||||
| Register B: 0 |  | ||||||
| Register C: 0 |  | ||||||
|  |  | ||||||
| Program: 0,3,5,4,3,0"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_main() { |  | ||||||
|         let result = process_part1(INPUT_MAIN); |  | ||||||
|         assert_eq!(result.0, "4,6,3,5,6,3,5,2,1,0".to_string()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_small_1() { |  | ||||||
|         let result = process_part1(INPUT_SMALL_1); |  | ||||||
|         assert_eq!(result.1.get("B").unwrap(), &1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_small_2() { |  | ||||||
|         let result = process_part1(INPUT_SMALL_2); |  | ||||||
|         assert_eq!(result.0, "0,1,2".to_string()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_small_3() { |  | ||||||
|         let result = process_part1(INPUT_SMALL_3); |  | ||||||
|         assert_eq!(result.1.get("A").unwrap(), &0); |  | ||||||
|         assert_eq!(result.0, "4,2,5,6,7,7,7,7,3,1,0".to_string()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_small_4() { |  | ||||||
|         let result = process_part1(INPUT_SMALL_4); |  | ||||||
|         assert_eq!(result.1.get("B").unwrap(), &26); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_small_5() { |  | ||||||
|         let result = process_part1(INPUT_SMALL_5); |  | ||||||
|         assert_eq!(result.1.get("B").unwrap(), &44354); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2() { |  | ||||||
|         let result = process_part2(INPUT_COPY); |  | ||||||
|         assert_eq!(result, 117440); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,294 +0,0 @@ | |||||||
| use std::{collections::HashSet, error::Error}; |  | ||||||
|  |  | ||||||
| use itertools::Itertools; |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str) -> u32 { |  | ||||||
|     let falling_bytes = &input |  | ||||||
|         .lines() |  | ||||||
|         .map(|line| { |  | ||||||
|             let (x, y) = line.split_once(",").unwrap(); |  | ||||||
|             (x.parse().unwrap(), y.parse().unwrap()) |  | ||||||
|         }) |  | ||||||
|         .collect_vec()[..1024]; |  | ||||||
|     let y_walls = vec![GridTile::Wall; 73]; |  | ||||||
|     let mut inner_rows = vec![GridTile::Path; 71]; |  | ||||||
|     inner_rows.insert(0, GridTile::Wall); |  | ||||||
|     inner_rows.push(GridTile::Wall); |  | ||||||
|     let mut grid = vec![inner_rows; 71]; |  | ||||||
|     grid.insert(0, y_walls.clone()); |  | ||||||
|     grid.push(y_walls); |  | ||||||
|     simulate(grid, falling_bytes).unwrap() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn simulate(mut grid: Vec<Vec<GridTile>>, falling_bytes: &[(usize, usize)]) -> Option<u32> { |  | ||||||
|     grid[1][1] = GridTile::Start; |  | ||||||
|     let height = grid.len(); |  | ||||||
|     let width = grid[0].len(); |  | ||||||
|     grid[height - 2][width - 2] = GridTile::End; |  | ||||||
|     falling_bytes.iter().for_each(|(x, y)| { |  | ||||||
|         grid[*y + 1][*x + 1] = GridTile::Wall; |  | ||||||
|     }); |  | ||||||
|     let mut visited = HashSet::new(); |  | ||||||
|     visited.insert((1, 1)); |  | ||||||
|     let mut next_paths = vec![MazeRunner { |  | ||||||
|         coords: (1, 1), |  | ||||||
|         visited: visited.clone(), |  | ||||||
|         ..Default::default() |  | ||||||
|     }]; |  | ||||||
|     let mut arrived: Vec<MazeRunner> = Vec::new(); |  | ||||||
|     while !next_paths.is_empty() { |  | ||||||
|         next_paths = next_paths |  | ||||||
|             .iter() |  | ||||||
|             .map(|maze_runner| { |  | ||||||
|                 let mut paths = Vec::new(); |  | ||||||
|                 if let Some(path) = maze_runner.get_next(&grid, Direction::Up) { |  | ||||||
|                     paths.push(path); |  | ||||||
|                 } |  | ||||||
|                 if let Some(path) = maze_runner.get_next(&grid, Direction::Down) { |  | ||||||
|                     paths.push(path); |  | ||||||
|                 } |  | ||||||
|                 if let Some(path) = maze_runner.get_next(&grid, Direction::Left) { |  | ||||||
|                     paths.push(path); |  | ||||||
|                 } |  | ||||||
|                 if let Some(path) = maze_runner.get_next(&grid, Direction::Right) { |  | ||||||
|                     paths.push(path); |  | ||||||
|                 } |  | ||||||
|                 paths |  | ||||||
|             }) |  | ||||||
|             .collect_vec() |  | ||||||
|             .concat(); |  | ||||||
|         for (idx, maze_runner) in next_paths.clone().iter().enumerate().rev() { |  | ||||||
|             if maze_runner.visited.contains(&maze_runner.coords) |  | ||||||
|                 || visited.contains(&maze_runner.coords) |  | ||||||
|             { |  | ||||||
|                 next_paths.remove(idx); |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|             visited.insert(maze_runner.coords); |  | ||||||
|             next_paths[idx].visited.insert(maze_runner.coords); |  | ||||||
|             if maze_runner.state == State::Arrived { |  | ||||||
|                 let arrived_reindeer = next_paths.remove(idx); |  | ||||||
|                 arrived.push(arrived_reindeer); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     //let visited = arrived |  | ||||||
|     //    .iter() |  | ||||||
|     //    .map(|reindeer| { |  | ||||||
|     //        reindeer |  | ||||||
|     //            .visited |  | ||||||
|     //            .iter() |  | ||||||
|     //            .map(|(coords, _)| coords) |  | ||||||
|     //            .collect_vec() |  | ||||||
|     //    }) |  | ||||||
|     //    .collect_vec() |  | ||||||
|     //    .concat(); |  | ||||||
|     //visited.iter().unique().count() |  | ||||||
|     arrived.sort_by(|a_runner, b_runner| a_runner.visited.len().cmp(&b_runner.visited.len())); |  | ||||||
|     if let Some(arrived) = arrived.first() { |  | ||||||
|         log_maze(&grid, arrived); |  | ||||||
|         Some(arrived.visited.len() as u32 - 1) |  | ||||||
|     } else { |  | ||||||
|         None |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str) -> String { |  | ||||||
|     let falling_bytes = &input |  | ||||||
|         .lines() |  | ||||||
|         .map(|line| { |  | ||||||
|             let (x, y) = line.split_once(",").unwrap(); |  | ||||||
|             (x.parse::<usize>().unwrap(), y.parse::<usize>().unwrap()) |  | ||||||
|         }) |  | ||||||
|         .collect_vec(); |  | ||||||
|     let y_walls = vec![GridTile::Wall; 73]; |  | ||||||
|     let mut inner_rows = vec![GridTile::Path; 71]; |  | ||||||
|     inner_rows.insert(0, GridTile::Wall); |  | ||||||
|     inner_rows.push(GridTile::Wall); |  | ||||||
|     let mut grid = vec![inner_rows; 71]; |  | ||||||
|     grid.insert(0, y_walls.clone()); |  | ||||||
|     grid.push(y_walls); |  | ||||||
|     let mut num_bytes = 1025; |  | ||||||
|     while simulate(grid.clone(), &falling_bytes[..num_bytes]).is_some() { |  | ||||||
|         num_bytes += 1; |  | ||||||
|     } |  | ||||||
|     let (x, y) = falling_bytes[num_bytes - 1]; |  | ||||||
|     format!("{x},{y}") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, PartialEq, Eq)] |  | ||||||
| enum Direction { |  | ||||||
|     Up, |  | ||||||
|     Down, |  | ||||||
|     Left, |  | ||||||
|     Right, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, PartialEq, Eq)] |  | ||||||
| enum State { |  | ||||||
|     #[default] |  | ||||||
|     Going, |  | ||||||
|     Arrived, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, PartialEq, Eq)] |  | ||||||
| struct MazeRunner { |  | ||||||
|     coords: (usize, usize), |  | ||||||
|     visited: HashSet<(usize, usize)>, |  | ||||||
|     state: State, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl MazeRunner { |  | ||||||
|     fn get_next(&self, grid: &[Vec<GridTile>], direction: Direction) -> Option<MazeRunner> { |  | ||||||
|         let tile = match direction { |  | ||||||
|             Direction::Up => grid[self.coords.1 - 1][self.coords.0], |  | ||||||
|             Direction::Down => grid[self.coords.1 + 1][self.coords.0], |  | ||||||
|             Direction::Right => grid[self.coords.1][self.coords.0 + 1], |  | ||||||
|             Direction::Left => grid[self.coords.1][self.coords.0 - 1], |  | ||||||
|         }; |  | ||||||
|         let coords = match direction { |  | ||||||
|             Direction::Up => (self.coords.0, self.coords.1 - 1), |  | ||||||
|             Direction::Down => (self.coords.0, self.coords.1 + 1), |  | ||||||
|             Direction::Left => (self.coords.0 - 1, self.coords.1), |  | ||||||
|             Direction::Right => (self.coords.0 + 1, self.coords.1), |  | ||||||
|         }; |  | ||||||
|         if tile == GridTile::Wall { |  | ||||||
|             None |  | ||||||
|         } else if tile == GridTile::End { |  | ||||||
|             Some(MazeRunner { |  | ||||||
|                 state: State::Arrived, |  | ||||||
|                 coords, |  | ||||||
|                 ..self.clone() |  | ||||||
|             }) |  | ||||||
|         } else { |  | ||||||
|             Some(MazeRunner { |  | ||||||
|                 coords, |  | ||||||
|                 ..self.clone() |  | ||||||
|             }) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)] |  | ||||||
| enum GridTile { |  | ||||||
|     Wall, |  | ||||||
|     #[default] |  | ||||||
|     Path, |  | ||||||
|     Start, |  | ||||||
|     End, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl TryFrom<char> for GridTile { |  | ||||||
|     type Error = Box<dyn Error>; |  | ||||||
|  |  | ||||||
|     fn try_from(value: char) -> std::result::Result<GridTile, Box<dyn Error>> { |  | ||||||
|         match value { |  | ||||||
|             '#' => Ok(Self::Wall), |  | ||||||
|             '.' => Ok(Self::Path), |  | ||||||
|             'S' => Ok(Self::Start), |  | ||||||
|             'E' => Ok(Self::End), |  | ||||||
|             _ => Err(Box::from(format!("{value} is not a valid tile"))), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn log_maze(grid: &[Vec<GridTile>], maze_runner: &MazeRunner) { |  | ||||||
|     for (yidx, row) in grid.iter().enumerate() { |  | ||||||
|         for (xidx, tile) in row.iter().enumerate() { |  | ||||||
|             let contains = { |  | ||||||
|                 maze_runner.visited.contains(&(xidx, yidx)) |  | ||||||
|                     || maze_runner.visited.contains(&(xidx, yidx)) |  | ||||||
|                     || maze_runner.visited.contains(&(xidx, yidx)) |  | ||||||
|                     || maze_runner.visited.contains(&(xidx, yidx)) |  | ||||||
|             }; |  | ||||||
|             if contains && !(*tile == GridTile::Start || *tile == GridTile::End) { |  | ||||||
|                 print!("O"); |  | ||||||
|             } else if *tile == GridTile::Wall { |  | ||||||
|                 print!("#"); |  | ||||||
|             } else if *tile == GridTile::Path { |  | ||||||
|                 print!("."); |  | ||||||
|             } else if *tile == GridTile::Start { |  | ||||||
|                 print!("S"); |  | ||||||
|             } else if *tile == GridTile::End { |  | ||||||
|                 print!("E"); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         println!(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT: &str = "5,4 |  | ||||||
| 4,2 |  | ||||||
| 4,5 |  | ||||||
| 3,0 |  | ||||||
| 2,1 |  | ||||||
| 6,3 |  | ||||||
| 2,4 |  | ||||||
| 1,5 |  | ||||||
| 0,6 |  | ||||||
| 3,3 |  | ||||||
| 2,6 |  | ||||||
| 5,1 |  | ||||||
| 1,2 |  | ||||||
| 5,5 |  | ||||||
| 2,5 |  | ||||||
| 6,5 |  | ||||||
| 1,4 |  | ||||||
| 0,4 |  | ||||||
| 6,4 |  | ||||||
| 1,1 |  | ||||||
| 6,1 |  | ||||||
| 1,0 |  | ||||||
| 0,5 |  | ||||||
| 1,6 |  | ||||||
| 2,0"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1() { |  | ||||||
|         let falling_bytes = &INPUT |  | ||||||
|             .lines() |  | ||||||
|             .map(|line| { |  | ||||||
|                 let (x, y) = line.split_once(",").unwrap(); |  | ||||||
|                 (x.parse().unwrap(), y.parse().unwrap()) |  | ||||||
|             }) |  | ||||||
|             .collect_vec()[..12]; |  | ||||||
|         let y_walls = vec![GridTile::Wall; 9]; |  | ||||||
|         let mut inner_rows = vec![GridTile::Path; 7]; |  | ||||||
|         inner_rows.insert(0, GridTile::Wall); |  | ||||||
|         inner_rows.push(GridTile::Wall); |  | ||||||
|         let mut grid = vec![inner_rows; 7]; |  | ||||||
|         grid.insert(0, y_walls.clone()); |  | ||||||
|         grid.push(y_walls); |  | ||||||
|         let result = simulate(grid, falling_bytes); |  | ||||||
|         assert_eq!(result, Some(22)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2() { |  | ||||||
|         let falling_bytes = INPUT |  | ||||||
|             .lines() |  | ||||||
|             .map(|line| { |  | ||||||
|                 let (x, y) = line.split_once(",").unwrap(); |  | ||||||
|                 (x.parse::<usize>().unwrap(), y.parse::<usize>().unwrap()) |  | ||||||
|             }) |  | ||||||
|             .collect_vec(); |  | ||||||
|         let y_walls = vec![GridTile::Wall; 9]; |  | ||||||
|         let mut inner_rows = vec![GridTile::Path; 7]; |  | ||||||
|         inner_rows.insert(0, GridTile::Wall); |  | ||||||
|         inner_rows.push(GridTile::Wall); |  | ||||||
|         let mut grid = vec![inner_rows; 7]; |  | ||||||
|         grid.insert(0, y_walls.clone()); |  | ||||||
|         grid.push(y_walls); |  | ||||||
|         let mut num_bytes = 12; |  | ||||||
|         while simulate(grid.clone(), &falling_bytes[..num_bytes]).is_some() { |  | ||||||
|             num_bytes += 1; |  | ||||||
|         } |  | ||||||
|         let (x, y) = falling_bytes[num_bytes - 1]; |  | ||||||
|         let result = format!("{x},{y}"); |  | ||||||
|         assert_eq!(result, "6,1".to_string()); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,96 +0,0 @@ | |||||||
| use std::collections::HashMap; |  | ||||||
|  |  | ||||||
| use itertools::Itertools; |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str) -> u64 { |  | ||||||
|     let (patterns, designs) = input.split_once("\n\n").unwrap(); |  | ||||||
|     let patterns = patterns.split(", ").collect_vec(); |  | ||||||
|     designs |  | ||||||
|         .lines() |  | ||||||
|         .map(|design| { |  | ||||||
|             if possible_design(design, &patterns) { |  | ||||||
|                 1 |  | ||||||
|             } else { |  | ||||||
|                 0 |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|         .sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn possible_design(design: &str, patterns: &[&str]) -> bool { |  | ||||||
|     for pattern in patterns { |  | ||||||
|         if design.starts_with(pattern) && design.len() == pattern.len() { |  | ||||||
|             return true; |  | ||||||
|         } else if design.starts_with(pattern) { |  | ||||||
|             if let Some(stripped) = design.strip_prefix(pattern) { |  | ||||||
|                 if possible_design(stripped, patterns) { |  | ||||||
|                     return true; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn possible_designs(design: &str, patterns: &[&str], memo: &mut HashMap<String, u64>) -> u64 { |  | ||||||
|     if design.is_empty() { |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
|     let mut num_possible_designs = 0; |  | ||||||
|     if let Some(count) = memo.get(design) { |  | ||||||
|         return *count; |  | ||||||
|     } |  | ||||||
|     for pattern in patterns { |  | ||||||
|         if design == *pattern { |  | ||||||
|             memo.insert(design.to_string(), 1); |  | ||||||
|             num_possible_designs += 1; |  | ||||||
|         } |  | ||||||
|         if design.starts_with(pattern) { |  | ||||||
|             if let Some(stripped) = design.strip_prefix(pattern) { |  | ||||||
|                 let for_stripped = possible_designs(stripped, patterns, memo); |  | ||||||
|                 memo.entry(stripped.to_string()).or_insert(for_stripped); |  | ||||||
|                 num_possible_designs += for_stripped; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     memo.insert(design.to_string(), num_possible_designs); |  | ||||||
|     num_possible_designs |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str) -> u64 { |  | ||||||
|     let (patterns, designs) = input.split_once("\n\n").unwrap(); |  | ||||||
|     let patterns = patterns.split(", ").collect_vec(); |  | ||||||
|     let mut memo = HashMap::new(); |  | ||||||
|     designs |  | ||||||
|         .lines() |  | ||||||
|         .map(|design| possible_designs(design, &patterns, &mut memo)) |  | ||||||
|         .sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT: &str = "r, wr, b, g, bwu, rb, gb, br |  | ||||||
|  |  | ||||||
| brwrr |  | ||||||
| bggr |  | ||||||
| gbbr |  | ||||||
| rrbgbr |  | ||||||
| ubwu |  | ||||||
| bwurrg |  | ||||||
| brgr |  | ||||||
| bbrgwb"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1() { |  | ||||||
|         let result = process_part1(INPUT); |  | ||||||
|         assert_eq!(result, 6); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2() { |  | ||||||
|         let result = process_part2(INPUT); |  | ||||||
|         assert_eq!(result, 16); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,232 +0,0 @@ | |||||||
| use std::{ |  | ||||||
|     collections::{HashMap, HashSet}, |  | ||||||
|     error::Error, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| use itertools::Itertools; |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str) -> u32 { |  | ||||||
|     simulate_all(input, 100, 2).values().copied().sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str) -> u32 { |  | ||||||
|     simulate_all(input, 100, 20).values().copied().sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn simulate_all(input: &str, time_to_save: usize, max_cheat_time: usize) -> HashMap<u32, u32> { |  | ||||||
|     let mut start = (0, 0); |  | ||||||
|     let grid = input |  | ||||||
|         .lines() |  | ||||||
|         .enumerate() |  | ||||||
|         .map(|(yidx, row)| { |  | ||||||
|             row.chars() |  | ||||||
|                 .enumerate() |  | ||||||
|                 .map(|(xidx, chara)| { |  | ||||||
|                     let tile = GridTile::try_from(chara).unwrap(); |  | ||||||
|                     if tile == GridTile::Start { |  | ||||||
|                         start = (xidx, yidx); |  | ||||||
|                     } |  | ||||||
|                     tile |  | ||||||
|                 }) |  | ||||||
|                 .collect_vec() |  | ||||||
|         }) |  | ||||||
|         .collect_vec(); |  | ||||||
|     let no_cheat = simulate(&grid, start); |  | ||||||
|     let mut saved = HashMap::new(); |  | ||||||
|     for (tile_idx, tile) in no_cheat[..no_cheat.len() - time_to_save].iter().enumerate() { |  | ||||||
|         for (cheat_idx, cheat) in no_cheat[tile_idx..].iter().enumerate() { |  | ||||||
|             let manhattan = tile.0.abs_diff(cheat.0) + tile.1.abs_diff(cheat.1); |  | ||||||
|             if manhattan <= max_cheat_time { |  | ||||||
|                 let time_saved = cheat_idx - manhattan; |  | ||||||
|                 if time_saved >= time_to_save { |  | ||||||
|                     saved |  | ||||||
|                         .entry(time_saved as u32) |  | ||||||
|                         .and_modify(|count| *count += 1) |  | ||||||
|                         .or_insert(1); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     saved |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn simulate(grid: &[Vec<GridTile>], start: (usize, usize)) -> Vec<(usize, usize)> { |  | ||||||
|     let mut visited = HashSet::new(); |  | ||||||
|     visited.insert(start); |  | ||||||
|     let mut next_paths = vec![MazeRunner { |  | ||||||
|         coords: start, |  | ||||||
|         visited: visited.clone(), |  | ||||||
|         ..Default::default() |  | ||||||
|     }]; |  | ||||||
|     let mut visited = Vec::new(); |  | ||||||
|     visited.push(start); |  | ||||||
|     let mut arrived: Vec<MazeRunner> = Vec::new(); |  | ||||||
|     while !next_paths.is_empty() { |  | ||||||
|         next_paths = next_paths |  | ||||||
|             .iter() |  | ||||||
|             .map(|maze_runner| { |  | ||||||
|                 let mut paths = Vec::new(); |  | ||||||
|                 if let Some(path) = maze_runner.get_next(grid, Direction::Up) { |  | ||||||
|                     paths.push(path); |  | ||||||
|                 } |  | ||||||
|                 if let Some(path) = maze_runner.get_next(grid, Direction::Down) { |  | ||||||
|                     paths.push(path); |  | ||||||
|                 } |  | ||||||
|                 if let Some(path) = maze_runner.get_next(grid, Direction::Left) { |  | ||||||
|                     paths.push(path); |  | ||||||
|                 } |  | ||||||
|                 if let Some(path) = maze_runner.get_next(grid, Direction::Right) { |  | ||||||
|                     paths.push(path); |  | ||||||
|                 } |  | ||||||
|                 paths |  | ||||||
|             }) |  | ||||||
|             .collect_vec() |  | ||||||
|             .concat(); |  | ||||||
|         for (idx, maze_runner) in next_paths.clone().iter().enumerate().rev() { |  | ||||||
|             if maze_runner.visited.contains(&maze_runner.coords) |  | ||||||
|                 || visited.contains(&maze_runner.coords) |  | ||||||
|             { |  | ||||||
|                 next_paths.remove(idx); |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|             visited.push(maze_runner.coords); |  | ||||||
|             next_paths[idx].visited.insert(maze_runner.coords); |  | ||||||
|             if maze_runner.state == State::Arrived { |  | ||||||
|                 let arrived_reindeer = next_paths.remove(idx); |  | ||||||
|                 arrived.push(arrived_reindeer); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     visited |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, PartialEq, Eq)] |  | ||||||
| enum Direction { |  | ||||||
|     Up, |  | ||||||
|     Down, |  | ||||||
|     Left, |  | ||||||
|     Right, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, PartialEq, Eq)] |  | ||||||
| enum State { |  | ||||||
|     #[default] |  | ||||||
|     Going, |  | ||||||
|     Arrived, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, PartialEq, Eq)] |  | ||||||
| struct MazeRunner { |  | ||||||
|     coords: (usize, usize), |  | ||||||
|     visited: HashSet<(usize, usize)>, |  | ||||||
|     state: State, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl MazeRunner { |  | ||||||
|     fn get_next(&self, grid: &[Vec<GridTile>], direction: Direction) -> Option<MazeRunner> { |  | ||||||
|         let tile = match direction { |  | ||||||
|             Direction::Up => grid[self.coords.1 - 1][self.coords.0], |  | ||||||
|             Direction::Down => grid[self.coords.1 + 1][self.coords.0], |  | ||||||
|             Direction::Right => grid[self.coords.1][self.coords.0 + 1], |  | ||||||
|             Direction::Left => grid[self.coords.1][self.coords.0 - 1], |  | ||||||
|         }; |  | ||||||
|         let coords = match direction { |  | ||||||
|             Direction::Up => (self.coords.0, self.coords.1 - 1), |  | ||||||
|             Direction::Down => (self.coords.0, self.coords.1 + 1), |  | ||||||
|             Direction::Left => (self.coords.0 - 1, self.coords.1), |  | ||||||
|             Direction::Right => (self.coords.0 + 1, self.coords.1), |  | ||||||
|         }; |  | ||||||
|         if tile == GridTile::Wall { |  | ||||||
|             None |  | ||||||
|         } else if tile == GridTile::End { |  | ||||||
|             Some(MazeRunner { |  | ||||||
|                 state: State::Arrived, |  | ||||||
|                 coords, |  | ||||||
|                 ..self.clone() |  | ||||||
|             }) |  | ||||||
|         } else { |  | ||||||
|             Some(MazeRunner { |  | ||||||
|                 coords, |  | ||||||
|                 ..self.clone() |  | ||||||
|             }) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)] |  | ||||||
| enum GridTile { |  | ||||||
|     Wall, |  | ||||||
|     #[default] |  | ||||||
|     Path, |  | ||||||
|     Start, |  | ||||||
|     End, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl TryFrom<char> for GridTile { |  | ||||||
|     type Error = Box<dyn Error>; |  | ||||||
|  |  | ||||||
|     fn try_from(value: char) -> std::result::Result<GridTile, Box<dyn Error>> { |  | ||||||
|         match value { |  | ||||||
|             '#' => Ok(Self::Wall), |  | ||||||
|             '.' => Ok(Self::Path), |  | ||||||
|             'S' => Ok(Self::Start), |  | ||||||
|             'E' => Ok(Self::End), |  | ||||||
|             _ => Err(Box::from(format!("{value} is not a valid tile"))), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use std::time::Instant; |  | ||||||
|  |  | ||||||
|     use utils::time::get_elapsed_string; |  | ||||||
|  |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT: &str = "############### |  | ||||||
| #...#...#.....# |  | ||||||
| #.#.#.#.#.###.# |  | ||||||
| #S#...#.#.#...# |  | ||||||
| #######.#.#.### |  | ||||||
| #######.#.#...# |  | ||||||
| #######.#.###.# |  | ||||||
| ###..E#...#...# |  | ||||||
| ###.#######.### |  | ||||||
| #...###...#...# |  | ||||||
| #.#####.#.###.# |  | ||||||
| #.#...#.#.#...# |  | ||||||
| #.#.#.#.#.#.### |  | ||||||
| #...#...#...### |  | ||||||
| ###############"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1() { |  | ||||||
|         let now = Instant::now(); |  | ||||||
|         println!("Test 2:"); |  | ||||||
|         let result = simulate_all(INPUT, 2, 2); |  | ||||||
|         result |  | ||||||
|             .iter() |  | ||||||
|             .sorted_by(|a, b| a.0.cmp(b.0)) |  | ||||||
|             .for_each(|(saved, count)| { |  | ||||||
|                 println!("There are {count} cheats that saved {saved} picoseconds"); |  | ||||||
|             }); |  | ||||||
|         println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|         assert_eq!(result.values().copied().sum::<u32>(), 44); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2() { |  | ||||||
|         let now = Instant::now(); |  | ||||||
|         println!("Test 2:"); |  | ||||||
|         let result = simulate_all(INPUT, 50, 20); |  | ||||||
|         result |  | ||||||
|             .iter() |  | ||||||
|             .sorted_by(|a, b| a.0.cmp(b.0)) |  | ||||||
|             .for_each(|(saved, count)| { |  | ||||||
|                 println!("There are {count} cheats that saved {saved} picoseconds"); |  | ||||||
|             }); |  | ||||||
|         println!("Ran in {}", get_elapsed_string(now.elapsed())); |  | ||||||
|         assert_eq!(result.values().copied().sum::<u32>(), 285); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,344 +0,0 @@ | |||||||
| use std::{char, collections::HashMap, error::Error, sync::mpsc}; |  | ||||||
|  |  | ||||||
| use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; |  | ||||||
|  |  | ||||||
| pub fn process_part1(input: &str) -> usize { |  | ||||||
|     let mut memo = HashMap::new(); |  | ||||||
|     input |  | ||||||
|         .lines() |  | ||||||
|         .map(|line| { |  | ||||||
|             let numpad = Numpad::from(line); |  | ||||||
|             println!("first robot {}", numpad.sequence); |  | ||||||
|             let _ = Numpad::revert_from(&numpad.sequence); |  | ||||||
|             let keypad_1 = Keypad::from(numpad.sequence.as_str()); |  | ||||||
|             println!("second robot {}", keypad_1.sequence); |  | ||||||
|             let _ = Keypad::revert_from(&keypad_1.sequence); |  | ||||||
|             let keypad_2 = Keypad::from(keypad_1.sequence.as_str()); |  | ||||||
|             println!("me {}", keypad_2.sequence); |  | ||||||
|             let _ = Keypad::revert_from(&keypad_2.sequence); |  | ||||||
|             keypad_2.sequence.len() * numeric_part(line) |  | ||||||
|         }) |  | ||||||
|         .sum() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn extend_sequence( |  | ||||||
|     sequence_parts: &[Vec<String>], |  | ||||||
|     memo: &mut HashMap<(char, char), Vec<String>>, |  | ||||||
| ) -> Vec<Vec<String>> { |  | ||||||
|     sequence_parts.iter().map(|possible_parts| { |  | ||||||
|         let (tx, rx) = mpsc::channel(); |  | ||||||
|         let mut new_possible_parts = Vec::new(); |  | ||||||
|         possible_parts.par_iter().for_each(|part| { |  | ||||||
|             let _ = tx.send(); |  | ||||||
|         }); |  | ||||||
|         drop(tx); |  | ||||||
|         while let Ok(part) = rx.recv() { |  | ||||||
|             new_possible_parts.extend_from_slice(part); |  | ||||||
|         } |  | ||||||
|         new_possible_parts |  | ||||||
|     }) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub fn process_part2(input: &str) -> usize { |  | ||||||
|     0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn numeric_part(code: &str) -> usize { |  | ||||||
|     let code = &code[..code.len() - 1]; |  | ||||||
|     code.parse().unwrap() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, Copy)] |  | ||||||
| enum NumpadState { |  | ||||||
|     Seven, |  | ||||||
|     Eight, |  | ||||||
|     Nine, |  | ||||||
|     Four, |  | ||||||
|     Five, |  | ||||||
|     Six, |  | ||||||
|     One, |  | ||||||
|     Two, |  | ||||||
|     Three, |  | ||||||
|     Zero, |  | ||||||
|     A, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl NumpadState { |  | ||||||
|     fn get_col(&self) -> i32 { |  | ||||||
|         match self { |  | ||||||
|             NumpadState::Seven | NumpadState::Four | NumpadState::One => 0, |  | ||||||
|             NumpadState::Eight | NumpadState::Five | NumpadState::Two | NumpadState::Zero => 1, |  | ||||||
|             NumpadState::Nine | NumpadState::Six | NumpadState::Three | NumpadState::A => 2, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn get_row(&self) -> i32 { |  | ||||||
|         match self { |  | ||||||
|             NumpadState::Seven | NumpadState::Eight | NumpadState::Nine => 0, |  | ||||||
|             NumpadState::Four | NumpadState::Five | NumpadState::Six => 1, |  | ||||||
|             NumpadState::One | NumpadState::Two | NumpadState::Three => 2, |  | ||||||
|             NumpadState::Zero | NumpadState::A => 3, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn get_sequences(&self, goto: NumpadState) -> Vec<String> { |  | ||||||
|         let row = self.get_row(); |  | ||||||
|         let col = self.get_col(); |  | ||||||
|         let goto_row = goto.get_row(); |  | ||||||
|         let goto_col = goto.get_col(); |  | ||||||
|         if row == goto_row && col == goto_col { |  | ||||||
|             return vec!["A".to_string()]; |  | ||||||
|         } |  | ||||||
|         let row_diff = row.abs_diff(goto_row); |  | ||||||
|         let col_diff = col.abs_diff(goto_col); |  | ||||||
|         let mut sequence = String::new(); |  | ||||||
|         let row_seq = match goto_row.cmp(&row) { |  | ||||||
|             std::cmp::Ordering::Less => vec!["^"; row_diff as usize].join(""), |  | ||||||
|             std::cmp::Ordering::Equal => "".to_string(), |  | ||||||
|             std::cmp::Ordering::Greater => vec!["v"; row_diff as usize].join(""), |  | ||||||
|         }; |  | ||||||
|         let col_seq = match goto_col.cmp(&col) { |  | ||||||
|             std::cmp::Ordering::Less => vec!["<"; col_diff as usize].join(""), |  | ||||||
|             std::cmp::Ordering::Equal => "".to_string(), |  | ||||||
|             std::cmp::Ordering::Greater => vec![">"; col_diff as usize].join(""), |  | ||||||
|         }; |  | ||||||
|         if (goto_col < col && row < 3) || col == 0 { |  | ||||||
|             sequence.push_str(&col_seq); |  | ||||||
|             sequence.push_str(&row_seq); |  | ||||||
|         } else { |  | ||||||
|             sequence.push_str(&row_seq); |  | ||||||
|             sequence.push_str(&col_seq); |  | ||||||
|         } |  | ||||||
|         sequence.push('A'); |  | ||||||
|         sequence |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl TryFrom<char> for NumpadState { |  | ||||||
|     type Error = Box<dyn Error>; |  | ||||||
|  |  | ||||||
|     fn try_from(value: char) -> Result<Self, Self::Error> { |  | ||||||
|         match value { |  | ||||||
|             'A' => Ok(NumpadState::A), |  | ||||||
|             '0' => Ok(NumpadState::Zero), |  | ||||||
|             '1' => Ok(NumpadState::One), |  | ||||||
|             '2' => Ok(NumpadState::Two), |  | ||||||
|             '3' => Ok(NumpadState::Three), |  | ||||||
|             '4' => Ok(NumpadState::Four), |  | ||||||
|             '5' => Ok(NumpadState::Five), |  | ||||||
|             '6' => Ok(NumpadState::Six), |  | ||||||
|             '7' => Ok(NumpadState::Seven), |  | ||||||
|             '8' => Ok(NumpadState::Eight), |  | ||||||
|             '9' => Ok(NumpadState::Nine), |  | ||||||
|             _ => Err(Box::from("Unrecognised keystate")), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl TryFrom<(usize, usize)> for NumpadState { |  | ||||||
|     type Error = Box<dyn Error>; |  | ||||||
|  |  | ||||||
|     fn try_from(value: (usize, usize)) -> Result<Self, Self::Error> { |  | ||||||
|         match value { |  | ||||||
|             (2, 3) => Ok(NumpadState::A), |  | ||||||
|             (1, 3) => Ok(NumpadState::Zero), |  | ||||||
|             (0, 2) => Ok(NumpadState::One), |  | ||||||
|             (1, 2) => Ok(NumpadState::Two), |  | ||||||
|             (2, 2) => Ok(NumpadState::Three), |  | ||||||
|             (0, 1) => Ok(NumpadState::Four), |  | ||||||
|             (1, 1) => Ok(NumpadState::Five), |  | ||||||
|             (2, 1) => Ok(NumpadState::Six), |  | ||||||
|             (0, 0) => Ok(NumpadState::Seven), |  | ||||||
|             (1, 0) => Ok(NumpadState::Eight), |  | ||||||
|             (2, 0) => Ok(NumpadState::Nine), |  | ||||||
|             (0, 3) => Err(Box::from("Robot arm hovering over numpad gap")), |  | ||||||
|             (x, y) => { |  | ||||||
|                 let err = format!("Unrecognised numpad key coord ({x}, {y})"); |  | ||||||
|                 Err(err.into()) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl From<NumpadState> for char { |  | ||||||
|     fn from(value: NumpadState) -> Self { |  | ||||||
|         match value { |  | ||||||
|             NumpadState::Seven => '7', |  | ||||||
|             NumpadState::Eight => '8', |  | ||||||
|             NumpadState::Nine => '9', |  | ||||||
|             NumpadState::Four => '4', |  | ||||||
|             NumpadState::Five => '5', |  | ||||||
|             NumpadState::Six => '6', |  | ||||||
|             NumpadState::One => '1', |  | ||||||
|             NumpadState::Two => '2', |  | ||||||
|             NumpadState::Three => '3', |  | ||||||
|             NumpadState::Zero => '0', |  | ||||||
|             NumpadState::A => 'A', |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, Copy)] |  | ||||||
| enum KeypadState { |  | ||||||
|     Up, |  | ||||||
|     A, |  | ||||||
|     Left, |  | ||||||
|     Down, |  | ||||||
|     Right, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl KeypadState { |  | ||||||
|     fn get_col(&self) -> i32 { |  | ||||||
|         match self { |  | ||||||
|             KeypadState::Left => 0, |  | ||||||
|             KeypadState::Up | KeypadState::Down => 1, |  | ||||||
|             KeypadState::A | KeypadState::Right => 2, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn get_row(&self) -> i32 { |  | ||||||
|         match self { |  | ||||||
|             KeypadState::Up | KeypadState::A => 0, |  | ||||||
|             KeypadState::Left | KeypadState::Down | KeypadState::Right => 1, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn get_sequence(&self, goto: KeypadState) -> Vec<String> { |  | ||||||
|         let row = self.get_row(); |  | ||||||
|         let col = self.get_col(); |  | ||||||
|         let goto_row = goto.get_row(); |  | ||||||
|         let goto_col = goto.get_col(); |  | ||||||
|         if row == goto_row && col == goto_col { |  | ||||||
|             return vec!["A".to_string()]; |  | ||||||
|         } |  | ||||||
|         let row_diff = row.abs_diff(goto_row); |  | ||||||
|         let col_diff = col.abs_diff(goto_col); |  | ||||||
|         let mut sequence = String::new(); |  | ||||||
|         let row_seq = match goto_row.cmp(&row) { |  | ||||||
|             std::cmp::Ordering::Less => vec!["^"; row_diff as usize].join(""), |  | ||||||
|             std::cmp::Ordering::Equal => "".to_string(), |  | ||||||
|             std::cmp::Ordering::Greater => vec!["v"; row_diff as usize].join(""), |  | ||||||
|         }; |  | ||||||
|         let col_seq = match goto_col.cmp(&col) { |  | ||||||
|             std::cmp::Ordering::Less => vec!["<"; col_diff as usize].join(""), |  | ||||||
|             std::cmp::Ordering::Equal => "".to_string(), |  | ||||||
|             std::cmp::Ordering::Greater => vec![">"; col_diff as usize].join(""), |  | ||||||
|         }; |  | ||||||
|         if (goto_col < col && row == 1) || col == 0 { |  | ||||||
|             sequence.push_str(&col_seq); |  | ||||||
|             sequence.push_str(&row_seq); |  | ||||||
|         } else { |  | ||||||
|             sequence.push_str(&row_seq); |  | ||||||
|             sequence.push_str(&col_seq); |  | ||||||
|         } |  | ||||||
|         sequence.push('A'); |  | ||||||
|         sequence |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl TryFrom<char> for KeypadState { |  | ||||||
|     type Error = Box<dyn Error>; |  | ||||||
|  |  | ||||||
|     fn try_from(value: char) -> Result<Self, Self::Error> { |  | ||||||
|         match value { |  | ||||||
|             'A' => Ok(KeypadState::A), |  | ||||||
|             '<' => Ok(KeypadState::Left), |  | ||||||
|             '>' => Ok(KeypadState::Right), |  | ||||||
|             'v' => Ok(KeypadState::Down), |  | ||||||
|             '^' => Ok(KeypadState::Up), |  | ||||||
|             _ => Err(Box::from("Unrecognised keystate")), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl TryFrom<(usize, usize)> for KeypadState { |  | ||||||
|     type Error = Box<dyn Error>; |  | ||||||
|  |  | ||||||
|     fn try_from(value: (usize, usize)) -> Result<Self, Self::Error> { |  | ||||||
|         match value { |  | ||||||
|             (2, 0) => Ok(KeypadState::A), |  | ||||||
|             (0, 1) => Ok(KeypadState::Left), |  | ||||||
|             (2, 1) => Ok(KeypadState::Right), |  | ||||||
|             (1, 1) => Ok(KeypadState::Down), |  | ||||||
|             (1, 0) => Ok(KeypadState::Up), |  | ||||||
|             (0, 0) => Err(Box::from("Robot arm hovering over keypad gap")), |  | ||||||
|             (x, y) => { |  | ||||||
|                 let err = format!("Unrecognised key coord ({x}, {y})"); |  | ||||||
|                 Err(err.into()) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl From<KeypadState> for char { |  | ||||||
|     fn from(value: KeypadState) -> Self { |  | ||||||
|         match value { |  | ||||||
|             KeypadState::A => 'A', |  | ||||||
|             KeypadState::Up => '^', |  | ||||||
|             KeypadState::Left => '<', |  | ||||||
|             KeypadState::Down => 'v', |  | ||||||
|             KeypadState::Right => '>', |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use super::*; |  | ||||||
|  |  | ||||||
|     const INPUT_1: &str = "029A"; |  | ||||||
|     const INPUT_2: &str = "980A"; |  | ||||||
|     const INPUT_3: &str = "179A"; |  | ||||||
|     const INPUT_4: &str = "456A"; |  | ||||||
|     const INPUT_5: &str = "379A"; |  | ||||||
|  |  | ||||||
|     const INPUT_1_BACK: &str = |  | ||||||
|         "<vA<AA>>^AvAA<^A>A<v<A>>^AvA^A<vA>^A<v<A>^A>AAvA^A<v<A>A>^AAAvA<^A>A"; |  | ||||||
|     const INPUT_2_BACK: &str = "<v<A>>^AAAvA^A<vA<AA>>^AvAA<^A>A<v<A>A>^AAAvA<^A>A<vA>^A<A>A"; |  | ||||||
|     const INPUT_3_BACK: &str = |  | ||||||
|         "<v<A>>^A<vA<A>>^AAvAA<^A>A<v<A>>^AAvA^A<vA>^AA<A>A<v<A>A>^AAAvA<^A>A"; |  | ||||||
|     const INPUT_4_BACK: &str = "<v<A>>^AA<vA<A>>^AAvAA<^A>A<vA>^A<A>A<vA>^A<A>A<v<A>A>^AAvA<^A>A"; |  | ||||||
|     const INPUT_5_BACK: &str = "<v<A>>^AvA^A<vA<AA>>^AAvA<^A>AAvA^A<vA>^AA<A>A<v<A>A>^AAAvA<^A>A"; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_full() { |  | ||||||
|         let result = process_part1(&[INPUT_1, INPUT_2, INPUT_3, INPUT_4, INPUT_5].join("\n")); |  | ||||||
|         assert_eq!(result, 126384); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_1() { |  | ||||||
|         let result = process_part1(INPUT_1); |  | ||||||
|         assert_eq!(result, 29 * 68); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_2() { |  | ||||||
|         let result = process_part1(INPUT_2); |  | ||||||
|         assert_eq!(result, 60 * 980); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_3() { |  | ||||||
|         let result = process_part1(INPUT_3); |  | ||||||
|         assert_eq!(result, 68 * 179); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_4() { |  | ||||||
|         let result = process_part1(INPUT_4); |  | ||||||
|         assert_eq!(result, 64 * 456); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part1_5() { |  | ||||||
|         let result = process_part1(INPUT_5); |  | ||||||
|         assert_eq!(result, 64 * 379); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn part2() { |  | ||||||
|         let result = process_part2(INPUT_1); |  | ||||||
|         assert_eq!(result, 0); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -9,25 +9,3 @@ pub mod d8; | |||||||
| pub mod d9; | pub mod d9; | ||||||
|  |  | ||||||
| pub mod d10; | pub mod d10; | ||||||
|  |  | ||||||
| pub mod d11; |  | ||||||
|  |  | ||||||
| pub mod d12; |  | ||||||
|  |  | ||||||
| pub mod d13; |  | ||||||
|  |  | ||||||
| pub mod d14; |  | ||||||
|  |  | ||||||
| pub mod d15; |  | ||||||
|  |  | ||||||
| pub mod d16; |  | ||||||
|  |  | ||||||
| pub mod d17; |  | ||||||
|  |  | ||||||
| pub mod d18; |  | ||||||
|  |  | ||||||
| pub mod d19; |  | ||||||
|  |  | ||||||
| pub mod d20; |  | ||||||
|  |  | ||||||
| pub mod d21; |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user