From 9e0d6fc06202b03a6a36993500d73c5990f3b549 Mon Sep 17 00:00:00 2001 From: RPJosh Date: Sat, 10 Dec 2022 10:12:29 +0100 Subject: [PATCH] Day 02-03 and 08-10 --- cmd/adventOfCode/main.go | 17 ++- internal/day_02/in.go | 97 ++++++++++++++++- internal/day_03/in.go | 81 +++++++++++++- internal/day_08/in.go | 188 +++++++++++++++++++++++++++++++- internal/day_09/in.go | 230 ++++++++++++++++++++++++++++++++++++++- internal/day_10/in.go | 81 +++++++++++++- pkg/utils/utils.go | 15 ++- run.sh | 2 +- 8 files changed, 695 insertions(+), 16 deletions(-) diff --git a/cmd/adventOfCode/main.go b/cmd/adventOfCode/main.go index ae51bcb..b01760b 100644 --- a/cmd/adventOfCode/main.go +++ b/cmd/adventOfCode/main.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "os" "strconv" @@ -54,10 +55,22 @@ func main() { } } + testRun := len(os.Args) >= 4 && os.Args[3] != "" + if testRun { + data = utils.GetFromClipboard() + } + + var result string if part == 1 { - utils.CopyToClipboard(challenge.Part1(data)) + result = challenge.Part1(data) } else { - utils.CopyToClipboard(challenge.Part2(data)) + result = challenge.Part2(data) + } + + if !testRun { + utils.CopyToClipboard(result) + } else { + fmt.Print(result + "\n") } } diff --git a/internal/day_02/in.go b/internal/day_02/in.go index bc6c878..daa5860 100644 --- a/internal/day_02/in.go +++ b/internal/day_02/in.go @@ -1,11 +1,104 @@ package day_02 +import ( + "fmt" + "strings" +) + type Day struct{} func (d *Day) Part1(in string) string { - return "" + sum := 0 + for _, val := range strings.Split(in, "\n") { + playersVal := strings.Split(val, " ") + + if len(playersVal) <= 1 { + continue + } + + me := d.getValue(playersVal[1]) + you := d.getValue(playersVal[0]) + + // 1 = stein + // 2 = papier + // 3 = schere + + // papier - stein + if me == 1 && you == 3 { + me += 6 + } else if me == 2 && you == 1 { + me += 6 + } else if me == 3 && you == 2 { + me += 6 + } else if me == you { + me += 3 + } + + sum += me + } + + return fmt.Sprintf("%d", sum) } func (d *Day) Part2(in string) string { - return "" + sum := 0 + for _, val := range strings.Split(in, "\n") { + playersVal := strings.Split(val, " ") + + if len(playersVal) <= 1 { + continue + } + + me := d.getValue(playersVal[1]) + you := d.getValue(playersVal[0]) + + // 1 = stein - verlieren + // 2 = papier - unentschieden + // 3 = schere - gewinnen + + if me == 3 { + if you == 1 { + me = 2 + } else if you == 2 { + me = 3 + } else { + me = 1 + } + } else if me == 2 { + me = you + } else { + if you == 1 { + me = 3 + } else if you == 2 { + me = 1 + } else { + me = 2 + } + } + + // papier - stein + if me == 1 && you == 3 { + me += 6 + } else if me == 2 && you == 1 { + me += 6 + } else if me == 3 && you == 2 { + me += 6 + } else if me == you { + me += 3 + } + + sum += me + } + + return fmt.Sprintf("%d", sum) +} + +func (d *Day) getValue(val string) int { + if val == "X" || val == "A" { + return 1 + } else if val == "Y" || val == "B" { + return 2 + } else { + return 3 + } } diff --git a/internal/day_03/in.go b/internal/day_03/in.go index d1da985..656e726 100644 --- a/internal/day_03/in.go +++ b/internal/day_03/in.go @@ -1,11 +1,88 @@ package day_03 +import ( + "fmt" + "strings" +) + type Day struct{} func (d *Day) Part1(in string) string { - return "" + sum := 0 + + for _, val := range strings.Split(in, "\n") { + center := len(val) / 2 + fSegment := []rune(val[0:center]) + sSegment := []rune(val[center:]) + //fmt.Printf("%s | %s\n", fSegment, sSegment) + + outer: + for _, fChar := range fSegment { + for o, sChar := range sSegment { + // Check if it is contained + if fChar == sChar { + sum += d.getPriority(fChar) + sSegment[o] = 0 + break outer + } + } + } + } + + return fmt.Sprintf("%d", sum) } func (d *Day) Part2(in string) string { - return "" + sum := 0 + + inArray := strings.Split(in, "\n") + +outer: + for i := 3; i <= len(inArray); i += 3 { + + // Loop for every character to find one every contains + for chars := 65; chars <= 122; chars++ { + if chars >= 91 && chars <= 96 { + continue + } + + numberFound := 0 + + // Find number in three pair + for ii := i - 3; ii < i; ii++ { + found := false + + // Loop a single one + for _, char := range []rune(inArray[ii]) { + if char == rune(chars) { + found = true + break + } + } + + if !found { + break + } else { + numberFound++ + } + } + + if numberFound == 3 { + sum += d.getPriority(rune(chars)) + continue outer + } + } + } + + return fmt.Sprintf("%d", sum) +} + +func (d *Day) getPriority(in rune) int { + //in := []byte(inString)[0] + fmt.Printf("Got: %d %s\n", in, string(in)) + if in >= 97 { + return int(in - 96) + } else { + return int(in - 38) + } } diff --git a/internal/day_08/in.go b/internal/day_08/in.go index ba756a5..f0f1b61 100644 --- a/internal/day_08/in.go +++ b/internal/day_08/in.go @@ -1,11 +1,193 @@ package day_08 -type Day struct{} +import ( + "fmt" + "strconv" + "strings" +) + +type Day struct { + data [][]int +} func (d *Day) Part1(in string) string { - return "" + for _, row := range strings.Split(in, "\n") { + columns := make([]int, len(row)) + if row == "" { + continue + } + for o := 0; o < len(row); o++ { + val, _ := strconv.Atoi(row[o : o+1]) + columns[o] = val + } + d.data = append(d.data, columns) + } + + sum := 0 + for i := range d.data { + for o, column := range d.data[i] { + if d.isEdge(i, o) || d.checkRow(i, o, column) || d.checkColumn(o, i, column) { + //if !d.isEdge(i, o) { + // fmt.Printf("For %d-%d | %t %t %t\n", i, o, d.isEdge(i, o), d.checkRow(i, o, column), d.checkColumn(o, i, column)) + //} + sum += 1 + } + } + } + + return fmt.Sprintf("%d", sum) } func (d *Day) Part2(in string) string { - return "" + for _, row := range strings.Split(in, "\n") { + columns := make([]int, len(row)) + if row == "" { + continue + } + for o := 0; o < len(row); o++ { + val, _ := strconv.Atoi(row[o : o+1]) + columns[o] = val + } + d.data = append(d.data, columns) + } + + max := 0 + // loop through every tree + for i := range d.data { + for o, column := range d.data[i] { + + sum := d.lookColumn(o, i, column) * d.lookRow(i, o, column) + if sum > max { + max = sum + } + } + } + + return fmt.Sprintf("%d", max) +} + +// Tree is standing on the edge +func (d *Day) isEdge(row int, col int) bool { + return row == 0 || row == len(d.data)-1 || + col == 0 || col == len(d.data[row])-1 +} + +// Checks if for top or bottom is visible +func (d *Day) checkColumn(column int, treeRow int, val int) bool { + + // Top + successfull := true + for i := 0; i < treeRow; i++ { + current := d.data[i][column] + if current >= val { + successfull = false + break + } + } + + if successfull { + return true + } + + // Bottom + successfull = true + for i := len(d.data) - 1; i > treeRow; i-- { + current := d.data[i][column] + if current >= val { + successfull = false + break + } + } + + return successfull +} + +// Checks if left or right is visible +func (d *Day) checkRow(row int, treeColumn int, val int) bool { + // Left + successfull := true + for i := 0; i < treeColumn; i++ { + current := d.data[row][i] + if current >= val { + successfull = false + break + } + } + + if successfull { + return true + } + + // Right + successfull = true + for i := len(d.data[row]) - 1; i > treeColumn; i-- { + current := d.data[row][i] + if current >= val { + successfull = false + break + } + } + + return successfull +} + +// Checks if for top or bottom is visible +func (d *Day) lookColumn(column int, treeRow int, val int) int { + + // Top + topCount := 0 + for i := treeRow - 1; i >= 0; i-- { + if i == -1 { + break + } + + current := d.data[i][column] + + topCount++ + if current >= val { + break + } + } + + // Bottom + bottomCount := 0 + for i := treeRow + 1; i < len(d.data); i++ { + current := d.data[i][column] + + bottomCount++ + if current >= val { + break + } + } + + //fmt.Printf("Bottom %d Top %d\n", bottomCount, topCount) + return bottomCount * topCount +} + +// Checks if left or right is visible +func (d *Day) lookRow(row int, treeColumn int, val int) int { + // Left + leftCount := 0 + for i := treeColumn - 1; i >= 0; i-- { + current := d.data[row][i] + + leftCount++ + if current >= val { + break + } + } + + // Right + rightCount := 0 + for i := treeColumn + 1; i < len(d.data[row]); i++ { + current := d.data[row][i] + + rightCount++ + if current >= val { + break + } + } + + //fmt.Printf("Left %d Right %d\n", leftCount, rightCount) + return leftCount * rightCount } diff --git a/internal/day_09/in.go b/internal/day_09/in.go index 4b931f3..90b6bf1 100644 --- a/internal/day_09/in.go +++ b/internal/day_09/in.go @@ -1,11 +1,235 @@ package day_09 -type Day struct{} +import ( + "fmt" + "strconv" + "strings" +) + +type Day struct { + board [][]bool + + curHead Position + curTail Position + + // Part two extras + tails []Position +} + +type Position struct { + row int + column int +} func (d *Day) Part1(in string) string { - return "" + + // Create initial board + initialSize := 2000 + d.board = make([][]bool, initialSize) + for i := range d.board { + d.board[i] = make([]bool, initialSize) + } + + // Initialize positions + d.curHead.row = initialSize / 2 + d.curHead.column = initialSize / 2 + + d.curTail.row = initialSize / 2 + d.curTail.column = initialSize / 2 + d.board[initialSize/2][initialSize/2] = true + + for _, val := range strings.Split(in, "\n") { + if val == "" { + continue + } + pos := val[0:1] + mov, _ := strconv.Atoi(val[2:]) + //fmt.Printf("Moving for %d in %s\n", mov, pos) + for i := 0; i < mov; i++ { + d.Move(pos) + } + } + + // Count positions + sum := 0 + for _, val := range d.board { + for _, wasOn := range val { + if wasOn { + sum++ + } + } + } + + return fmt.Sprintf("%d", sum) +} + +// Left or right or Up and Down +func (d *Day) Move(direction string) { + origHead := d.curHead + if direction == "L" { + d.curHead.column-- + } else if direction == "R" { + d.curHead.column++ + } else if direction == "U" { + d.curHead.row-- + } else if direction == "D" { + d.curHead.row++ + } + + //fmt.Printf("Head: %s | Tail: %s\n", d.curHead, d.curTail) + // Check if tail should move + if d.isTailOnlyOneAway() || d.isDiagonally() || (d.curHead.row == d.curTail.row && d.curHead.column == d.curTail.column) { + // The Head is already on the way :) + } else { + d.curTail = origHead + // Update positions + d.board[d.curTail.row][d.curTail.column] = true + } + //fmt.Printf("Head: %s | Tail: %s\n", d.curHead, d.curTail) + +} + +func (d *Day) isTailOnlyOneAway() bool { + return (d.curHead.column == d.curTail.column && isOnlyOneAway(d.curHead.row, d.curTail.row)) || + (d.curHead.row == d.curTail.row && isOnlyOneAway(d.curHead.column, d.curTail.column)) +} +func isOnlyOneAway(one int, two int) bool { + //fmt.Printf("Comparing: %d %d %t %t\n", one, two, (one-1) == two, (one+1) == two) + return (one-1) == two || (one+1) == two +} + +func (d *Day) isDiagonally() bool { + topRight := d.curHead.row-1 == d.curTail.row && d.curHead.column-1 == d.curTail.column + topLeft := d.curHead.row-1 == d.curTail.row && d.curHead.column+1 == d.curTail.column + bottomRight := d.curHead.row+1 == d.curTail.row && d.curHead.column-1 == d.curTail.column + bottomLeft := d.curHead.row+1 == d.curTail.row && d.curHead.column+1 == d.curTail.column + + return topRight || topLeft || bottomLeft || bottomRight } func (d *Day) Part2(in string) string { - return "" + // Create initial board + initialSize := 2000 + d.board = make([][]bool, initialSize) + for i := range d.board { + d.board[i] = make([]bool, initialSize) + } + + // Initialize positions + d.curHead.row = initialSize / 2 + d.curHead.column = initialSize / 2 + + d.tails = make([]Position, 10) + for i := 0; i < 10; i++ { + d.tails[i].row = initialSize / 2 + d.tails[i].column = initialSize / 2 + } + d.board[initialSize/2][initialSize/2] = true + + for _, val := range strings.Split(in, "\n") { + if val == "" { + continue + } + pos := val[0:1] + mov, _ := strconv.Atoi(val[2:]) + //fmt.Printf("Moving for %d in %s\n", mov, pos) + for i := 0; i < mov; i++ { + d.Move2(pos) + } + } + + // Count positions + sum := 0 + for _, val := range d.board { + for _, wasOn := range val { + if wasOn { + sum++ + } + } + } + + return fmt.Sprintf("%d", sum) +} + +// Left or right or Up and Down +func (d *Day) Move2(direction string) { + //origHead := d.curHead + if direction == "L" { + d.curHead.column-- + } else if direction == "R" { + d.curHead.column++ + } else if direction == "U" { + d.curHead.row++ + } else if direction == "D" { + d.curHead.row-- + } + + for i := 0; i < 9; i++ { + prevHead := d.curHead + if i != 0 { + prevHead = d.tails[i-1] + } + + // Check if tail should moved + if d.isTailOnlyOneAway2(d.tails[i], prevHead) || d.isDiagonally2(d.tails[i], prevHead) || (prevHead.row == d.tails[i].row && prevHead.column == d.tails[i].column) { + // Not moving + } else { + // Up and Down + if direction == "U" || direction == "D" { + if d.tails[i].row < prevHead.row { + d.tails[i].row++ + } + if d.tails[i].row > prevHead.row { + d.tails[i].row-- + } + + // left or right? + if d.tails[i].column < prevHead.column { + d.tails[i].column++ + } else if d.tails[i].column > prevHead.column { + d.tails[i].column-- + } + // Left and Right + } else if direction == "L" || direction == "R" { + if d.tails[i].column > prevHead.column { + d.tails[i].column-- + } + if d.tails[i].column < prevHead.column { + d.tails[i].column++ + } + + // Up or down + if d.tails[i].row < prevHead.row { + d.tails[i].row++ + } else if d.tails[i].row > prevHead.row { + d.tails[i].row-- + } + } + } + + if i == 8 { + d.board[d.tails[i].row][d.tails[i].column] = true + } + + //fmt.Printf("%d: Head: %s | Tail: %s\n", i+1, prevHead, d.tails[i]) + } + + //fmt.Printf("Head: %s | Tail: %s\n", d.curHead, d.curTail) +} +func (d *Day) isTailOnlyOneAway2(tail Position, prevTail Position) bool { + return (prevTail.column == tail.column && isOnlyOneAway2(prevTail.row, tail.row)) || + (prevTail.row == tail.row && isOnlyOneAway2(prevTail.column, tail.column)) +} +func isOnlyOneAway2(one int, two int) bool { + //fmt.Printf("Comparing: %d %d %t %t\n", one, two, (one-1) == two, (one+1) == two) + return (one-1) == two || (one+1) == two +} + +func (d *Day) isDiagonally2(tail Position, prevTail Position) bool { + topRight := prevTail.row-1 == tail.row && prevTail.column-1 == tail.column + topLeft := prevTail.row-1 == tail.row && prevTail.column+1 == tail.column + bottomRight := prevTail.row+1 == tail.row && prevTail.column-1 == tail.column + bottomLeft := prevTail.row+1 == tail.row && prevTail.column+1 == tail.column + + return topRight || topLeft || bottomLeft || bottomRight } diff --git a/internal/day_10/in.go b/internal/day_10/in.go index d92902b..0545781 100644 --- a/internal/day_10/in.go +++ b/internal/day_10/in.go @@ -1,11 +1,90 @@ package day_10 +import ( + "fmt" + "strconv" + "strings" +) + type Day struct{} func (d *Day) Part1(in string) string { - return "" + sumSignals := 0 + cycle := 0 + sumValue := 1 + + for _, val := range strings.Split(in, "\n") { + if val == "" { + continue + } + + iterator := 1 + if val[0:4] == "addx" { + iterator = 2 + } + + for i := 0; i < iterator; i++ { + cycle++ + if (cycle-20)%40 == 0 { + //fmt.Printf("Cycle: %d | Strength: %d\n", cycle, sumValue) + sumSignals += cycle * sumValue + } + } + + if val[0:4] == "addx" { + valToAdd, _ := strconv.Atoi(val[5:]) + sumValue += valToAdd + } + } + + return fmt.Sprintf("%d", sumSignals) } func (d *Day) Part2(in string) string { + //var screen [][]string = make([]string, 200) + //for i := range screen { + // screen [i] = append(screen, 39) + //} + + cycle := 0 + sumValue := 1 + lastSpriteRow := 0 + + for _, val := range strings.Split(in, "\n") { + if val == "" { + continue + } + + iterator := 1 + if val[0:4] == "addx" { + iterator = 2 + } + + for i := 0; i < iterator; i++ { + // The middle of the sprite + spriteColumn := sumValue % 40 + + cyclePos := cycle % 40 + if cyclePos-1 == spriteColumn || cyclePos == spriteColumn || cyclePos+1 == spriteColumn { + fmt.Print("#") + } else { + fmt.Print(".") + } + + cycle++ + // Print new line + spriteRow := cycle / 40 + if lastSpriteRow != spriteRow { + fmt.Print("\n") + lastSpriteRow = spriteRow + } + } + + if val[0:4] == "addx" { + valToAdd, _ := strconv.Atoi(val[5:]) + sumValue += valToAdd + } + } + return "" } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 6fd18dd..4b4ff6d 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -12,7 +12,7 @@ import ( ) // Copies the given string to the clipboard. -// The tool 'xclip needs to be installed' +// The tool 'xclip' needs to be installed func CopyToClipboard(text string) { command := fmt.Sprintf("echo '%s' | xclip -selection clipboard", strings.ReplaceAll(text, "'", "''")) cmd := exec.Command("bash", "-c", command) @@ -21,7 +21,18 @@ func CopyToClipboard(text string) { PrintError("Error while executing command: %s", err) } - fmt.Print(text) + fmt.Print(text + "\n") +} + +// Gets the content of the clipboard. +// The tool 'xclip' needs to be installed +func GetFromClipboard() string { + out, err := exec.Command("bash", "-c", "xclip -o -selection clipboard").Output() + if err != nil { + PrintError("Error while getting clipboard content: %s", err) + } + + return string(out) } // Get's the input data for the task diff --git a/run.sh b/run.sh index 8dcf710..cda1a16 100755 --- a/run.sh +++ b/run.sh @@ -1,3 +1,3 @@ #!/bin/sh -nodemon --quiet -e go,html,yaml --ignore web/app/ --signal SIGTERM --exec 'go run ./cmd/adventOfCode '$1' '$2' || exit 1' \ No newline at end of file +nodemon --quiet -e go,html,yaml --ignore web/app/ --signal SIGTERM --exec 'go run ./cmd/adventOfCode '$1' '$2' '$3' || exit 1' \ No newline at end of file