day19, part2, finally

This commit is contained in:
efim 2023-12-19 11:46:16 +00:00
parent 52beb4196f
commit e771ac9d9b
3 changed files with 42 additions and 37 deletions

5
day19/example1 Normal file
View File

@ -0,0 +1,5 @@
in{x<4000:R,m<4000:R,A}
px{a<4000:R,A}
qqz{s>2770:R,m<1801:A,R}
{x=787,m=2655,a=1222,s=2876}

View File

@ -41,3 +41,7 @@ and results from each rule application should be joined
so. i need interval deduction so. i need interval deduction
and i need interval join and i need interval join
* found a bug in always using initial intervals to calculate 'failing' after each step
2023/12/19 11:45:14 got and checked 167409079868000
In the above example, there are 167409079868000 distinct combinations of ratings that will be accepted.

View File

@ -12,7 +12,7 @@ import (
func Run() int { func Run() int {
fmt.Println("hello day 19. sorting parts") fmt.Println("hello day 19. sorting parts")
filename := "day19/example" filename := "day19/input"
bytes, err := os.ReadFile(filename) bytes, err := os.ReadFile(filename)
if err != nil { if err != nil {
@ -38,8 +38,9 @@ func Run() int {
"s": [][]int{[]int{1, 4000}}, "s": [][]int{[]int{1, 4000}},
} }
andChecked := processInterval(fullIntervals, "qqz", sorters) andChecked := processInterval(fullIntervals, "in", sorters)
log.Print("got and checked ", andChecked) log.Print("got and checked ", andChecked)
result = andChecked
return result return result
} }
@ -96,13 +97,19 @@ const (
LessThan Operation = '<' LessThan Operation = '<'
MoreThan Operation = '>' MoreThan Operation = '>'
) )
func (o Operation)String() string {
return string(o)
}
type OperationData struct { type OperationData struct {
AttrName string AttrName string
Operation Operation Operation Operation
Num int Num int
SentToName string SentToName string
String string InitialString string
}
func (od OperationData)String() string {
return od.InitialString
} }
type SorterData struct { type SorterData struct {
@ -149,7 +156,7 @@ func ReadSorterLine(line string) (result SorterData) {
// s>2770:qs // s>2770:qs
func ReadOperationLine(line string) (result OperationData) { func ReadOperationLine(line string) (result OperationData) {
result.String = line result.InitialString = line
re := regexp.MustCompile(`(?P<ATTRNAME>\D)(?P<OPERATION>[\>\<])(?P<NUMBER>\d+):(?P<TARGET>\D+)`) re := regexp.MustCompile(`(?P<ATTRNAME>\D)(?P<OPERATION>[\>\<])(?P<NUMBER>\d+):(?P<TARGET>\D+)`)
split := re.FindStringSubmatch(line) split := re.FindStringSubmatch(line)
log.Printf("matching operation %s into %+v\n", line, split) log.Printf("matching operation %s into %+v\n", line, split)
@ -285,19 +292,25 @@ func (o OperationData) getFailingIntervals(i AttrIntervals) AttrIntervals {
return result return result
} }
func processInterval(i AttrIntervals, sorterName string, sorters map[string]SorterData) AttrIntervals { func processInterval(i AttrIntervals, sorterName string, sorters map[string]SorterData) (combinationsAccepted int) {
result := AttrIntervals{
"x": [][]int{},
"m": [][]int{},
"a": [][]int{},
"s": [][]int{},
}
if sorterName == "A" { if sorterName == "A" {
return i mul := 1
for key, attrIntervals := range i {
allowedValuesOfAttr := 0
for _, interval := range attrIntervals {
from := interval[0]
to := interval[1]
len := to - from + 1
allowedValuesOfAttr += len
log.Printf("for %s allowed attrs are %d", key, allowedValuesOfAttr)
}
mul *= allowedValuesOfAttr
}
log.Printf("exit recursion for %s. Accept interval %+v . result %d. max is %d", sorterName, i, mul, 40000 * 4000 * 4000 * 4000)
return mul
} }
if sorterName == "R" { if sorterName == "R" {
return result return 0
} }
s := sorters[sorterName] s := sorters[sorterName]
@ -309,10 +322,10 @@ func processInterval(i AttrIntervals, sorterName string, sorters map[string]Sor
log.Printf(">> %s; in operation %+v. passing are %+v", sorterName, operation, intervalsPassing) log.Printf(">> %s; in operation %+v. passing are %+v", sorterName, operation, intervalsPassing)
ofThoseAreAccepted := processInterval(intervalsPassing, operation.SentToName, sorters) ofThoseAreAccepted := processInterval(intervalsPassing, operation.SentToName, sorters)
result = MergeAuthIntervals(result, ofThoseAreAccepted) combinationsAccepted += ofThoseAreAccepted
log.Printf(">> %s; results so far are %+v", sorterName, result) log.Printf(">> %s; results so far are %d", sorterName, combinationsAccepted)
intervalsFailingAndPassedToNextCheck := operation.getFailingIntervals(i) intervalsFailingAndPassedToNextCheck := operation.getFailingIntervals(intervalsPassingOnThisStep)
log.Printf(">> %s; failing for the next step %+v", sorterName, intervalsFailingAndPassedToNextCheck) log.Printf(">> %s; failing for the next step %+v", sorterName, intervalsFailingAndPassedToNextCheck)
intervalsPassingOnThisStep = intervalsFailingAndPassedToNextCheck intervalsPassingOnThisStep = intervalsFailingAndPassedToNextCheck
} }
@ -320,26 +333,9 @@ func processInterval(i AttrIntervals, sorterName string, sorters map[string]Sor
log.Printf(">> %s; about to go into DEFAULT", sorterName) log.Printf(">> %s; about to go into DEFAULT", sorterName)
intervalsAfterDefault := processInterval(intervalsPassingOnThisStep, s.DefaultState, sorters) intervalsAfterDefault := processInterval(intervalsPassingOnThisStep, s.DefaultState, sorters)
log.Printf(">> %s; after defaul. passing are %+v", sorterName, intervalsAfterDefault) log.Printf(">> %s; after defaul. passing are %+v", sorterName, intervalsAfterDefault)
result = MergeAuthIntervals(result, intervalsAfterDefault) combinationsAccepted += intervalsAfterDefault
log.Printf(">> %s; results after default %+v", sorterName, result) log.Printf(">> %s; results after default %d", sorterName, combinationsAccepted)
return result return
} }
func MergeAuthIntervals(a AttrIntervals, b AttrIntervals) AttrIntervals {
result := AttrIntervals{
"x": [][]int{},
"m": [][]int{},
"a": [][]int{},
"s": [][]int{},
}
for key := range result {
aAttrIntervals := a[key]
bAttrIntervals := b[key]
allIntervals := append(aAttrIntervals, bAttrIntervals...)
result[key] = merge(allIntervals)
}
return result
}