Solve 2021/03
parent
7d77a1cfcf
commit
4f13984375
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day03"
|
||||||
|
version = "0.1.0"
|
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "day03"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
@ -0,0 +1,59 @@
|
|||||||
|
https://adventofcode.com/2021/day/3
|
||||||
|
|
||||||
|
## \--- Day 3: Binary Diagnostic ---
|
||||||
|
|
||||||
|
The submarine has been making some odd creaking noises, so you ask it to
|
||||||
|
produce a diagnostic report just in case.
|
||||||
|
|
||||||
|
The diagnostic report (your puzzle input) consists of a list of binary numbers
|
||||||
|
which, when decoded properly, can tell you many useful things about the
|
||||||
|
conditions of the submarine. The first parameter to check is the _power
|
||||||
|
consumption_.
|
||||||
|
|
||||||
|
You need to use the binary numbers in the diagnostic report to generate two
|
||||||
|
new binary numbers (called the _gamma rate_ and the _epsilon rate_ ). The
|
||||||
|
power consumption can then be found by multiplying the gamma rate by the
|
||||||
|
epsilon rate.
|
||||||
|
|
||||||
|
Each bit in the gamma rate can be determined by finding the _most common bit
|
||||||
|
in the corresponding position_ of all numbers in the diagnostic report. For
|
||||||
|
example, given the following diagnostic report:
|
||||||
|
|
||||||
|
[code]
|
||||||
|
|
||||||
|
00100
|
||||||
|
11110
|
||||||
|
10110
|
||||||
|
10111
|
||||||
|
10101
|
||||||
|
01111
|
||||||
|
00111
|
||||||
|
11100
|
||||||
|
10000
|
||||||
|
11001
|
||||||
|
00010
|
||||||
|
01010
|
||||||
|
|
||||||
|
[/code]
|
||||||
|
|
||||||
|
Considering only the first bit of each number, there are five `0` bits and
|
||||||
|
seven `1` bits. Since the most common bit is `1`, the first bit of the gamma
|
||||||
|
rate is `1`.
|
||||||
|
|
||||||
|
The most common second bit of the numbers in the diagnostic report is `0`, so
|
||||||
|
the second bit of the gamma rate is `0`.
|
||||||
|
|
||||||
|
The most common value of the third, fourth, and fifth bits are `1`, `1`, and
|
||||||
|
`0`, respectively, and so the final three bits of the gamma rate are `110`.
|
||||||
|
|
||||||
|
So, the gamma rate is the binary number `10110`, or `_22_` in decimal.
|
||||||
|
|
||||||
|
The epsilon rate is calculated in a similar way; rather than use the most
|
||||||
|
common bit, the least common bit from each position is used. So, the epsilon
|
||||||
|
rate is `01001`, or `_9_` in decimal. Multiplying the gamma rate (`22`) by the
|
||||||
|
epsilon rate (`9`) produces the power consumption, `_198_`.
|
||||||
|
|
||||||
|
Use the binary numbers in your diagnostic report to calculate the gamma rate
|
||||||
|
and epsilon rate, then multiply them together. _What is the power consumption
|
||||||
|
of the submarine?_ (Be sure to represent your answer in decimal, not binary.)
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
00100
|
||||||
|
11110
|
||||||
|
10110
|
||||||
|
10111
|
||||||
|
10101
|
||||||
|
01111
|
||||||
|
00111
|
||||||
|
11100
|
||||||
|
10000
|
||||||
|
11001
|
||||||
|
00010
|
||||||
|
01010
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,171 @@
|
|||||||
|
use std::env;
|
||||||
|
use std::io::stdin;
|
||||||
|
use std::io::BufRead;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
|
||||||
|
if args.len() > 1 && args[1] == "part1" {
|
||||||
|
part1();
|
||||||
|
} else {
|
||||||
|
part2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1() {
|
||||||
|
let mut vec: Vec<i32> = Vec::new();
|
||||||
|
|
||||||
|
for line in stdin().lock().lines() {
|
||||||
|
let line_result = line.unwrap();
|
||||||
|
|
||||||
|
if vec.len() == 0 {
|
||||||
|
for _ in 0..line_result.len() {
|
||||||
|
vec.push(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut idx = 0;
|
||||||
|
for character in line_result.chars() {
|
||||||
|
match character {
|
||||||
|
'0' => vec[idx] -= 1,
|
||||||
|
'1' => vec[idx] += 1,
|
||||||
|
_ => panic!("Unrecognized bit: {}", character),
|
||||||
|
}
|
||||||
|
idx += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec = vec
|
||||||
|
.into_iter()
|
||||||
|
.map(|value| match value > 0 {
|
||||||
|
true => 1,
|
||||||
|
false => 0,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let gamma = bin2dec(&vec);
|
||||||
|
vec = vec
|
||||||
|
.into_iter()
|
||||||
|
.map(|bit| match bit {
|
||||||
|
1 => 0,
|
||||||
|
0 => 1,
|
||||||
|
_ => panic!("Unrecognizet bit: {}", bit),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let epsilon = bin2dec(&vec);
|
||||||
|
dbg!(gamma);
|
||||||
|
dbg!(epsilon);
|
||||||
|
|
||||||
|
let power_comsumption = gamma * epsilon;
|
||||||
|
dbg!(power_comsumption);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() {
|
||||||
|
let input: Vec<String> = stdin().lock().lines().map(|line| line.unwrap()).collect();
|
||||||
|
|
||||||
|
// dbg!(&input);
|
||||||
|
|
||||||
|
let mut oxygen_vec: Vec<&String> = input.iter().collect();
|
||||||
|
|
||||||
|
let mut current_bit = 0;
|
||||||
|
while oxygen_vec.len() != 1 {
|
||||||
|
oxygen_vec = keep_by_oxygen_criteria(&oxygen_vec, current_bit);
|
||||||
|
current_bit += 1;
|
||||||
|
// dbg!(&oxygen_vec);
|
||||||
|
}
|
||||||
|
// println!("Oxycen_vec: {}", &oxygen_vec[0]);
|
||||||
|
// dbg!(&input);
|
||||||
|
|
||||||
|
let mut co2_scrubber_vec: Vec<&String> = input.iter().collect();
|
||||||
|
|
||||||
|
let mut current_bit = 0;
|
||||||
|
while co2_scrubber_vec.len() != 1 {
|
||||||
|
co2_scrubber_vec = keep_by_co2_criteria(&co2_scrubber_vec, current_bit);
|
||||||
|
current_bit += 1;
|
||||||
|
// dbg!(&co2_scrubber_vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("CO2 Scrubber: {}", co2_scrubber_vec[0]);
|
||||||
|
|
||||||
|
let oxygen = oxygen_vec[0];
|
||||||
|
let oxygen: Vec<i32> = oxygen
|
||||||
|
.chars()
|
||||||
|
.map(|character| character.to_string().parse().unwrap())
|
||||||
|
.collect();
|
||||||
|
let oxygen = bin2dec(&oxygen);
|
||||||
|
let co2_scrubber = co2_scrubber_vec[0];
|
||||||
|
let co2_scrubber: Vec<i32> = co2_scrubber
|
||||||
|
.chars()
|
||||||
|
.map(|character| character.to_string().parse().unwrap())
|
||||||
|
.collect();
|
||||||
|
let co2_scrubber = bin2dec(&co2_scrubber);
|
||||||
|
|
||||||
|
dbg!(&oxygen);
|
||||||
|
dbg!(&co2_scrubber);
|
||||||
|
|
||||||
|
let life_support_rating = oxygen * co2_scrubber;
|
||||||
|
|
||||||
|
dbg!(life_support_rating);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bin2dec(vec: &Vec<i32>) -> i32 {
|
||||||
|
let mut bit_value = 1;
|
||||||
|
let mut num = 0;
|
||||||
|
for bit in vec.iter().rev() {
|
||||||
|
num += bit * bit_value;
|
||||||
|
bit_value = bit_value << 1;
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn most_common_bit(vec: &Vec<&String>, current_bit: usize, on_equal: i32) -> i32 {
|
||||||
|
let mut result: i32 = vec
|
||||||
|
.into_iter()
|
||||||
|
.map(|number| number.chars().nth(current_bit).unwrap())
|
||||||
|
.map(|character| character.to_string().parse::<i32>().unwrap())
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
result = result * 2 - vec.len() as i32;
|
||||||
|
|
||||||
|
if result > 0 {
|
||||||
|
return 1;
|
||||||
|
} else if result < 0 {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return on_equal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn keep_by_oxygen_criteria<'a>(vec: &Vec<&'a String>, current_bit: usize) -> Vec<&'a String> {
|
||||||
|
let most_common = most_common_bit(vec, current_bit, 1);
|
||||||
|
|
||||||
|
let compare_char = match most_common {
|
||||||
|
0 => '0',
|
||||||
|
1 => '1',
|
||||||
|
_ => panic!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let filtered: Vec<&String> = vec
|
||||||
|
.into_iter()
|
||||||
|
.filter(|number| number.chars().nth(current_bit).unwrap() == compare_char)
|
||||||
|
.map(|number| *number)
|
||||||
|
.collect();
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn keep_by_co2_criteria<'a>(vec: &Vec<&'a String>, current_bit: usize) -> Vec<&'a String> {
|
||||||
|
let most_common = most_common_bit(vec, current_bit, 1);
|
||||||
|
|
||||||
|
let compare_char = match most_common {
|
||||||
|
0 => '1',
|
||||||
|
1 => '0',
|
||||||
|
_ => panic!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let filtered: Vec<&String> = vec
|
||||||
|
.into_iter()
|
||||||
|
.filter(|number| number.chars().nth(current_bit).unwrap() == compare_char)
|
||||||
|
.map(|number| *number)
|
||||||
|
.collect();
|
||||||
|
return filtered;
|
||||||
|
}
|
Loading…
Reference in New Issue