Add 2021-08 in Python and Go

This commit is contained in:
akp 2021-12-08 22:50:54 +00:00
parent 7b364a97f9
commit a038dccaef
No known key found for this signature in database
GPG key ID: AA5726202C8879B7
8 changed files with 350 additions and 9 deletions

View file

@ -0,0 +1,2 @@
# [Day 8: Sevent Segment Search](https://adventofcode.com/2021/day/8)

View file

@ -0,0 +1,23 @@
{
"day": 8,
"dir": "challenges/2021/08-seventSegmentSearch",
"implementations": {
"Golang": {
"part.1.avg": 0.0011630151239999996,
"part.1.max": 0.002068547,
"part.1.min": 0.000927415,
"part.2.avg": 0.326909703884,
"part.2.max": 0.398817152,
"part.2.min": 0.296369163
},
"Python": {
"part.1.avg": 0.0018209447860717772,
"part.1.max": 0.0030808448791503906,
"part.1.min": 0.0014312267303466797,
"part.2.avg": 0.7365821332931518,
"part.2.max": 0.8698751926422119,
"part.2.min": 0.6725485324859619
}
},
"numRuns": 250
}

View file

@ -0,0 +1,149 @@
package challenge
import (
"errors"
"sort"
"strings"
"github.com/codemicro/adventOfCode/lib/aocgo"
)
var (
digits = []string{
"abcefg",
"cf",
"acdeg",
"acdfg",
"bcdf",
"abdfg",
"abdefg",
"acf",
"abcdefg",
"abcdfg",
}
possibleWirings = aocgo.StringPermutations("abcdefg")
)
type Display struct {
samples []string
outputs []string
}
func sortString(s string) string {
x := []rune(s)
sort.Slice(x, func(i, j int) bool {
return x[i] < x[j]
})
return string(x)
}
func parse(instr string) []*Display {
var o []*Display
for _, line := range strings.Split(strings.TrimSpace(instr), "\n") {
sp := strings.Split(line, " | ")
rawSampleString := sp[0]
rawOutputString := sp[1]
var samples []string
for _, x := range strings.Split(rawSampleString, " ") {
samples = append(samples, sortString(x))
}
var outputs []string
for _, x := range strings.Split(rawOutputString, " ") {
outputs = append(outputs, sortString(x))
}
o = append(o, &Display{
samples: samples,
outputs: outputs,
})
}
return o
}
func isDigitValid(digit string) bool {
for _, d := range digits {
if digit == d {
return true
}
}
return false
}
func translateDigit(mapping, inputDigit string) string {
var o string
for _, char := range inputDigit {
n := rune(char) - 'a'
o += string(mapping[n])
}
return sortString(o)
}
func isWiringValid(samples []string, wiring string) bool {
for _, sample := range samples {
if !isDigitValid(translateDigit(wiring, sample)) {
return false
}
}
return true
}
func findValidWiringFromSamples(samples []string) (string, error) {
for _, wiring := range possibleWirings {
if isWiringValid(samples, wiring) {
return wiring, nil
}
}
return "", errors.New("no valid wiring")
}
func getDisplayOutput(display *Display) (int, error) {
validWiring, err := findValidWiringFromSamples(display.samples)
if err != nil {
return 0, err
}
var o int
for _, digit := range display.outputs {
o *= 10
translated := translateDigit(validWiring, digit)
for i, y := range digits {
if translated == y {
o += i
break
}
}
}
return o, nil
}
type Challenge struct {
aocgo.BaseChallenge
}
func (c Challenge) One(instr string) (interface{}, error) {
displays := parse(instr)
var sigma int
for _, display := range displays {
for _, digit := range display.outputs {
ld := len(digit)
if ld == len(digits[1]) || ld == len(digits[4]) || ld == len(digits[7]) ||ld == len(digits[8]) {
sigma += 1
}
}
}
return sigma, nil
}
func (c Challenge) Two(instr string) (interface{}, error) {
displays := parse(instr)
var sigma int
for _, display := range displays {
s, err := getDisplayOutput(display)
if err != nil {
return nil, err
}
sigma += s
}
return sigma, nil
}

View file

@ -0,0 +1,17 @@
{
"inputFile": "input.txt",
"testCases": {
"one": [
{
"input": "be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe\nedbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc\nfgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg\nfbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb\naecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea\nfgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb\ndbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe\nbdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef\negadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb\ngcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce",
"expected": "26"
}
],
"two": [
{
"input": "be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe\nedbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc\nfgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg\nfbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb\naecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea\nfgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb\ndbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe\nbdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef\negadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb\ngcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce",
"expected": "61229"
}
]
}
}

View file

