Day 19.2 solved.
This commit is contained in:
parent
817a08aba7
commit
f09b1fc787
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue
Block a user