From e771ac9d9bc8626d01c8b7dde21a2a7cc7926b73 Mon Sep 17 00:00:00 2001 From: efim Date: Tue, 19 Dec 2023 11:46:16 +0000 Subject: [PATCH] day19, part2, finally --- day19/example1 | 5 ++++ day19/notes.org | 4 +++ day19/sortingParts.go | 70 ++++++++++++++++++++----------------------- 3 files changed, 42 insertions(+), 37 deletions(-) create mode 100644 day19/example1 diff --git a/day19/example1 b/day19/example1 new file mode 100644 index 0000000..0b3a3d0 --- /dev/null +++ b/day19/example1 @@ -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} diff --git a/day19/notes.org b/day19/notes.org index 6956293..ff560d8 100644 --- a/day19/notes.org +++ b/day19/notes.org @@ -41,3 +41,7 @@ and results from each rule application should be joined so. i need interval deduction 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. diff --git a/day19/sortingParts.go b/day19/sortingParts.go index 825f165..8d84449 100644 --- a/day19/sortingParts.go +++ b/day19/sortingParts.go @@ -12,7 +12,7 @@ import ( func Run() int { fmt.Println("hello day 19. sorting parts") - filename := "day19/example" + filename := "day19/input" bytes, err := os.ReadFile(filename) if err != nil { @@ -38,8 +38,9 @@ func Run() int { "s": [][]int{[]int{1, 4000}}, } - andChecked := processInterval(fullIntervals, "qqz", sorters) + andChecked := processInterval(fullIntervals, "in", sorters) log.Print("got and checked ", andChecked) + result = andChecked return result } @@ -96,13 +97,19 @@ const ( LessThan Operation = '<' MoreThan Operation = '>' ) +func (o Operation)String() string { + return string(o) +} type OperationData struct { AttrName string Operation Operation Num int SentToName string - String string + InitialString string +} +func (od OperationData)String() string { + return od.InitialString } type SorterData struct { @@ -149,7 +156,7 @@ func ReadSorterLine(line string) (result SorterData) { // s>2770:qs func ReadOperationLine(line string) (result OperationData) { - result.String = line + result.InitialString = line re := regexp.MustCompile(`(?P\D)(?P[\>\<])(?P\d+):(?P\D+)`) split := re.FindStringSubmatch(line) log.Printf("matching operation %s into %+v\n", line, split) @@ -285,19 +292,25 @@ func (o OperationData) getFailingIntervals(i AttrIntervals) AttrIntervals { return result } -func processInterval(i AttrIntervals, sorterName string, sorters map[string]SorterData) AttrIntervals { - result := AttrIntervals{ - "x": [][]int{}, - "m": [][]int{}, - "a": [][]int{}, - "s": [][]int{}, - } - +func processInterval(i AttrIntervals, sorterName string, sorters map[string]SorterData) (combinationsAccepted int) { 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" { - return result + return 0 } 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) ofThoseAreAccepted := processInterval(intervalsPassing, operation.SentToName, sorters) - result = MergeAuthIntervals(result, ofThoseAreAccepted) - log.Printf(">> %s; results so far are %+v", sorterName, result) + combinationsAccepted += ofThoseAreAccepted + 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) 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) intervalsAfterDefault := processInterval(intervalsPassingOnThisStep, s.DefaultState, sorters) log.Printf(">> %s; after defaul. passing are %+v", sorterName, intervalsAfterDefault) - result = MergeAuthIntervals(result, intervalsAfterDefault) - log.Printf(">> %s; results after default %+v", sorterName, result) + combinationsAccepted += intervalsAfterDefault + 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 -}