@ -0,0 +1,104 @@
import itertools
from typing import List
from aocpy import BaseChallenge
from dataclasses import dataclass
DIGITS = [
"abcefg",
"cf",
"acdeg",
"acdfg",
"bcdf",
"abdfg",
"abdefg",
"acf",
"abcdefg",
"abcdfg",
]
POSSIBLE_WIRINGS = list(itertools.permutations("abcdefg", 7))
@dataclass
class Display:
samples: List[str]
outputs: List[str]
def parse(instr: str) -> List[Display]:
def sort_string(s: str) -> str:
return "".join(sorted(s))
o = []
for line in instr.strip().splitlines():
samples, output = line.split(" | ")
o.append(
Display(
[sort_string(x) for x in samples.split(" ")],
[sort_string(x) for x in output.split(" ")],
)
)
return o
def is_digit_valid(digit: str) -> bool:
return digit in DIGITS
def translate_digit(mapping: str, input_digit: str) -> str:
o = ""
for char in input_digit:
n = ord(char) - ord("a")
o += mapping[n]
return "".join(sorted(o))
def is_wiring_valid(samples: List[str], wiring: str) -> bool:
for sample in samples:
if not is_digit_valid(translate_digit(wiring, sample)):
return False
return True
def find_valid_wiring_from_samples(samples: List[str]) -> str:
for wiring in POSSIBLE_WIRINGS:
if is_wiring_valid(samples, wiring):
return wiring
raise ValueError("no valid wiring")
def get_display_output(display: Display) -> int:
valid_wiring = find_valid_wiring_from_samples(display.samples)
o = 0
for digit in display.outputs:
o *= 10
translated = translate_digit(valid_wiring, digit)
o += DIGITS.index(translated)
return o
class Challenge(BaseChallenge):
@staticmethod
def one(instr: str) -> int:
displays = parse(instr)
sigma = 0
for display in displays:
for digit in display.outputs:
ld = len(digit)
if (
ld == len(DIGITS[1])
or ld == len(DIGITS[4])
or ld == len(DIGITS[7])
or ld == len(DIGITS[8])
):
sigma += 1
return sigma
@staticmethod
def two(instr: str) -> int:
displays = parse(instr)
sigma = 0
for display in displays:
sigma += get_display_output(display)
return sigma

View file

@ -8,15 +8,16 @@ 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) | Numbers and sliding windows. |
| 02 - Dive! | Complete | [Python](02-dive/py), [Go](02-dive/go) | Have this set of instructions and do something sensible with it. |
| 03 - Binary Diagnostic | Complete | [Python](03-binaryDiagnostic/py), [Nim](03-binaryDiagnostic/nim) | Bit twiddling aplenty! |
| 04 - Giant Squid | Complete | [Python](04-giantSquid/py) | B-I-N-G-O, B-I-N-G-O, B-I-N-G-O and Bingo was his name-o! |
| 05 - Hydrothermal Venture | Complete | [Python](05-hydrothermalVenture/py), [Go](05-hydrothermalVenture/go), [Nim](05-hydrothermalVenture/nim) | Pointy. |
| 06 - Lanternfish | Complete | [Python](06-lanternfish/py) | At this rate, the mass of the fish would surpass that of the Earth pretty quickly. |
| 07 - The Treachery of Whales | Complete | [Python](07-theTreacheryOfWhales/py) | I'm not 100% sure my solution for part two is valid for all possible inputs. |
| Day | Status | Solutions | Notes |
| ----------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| 01 - Sonar Sweep | Complete | [Python](01-sonarSweep/py), [Go](01-sonarSweep/go), [Nim](01-sonarSweep/nim) | Numbers and sliding windows. |
| 02 - Dive! | Complete | [Python](02-dive/py), [Go](02-dive/go) | Have this set of instructions and do something sensible with it. |
| 03 - Binary Diagnostic | Complete | [Python](03-binaryDiagnostic/py), [Nim](03-binaryDiagnostic/nim) | Bit twiddling aplenty! |
| 04 - Giant Squid | Complete | [Python](04-giantSquid/py) | B-I-N-G-O, B-I-N-G-O, B-I-N-G-O and Bingo was his name-o! |
| 05 - Hydrothermal Venture | Complete | [Python](05-hydrothermalVenture/py), [Go](05-hydrothermalVenture/go), [Nim](05-hydrothermalVenture/nim) | Pointy. |
| 06 - Lanternfish | Complete | [Python](06-lanternfish/py) | At this rate, the mass of the fish would surpass that of the Earth pretty quickly. |
| 07 - The Treachery of Whales | Complete | [Python](07-theTreacheryOfWhales/py) | I'm not 100% sure my solution for part two is valid for all possible inputs. |
| 08 - Seven Segment Search | Complete | [Python](08-sevenSegmentSearch/py), [Go](08-sevenSegmentSearch) | I may have taken the easy way out for part two, but it does work! No-one ever said the smart solution is the best solution, anyway. |
<!-- PARSE END -->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Before After
Before After

View file

@ -15,3 +15,48 @@ func (b BaseChallenge) Two(instr string) (interface{}, error) {
func (b BaseChallenge) Vis(instr string, outdir string) error {
return errors.New("not implemented")
}
func IntPermutations(arr []int) [][]int {
var helper func([]int, int)
res := [][]int{}
helper = func(arr []int, n int) {
if n == 1 {
tmp := make([]int, len(arr))
copy(tmp, arr)
res = append(res, tmp)
} else {
for i := 0; i < n; i++ {
helper(arr, n-1)
if n%2 == 1 {
tmp := arr[i]
arr[i] = arr[n-1]
arr[n-1] = tmp
} else {
tmp := arr[0]
arr[0] = arr[n-1]
arr[n-1] = tmp
}
}
}
}
helper(arr, len(arr))
return res
}
func StringPermutations(x string) []string {
var asInts []int
for _, char := range x {
asInts = append(asInts, int(char))
}
ip := IntPermutations(asInts)
var o []string
for _, x := range ip {
var b string
for _, y := range x {
b += string(rune(y))
}
o = append(o, b)
}
return o
}