Initial commit

This commit is contained in:
2024-12-01 17:41:25 +01:00
commit dc284b7f47
9 changed files with 1419 additions and 0 deletions

142
days/day1/day1.go Normal file
View File

@ -0,0 +1,142 @@
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)
}