I'm a Sr. Software Engineer at Flashpoint. I specialize in Python and Go, building functional, practical, and maintainable web systems leveraging Kubernetes and the cloud. Blog opinions are my own.
I really struggled with part 1. Not because I couldn't figure out the problem, or get my code to compile. I had my tests running pretty quickly! But I kept getting the wrong answer! I was on the very precipice of giving up and checking the subreddit when I realized that str.matches(|c| c.is_digit(10)) only finds single digit at a time -- it doesn't build consecutive digits into a single "find." So with input string #1 @ 55,22: 10x10, it was reading this as id: 1, left: 5, top: 5, width: 2, height: 2 and throwing away the rest. 💩
After scratching my head and then bringing in my first external dependency ever in Rust (pretty painless, all things considered) things worked out just fine.
Since the dependency I brought in was just a regex crate, which would be built-in in some languages, I figured that was OK. I wasn't bringing in the find-overlapping-squares crate.
Anyhow, here's part 1:
useregex::Regex;usestd::collections::HashMap;/// An X, Y grid of Santa's fabric that elves can lay claim tostructFabric{squares:HashMap<(usize,usize),usize>,}/// The data for a rectangular claim an elf makes on a section of fabricstructClaim{id:usize,left:usize,top:usize,width:usize,height:usize,}implFabric{fnnew()->Self{Self{squares:HashMap::new()}}/// Increments the amount of claims covering each of the cells inside/// the rectangle.fnclaim(&mutself,claim:&Claim){forxinclaim.left..(claim.left+claim.width){foryinclaim.top..(claim.top+claim.height){ifx>999||y>999{continue;}*self.squares.entry((x,y)).or_insert(0)+=1;}}}/// Counts how many cells have more than one claim on themfncount_conflicts(&self)->usize{self.squares.values().filter(|count|**count>=2).count()}/// Counts the total squares claimed/// /// A helper function I wrote to help with debugging... #didnthelpfntotal_squares(&self)->usize{self.squares.iter().count()}}/// Processes a claim string into an actual Claim/// /// claim string pattern is #<id> @ <left>,<top>: <width>x<height>/// Since all the numbers are disjoint, we can just match all the /// separated numbers in order.fnprocess_claim(claim_text:&str)->Claim{// This makes it so we only compile the regex oncelazy_static!{staticrefclaim_re:Regex=Regex::new(r"#(?P<id>\d+) @ (?P<left>\d+),(?P<top>\d+): (?P<width>\d+)x(?P<height>\d+)").unwrap();}letclaim_parts=claim_re.captures(claim_text).unwrap();Claim{id:claim_parts["id"].parse().unwrap(),left:claim_parts["left"].parse().unwrap(),top:claim_parts["top"].parse().unwrap(),width:claim_parts["width"].parse().unwrap(),height:claim_parts["height"].parse().unwrap(),}}/// Counts the number of squares with more than one claim on thempubfncount_conflicting_squares(text:&str)->usize{letmutfabric=Fabric::new();forlineintext.lines(){letclaim=process_claim(line);fabric.claim(&claim);}fabric.count_conflicts()}
Part 2
Actually, for part 1, I didn't even keep track of the ID of the claims -- I just threw that data away! And then I read part two and sat there in sadness for a few minutes.
But!
Then I realized that I wouldn't have to come up with an entirely new approach. I could process the claims like normal, and then re-run through the claims and recheck all of their squares, to see if any have all cells with only one claim on them. Yeah, it doubles the run-time, but O(n) is O(n), even if you double it (sort of). Anyways, I'm pretty happy with today's challenge. Especially my top level functions count_conflicting_squares and find_unconflicting_id: I was able to make them abstract enough that they're pretty easy to read and figure out.
implFabric{/// Checks whether or not a given claim has any overlapping cellsfncheck_overlap(&self,claim:&Claim)->bool{forxinclaim.left..(claim.left+claim.width){foryinclaim.top..(claim.top+claim.height){ifself.squares.get(&(x,y))!=Some(&1){returntrue;}}}false}}/// Finds out if a claim in a group of claims doesn't overlap. Returns/// the first one that doesn't.pubfnfind_unconflicting_id(text:&str)->usize{letmutfabric=Fabric::new();letmutclaims:Vec<Claim>=Vec::new();// Load all the claims inforlineintext.lines(){letclaim=process_claim(line);fabric.claim(&claim);claims.push(claim);}// Check them all for overlapsforclaiminclaims{if!fabric.check_overlap(&claim){returnclaim.id;}}return0;}
I made the exact same mistake with my initial attempt, where I was only grabbing the first digit with my regex. I'm glad it wasn't just me 😅I was so frustrated because the test input worked, since each number in the test input was only one digit! Sometimes I wish that AoC gave just a little more test data to work with before grabbing your final input.
I'm a Sr. Software Engineer at Flashpoint. I specialize in Python and Go, building functional, practical, and maintainable web systems leveraging Kubernetes and the cloud. Blog opinions are my own.
Yes! The first test input kept passing, and then I wrote like 4 or 5 more tests to check different things, and they all passed! But I never checked double-digit numbers. :|
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Part 1
I really struggled with part 1. Not because I couldn't figure out the problem, or get my code to compile. I had my tests running pretty quickly! But I kept getting the wrong answer! I was on the very precipice of giving up and checking the subreddit when I realized that
str.matches(|c| c.is_digit(10))only finds single digit at a time -- it doesn't build consecutive digits into a single "find." So with input string#1 @ 55,22: 10x10, it was reading this asid: 1, left: 5, top: 5, width: 2, height: 2and throwing away the rest. 💩After scratching my head and then bringing in my first external dependency ever in Rust (pretty painless, all things considered) things worked out just fine.
Since the dependency I brought in was just a
regexcrate, which would be built-in in some languages, I figured that was OK. I wasn't bringing in thefind-overlapping-squarescrate.Anyhow, here's part 1:
Part 2
Actually, for part 1, I didn't even keep track of the ID of the claims -- I just threw that data away! And then I read part two and sat there in sadness for a few minutes.
But!
Then I realized that I wouldn't have to come up with an entirely new approach. I could process the claims like normal, and then re-run through the claims and recheck all of their squares, to see if any have all cells with only one claim on them. Yeah, it doubles the run-time, but O(n) is O(n), even if you double it (sort of). Anyways, I'm pretty happy with today's challenge. Especially my top level functions
count_conflicting_squaresandfind_unconflicting_id: I was able to make them abstract enough that they're pretty easy to read and figure out.I made the exact same mistake with my initial attempt, where I was only grabbing the first digit with my regex. I'm glad it wasn't just me 😅I was so frustrated because the test input worked, since each number in the test input was only one digit! Sometimes I wish that AoC gave just a little more test data to work with before grabbing your final input.
Yes! The first test input kept passing, and then I wrote like 4 or 5 more tests to check different things, and they all passed! But I never checked double-digit numbers. :|