Add 2021-08 in Python and Go
This commit is contained in:
parent
7b364a97f9
commit
a038dccaef
8 changed files with 350 additions and 9 deletions
2
challenges/2021/08-seventSegmentSearch/README.md
Normal file
2
challenges/2021/08-seventSegmentSearch/README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# [Day 8: Sevent Segment Search](https://adventofcode.com/2021/day/8)
|
||||
|
23
challenges/2021/08-seventSegmentSearch/benchmark.json
Normal file
23
challenges/2021/08-seventSegmentSearch/benchmark.json
Normal 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
|
||||
}
|
149
challenges/2021/08-seventSegmentSearch/go/challenge.go
Normal file
149
challenges/2021/08-seventSegmentSearch/go/challenge.go
Normal 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
|
||||
}
|
17
challenges/2021/08-seventSegmentSearch/info.json
Normal file
17
challenges/2021/08-seventSegmentSearch/info.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
104
challenges/2021/08-seventSegmentSearch/py/__init__.py
Normal file
104
challenges/2021/08-seventSegmentSearch/py/__init__.py
Normal 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
|
|
@ -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 |
|
@ -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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue