diff --git a/2025/five/five.go b/2025/five/five.go new file mode 100644 index 0000000..4fba271 --- /dev/null +++ b/2025/five/five.go @@ -0,0 +1,101 @@ +package main + +import ( + "bufio" + "errors" + "fmt" + "os" + "strconv" + "strings" +) + +type freshRange struct { + start, end int +} + +func (r *freshRange) contains(c int) bool { + return c >= r.start && c <= r.end +} + +func (r *freshRange) nInRange() int { + return (r.end - r.start) + 1 +} + +func check(err error) { + if err != nil { + panic(err) + } +} + +func getRanges(scanner *bufio.Scanner) (ranges []freshRange, err error) { + ranges = make([]freshRange, 0, 5) + + for scanner.Scan() { + text := scanner.Text() + + if text == "" { + return ranges, nil + } + + startEnd := strings.Split(text, "-") + + if len(startEnd) != 2 { + return nil, errors.New("Fresh range does not contain exactly two numbers") + } + + start, err := strconv.Atoi(startEnd[0]) + if err != nil { + return nil, err + } + + end, err := strconv.Atoi(startEnd[1]) + if err != nil { + return nil, err + } + + ranges = append(ranges, freshRange{start, end}) + } + return nil, errors.New("No empty line in file to delimit fresh ranges") +} + +func main() { + + file, err := os.Open("five.txt") + check(err) + defer file.Close() + + scanner := bufio.NewScanner(file) + ranges, err := getRanges(scanner) + check(err) + + authRanges := make([]freshRange, 1, len(ranges)) + authRanges[0] = ranges[0] + +RANGE: + for _, r := range ranges { + + for _, authR := range authRanges { + if authR.contains(r.start) { + if r.end > authR.end { + authR.end = r.end + } + continue RANGE + } + + if authR.contains(r.end) { + if r.start < authR.start { + authR.start = r.start + } + continue RANGE + } + } + authRanges = append(authRanges, r) + } + + potentialNFresh := 0 + for _, r := range authRanges { + potentialNFresh += r.nInRange() + } + + fmt.Printf("N raw %d and consolidated %d. %d potential fresh ingredients.\n", len(ranges), len(authRanges), potentialNFresh) +}