Initial commit
This commit is contained in:
142
days/day1/day1.go
Normal file
142
days/day1/day1.go
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user