Parallelized solution for day 2

This commit is contained in:
Nic
2025-12-02 19:16:49 +01:00
parent 1e223738eb
commit 1f17c73a60
2 changed files with 85 additions and 62 deletions

View File

@@ -11,64 +11,78 @@ type Interval struct {
}
// ScanLevel1 searches for invalid IDs (Level 1)
func (i *Interval) ScanLevel1() []int {
invalidIds := []int{}
func (i *Interval) ScanLevel1(intervals <-chan Interval, results chan<- int) {
for range intervals {
invalidIds := []int{}
for x := i.Start; x <= i.End; x++ {
strValue := strconv.Itoa(x)
for x := i.Start; x <= i.End; x++ {
strValue := strconv.Itoa(x)
// skip for ids with odd number of digits
if len(strValue)%2 == 1 {
continue
// skip for ids with odd number of digits
if len(strValue)%2 == 1 {
continue
}
halfLen := len(strValue) / 2
firstHalf := strValue[0:halfLen]
secondHalf := strValue[halfLen:]
if firstHalf == secondHalf {
invalidIds = append(invalidIds, x)
}
}
halfLen := len(strValue) / 2
firstHalf := strValue[0:halfLen]
secondHalf := strValue[halfLen:]
if firstHalf == secondHalf {
invalidIds = append(invalidIds, x)
var sum int
for _, id := range invalidIds {
sum += id
}
results <- sum
}
return invalidIds
}
// ScanLevel2 searches for invalid IDs (Level 2)
func (i *Interval) ScanLevel2() []int {
invalidIds := []int{}
func (i *Interval) ScanLevel2(intervals <-chan Interval, results chan<- int) {
for range intervals {
invalidIds := []int{}
for x := i.Start; x <= i.End; x++ {
strValue := strconv.Itoa(x)
for x := i.Start; x <= i.End; x++ {
strValue := strconv.Itoa(x)
// start of string, expands over time
head := string(strValue[0])
// start of string, expands over time
head := string(strValue[0])
var tail string = strValue
var tail string = strValue
for {
// abort if head is longer than half of input
if len(head) > len(strValue)/2 {
break
}
// check for prefix
if strings.HasPrefix(tail, head) {
// tail is remaining tail without first sequence
tail = strings.TrimPrefix(tail, head)
if tail == "" {
invalidIds = append(invalidIds, x)
for {
// abort if head is longer than half of input
if len(head) > len(strValue)/2 {
break
}
} else {
// reset tail, expand head
tail = strValue
head = strValue[0 : len(head)+1]
// check for prefix
if strings.HasPrefix(tail, head) {
// tail is remaining tail without first sequence
tail = strings.TrimPrefix(tail, head)
if tail == "" {
invalidIds = append(invalidIds, x)
break
}
} else {
// reset tail, expand head
tail = strValue
head = strValue[0 : len(head)+1]
}
}
}
}
var sum int
for _, id := range invalidIds {
sum += id
}
return invalidIds
results <- sum
}
}

View File

@@ -33,18 +33,6 @@ func getIntervals(content string) []Interval {
rawValues := strings.Split(split, "-")
// check length
if len(rawValues) < 2 {
log.Println("Skipped malformed interval:", split)
continue
}
// check for empty segments
if rawValues[0] == "" || rawValues[1] == "" {
log.Println("Skipped malformed interval:", split)
continue
}
// parse start to int
start, err := strconv.Atoi(rawValues[0])
if err != nil {
@@ -71,7 +59,7 @@ func getIntervals(content string) []Interval {
func main() {
// init
filename := "example.txt"
filename := "input.txt"
sum_lv1 := 0
sum_lv2 := 0
@@ -81,21 +69,42 @@ func main() {
filename = os.Args[1]
}
// read inputs
input := readFile(filename)
intervals := getIntervals(input)
// create channels, one for intervals and one for results for both
// level 1 and level 2
intervalsLevel1 := make(chan Interval)
intervalsLevel2 := make(chan Interval)
resultsLevel1 := make(chan int)
resultsLevel2 := make(chan int)
// scan each interval, collect invalid IDs, add them to total sum
for _, i := range intervals {
ids_lv1 := i.ScanLevel1()
ids_lv2 := i.ScanLevel2()
// spawn goroutines
go i.ScanLevel1(intervalsLevel1, resultsLevel1)
go i.ScanLevel2(intervalsLevel2, resultsLevel2)
for _, id := range ids_lv1 {
sum_lv1 += id
}
// pass intervals
intervalsLevel1 <- i
intervalsLevel2 <- i
}
for _, id := range ids_lv2 {
sum_lv2 += id
}
// close interval channels
close(intervalsLevel1)
close(intervalsLevel2)
// sum up results for level 1
for range len(intervals) {
r := <-resultsLevel1
sum_lv1 += r
}
// sum up results for level 2
for range len(intervals) {
r := <-resultsLevel2
sum_lv2 += r
}
// ta-daa