Day 7 (Golang)

This commit is contained in:
akp 2020-12-07 19:22:47 +00:00
parent 62d2c5efa1
commit 5b63f4957c
No known key found for this signature in database
GPG key ID: D3E7EAA31B39637E
6 changed files with 251 additions and 27 deletions

54
.github/README.md vendored
View file

@ -10,33 +10,33 @@ Go solutions are near direct copies of the Python solutions and may be added a f
<!-- PARSE START -->
| Day | | Python | Go |
| --------------------------- | ----------------------------- | ------------------------------------- | --------------------------------- |
| [1](/01-reportRepair) | ![Completed][check] | [Link](/01-reportRepair/python) | [Link](/01-reportRepair/go) |
| [2](/02-passwordPhilosophy) | ![Completed][check] | [Link](/02-passwordPhilosophy/python) | [Link](/02-passwordPhilosophy/go) |
| [3](/03-tobogganTrajectory) | ![Completed][check] | [Link](/03-tobogganTrajectory/python) | [Link](/03-tobogganTrajectory/go) |
| [4](/04-passportProcessing) | ![Completed][check] | [Link](/04-passportProcessing/python) | [Link](/04-passportProcessing/go) |
| [5](/05-binaryBoarding) | ![Completed][check] | [Link](/05-binaryBoarding/python) | [Link](/05-binaryBoarding/go) |
| [6](/06-customCustoms) | ![Completed][check] | [Link](/06-customCustoms/python) | [Link](/06-customCustoms/go) |
| [7](/07-handyHaversacks) | ![Partially complete][partial]| [Link](/07-handyHaversacks/python) | |
| 8 | | | |
| 9 | | | |
| 10 | | | |
| 11 | | | |
| 12 | | | |
| 13 | | | |
| 14 | | | |
| 15 | | | |
| 16 | | | |
| 17 | | | |
| 18 | | | |
| 19 | | | |
| 20 | | | |
| 21 | | | |
| 22 | | | |
| 23 | | | |
| 24 | | | |
| 25 | | | |
| Day | | Python | Go |
| --------------------------- | ------------------- | ------------------------------------- | --------------------------------- |
| [1](/01-reportRepair) | ![Completed][check] | [Link](/01-reportRepair/python) | [Link](/01-reportRepair/go) |
| [2](/02-passwordPhilosophy) | ![Completed][check] | [Link](/02-passwordPhilosophy/python) | [Link](/02-passwordPhilosophy/go) |
| [3](/03-tobogganTrajectory) | ![Completed][check] | [Link](/03-tobogganTrajectory/python) | [Link](/03-tobogganTrajectory/go) |
| [4](/04-passportProcessing) | ![Completed][check] | [Link](/04-passportProcessing/python) | [Link](/04-passportProcessing/go) |
| [5](/05-binaryBoarding) | ![Completed][check] | [Link](/05-binaryBoarding/python) | [Link](/05-binaryBoarding/go) |
| [6](/06-customCustoms) | ![Completed][check] | [Link](/06-customCustoms/python) | [Link](/06-customCustoms/go) |
| [7](/07-handyHaversacks) | ![Completed][check] | [Link](/07-handyHaversacks/python) | [Link](/07-handyHaversacks/go) |
| 8 | | | |
| 9 | | | |
| 10 | | | |
| 11 | | | |
| 12 | | | |
| 13 | | | |
| 14 | | | |
| 15 | | | |
| 16 | | | |
| 17 | | | |
| 18 | | | |
| 19 | | | |
| 20 | | | |
| 21 | | | |
| 22 | | | |
| 23 | | | |
| 24 | | | |
| 25 | | | |
<!-- PARSE END -->

View file

@ -89,6 +89,19 @@ Test cases
2.1 pass
2.2 pass
Answers
Part 1: 300
Part 2: 8030
go run .\go\
AoC 2020: day 7 - Handy Haversacks
Go go1.15.2
Test cases
1.1 pass
2.1 pass
2.2 pass
Answers
Part 1: 300
Part 2: 8030

View file

@ -0,0 +1,42 @@
package challenge
import (
"regexp"
"strconv"
"strings"
)
var (
ruleRegex = regexp.MustCompile(`(.+) bags contain (.+).`)
definitionRegex = regexp.MustCompile(`(\d+) (.+) bags?`)
)
const (
targetColour = "shiny gold"
)
func parse(instr string) map[string]map[string]int {
inp := strings.Split(strings.TrimSpace(instr), "\n")
rules := make(map[string]map[string]int)
for _, rule := range inp {
rr := ruleRegex.FindAllStringSubmatch(rule, -1)
containerBag := rr[0][1]
ruleSet := strings.Split(rr[0][2], ", ")
bagRules := make(map[string]int)
for _, definition := range ruleSet {
rsr := definitionRegex.FindAllStringSubmatch(definition, -1)
if len(rsr) != 0 {
i, _ := strconv.Atoi(rsr[0][1])
bagRules[rsr[0][2]] = i
}
}
rules[containerBag] = bagRules
}
return rules
}

