Zwischenstand
This commit is contained in:
parent
bfb0506816
commit
a4b68faa9d
248
day17/day17.go
Normal file
248
day17/day17.go
Normal file
@ -0,0 +1,248 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"AOC2022/helper"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Field struct {
|
||||
field [][]rune
|
||||
currentBlock Block
|
||||
spawnedBlocks int
|
||||
}
|
||||
|
||||
type Block struct {
|
||||
form [][2]int
|
||||
position [2]int
|
||||
}
|
||||
|
||||
func main() {
|
||||
//args := os.Args[1:]
|
||||
lines := helper.ReadTextFile("day17/input")
|
||||
field := Field{createField(), Block{}, 0}
|
||||
field.addBlock()
|
||||
fieldCopy := Field{createField(), Block{}, 0}
|
||||
fieldCopy.addBlock()
|
||||
heightForBlocks := part1(fieldCopy, lines)
|
||||
currentPrefix := 0
|
||||
currentCycle := len(lines[0])
|
||||
finished := false
|
||||
for !finished {
|
||||
if currentPrefix < currentCycle {
|
||||
currentPrefix++
|
||||
fmt.Println(currentPrefix)
|
||||
} else {
|
||||
fmt.Println(currentCycle)
|
||||
currentCycle += len(lines[0])
|
||||
}
|
||||
fieldCopy = Field{createField(), Block{}, 0}
|
||||
fieldCopy.addBlock()
|
||||
finished = checkCycle(currentPrefix, currentCycle, fieldCopy, lines)
|
||||
}
|
||||
fmt.Println(currentCycle)
|
||||
|
||||
part2(field, lines)
|
||||
|
||||
}
|
||||
|
||||
func checkCycle(prefix, cycle int, field Field, lines []string) bool {
|
||||
currentJetMove := 0
|
||||
values := make(map[int]int)
|
||||
for field.spawnedBlocks != 4*cycle+prefix {
|
||||
field.move(rune(lines[0][currentJetMove]))
|
||||
if (field.spawnedBlocks-prefix)%cycle == 0 {
|
||||
values[field.spawnedBlocks] = len(field.field) - field.getLineWithHighestRock()
|
||||
}
|
||||
currentJetMove++
|
||||
if currentJetMove == len(lines[0]) {
|
||||
currentJetMove = 0
|
||||
}
|
||||
}
|
||||
cycleHeight := values[cycle+prefix] - values[prefix]
|
||||
for i := prefix; i < 3*cycle+prefix; i += cycle {
|
||||
if !(values[i+cycle]-values[i] == cycleHeight) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func part2(field Field, lines []string) {
|
||||
prefix := 25
|
||||
cycle := 35
|
||||
suffix := (1000000000000 - prefix) % cycle
|
||||
prefixHeight := 0
|
||||
cycleHeight := 0
|
||||
suffixHeight := 0
|
||||
currentJetMove := 0
|
||||
for field.spawnedBlocks != 3*cycle+prefix {
|
||||
field.move(rune(lines[0][currentJetMove]))
|
||||
if field.spawnedBlocks == prefix+1 {
|
||||
prefixHeight = (len(field.field) - field.getLineWithHighestRock())
|
||||
}
|
||||
if field.spawnedBlocks == prefix+cycle+1 {
|
||||
cycleHeight = (len(field.field) - field.getLineWithHighestRock()) - prefixHeight
|
||||
}
|
||||
if field.spawnedBlocks == cycle+prefix+suffix+1 {
|
||||
suffixHeight = (len(field.field) - field.getLineWithHighestRock()) - cycleHeight - prefixHeight
|
||||
}
|
||||
currentJetMove++
|
||||
if currentJetMove == len(lines[0]) {
|
||||
currentJetMove = 0
|
||||
}
|
||||
}
|
||||
fmt.Println(((1000000000000 - prefix) / cycle * cycleHeight) + prefixHeight + suffixHeight)
|
||||
}
|
||||
|
||||
func part1(field Field, lines []string) (heightForBlocks map[int]int) {
|
||||
currentJetMove := 0
|
||||
for field.spawnedBlocks != 2023 {
|
||||
field.move(rune(lines[0][currentJetMove]))
|
||||
heightForBlocks[field.spawnedBlocks] = len(field.field) - field.getLineWithHighestRock()
|
||||
currentJetMove++
|
||||
if currentJetMove == len(lines[0]) {
|
||||
currentJetMove = 0
|
||||
}
|
||||
}
|
||||
fmt.Printf("%v : %v \n", field.spawnedBlocks, (len(field.field) - field.getLineWithHighestRock()))
|
||||
}
|
||||
|
||||
func getNewBlock(spawnedBlocks int) Block {
|
||||
lineBlock := [][2]int{{0, 0}, {0, 1}, {0, 2}, {0, 3}}
|
||||
crossBlock := [][2]int{{0, 1}, {1, 1}, {1, 0}, {1, 2}, {2, 1}}
|
||||
lBlock := [][2]int{{2, 0}, {2, 1}, {2, 2}, {1, 2}, {0, 2}}
|
||||
iBlock := [][2]int{{0, 0}, {1, 0}, {2, 0}, {3, 0}}
|
||||
squareBlock := [][2]int{{0, 0}, {0, 1}, {1, 1}, {1, 0}}
|
||||
blocks := [][][2]int{lineBlock, crossBlock, lBlock, iBlock, squareBlock}
|
||||
blockForm := blocks[(spawnedBlocks)%5]
|
||||
return Block{blockForm, [2]int{0, 2}}
|
||||
}
|
||||
|
||||
func (field *Field) move(exhaust rune) {
|
||||
direction := [2]int{0, 0}
|
||||
switch exhaust {
|
||||
case '<':
|
||||
direction[1] = -1
|
||||
case '>':
|
||||
direction[1] = +1
|
||||
}
|
||||
field.moveBlock(direction)
|
||||
oldPos := field.currentBlock.position
|
||||
field.moveBlock([2]int{1, 0})
|
||||
if oldPos == field.currentBlock.position {
|
||||
field.writeBlockToField()
|
||||
field.addBlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (field *Field) writeBlockToField() {
|
||||
currentBlockPoints := field.getCurrentBLockPoints()
|
||||
for _, point := range currentBlockPoints {
|
||||
field.field[point[0]][point[1]] = '#'
|
||||
}
|
||||
}
|
||||
|
||||
func (field *Field) getCurrentBLockPoints() [][2]int {
|
||||
curretnPoints := [][2]int{}
|
||||
for _, point := range field.currentBlock.form {
|
||||
blocPoint := [2]int{point[0] + field.currentBlock.position[0], point[1] + field.currentBlock.position[1]}
|
||||
curretnPoints = append(curretnPoints, blocPoint)
|
||||
}
|
||||
return curretnPoints
|
||||
}
|
||||
|
||||
func (field *Field) moveBlock(direction [2]int) {
|
||||
possibleNewPos := addPosition(field.currentBlock.position, direction)
|
||||
for _, point := range field.currentBlock.form {
|
||||
pointToCheck := [2]int{point[0] + possibleNewPos[0], point[1] + possibleNewPos[1]}
|
||||
if pointToCheck[0] >= len(field.field) {
|
||||
return
|
||||
}
|
||||
if pointToCheck[1] >= len(field.field[pointToCheck[0]]) || pointToCheck[1] < 0 {
|
||||
return
|
||||
}
|
||||
if field.field[pointToCheck[0]][pointToCheck[1]] == '#' {
|
||||
return
|
||||
}
|
||||
}
|
||||
field.currentBlock.position = possibleNewPos
|
||||
}
|
||||
|
||||
func addPosition(a [2]int, b [2]int) [2]int {
|
||||
return [2]int{a[0] + b[0], a[1] + b[1]}
|
||||
}
|
||||
|
||||
func (field *Field) addBlock() {
|
||||
//if (field.spawnedBlocks-25)%35 == 0 {
|
||||
// fmt.Printf("%v : %v \n", field.spawnedBlocks, (len(field.field) - field.getLineWithHighestRock()))
|
||||
//}
|
||||
|
||||
lineWithHighestRock := field.getLineWithHighestRock()
|
||||
field.field = field.field[lineWithHighestRock:]
|
||||
field.currentBlock = getNewBlock(field.spawnedBlocks)
|
||||
blockHeight := field.currentBlock.getBlockHeight()
|
||||
field.addLines(3 + blockHeight)
|
||||
field.spawnedBlocks++
|
||||
}
|
||||
|
||||
func (block Block) getBlockHeight() int {
|
||||
height := 0
|
||||
for _, pos := range block.form {
|
||||
if pos[0] > height {
|
||||
height = pos[0]
|
||||
}
|
||||
}
|
||||
return height + 1
|
||||
}
|
||||
|
||||
func (field *Field) getLineWithHighestRock() int {
|
||||
for i, line := range field.field {
|
||||
for _, elem := range line {
|
||||
if elem == '#' {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
return len(field.field)
|
||||
}
|
||||
|
||||
func (field *Field) addLines(n int) {
|
||||
newLines := [][]rune{}
|
||||
for i := 0; i < n; i++ {
|
||||
fieldLine := []rune{}
|
||||
for j := 0; j < 7; j++ {
|
||||
fieldLine = append(fieldLine, '.')
|
||||
}
|
||||
newLines = append(newLines, fieldLine)
|
||||
}
|
||||
newLines = append(newLines, field.field...)
|
||||
field.field = newLines
|
||||
}
|
||||
|
||||
func createField() [][]rune {
|
||||
field := [][]rune{}
|
||||
for i := 0; i < 4; i++ {
|
||||
fieldLine := []rune{}
|
||||
for j := 0; j < 7; j++ {
|
||||
fieldLine = append(fieldLine, '.')
|
||||
}
|
||||
field = append(field, fieldLine)
|
||||
}
|
||||
return field
|
||||
}
|
||||
|
||||
func (field Field) printField() {
|
||||
currentBlockPoints := field.getCurrentBLockPoints()
|
||||
fieldCopy := make([][]rune, len(field.field))
|
||||
for i := range field.field {
|
||||
fieldCopy[i] = make([]rune, len(field.field[i]))
|
||||
copy(fieldCopy[i], field.field[i])
|
||||
}
|
||||
for _, point := range currentBlockPoints {
|
||||
fieldCopy[point[0]][point[1]] = '@'
|
||||
}
|
||||
for i := 0; i < len(fieldCopy); i++ {
|
||||
fmt.Println(string(fieldCopy[i]))
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
1
day17/input
Normal file
1
day17/input
Normal file
File diff suppressed because one or more lines are too long
1
day17/testInput
Normal file
1
day17/testInput
Normal file
@ -0,0 +1 @@
|
||||
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
Loading…
Reference in New Issue
Block a user