DEV Community

Nicky Meuleman
Nicky Meuleman

Posted on • Originally published at nickymeuleman.netlify.app

Advent of Code 2022 Day 4

Day 4: Camp Cleanup

https://adventofcode.com/2022/day/4

TL;DR: my solution in Rust

Today, the elves have to clean up their camp.

  • Each area of the camp has a unique ID number.
  • Each elf is assigned a range of those IDs to clean.

The elves are split into groups of 2.

Your input is a big list of the section assignments for each pair.
Each line of the input represents a pair of elves.

The two elves in a line are seperated by a comma ,.

The start and end (inclusive) of their assigned range is seperated by a dash -.

An example input looks like this:

2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8
Enter fullscreen mode Exit fullscreen mode

Part 1

The question asks to find in how many pairs one range fully contains the other.

I looped through every line of the input, only keps the ones with a full overlap, and counted how many were left.

I started off with this pseudocode that I then filled in:

input
    .lines()
    .filter()
    .count()
Enter fullscreen mode Exit fullscreen mode

A range completely overlaps an other range if:

Its minimum is lower (or equal) than the other minimum and its maximum is higher (or equal) than the other maximum.

I did this check twice, once for each elf.

  • Once to check if elf1 completely overlaps with elf2
  • Once to check if elf2 completely overlaps with elf1.

The longest part of this solution is parsing those strings into 4 numbers: min1, max1, min2, and max2.

The solution includes a commented out alternative way to check for a complete overlap

pub fn part_1() -> usize {
    let input = std::fs::read_to_string("src/day04.txt").unwrap();

    input
        .lines()
        .filter(|line| {
            let (elf1, elf2) = line.split_once(',').unwrap();
            let (min1, max1) = elf1.split_once('-').unwrap();
            let (min2, max2) = elf2.split_once('-').unwrap();
            let min1: u32 = min1.parse().unwrap();
            let max1: u32 = max1.parse().unwrap();
            let min2: u32 = min2.parse().unwrap();
            let max2: u32 = max2.parse().unwrap();

            // (min1 >= min2 && max1 <= max2) || (min2 >= min1 && max2 <= max1)
            // equivalent:
            (min1 <= min2 && max1 >= max2) || (min2 <= min1 && max2 >= max1)
        })
        .count()
}
Enter fullscreen mode Exit fullscreen mode

Part 2

The question asks to find in how many pairs one range overlaps the other (partially, or completely).

The overall setup and the number parsing piece are identical to part1.
The only change is the line that determines if a line is kept or not.

A range overlaps an other when:

the biggest minimum is smaller (or equal) than the smallest maximum.

The solution includes a commented out alternative way to check for an overlap

pub fn part_2() -> usize {
    let input = std::fs::read_to_string("src/day04.txt").unwrap();

    input
        .lines()
        .filter(|line| {
            let (elf1, elf2) = line.split_once(',').unwrap();
            let (min1, max1) = elf1.split_once('-').unwrap();
            let (min2, max2) = elf2.split_once('-').unwrap();
            let min1: u32 = min1.parse().unwrap();
            let max1: u32 = max1.parse().unwrap();
            let min2: u32 = min2.parse().unwrap();
            let max2: u32 = max2.parse().unwrap();

            min1 <= max2 && max1 >= min2
            // equivalent:
            // min1.max(min2) <= max1.min(max2)
        })
        .count()
}
Enter fullscreen mode Exit fullscreen mode

Oldest comments (0)