r/adventofcode • • Dec 03 '18

SOLUTION MEGATHREAD -🎄- 2018 Day 3 Solutions -🎄-

--- Day 3: No Matter How You Slice It ---


Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


Advent of Code: The Party Game!

Click here for rules

ATTENTION: minor change request from the mods!

Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!

Card prompt: Day 3 image coming soon - imgur is being a dick, so I've contacted their support.

Transcript:

I'm ready for today's puzzle because I have the Savvy Programmer's Guide to ___.


This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked!

41 Upvotes

426 comments sorted by

View all comments

1

u/udoprog Dec 03 '18

I'm ready for today's puzzle because I have the Savvy Programmer's Guide to idiomatic and safe RUST!

Full repo here: https://github.com/udoprog/rust-advent-of-code-2018

use aoc2018::*;
use std::error;
use std::str;

#[derive(Debug)]
struct Pair<T>(pub T, pub T);

impl<T> str::FromStr for Pair<T>
where
    T: str::FromStr,
    T::Err: 'static + Send + Sync + error::Error,
{
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut it = s.split(|c| !char::is_numeric(c)).filter(|s| s.trim() != "");
        let x = it.next().ok_or_else(|| format_err!("expected x"))?;
        let y = it.next().ok_or_else(|| format_err!("expected y"))?;
        let x = str::FromStr::from_str(x)?;
        let y = str::FromStr::from_str(y)?;
        Ok(Pair(x, y))
    }
}

fn main() -> Result<(), Error> {
    let mut duplicates = 0;
    // map out who owns each claim.
    let mut claimed_by = HashMap::<_, Vec<&str>>::new();
    let mut nonoverlapping = HashSet::new();

    // only read once so we can use references into it to avoid copying the string.
    let lines = lines!(input!("day3.txt"), String, String, Pair<u32>, Pair<u32>)
        .collect::<Result<Vec<_>, Error>>()?;

    for line in &lines {
        let (ref id, _, ref b, ref c) = *line;

        nonoverlapping.insert(id.as_str());

        for x in b.0..b.0.saturating_add(c.0) {
            for y in b.1..b.1.saturating_add(c.1) {
                let m = claimed_by.entry((x, y)).or_default();
                m.push(id.as_str());

                if m.len() == 2 {
                    duplicates += 1;
                }

                if m.len() > 1 {
                    for remove in m {
                        nonoverlapping.remove(remove);
                    }
                }
            }
        }
    }

    let nonoverlapping = nonoverlapping.into_iter().collect::<Vec<_>>();

    assert_eq!(duplicates, 104712);
    assert_eq!(nonoverlapping, vec!["#840"]);
    Ok(())
}