Parallelized solution for day 2
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user