package day1 import ( "bufio" "fmt" "os" "slices" "strconv" "strings" ) func getDistance(x, y int) int { // Take the distance between two numbers. // The distance is the difference between the two numbers. if x > y { return (x - y) } else { return (y - x) } } func processLine(line string) (int, int, error) { // Split the line into fields. fields := strings.Fields(line) if len(fields) != 2 { return 0, 0, fmt.Errorf("Expected 2 fields, got %d", len(fields)) } num1, err := strconv.Atoi(fields[0]) if err != nil { return 0, 0, fmt.Errorf("Failed to parse first number: %w", err) } num2, err := strconv.Atoi(fields[1]) if err != nil { return 0, 0, fmt.Errorf("Failed to parse the second number: %w", err) } return num1, num2, nil } func readDataSet(filename string) ([]int, []int, error) { file, err := os.Open(filename) if err != nil { return nil, nil, err } defer file.Close() var firstSet, secondSet []int scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() num1, num2, err := processLine(line) if err != nil { return nil, nil, err } firstSet = append(firstSet, num1) secondSet = append(secondSet, num2) } return firstSet, secondSet, nil } func numFreq(dataset []int) map[int]int { // Take a slice of numbers and return an array of each number and the amount of times it occurs. distribution := make(map[int]int) for _, num := range dataset { elem, ok := distribution[num] if ok { distribution[num] = elem + 1 } else { distribution[num] = 1 } } return distribution } func partTwo(filename string) (int, error) { //Solve part two. var similarities int firstSet, secondSet, err := readDataSet(filename) if err != nil { return 0, err } secondDistribution := numFreq(secondSet) for _, num := range firstSet { freq, ok := secondDistribution[num] if ok { similarity := num * freq similarities = similarities + similarity } } return similarities, nil } func partOne(filename string) (int, error) { // Solve part one. firstSet, secondSet, err := readDataSet(filename) if err != nil { return 0, err } slices.Sort(firstSet) slices.Sort(secondSet) if len(firstSet) != len(secondSet) { return 0, fmt.Errorf("Error: Datasets are not the same size. %v != %v", len(firstSet), len(secondSet)) } var distances int for i := 0; i < len(firstSet); i++ { distance := getDistance(firstSet[i], secondSet[i]) distances = distances + distance } return distances, nil } func Day1(filename string) { distances, err := partOne(filename) if err != nil { fmt.Printf("Error: %v", err) os.Exit(1) } fmt.Println("-------- PART 1 -------") fmt.Printf("The total distance is %v\n", distances) similarities, err := partTwo(filename) if err != nil { fmt.Printf("Error: %v", err) os.Exit(1) } fmt.Println("-------- PART 2 -------") fmt.Printf("The similarities between the two sets: %v\n", similarities) }