Solving Advent of Code 2024 in Go
·
Manthan Gupta
Day 1
Link: Day 1
package main
import (
"bufio"
"fmt"
"log"
"os"
"sort"
"strconv"
"strings"
)
func main() {
fmt.Println(part1())
fmt.Println(part2())
}
func readInput() ([]int, []int) {
fi, err := os.Open("day1_input.txt")
if err != nil {
log.Fatal(err)
}
defer fi.Close()
scanner := bufio.NewScanner(fi)
left_list := make([]int, 0, 1000)
right_list := make([]int, 0, 1000)
for scanner.Scan() {
line := scanner.Text()
nums := strings.Fields(line)
if len(nums) != 2 {
log.Fatalf("expected 2 numbers, got %d", len(nums))
}
left, err := strconv.Atoi(nums[0])
if err != nil {
log.Fatalf("failed to parse left number: %v", err)
}
right, err := strconv.Atoi(nums[1])
if err != nil {
log.Fatalf("failed to parse right number: %v", err)
}
left_list = append(left_list, left)
right_list = append(right_list, right)
}
return left_list, right_list
}
func part1() int {
left_list, right_list := readInput()
sort.Ints(left_list)
sort.Ints(right_list)
res := 0
for i := range left_list {
diff := left_list[i] - right_list[i]
if diff < 0 {
diff = -diff
}
res += diff
}
return res
}
func part2() int {
left_list, right_list := readInput()
freq_dict := make(map[int]int)
for _, num := range right_list {
freq_dict[num]++
}
res := 0
for _, num := range left_list {
res += (freq_dict[num] * num)
}
return res
}
Day 2
Link: Day 2
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
nums := part1()
fmt.Println(nums)
nums2 := part2()
fmt.Println(nums2)
}
func part1() int {
fi, err := os.Open("input.txt")
if err != nil {
panic(err)
}
defer fi.Close()
scanner := bufio.NewScanner(fi)
safe := 0
for scanner.Scan() {
line := scanner.Text()
nums := strings.Fields(line)
intNums, err := convertToIntSlice(nums)
if err != nil {
panic(err)
}
increasing := intNums[0] <= intNums[1]
changed := false
for i := 1; i < len(intNums); i++ {
diff := intNums[i] - intNums[i-1]
if (diff < 0 && increasing) || (diff > 0 && !increasing) || abs(diff) > 3 || diff == 0 {
changed = true
break
}
}
if !changed {
safe++
}
}
return safe
}
func part2() int {
fi, err := os.Open("input.txt")
if err != nil {
panic(err)
}
defer fi.Close()
scanner := bufio.NewScanner(fi)
safe := 0
for scanner.Scan() {
line := scanner.Text()
nums := strings.Fields(line)
intNums, err := convertToIntSlice(nums)
if err != nil {
panic(err)
}
increasing := intNums[0] <= intNums[1]
changed := 0
for i := 1; i < len(intNums); i++ {
diff := intNums[i] - intNums[i-1]
if (diff < 0 && increasing) || (diff > 0 && !increasing) || abs(diff) > 3 || diff == 0 {
changed++
}
}
if changed <= 1 {
safe++
}
}
return safe
}
func convertToIntSlice(nums []string) ([]int, error) {
intNums := make([]int, len(nums))
for i, num := range nums {
var err error
intNums[i], err = strconv.Atoi(num)
if err != nil {
return nil, err
}
}
return intNums, nil
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
Day 3
Link: Day 3
package main
import (
"bufio"
"fmt"
"os"
"regexp"
"strconv"
)
func main() {
part1()
part2()
}
func readInput() []string {
fi, err := os.Open("input.txt")
if err != nil {
panic(err)
}
defer fi.Close()
scanner := bufio.NewScanner(fi)
var lines []string
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
return lines
}
func part1() {
lines := readInput()
re := regexp.MustCompile(`mul\(\s*(\d+)\s*,\s*(\d+)\s*\)`)
res := 0
for _, line := range lines {
matches := re.FindAllStringSubmatch(line, -1)
for _, match := range matches {
a, _ := strconv.Atoi(match[1])
b, _ := strconv.Atoi(match[2])
res += a * b
}
}
fmt.Println(res)
}
func part2() {
lines := readInput()
re := regexp.MustCompile(`do\(\)|don't\(\)|mul\((\d{1,3}),(\d{1,3})\)`)
res := 0
switching := true
for _, line := range lines {
matches := re.FindAllStringSubmatch(line, -1)
for _, match := range matches {
if match[0] == "do()" {
switching = true
} else if match[0] == "don't()" {
switching = false
} else if len(match) == 3 && switching {
a, _ := strconv.Atoi(match[1])
b, _ := strconv.Atoi(match[2])
res += a * b
}
}
}
fmt.Println(res)
}
Star the github repo if you liked the solution.