Compare commits
No commits in common. "66a9f3f9e60228373bee52baf25ebc3c471d1b17" and "9c97386cef61e23946a0620ed3f21263367fd8a1" have entirely different histories.
66a9f3f9e6
...
9c97386cef
10
day1.go
10
day1.go
@ -12,7 +12,7 @@ type Day1Input struct {
|
|||||||
column2 []int64
|
column2 []int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func Day1Parse(lines []string) (*Day1Input, error) {
|
func day1_parse(lines []string) (*Day1Input, error) {
|
||||||
column1 := make([]int64, len(lines))
|
column1 := make([]int64, len(lines))
|
||||||
column2 := make([]int64, len(lines))
|
column2 := make([]int64, len(lines))
|
||||||
|
|
||||||
@ -42,8 +42,8 @@ func Day1Parse(lines []string) (*Day1Input, error) {
|
|||||||
return &parsed, nil
|
return &parsed, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Day1Part1(lines []string) (error) {
|
func day1_part1(lines []string) (error) {
|
||||||
input, err := Day1Parse(lines)
|
input, err := day1_parse(lines)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -70,8 +70,8 @@ func Day1Part1(lines []string) (error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Day1Part2(lines []string) (error) {
|
func day1_part2(lines []string) (error) {
|
||||||
input, err := Day1Parse(lines)
|
input, err := day1_parse(lines)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
109
day2.go
109
day2.go
@ -1,109 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Day2Input [][]int64
|
|
||||||
|
|
||||||
func Day2Parse(lines []string) (Day2Input, error) {
|
|
||||||
rows := make([][]int64, len(lines))
|
|
||||||
for i, line := range lines {
|
|
||||||
levelsCount := strings.Count(line, " ") + 1
|
|
||||||
rows[i] = make([]int64, levelsCount)
|
|
||||||
|
|
||||||
for j, level := range strings.Split(line, " ") {
|
|
||||||
number, err := strconv.ParseInt(level, 10, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rows[i][j] = number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rows, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func absInt(value int64) int64 {
|
|
||||||
if value < 0 {
|
|
||||||
return -value
|
|
||||||
} else {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Day2IsReportSafe(report []int64) bool {
|
|
||||||
increasing := false
|
|
||||||
decreasing := false
|
|
||||||
|
|
||||||
for i := range len(report)-1 {
|
|
||||||
if report[i+1] >= report[i] {
|
|
||||||
increasing = true
|
|
||||||
}
|
|
||||||
if report[i+1] <= report[i] {
|
|
||||||
decreasing = true
|
|
||||||
}
|
|
||||||
if absInt(report[i+1] - report[i]) >= 4 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if increasing && decreasing {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return !(increasing && decreasing) && (increasing || decreasing)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Day2Part1(lines []string) error {
|
|
||||||
input, err := Day2Parse(lines)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
answer := 0
|
|
||||||
for _, row := range input {
|
|
||||||
if Day2IsReportSafe(row) {
|
|
||||||
answer += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(answer)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func DeleteAtIndex(slice []int64, index int) []int64 {
|
|
||||||
result := make([]int64, len(slice))
|
|
||||||
copy(result, slice)
|
|
||||||
return append(result[:index], result[index+1:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Day2Part2(lines []string) error {
|
|
||||||
input, err := Day2Parse(lines)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
answer := 0
|
|
||||||
for _, row := range input {
|
|
||||||
if Day2IsReportSafe(row) {
|
|
||||||
answer += 1
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range len(row) {
|
|
||||||
if Day2IsReportSafe(DeleteAtIndex(row, i)) {
|
|
||||||
answer += 1
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(answer)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
142
day3.go
142
day3.go
@ -1,142 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Day3Mul struct {
|
|
||||||
size int
|
|
||||||
number1 int
|
|
||||||
number2 int
|
|
||||||
}
|
|
||||||
|
|
||||||
func Day3ParseMulInstruction(text string) *Day3Mul {
|
|
||||||
max_length := 0
|
|
||||||
max_length += 4 // mul(
|
|
||||||
max_length += 3 // 999
|
|
||||||
max_length += 1 // ,
|
|
||||||
max_length += 3 // 999
|
|
||||||
max_length += 1 // )
|
|
||||||
|
|
||||||
if len(text) < 4 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(text) > max_length {
|
|
||||||
text = text[:max_length]
|
|
||||||
}
|
|
||||||
|
|
||||||
if text[0:4] != "mul(" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
comma_index := strings.IndexRune(text, ',')
|
|
||||||
if (comma_index == -1) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
closing_index := strings.IndexRune(text, ')')
|
|
||||||
if (closing_index == -1) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
number1_text := text[4:comma_index]
|
|
||||||
number2_text := text[(comma_index+1):closing_index]
|
|
||||||
|
|
||||||
number1, err := strconv.ParseUint(number1_text, 10, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if number1 > 999 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
number2, err := strconv.ParseUint(number2_text, 10, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if number2 > 999 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
inst := Day3Mul{
|
|
||||||
size: closing_index + 1,
|
|
||||||
number1: int(number1),
|
|
||||||
number2: int(number2),
|
|
||||||
}
|
|
||||||
|
|
||||||
return &inst
|
|
||||||
}
|
|
||||||
|
|
||||||
func Day3Part1(lines []string) error {
|
|
||||||
answer := 0
|
|
||||||
|
|
||||||
for _, line := range lines {
|
|
||||||
cursor := 0
|
|
||||||
for cursor < len(line) {
|
|
||||||
inst := Day3ParseMulInstruction(line[cursor:])
|
|
||||||
if inst != nil {
|
|
||||||
cursor += inst.size
|
|
||||||
answer += inst.number1 * inst.number2
|
|
||||||
} else {
|
|
||||||
cursor += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
println(answer)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Day3StartsWith(haystack string, needle string) bool {
|
|
||||||
if len(haystack) < len(needle) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return haystack[:len(needle)] == needle
|
|
||||||
}
|
|
||||||
|
|
||||||
func Day3Part2(lines []string) error {
|
|
||||||
answer := 0
|
|
||||||
|
|
||||||
do_inst := "do()"
|
|
||||||
dont_inst := "don't()"
|
|
||||||
|
|
||||||
enabled := true
|
|
||||||
for _, line := range lines {
|
|
||||||
cursor := 0
|
|
||||||
for cursor < len(line) {
|
|
||||||
rest := line[cursor:]
|
|
||||||
if Day3StartsWith(rest, do_inst) {
|
|
||||||
enabled = true
|
|
||||||
cursor += len(do_inst)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if Day3StartsWith(rest, dont_inst) {
|
|
||||||
enabled = false
|
|
||||||
cursor += len(dont_inst)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if enabled {
|
|
||||||
inst := Day3ParseMulInstruction(rest)
|
|
||||||
if inst != nil {
|
|
||||||
cursor += inst.size
|
|
||||||
answer += inst.number1 * inst.number2
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
println(answer)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
110
day4.go
110
day4.go
@ -1,110 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
type Day4Offset struct {
|
|
||||||
x int
|
|
||||||
y int
|
|
||||||
}
|
|
||||||
|
|
||||||
func Day4IsWordValid(lines []string, x int, y int, table []Day4Offset, word string) bool {
|
|
||||||
for i, offset := range table {
|
|
||||||
y := y + offset.y
|
|
||||||
if y < 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if y >= len(lines) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
x := x + offset.x
|
|
||||||
if x < 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if x >= len(lines[y]) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if lines[y][x] != word[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func Day4Part1(lines []string) error {
|
|
||||||
offsetTables := [][]Day4Offset{
|
|
||||||
[]Day4Offset{
|
|
||||||
Day4Offset{ x: 0, y: 0, },
|
|
||||||
Day4Offset{ x: 1, y: 0, },
|
|
||||||
Day4Offset{ x: 2, y: 0, },
|
|
||||||
Day4Offset{ x: 3, y: 0, },
|
|
||||||
},
|
|
||||||
[]Day4Offset{
|
|
||||||
Day4Offset{ x: 0, y: 0, },
|
|
||||||
Day4Offset{ x: 0, y: 1, },
|
|
||||||
Day4Offset{ x: 0, y: 2, },
|
|
||||||
Day4Offset{ x: 0, y: 3, },
|
|
||||||
},
|
|
||||||
[]Day4Offset{
|
|
||||||
Day4Offset{ x: 0, y: 0, },
|
|
||||||
Day4Offset{ x: 1, y: 1, },
|
|
||||||
Day4Offset{ x: 2, y: 2, },
|
|
||||||
Day4Offset{ x: 3, y: 3, },
|
|
||||||
},
|
|
||||||
[]Day4Offset{
|
|
||||||
Day4Offset{ x: 0, y: 0, },
|
|
||||||
Day4Offset{ x: -1, y: 1, },
|
|
||||||
Day4Offset{ x: -2, y: 2, },
|
|
||||||
Day4Offset{ x: -3, y: 3, },
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
answer := 0
|
|
||||||
for y := range len(lines) {
|
|
||||||
for x := range len(lines[y]) {
|
|
||||||
for _, table := range offsetTables {
|
|
||||||
if Day4IsWordValid(lines, x, y, table, "XMAS") {
|
|
||||||
answer += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if Day4IsWordValid(lines, x, y, table, "SAMX") {
|
|
||||||
answer += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println(answer)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Day4Part2(lines []string) error {
|
|
||||||
table1 := []Day4Offset{
|
|
||||||
Day4Offset{ x: 0, y: 0, },
|
|
||||||
Day4Offset{ x: 1, y: 1, },
|
|
||||||
Day4Offset{ x: 2, y: 2, },
|
|
||||||
}
|
|
||||||
|
|
||||||
table2 := []Day4Offset{
|
|
||||||
Day4Offset{ x: 2, y: 0, },
|
|
||||||
Day4Offset{ x: 1, y: 1, },
|
|
||||||
Day4Offset{ x: 0, y: 2, },
|
|
||||||
}
|
|
||||||
|
|
||||||
answer := 0
|
|
||||||
for y := range len(lines) {
|
|
||||||
for x := range len(lines[y]) {
|
|
||||||
diagonal1 := Day4IsWordValid(lines, x, y, table1, "MAS") || Day4IsWordValid(lines, x, y, table1, "SAM")
|
|
||||||
diagonal2 := Day4IsWordValid(lines, x, y, table2, "MAS") || Day4IsWordValid(lines, x, y, table2, "SAM")
|
|
||||||
|
|
||||||
if diagonal1 && diagonal2 {
|
|
||||||
answer += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println(answer)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
27
main.go
27
main.go
@ -12,12 +12,6 @@ func showUsage() {
|
|||||||
fmt.Printf("Usage: %s <day> <part> [input.txt]\n", os.Args[0])
|
fmt.Printf("Usage: %s <day> <part> [input.txt]\n", os.Args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
type DayPartSolver func([]string) error
|
|
||||||
type DaySolver struct {
|
|
||||||
day1 DayPartSolver
|
|
||||||
day2 DayPartSolver
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if (len(os.Args) < 3) {
|
if (len(os.Args) < 3) {
|
||||||
showUsage()
|
showUsage()
|
||||||
@ -41,26 +35,11 @@ func main() {
|
|||||||
|
|
||||||
lines := strings.Split(strings.TrimRight(string(contents), "\n"), "\n")
|
lines := strings.Split(strings.TrimRight(string(contents), "\n"), "\n")
|
||||||
|
|
||||||
solvers := make(map[string]DaySolver)
|
if day == "1" {
|
||||||
solvers["1"] = DaySolver{ day1: Day1Part1, day2: Day1Part2 }
|
|
||||||
solvers["2"] = DaySolver{ day1: Day2Part1, day2: Day2Part2 }
|
|
||||||
solvers["3"] = DaySolver{ day1: Day3Part1, day2: Day3Part2 }
|
|
||||||
solvers["4"] = DaySolver{ day1: Day4Part1, day2: Day4Part2 }
|
|
||||||
|
|
||||||
solver, ok := solvers[day]
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
var err error
|
|
||||||
if part == "1" {
|
if part == "1" {
|
||||||
err = solver.day1(lines)
|
day1_part1(lines)
|
||||||
} else if part == "2" {
|
} else if part == "2" {
|
||||||
err = solver.day1(lines)
|
day1_part2(lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Fatal("Day not found")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user