View file

@ -0,0 +1,41 @@
package challenge
func checkBag(ruleset map[string]map[string]int, testCl, targetCl string) bool {
{
var isPresent bool
for v := range ruleset[testCl] {
if v == targetCl {
isPresent = true
break
}
}
if isPresent {
return true
}
}
for childColour := range ruleset[testCl] {
if checkBag(ruleset, childColour, targetCl) {
return true
}
}
return false
}
func PartOne(instr string) int {
rules := parse(instr)
canContainTarget := 0
for bagColour, _ := range rules {
if bagColour != targetColour {
if checkBag(rules, bagColour, targetColour) {
canContainTarget += 1
}
}
}
return canContainTarget
}

View file

@ -0,0 +1,28 @@
package challenge
func countForBag(ruleset map[string]map[string]int, testCl string) int {
if len(ruleset[testCl]) == 0 {
return -1
}
count := 0
for childColour := range ruleset[testCl] {
childBags := countForBag(ruleset, childColour)
var v int
if childBags == -1 {
v = ruleset[testCl][childColour]
} else {
v = ruleset[testCl][childColour] * childBags
v += ruleset[testCl][childColour]
}
count += v
}
return count
}
func PartTwo(instr string) int {
return countForBag(parse(instr), targetColour)
}

View file

@ -0,0 +1,100 @@
package main
import (
"adventOfCode/07-handyHaversacks/go/challenge"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"runtime"
"strconv"
"github.com/fatih/color"
)
func main() {
var infoStruct info
{
inb, err := ioutil.ReadFile("info.json")
if err != nil {
fmt.Println("Error: could not open info.json")
os.Exit(-1)
}
err = json.Unmarshal(inb, &infoStruct)
if err != nil {
fmt.Println("Error: could not parse info.json")
os.Exit(-1)
}
}
var (
year = infoStruct.Year
day = infoStruct.Day
title = infoStruct.Title
)
fmt.Fprintf(color.Output, "%s: day %s - %s\n", color.YellowString("AoC "+year), color.BlueString(day), title)
fmt.Fprintf(color.Output, "Go %s\n\n", color.BlueString(runtime.Version()))
var challengeInput string
{
inb, err := ioutil.ReadFile("input.txt")
if err != nil {
fmt.Println("Error: could not open input.txt")
os.Exit(-1)
}
challengeInput = string(inb)
}
runTests(infoStruct)
fmt.Println("Answers")
fmt.Fprintf(color.Output, "Part %s: %s\n", color.BlueString("1"), color.BlueString(strconv.Itoa(challenge.PartOne(challengeInput))))
fmt.Fprintf(color.Output, "Part %s: %s\n", color.BlueString("2"), color.BlueString(strconv.Itoa(challenge.PartTwo(challengeInput))))
}
type tc struct {
Input string `json:"input"`
Expected int `json:"expected"`
}
type info struct {
Year string `json:"year"`
Day string `json:"day"`
Title string `json:"title"`
TestCases struct {
One []tc `json:"one"`
Two []tc `json:"two"`
} `json:"testCases"`
}
func runTests(infoStruct info) {
if len(infoStruct.TestCases.One) == 0 && len(infoStruct.TestCases.Two) == 0 {
fmt.Println("Info: no test cases specified. Skipping tests")
fmt.Println()
return
}
fmt.Println("Test cases")
rt := func(tcs []tc, f func(string) int, n string) {
for i, tc := range tcs {
fmt.Fprintf(color.Output, "%s ", color.BlueString(n+"."+strconv.Itoa(i+1)))
result := f(tc.Input)
if result == tc.Expected {
fmt.Fprintf(color.Output, "%s", color.GreenString("pass"))
} else {
fmt.Fprintf(color.Output, "%s (got %s, expected %s)", color.RedString("fail"), color.BlueString(strconv.Itoa(result)), color.BlueString(strconv.Itoa(tc.Expected)))
}
fmt.Println()
}
}
rt(infoStruct.TestCases.One, challenge.PartOne, "1")
rt(infoStruct.TestCases.Two, challenge.PartTwo, "2")
fmt.Println()
}