Add 2021-03 in Python
Signed-off-by: AKU <tom@tdpain.net>
This commit is contained in:
parent
e6847a3fdc
commit
020cf34fa2
4 changed files with 122 additions and 4 deletions
2
challenges/2021/03-binaryDiagnostic/README.md
Normal file
2
challenges/2021/03-binaryDiagnostic/README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# [Day 3: Binary Diagnostic](https://adventofcode.com/2021/day/3)
|
||||
|
17
challenges/2021/03-binaryDiagnostic/info.json
Normal file
17
challenges/2021/03-binaryDiagnostic/info.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"inputFile": "input.txt",
|
||||
"testCases": {
|
||||
"one": [
|
||||
{
|
||||
"input": "00100\n11110\n10110\n10111\n10101\n01111\n00111\n11100\n10000\n11001\n00010\n01010\n",
|
||||
"expected": "198"
|
||||
}
|
||||
],
|
||||
"two": [
|
||||
{
|
||||
"input": "00100\n11110\n10110\n10111\n10101\n01111\n00111\n11100\n10000\n11001\n00010\n01010\n",
|
||||
"expected": "230"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
98
challenges/2021/03-binaryDiagnostic/py/__init__.py
Normal file
98
challenges/2021/03-binaryDiagnostic/py/__init__.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
from typing import List, Tuple
|
||||
from aocpy import BaseChallenge
|
||||
|
||||
|
||||
def parse(instr: str) -> Tuple[List[int], int]:
|
||||
# parse returns a list of integers and the original length of the first of
|
||||
# those integers in the binary representation in the input.
|
||||
|
||||
y = instr.strip().splitlines()
|
||||
return [int(x, base=2) for x in y], len(y[0])
|
||||
|
||||
|
||||
def get_bit(number: int, n: int) -> int:
|
||||
# get_bit returns a given bit from the binary representation of `number`.
|
||||
#
|
||||
# In the number 111001011110, n=4 would refer to this bit:
|
||||
# ^
|
||||
return (number >> n) & 0b1
|
||||
|
||||
def analyse_bits(numbers: List[int], n: int) -> Tuple[int, int]:
|
||||
# analyse_bits returns a tuple containing the most common bit (either 1 or
|
||||
# 0) and the least common bit (either 1 or 0) in position `n` of each
|
||||
# number in `numbers`.
|
||||
#
|
||||
# If the most common bit and least common bit occur the same amount of
|
||||
# times, both return values are -1.
|
||||
#
|
||||
# Returns: most common bit, least common bit
|
||||
|
||||
zeros = 0
|
||||
ones = 0
|
||||
|
||||
for number in numbers:
|
||||
sel = get_bit(number, n)
|
||||
if sel == 0:
|
||||
zeros += 1
|
||||
elif sel == 1:
|
||||
ones += 1
|
||||
|
||||
if zeros > ones:
|
||||
return 0, 1
|
||||
elif ones > zeros:
|
||||
return 1, 0
|
||||
return -1, -1
|
||||
|
||||
|
||||
class Challenge(BaseChallenge):
|
||||
|
||||
@staticmethod
|
||||
def one(instr: str) -> int:
|
||||
numbers, bit_length = parse(instr)
|
||||
|
||||
gamma = ""
|
||||
epsilon = ""
|
||||
|
||||
for bit_number in reversed(range(bit_length)):
|
||||
|
||||
most_common, least_common = analyse_bits(numbers, bit_number)
|
||||
gamma += str(most_common)
|
||||
epsilon += str(least_common)
|
||||
|
||||
return int(gamma, 2) * int(epsilon, 2)
|
||||
|
||||
@staticmethod
|
||||
def two(instr: str) -> int:
|
||||
numbers, bit_length = parse(instr)
|
||||
|
||||
def find(inp: List[int], use_most_common: bool, n: int = bit_length-1) -> int:
|
||||
# find implements the bit criteria-based filtering as defined in
|
||||
# AoC 2021 day 3 part 2. If `use_most_common` is True, the bit
|
||||
# criteria for the oxygen generator rating is used, else, the bit
|
||||
# criteria for the CO2 scrubber rating is used.
|
||||
|
||||
if len(inp) == 1:
|
||||
return inp[0]
|
||||
|
||||
most_common, least_common = analyse_bits(inp, n)
|
||||
|
||||
target = None
|
||||
if most_common == -1 or least_common == -1:
|
||||
target = 1 if use_most_common else 0
|
||||
else:
|
||||
target = most_common if use_most_common else least_common
|
||||
|
||||
# oooo, accidental tail recursion!
|
||||
return find(
|
||||
list(filter(
|
||||
lambda x: get_bit(x, n) == target,
|
||||
inp,
|
||||
)),
|
||||
use_most_common,
|
||||
n - 1,
|
||||
)
|
||||
|
||||
o2_rating = find(numbers, True)
|
||||
co2_rating = find(numbers, False)
|
||||
|
||||
return o2_rating * co2_rating
|
|
@ -8,9 +8,10 @@ Solutions to the [2021 Advent of Code](https://adventofcode.com/2021).
|
|||
|
||||
<!-- PARSE START -->
|
||||
|
||||
| Day | Status | Solutions | Notes |
|
||||
| ----------------------------------- | ------------------ | ---------------------------------------------------------------------------- | -------------------- |
|
||||
| 01 - Sonar Sweep | Complete | [Python](01-sonarSweep/py), [Go](01-sonarSweep/go), [Nim](01-sonarSweep/nim) | |
|
||||
| 02 - Dive! | Complete | [Python](02-dive/py), [Go](02-dive/go) | |
|
||||
| Day | Status | Solutions | Notes |
|
||||
| ----------------------------------- | ------------------ | ---------------------------------------------------------------------------- | ---------------------------- |
|
||||
| 01 - Sonar Sweep | Complete | [Python](01-sonarSweep/py), [Go](01-sonarSweep/go), [Nim](01-sonarSweep/nim) | |
|
||||
| 02 - Dive! | Complete | [Python](02-dive/py), [Go](02-dive/go) | |
|
||||
| 02 - Binary Diagnostic | Complete | [Python](03-binaryDiagnostic/py) | Bit twiddling, my favourite! |
|
||||
|
||||
<!-- PARSE END -->
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue