Day 19.2 solved.

This commit is contained in:
Anna Rose 2020-12-20 04:00:20 +00:00
parent 817a08aba7
commit f09b1fc787

View File

@ -9,16 +9,16 @@ import (
"git.annabunch.es/annabunches/adventofcode/2020/lib/util"
)
type Node struct {
name string
children [][]*Node
}
const (
STATE_RULES = iota
STATE_DATA
)
type Node struct {
name string
children [][]*Node
}
func NewRule(name string) *Node {
return &Node{
name: name,
@ -26,8 +26,6 @@ func NewRule(name string) *Node {
}
}
var expandRe = regexp.MustCompile("[0-9]+")
func parseRule(name string, rules map[string]string) *Node {
ruleString := rules[name]
rule := NewRule(name)
@ -50,12 +48,11 @@ func parseRule(name string, rules map[string]string) *Node {
return rule
}
func parseInput(input []string) (map[string]bool, []string) {
func parseInput(input []string) (map[string]string, []string) {
stateRe := regexp.MustCompile("^([0-9]+): (.*)$")
state := STATE_RULES
data := make([]string, 0)
var root *Node
rules := make(map[string]string) // unparsed rules
for _, line := range input {
@ -75,8 +72,11 @@ func parseInput(input []string) (map[string]bool, []string) {
}
}
// now parse the rules we stored
root = parseRule("0", rules)
return rules, data
}
func createLanguage(rules map[string]string, rootName string) map[string]bool {
root := parseRule(rootName, rules)
// now we expand the grammar - generate all possible strings in the language
rawLanguage := expand(root)
@ -85,7 +85,7 @@ func parseInput(input []string) (map[string]bool, []string) {
language[term] = true
}
return language, data
return language
}
// Expand the list of all possible substrings starting with node
@ -133,13 +133,61 @@ func combine(terms [][]string, acc string) []string {
}
func main() {
// step := os.Args[1]
step := os.Args[1]
values := util.InputParserStrings(os.Args[2])
language, data := parseInput(values)
rules, data := parseInput(values)
count := 0
for _, item := range data {
if language[item] {
count++
switch step {
case "1":
language := createLanguage(rules, "0")
for _, item := range data {
if language[item] {
count++
}
}
case "2":
// stub
// for step 2, our base rule expands to 0: 42{N} 31{M}, for N > M and N > 2
// we exploit this, along with the fact that all valid strings for 42 and 31 are
// 8 characters long, to "cheat" a little
matchLength := 8
left := createLanguage(rules, "42")
right := createLanguage(rules, "31")
for _, item := range data {
leftCount := 0
rightCount := 0
onLeft := true
valid := true // valid until proven otherwise
for index := 0; index < len(item); index += matchLength {
if len(item[index:]) < matchLength {
fmt.Println("Bad Length")
valid = false // wrong length alignment
break
}
subString := item[index : index+matchLength]
if onLeft {
if left[subString] {
leftCount++
} else {
onLeft = false
}
}
if !onLeft {
if right[subString] {
rightCount++
} else {
valid = false
break
}
}
}
if valid && leftCount > 1 && rightCount > 0 && leftCount > rightCount {
count++
}
}
}
fmt.Println(count)