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