day19, struggling part2, not quite yet

This commit is contained in:
efim
2023-12-19 11:00:59 +00:00
parent 5f62ea45f7
commit 52beb4196f
3 changed files with 205 additions and 20 deletions

View File

@@ -28,9 +28,20 @@ func Run() int {
log.Printf("yay, got sorters\n%+v\nand details\n%+v", sorters, details)
countApproved := CountApprovedDetails(details, sorters)
// countApproved := CountApprovedDetails(details, sorters)
result := 0
return countApproved
fullIntervals := AttrIntervals{
"x": [][]int{[]int{1, 4000}},
"m": [][]int{[]int{1, 4000}},
"a": [][]int{[]int{1, 4000}},
"s": [][]int{[]int{1, 4000}},
}
andChecked := processInterval(fullIntervals, "qqz", sorters)
log.Print("got and checked ", andChecked)
return result
}
func CountApprovedDetails(details []DetailData, sorters map[string]SorterData) int {
@@ -39,7 +50,7 @@ func CountApprovedDetails(details []DetailData, sorters map[string]SorterData) i
approvedDetails := make(chan DetailData)
go func(){
go func() {
wg.Wait()
close(approvedDetails)
}()
@@ -49,7 +60,7 @@ func CountApprovedDetails(details []DetailData, sorters map[string]SorterData) i
done := make(chan any)
go func(){
go func() {
for detail := range approvedDetails {
log.Println("got approved ", detail)
count += 1
@@ -74,28 +85,30 @@ func CountApprovedDetails(details []DetailData, sorters map[string]SorterData) i
}(d)
}
<- done
<-done
return acceptedScore
}
type Operation rune
const (LessThan Operation = '<'
const (
LessThan Operation = '<'
MoreThan Operation = '>'
)
type OperationData struct {
AttrName string
Operation Operation
Num int
AttrName string
Operation Operation
Num int
SentToName string
String string
String string
}
type SorterData struct {
Name string
Name string
DefaultState string
Operations []OperationData
Operations []OperationData
}
func ReadSorters(sortersText string) map[string]SorterData {
@@ -104,7 +117,7 @@ func ReadSorters(sortersText string) map[string]SorterData {
lines := strings.Split(sortersText, "\n")
for _, line := range lines {
sorter := ReadSorterLine(line)
sorter := SimplifyOperation( ReadSorterLine(line) )
result[sorter.Name] = sorter
}
@@ -120,12 +133,12 @@ func ReadSorterLine(line string) (result SorterData) {
result.Name = firstSplit[1]
operationLines := strings.Split(firstSplit[2], ",")
operations := make([]OperationData, len(operationLines) - 1)
operations := make([]OperationData, len(operationLines)-1)
result.Operations = operations
result.DefaultState = operationLines[len(operationLines) - 1]
result.DefaultState = operationLines[len(operationLines)-1]
for i, line := range operationLines[:len(operationLines) - 1] {
for i, line := range operationLines[:len(operationLines)-1] {
operations[i] = ReadOperationLine(line)
}
@@ -182,7 +195,7 @@ func ReadDetailsPart(text string) (result []DetailData) {
func ReadDetailLine(line string) (result DetailData) {
attrs := make(map[string]int)
result.Attrs = attrs
line = line[1:len(line)-1]
line = line[1 : len(line)-1]
attrsLine := strings.Split(line, ",")
re := regexp.MustCompile(`(?P<ATTR>\D)=(?P<NUM>\d+)`)
for _, attrLine := range attrsLine {
@@ -200,7 +213,7 @@ func ReadDetailLine(line string) (result DetailData) {
func ProcessDetail(d DetailData, sorters map[string]SorterData) (isAccepted bool) {
curSorterName := "in"
for (curSorterName != "A" && curSorterName != "R") {
for curSorterName != "A" && curSorterName != "R" {
sorter, found := sorters[curSorterName]
if !found {
panic(fmt.Sprint("error finding soter ", curSorterName))
@@ -210,7 +223,7 @@ func ProcessDetail(d DetailData, sorters map[string]SorterData) (isAccepted bool
return curSorterName == "A"
}
func (s SorterData)NextSorterNameFor(d DetailData) string {
func (s SorterData) NextSorterNameFor(d DetailData) string {
for _, operation := range s.Operations {
if operation.IsDetailPassing(d) {
return operation.SentToName
@@ -220,7 +233,7 @@ func (s SorterData)NextSorterNameFor(d DetailData) string {
return s.DefaultState
}
func (o OperationData)IsDetailPassing(d DetailData) bool {
func (o OperationData) IsDetailPassing(d DetailData) bool {
detailValue := d.Attrs[o.AttrName]
switch o.Operation {
case LessThan:
@@ -231,3 +244,102 @@ func (o OperationData)IsDetailPassing(d DetailData) bool {
panic(fmt.Sprint("unknown operation. ", o, d))
}
type AttrIntervals map[string][][]int
func (o OperationData) getPassingIntervals(i AttrIntervals) AttrIntervals {
result := make(AttrIntervals, 0)
for key, value := range i {
result[key] = value
}
operationKey := o.AttrName
operatedIntervals := result[operationKey]
switch o.Operation {
case LessThan:
result[operationKey] = applyLessThan(operatedIntervals, o.Num)
case MoreThan:
result[operationKey] = applyMoreThan(operatedIntervals, o.Num)
}
return result
}
func (o OperationData) getFailingIntervals(i AttrIntervals) AttrIntervals {
result := make(AttrIntervals, 0)
for key, value := range i {
result[key] = value
}
operationKey := o.AttrName
operatedIntervals := result[operationKey]
switch o.Operation {
case LessThan:
result[operationKey] = applyMoreThan(operatedIntervals, o.Num-1)
case MoreThan:
result[operationKey] = applyLessThan(operatedIntervals, o.Num+1)
}
return result
}
func processInterval(i AttrIntervals, sorterName string, sorters map[string]SorterData) AttrIntervals {
result := AttrIntervals{
"x": [][]int{},
"m": [][]int{},
"a": [][]int{},
"s": [][]int{},
}
if sorterName == "A" {
return i
}
if sorterName == "R" {
return result
}
s := sorters[sorterName]
log.Printf("> starting interval check for %s (%+v) on %+v", sorterName, s, i)
intervalsPassingOnThisStep := i
for _, operation := range s.Operations {
intervalsPassing := operation.getPassingIntervals(intervalsPassingOnThisStep)
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)
intervalsFailingAndPassedToNextCheck := operation.getFailingIntervals(i)
log.Printf(">> %s; failing for the next step %+v", sorterName, intervalsFailingAndPassedToNextCheck)
intervalsPassingOnThisStep = intervalsFailingAndPassedToNextCheck
}
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)
return result
}
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
}