day19, part2, finally
This commit is contained in:
parent
52beb4196f
commit
e771ac9d9b
|
@ -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}
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue