diff --git a/.run/run-day-6.run.xml b/.run/run-day-6.run.xml new file mode 100644 index 0000000..c701f73 --- /dev/null +++ b/.run/run-day-6.run.xml @@ -0,0 +1,19 @@ + + + + \ No newline at end of file diff --git a/input/day6.txt b/input/day6.txt new file mode 100644 index 0000000..c516c34 --- /dev/null +++ b/input/day6.txt @@ -0,0 +1 @@ +qzbzwwghwhwdhdqhhbhfbfsstggdsssgzgdzzdbbbzmbzzvlldppjnjlltwtsszwswgssjnsjnnfqfzqqjzjfjmfmwfmfhfnnmdnmnllbzzlbzlzflldzdbzbsbdddpgdppzhphhjjtccjgcgrgjgcjgjjsbjbffsgsqqrsqqgppgmgcmmrdrqdqbqmmctchcgcdgdwdwcdcjcfjccmpmlpllqqpmpllhfhchppwwdmdhdphpvprrhwhgwwlrwlwggwlwqqnmqnqrrbbzdzwddqzznllzwlljsscqqtlltppqspswsttlrttnvvvwllfslsjsfjssnqnbbbvgvlltjtltjljmljjfgfbggcbgbmbjjvwjvjgvgzvvzddrjdddrwrlrlgldlhlwwcddbsbbtwwcssrnndvvsbsnbsbmbnmngnpgpphfhzhshllltqtppnrrzpzrpzzrttmbmssbrbmbsmsnspnsncscwwmjwmwdmwmrmvmqvqvjqvvnrrtntwwwwsrwrnwnrwwwlslrlhrllvpvhppdpprrgzrgzggqmqgmgvghhsmhhjljfflrflfrlrzzbjjqmmmcncddvhhzjjqzzjfzzbssjqqtsqtqccmttdhttmwtmtffspplhlrhrdhhhpghgrhrchhmgmqgqlglssvnnwrrrrqqbmmpgmpmdmmljlflzzjttqntqqcnqccrvcczffclffmvfvwvmvnvsvnvffczzljzztdtztcztctbtppmrprqprpbbhlhphphhvppvdvmddvcctvvjbvvpmpbpnpllvclvlqlwqqpcpffdwdsdttzftfddbrrgsrgsgvgpgjpggfvgfvvtqtnnscssmnnfqnnblnnjlnlbbjrrmmpgmgnnqbbcjbcjbbmjjljsjrsjrsrwrgwgpgqgccqppfdpdssffgdgwddcvdvzzpttjlttmwwhnnlntncttfvfwvvwrvrwwlhlwlvwvzvpvfpvvsbslblrlssjddwhwfhwffqjfjzfjfmfrrvsrrlbrrdfdmdwmddpnpfnpfnfppczpprzprpvpjjtltptvvrgvvsttflfvfqqhnnbmnbmmpsptpdpttrbbhjbbdnntppbsbmssgccfdfflppbcpbblclrlhrhttffvqqvvnpnmpnnrbnnhqnqrrwvwrrbvbffcvctcjcwwmzmvvtdvtvbtblbvlbvlvdvdrdsrdrprllnzznzhhcjjsgglfglgrlrwwfcfzfjzfztfztzggffjftjffcbfbhhwfwnnbssrpsppmllszstztwwgbwgbgtbgggztgztzwtztbbrffznndhdmmqggssjfssrgssbnsndnqnvqvqvjqvqttlctltvlttrzrqrrdprddpqqvppvddgmdddpldllnvvjdjcjdjvvznzqqbgqbgbpbnbvvdjvvsnndsdjjjhnhggrnnrvrvlvqllqhhsbhssvvlhlssgqgmqqcscpsspsrpsrpspvvdmvdvwwcjwwvhwvvmzvzvfvccfzczjccscbcrcjrrrsgrsspnsntsnnrnwwhdwwzhzbbwgwcgglvlttqrttvrrgprrljlddnttqrqffgdfgdgzzhghthhmdmsmtsshhsfhhgzgvzgzwzffvlffzjjrttsdddbldljlvjvjttwdwzzrbblwbbgmbmgmbggbdbsbqqwzzgnzgzczpzfztftbtwbtbsttrwrfrssbrrdqdjqdqppdsswrwttmgmllqbqnnpspjjzjjmbbsddgjgbjggqqlgqgmgdmmwcmwcmwwsddvgvpphmhqmmlvlpvlpltllphhcshhrsrgsgzssspjspplgghvvwhwgwssbhshvvscshhbccbtcbcvvmnndsdwwbzbffhmmbppfjppbsblbtlltggzczdczdzjdjpjtppwdwlwqwnwjnnvttmcmzzqccvfcvvmrmzmwmhmttgdgmsrlddnbgqfbbmrpdglpbtdqpmctzjrffvvqnltcqlfddwqhvjpzhczzwhsmjtrpgsdtqlcqsljsjzqwhcfwttgghsjqhzqlgjzgrtgttwblpprbppcpzsbntrwwmvfvbmjjrjwjqcjhnstmvwzrbnjpzznnctrtllzhtwttntjqwjnfspzccqpjlzbncgbjjjztbgfmzflzsqflflcrfhtlsgbdfdbtwwqfdrqhzmmqdqthwzwqqqzddfvbwhnqwqtgwhtzlqqpwhcjhglcmmncvfcmqdwnzzmjbflwjrcjzwcblftzrpdcjzcmtzccjbsqmcnfmbsmrvlhswnmrqdczvvzzcnffgljdbtlvjgrqttcjhjmcdllnvhcdpztqghfgvjcqmqvmdwhcgrtwpjlmjfbqmnjnbvvjczcwfcrhcgzmsvmjlplcpghnqtpzddnwtmrwmqwbttsnlngszfbnslqvlbzbfzqnjpdvcdpmjpmmjhvzwwgzfjfqwbqwrznhsdpjgsvzlsrtlmhjrfnwrmljlqzwnfnsmqtzfsldwrgmbrrvcmmmdmwflwnvpwsrrstmffwbtwqmjzdnzbwmqfrfdgsmhzhprdsgsqtljqhtdqmvnzlwhrrqqftbvnhmjnzvmbdqpjhzjnszgcfptfcmthpfcvfvdmwdswzfgwjblglfbpfvvwrmnzlcvtgqbcrhfqlffrznnhbtbwdwdldthbhdsqvnghpqdlvpfmzhjbtdhfmrdzpghtppmvddnphcnnczvznwzrvtcwvpslhrhmhzbzqtjqjvdpwncjbqdnwwpnfblqtqdwwqncbvtsncfhgncrprvhvzppwjfpdmtdrmtfcqdmdhwzrhpnrvspfbzhsvlpwzgrrhnrllhmpcdfcqdhcnphlffpbfmbsznmvfdgshbsjcjjvhqqfpmjgpdpcrglbqdrnqmftqtnwcsgqzdwntfplsnlhdbdmcgwfldzzgmzjsdnldbnlnhjqhpmnsljsbhrglhjbbrmlhrmjnvzhnlvnfpdzfzwwdpzwhnqhlbqhrgfmvzpctdvscqbgznzdsvvvvcjnmbzlvsptslmqnggqjcmgvtgbnrzlmzqzmtdfvhjqqcpvbngmngjvrtcfvsmbvthvhmdcfhthmnjcvsvmsbwsjtmrwshspcsmnhvzqvglntngbmgtdngbvvcjrznpdmmsssljnnqjwwfzgwtlfqqpsqghjgrghldrcdmcqvqdjsfrfrnlnvltpfjhmcclwbsdcbmvmlnwltztfggzmrtnsczwvqgpqtwffmphprgrmjlnftlgqjvrngbcndlmrblmvcjsdhdcmtgsztjttpbgcznfcgdwfwdnqmrrjgdgrgshjfjqrbsjdhblvrqhlfphnbdslrjszcnpfhhwrfhhdvqbjpsmzznzbtbsgcggtctfbsrscvzlplfhlwjlrmzhbwjqhffdhrwcdctwvttwqzbdtrhdhdvtgvdbzjtqvdgbpwtzqqqnljztgpbjjcrgdgmrrsfvngcdbgzvcfpdppbgfrmmdnqdvtlwwglmghjwfjjrwjfnwgwdplbmlfljhsmshwvvvtdnvfcbbwplwnvzfcjwgsrrlctpsrhprttcjgcmfsjggfvbbljsbjtzplvjdwnwgsgvvntjwdwdqbwmtnnlgdcmfcccnwnrjlqtznjhdzwfpbzhjdmwwpcmffcwsnpfhmgqgwwnvpmqvrdfhlqtghrrbggdmtvpqgqsspmchnrqnrmqlddnspcdrwqpvclhrvjtzhpvthpltwqqbrdfjtnwncwrmdqszdpmmdzmjwjvqnfszvbchfdvwzhtrfgfhfmgwprdpqgmbfntsqztvqmtjvgbsjvzsbhfznbbzrstqbrrmqdjcztmfpnwbmvtccmvlhtvmgfdzcchbccrzznscbdwrdtnpslvcqmgrrvwhnjgjdpvbfgsdtdcmhpnwfwnnntqjqnwzfwnhsrjbhtqtlncvsnhgvtntfwldqfzztcdctsscfdmtnmdqgqgwmtqhlmswtqrvqbchdwtjsdlqjvfjdtmzlvrzwvfprzvjzrrfn \ No newline at end of file diff --git a/input/day6_example.txt b/input/day6_example.txt new file mode 100644 index 0000000..5a2b0a7 --- /dev/null +++ b/input/day6_example.txt @@ -0,0 +1 @@ +mjqjpqmgbljsphdztnvjfqwrcgsmlb \ No newline at end of file diff --git a/input/day6_example2.txt b/input/day6_example2.txt new file mode 100644 index 0000000..9e3311c --- /dev/null +++ b/input/day6_example2.txt @@ -0,0 +1 @@ +bvwbjplbgvbhsrlpgdmjqwftvncz \ No newline at end of file diff --git a/input/day6_example3.txt b/input/day6_example3.txt new file mode 100644 index 0000000..cca46f5 --- /dev/null +++ b/input/day6_example3.txt @@ -0,0 +1 @@ +nppdvjthqldpwncqszvftbrmjlhg \ No newline at end of file diff --git a/src/day5.rs b/src/day5.rs index e3789dd..4516098 100644 --- a/src/day5.rs +++ b/src/day5.rs @@ -1,6 +1,3 @@ -use std::collections::HashMap; -use nohash_hasher::{BuildNoHashHasher, NoHashHasher}; -use rustc_hash::FxHashMap; use crate::day_solver::DaySolver; use super::util; @@ -49,7 +46,7 @@ impl Day5 { fn execute_instruction_part2(&mut self, instr: &StackInstruction) { - // TODO prevent copying into a Vec here (we don't need a stack allocation...) + // TODO prevent copying into a Vec here (we don't need a heap allocation...) let from_stack = &self.stacks[instr.from as usize]; let from_stack_remaining = from_stack.len() - instr.amount as usize; let to_move: Vec = from_stack.iter().skip(from_stack_remaining).cloned().collect(); diff --git a/src/day6.rs b/src/day6.rs new file mode 100644 index 0000000..e286f0e --- /dev/null +++ b/src/day6.rs @@ -0,0 +1,76 @@ +use std::collections::HashSet; +use crate::day_solver::DaySolver; + +use super::util; + +pub struct Day6 { + data: Vec +} + +impl Day6 { + + pub fn create() -> Self { + // let lines = util::read_file("input/day6_example.txt"); + // let lines = util::read_file("input/day6_example2.txt"); + // let lines = util::read_file("input/day6_example3.txt"); + let lines = util::read_file("input/day6.txt"); + + // Put the input into the day struct + return Day6 { + data: lines.first().unwrap().chars().collect() + } + } + + const A_CHAR: usize = 'a' as usize; + + // Part 1 took 290 μs on average (Min: 237 μs, Max: 1100 μs, Median: 284 μs) + // Part 2 took 1098 μs on average (Min: 792 μs, Max: 1814 μs, Median: 1081 μs) + fn are_unique_v1(chars: &[char]) -> bool { + return chars.iter().cloned().collect::>().len() == chars.len(); + } + + // Part 1 took 8 μs on average (Min: 7 μs, Max: 53 μs, Median: 8 μs) + // Part 2 took 17 μs on average (Min: 15 μs, Max: 83 μs, Median: 17 μs) + fn are_unique_v2(chars: &[char]) -> bool { + let mut x: u32 = 0; + for c in chars { + let c_mask = 1 << (c.to_owned() as usize - Day6::A_CHAR); + let prev_x = x; + x = x | c_mask; + if prev_x == x { return false } + } + return true + } + + // Part 1 took 5 μs on average (Min: 5 μs, Max: 17 μs, Median: 5 μs) + // Part 2 took 14 μs on average (Min: 14 μs, Max: 105 μs, Median: 14 μs) + fn are_unique_v3(chars: &[char]) -> bool { + let mut x: u32 = 0; + for c in chars { + x = x | 1 << (c.to_owned() as usize - Day6::A_CHAR) + } + return x.count_ones() == chars.len() as u32; + } + + fn find_unique_chain(&self, len: usize) -> Option { + for i in (len-1)..self.data.len() { + if Day6::are_unique_v1(&self.data[i-(len - 1)..i+1]) { + return Some(i); + } + } + return None + } +} + +impl DaySolver for Day6 { + + + fn solve_part1(&mut self) -> String { + + return self.find_unique_chain(4).map_or("-".to_string(), |n| (n+1).to_string()); + } + + fn solve_part2(&mut self) -> String { + return self.find_unique_chain(14).map_or("-".to_string(), |n| (n+1).to_string()); + } +} diff --git a/src/main.rs b/src/main.rs index 6d69075..b0294d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use crate::day2::Day2; use crate::day3::Day3; use crate::day4::Day4; use crate::day5::Day5; +use crate::day6::Day6; use crate::day_solver::DaySolver; mod util; @@ -13,6 +14,7 @@ mod day2; mod day3; mod day4; mod day5; +mod day6; const MAX_DAY: u8 = 5; const DEFAULT_BENCHMARK_AMOUNT: u32 = 100; @@ -83,6 +85,7 @@ fn build_day_solver(day: u8) -> Option> { 3 => Some(Box::new(Day3::create())), 4 => Some(Box::new(Day4::create())), 5 => Some(Box::new(Day5::create())), + 6 => Some(Box::new(Day6::create())), _ => None } }