Browse Source

Initial working version for both parts

pull/3/head
Ryan Reed 3 years ago
parent
commit
614bdb6f99
2 changed files with 99 additions and 28 deletions
  1. +94
    -20
      puzzles/day03.py
  2. +5
    -8
      puzzles/test_day03.py

+ 94
- 20
puzzles/day03.py View File

@ -7,43 +7,117 @@ Run with:
import pathlib
import sys
from typing import List, Tuple
from typing import Dict, List, Tuple
from collections import defaultdict
class Submarine:
gamma: int = 0
epsilon: int = 0
power: int = 0
class Diagnostics:
_most_common = None
report = None
def __init__(self, report: List[int]) -> None:
self.report = report
self._most_common = self.commonality(report)
def decode_report(self, report: List[int]) -> None:
num_1 = defaultdict(int)
for binary in report:
for index, bit in enumerate(binary):
num_1[index] += int(bit)
total = len(report)
def power_usage(self) -> None:
half_count = len(self.report)/2
gamma = epsilon = ""
for binary in num_1.values():
if binary > (total/2):
for common in self._most_common:
if common == 1:
gamma += "1"
epsilon += "0"
else:
gamma += "0"
epsilon += "1"
self.gamma = int(gamma, 2)
self.epsilon = int(epsilon, 2)
self.power = self.gamma * self.epsilon
gamma = int(gamma, 2)
epsilon = int(epsilon, 2)
return gamma * epsilon
def calculate_oxygen_generator_rating(self, inputs) -> int:
"""
Bit Criteria:
Most common value in current bit position
If 0 and 1 are equally common, keep values with a 1
Keep only values with this bit in this position
"""
report = inputs.copy()
for column in range(len(report[0])):
most_common = self.commonality(report)
for binary in list(report):
if (int(binary[column]) != most_common[column] and most_common[column] != 2) or (most_common[column] == 2 and binary[column] != "1"):
report.remove(binary)
if len(report) == 1:
return int(report[0], 2)
if len(report) > 1: # May not be necessary
report = self.calculate_oxygen_generator_rating(report)
return int(report[0], 2)
def calculate_co2_scrubber_rating(self, inputs) -> int:
"""
Bit Criteria:
Least common value in current position
If 0 and 1 are equally common, keep values with a 0
Keep only values with this bit in this position
"""
report = inputs.copy()
for column in range(len(report[0])):
most_common = self.commonality(report)
for binary in list(report):
if (int(binary[column]) == most_common[column]) or (most_common[column] == 2 and binary[column] != "0"):
report.remove(binary)
if len(report) == 1:
return int(report[0], 2)
if len(report) > 1: # May not be necessary
report = self.calculate_oxygen_generator_rating(report)
return int(report[0], 2)
def calculate_life_support_rating(self) -> int:
oxygen_generator_rating = self.calculate_oxygen_generator_rating(self.report)
co2_scrubber_rating = self.calculate_co2_scrubber_rating(self.report)
return oxygen_generator_rating * co2_scrubber_rating
@staticmethod
def commonality(report: List[int]) -> List[Dict[str, int]]:
common_counts = []
for binary in report:
for column, bit in enumerate(binary):
try:
common_counts[column][bit] += 1
except IndexError:
common_counts.append(defaultdict(int))
common_counts[column][bit] = 1
common = []
half_total = len(report)/2
for count in common_counts:
if count["1"] == half_total:
common.append(2) # Indicating equally common
elif count["1"] > half_total:
common.append(1)
else:
common.append(0)
return common
def part1(inputs: List[int]) -> int:
sub = Submarine()
sub.decode_report(inputs)
return sub.power
diag = Diagnostics(inputs)
return diag.power_usage()
def part2(inputs: List[int]) -> int:
return False
diag = Diagnostics(inputs)
return diag.calculate_life_support_rating()
def parse(inputs: str) -> List[int]:


+ 5
- 8
puzzles/test_day03.py View File

@ -23,16 +23,13 @@ def test_example1(example_data):
assert aoc.part1(example_data) == 198
@pytest.mark.skip(reason="Not implemented")
def test_example2(example_data):
assert aoc.part2(example_data) == ...
assert aoc.part2(example_data) == 230
@pytest.mark.skip(reason="Not implemented")
def test_part1(day02_data):
assert aoc.part1(day02_data) == ...
def test_part1(day03_data):
assert aoc.part1(day03_data) == 3885894
@pytest.mark.skip(reason="Not implemented")
def test_part2(day02_data):
assert aoc.part2(day02_data) == ...
def test_part2(day03_data):
assert aoc.part2(day03_data) == 4375225

Loading…
Cancel
Save