day19, struggling part2, not quite yet
This commit is contained in:
parent
5f62ea45f7
commit
52beb4196f
|
@ -0,0 +1,57 @@
|
|||
package day19
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
func merge(intervals [][]int) [][]int {
|
||||
const start, end = 0, 1
|
||||
|
||||
var merged [][]int
|
||||
|
||||
if len(intervals) > 1 {
|
||||
sort.Slice(intervals, func(i, j int) bool {
|
||||
return intervals[i][start] < intervals[j][start]
|
||||
})
|
||||
}
|
||||
|
||||
for _, interval := range intervals {
|
||||
last := len(merged) - 1
|
||||
if last < 0 || interval[start] > merged[last][end] {
|
||||
merged = append(merged,
|
||||
[]int{start: interval[start], end: interval[end]},
|
||||
)
|
||||
} else if interval[end] > merged[last][end] {
|
||||
merged[last][end] = interval[end]
|
||||
}
|
||||
}
|
||||
|
||||
return merged[:len(merged):len(merged)]
|
||||
}
|
||||
|
||||
func applyLessThan(intervals [][]int, n int) [][]int {
|
||||
var lessers [][]int
|
||||
for _, interval := range intervals {
|
||||
from := interval[0]
|
||||
if from >= n {
|
||||
continue
|
||||
}
|
||||
lessers = append(lessers, []int{from, n-1})
|
||||
}
|
||||
|
||||
return lessers
|
||||
}
|
||||
|
||||
func applyMoreThan(intervals [][]int, n int) [][]int {
|
||||
var greaters [][]int
|
||||
for _, interval := range intervals {
|
||||
to := interval[1]
|
||||
if to <= n {
|
||||
continue
|
||||
}
|
||||
greaters = append(greaters, []int{n+1, to})
|
||||
}
|
||||
// log.Printf(">>>> in applyMoreThan %d to %+v ; result %+v", n, intervals, greaters)
|
||||
|
||||
return greaters
|
||||
}
|
|
@ -25,3 +25,19 @@ with special cases for "R" and "A"
|
|||
|
||||
so. have funciton from OpeartionData & Detail -> true/false
|
||||
if true take the destination, if false, check next
|
||||
* well. only way to do this is with intervals
|
||||
|
||||
so, sorter check takes in interval.
|
||||
|
||||
then for each of the rule,
|
||||
call first rule with full interval,
|
||||
deduct first rule (for those that don't match) and pass to second.
|
||||
deduct second and pass to next
|
||||
|
||||
A will return full
|
||||
R will return empty
|
||||
|
||||
and results from each rule application should be joined
|
||||
|
||||
so. i need interval deduction
|
||||
and i need interval join
|
||||
|
|
|
@ -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 {
|
||||
|
@ -80,7 +91,9 @@ func CountApprovedDetails(details []DetailData, sorters map[string]SorterData) i
|
|||
}
|
||||
|
||||
type Operation rune
|
||||
const (LessThan Operation = '<'
|
||||
|
||||
const (
|
||||
LessThan Operation = '<'
|
||||
MoreThan Operation = '>'
|
||||
)
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue