2021 Day 03
This commit is contained in:
parent
813cecc174
commit
ea38be1d46
75
2021/03/README.md
Normal file
75
2021/03/README.md
Normal file
@ -0,0 +1,75 @@
|
||||
# 2021 Day 03: Binary Diagnostic
|
||||
Copyright (c) Eric Wastl
|
||||
#### [Direct Link](https://adventofcode.com/2021/day/03)
|
||||
|
||||
## Part 1
|
||||
|
||||
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:
|
||||
|
||||
```
|
||||
00100
|
||||
11110
|
||||
10110
|
||||
10111
|
||||
10101
|
||||
01111
|
||||
00111
|
||||
11100
|
||||
10000
|
||||
11001
|
||||
00010
|
||||
01010
|
||||
```
|
||||
|
||||
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.)
|
||||
|
||||
## Part 2
|
||||
|
||||
Next, you should verify the **life support rating**, which can be determined by multiplying the **oxygen generator rating** by the **CO2 scrubber rating**.
|
||||
|
||||
Both the oxygen generator rating and the CO2 scrubber rating are values that can be found in your diagnostic report - finding them is the tricky part. Both values are located using a similar process that involves filtering out values until only one remains. Before searching for either rating value, start with the full list of binary numbers from your diagnostic report and **consider just the first bit** of those numbers. Then:
|
||||
|
||||
- Keep only numbers selected by the **bit criteria** for the type of rating value for which you are searching. Discard numbers which do not match the bit criteria.
|
||||
- If you only have one number left, stop; this is the rating value for which you are searching.
|
||||
- Otherwise, repeat the process, considering the next bit to the right.
|
||||
|
||||
The **bit criteria** depends on which type of rating value you want to find:
|
||||
|
||||
- To find **oxygen generator rating**, determine the **most common** value (`0` or `1`) in the current bit position, and keep only numbers with that bit in that position. If `0` and `1` are equally common, keep values with a **`1`** in the position being considered.
|
||||
- To find **CO2 scrubber rating**, determine the **least common** value (`0` or `1`) in the current bit position, and keep only numbers with that bit in that position. If `0` and `1` are equally common, keep values with a **`0`** in the position being considered.
|
||||
|
||||
For example, to determine the **oxygen generator rating** value using the same example diagnostic report from above:
|
||||
|
||||
- Start with all 12 numbers and consider only the first bit of each number. There are more `1` bits (7) than `0` bits (5), so keep only the 7 numbers with a `1` in the first position: `11110`, `10110`, `10111`, `10101`, `11100`, `10000`, and `11001`.
|
||||
- Then, consider the second bit of the 7 remaining numbers: there are more `0` bits (4) than `1` bits (3), so keep only the 4 numbers with a `0` in the second position: `10110`, `10111`, `10101`, and `10000`.
|
||||
- In the third position, three of the four numbers have a `1`, so keep those three: `10110`, `10111`, and `10101`.
|
||||
- In the fourth position, two of the three numbers have a `1`, so keep those two: `10110` and `10111`.
|
||||
- In the fifth position, there are an equal number of `0` bits and `1` bits (one each). So, to find the **oxygen generator rating**, keep the number with a `1` in that position: `10111`.
|
||||
- As there is only one number left, stop; the **oxygen generator rating** is `10111`, or **`23`** in decimal.
|
||||
|
||||
Then, to determine the **CO2 scrubber rating** value from the same example above:
|
||||
|
||||
- Start again with all 12 numbers and consider only the first bit of each number. There are fewer `0` bits (5) than `1` bits (7), so keep only the 5 numbers with a `0` in the first position: `00100`, `01111`, `00111`, `00010`, and `01010`.
|
||||
- Then, consider the second bit of the 5 remaining numbers: there are fewer `1` bits (2) than `0` bits (3), so keep only the 2 numbers with a `1` in the second position: `01111` and `01010`.
|
||||
- In the third position, there are an equal number of `0` bits and `1` bits (one each). So, to find the CO2 scrubber rating, keep the number with a `0` in that position: `01010`.
|
||||
- As there is only one number left, stop; the **CO2 scrubber rating** is `01010`, or **`10`** in decimal.
|
||||
|
||||
Finally, to find the life support rating, multiply the oxygen generator rating (`23`) by the CO2 scrubber rating (`10`) to get **`230`**.
|
||||
|
||||
Use the binary numbers in your diagnostic report to calculate the oxygen generator rating and CO2 scrubber rating, then multiply them together. **What is the life support rating of the submarine?** (Be sure to represent your answer in decimal, not binary.)
|
37
2021/03/code.py
Normal file
37
2021/03/code.py
Normal file
@ -0,0 +1,37 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2021 Akumatic
|
||||
#
|
||||
# https://adventofcode.com/2021/day/03
|
||||
|
||||
def read_file() -> list:
|
||||
with open(f"{__file__.rstrip('code.py')}input.txt", "r") as f:
|
||||
return [line for line in f.read().strip().split("\n")]
|
||||
|
||||
def get_mcb(vals: list) -> list:
|
||||
bit_count = [sum(int(num[i]) for num in vals) for i in range(len(vals[0]))]
|
||||
return [1 if cnt >= (len(vals) - cnt) else 0 for cnt in bit_count]
|
||||
|
||||
def reduce_reports(reports: list, invert: bool = False) -> int:
|
||||
for i in range(0, len(reports[0])):
|
||||
mcb = get_mcb(reports)[i]
|
||||
bit = str(mcb if not invert else 1 - mcb)
|
||||
reports = [rep for rep in reports if rep[i] == bit]
|
||||
if len(reports) == 1:
|
||||
break
|
||||
return int(reports[0], 2)
|
||||
|
||||
def part1(vals: list) -> int:
|
||||
mcb = get_mcb(vals)
|
||||
gamma = "".join(["1" if bit else "0" for bit in mcb])
|
||||
epsilon = "".join(["0" if bit else "1" for bit in mcb])
|
||||
return int(gamma, 2) * int(epsilon, 2)
|
||||
|
||||
def part2(vals: list) -> int:
|
||||
ogr = reduce_reports(vals[:]) # oxygen generator rating
|
||||
csr = reduce_reports(vals[:], invert=True) # CO2 scrubber rating
|
||||
return ogr * csr
|
||||
|
||||
if __name__ == "__main__":
|
||||
vals = read_file()
|
||||
print(f"Part 1: {part1(vals)}")
|
||||
print(f"Part 2: {part2(vals)}")
|
1000
2021/03/input.txt
Normal file
1000
2021/03/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
2
2021/03/solution.txt
Normal file
2
2021/03/solution.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Part 1: 845186
|
||||
Part 2: 4636702
|
15
2021/03/test_code.py
Normal file
15
2021/03/test_code.py
Normal file
@ -0,0 +1,15 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2021 Akumatic
|
||||
|
||||
from code import part1, part2
|
||||
|
||||
def test():
|
||||
vals = ["00100", "11110", "10110", "10111", "10101", "01111",
|
||||
"00111", "11100", "10000", "11001", "00010", "01010"]
|
||||
assert part1(vals) == 198
|
||||
print("Passed Part 1")
|
||||
assert part2(vals) == 230
|
||||
print("Passed Part 2")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test()
|
@ -17,6 +17,7 @@ Collect stars by solving puzzles. Two puzzles will be made available on each day
|
||||
| --- | --- | --- |---| --- |
|
||||
| 01 | :white_check_mark: | :white_check_mark: | [Solution](01/code.py) | [Day 01](https://adventofcode.com/2021/day/1) |
|
||||
| 02 | :white_check_mark: | :white_check_mark: | [Solution](02/code.py) | [Day 02](https://adventofcode.com/2021/day/2) |
|
||||
| 03 | :white_check_mark: | :white_check_mark: | [Solution](03/code.py) | [Day 03](https://adventofcode.com/2021/day/3) |
|
||||
| 03 | | | | |
|
||||
| 04 | | | | |
|
||||
| 05 | | | | |
|
||||
|
Loading…
x
Reference in New Issue
Block a user