• 12 Posts
  • 44 Comments
Joined 9 months ago
cake
Cake day: September 17th, 2023

help-circle









  • This would be the best way. Unfortunately they made it the other way around. A screen at the door shows the code, and you scan it with the app.

    In my previous gym the code was on the app, but I’m not sure anymore if it was static or it changed over time. But the reader on the door was awful, I used to spend a good 3 minutes trying different angles with my phone to make it recognize the code.



















  • Golang

    Avoided recursion by having an array of “pending paths”. Whenever I hit a splitter, I follow one of the paths straight away, and push the starting point and direction of the other path to the array.

    First time I ran it, hit an infinite loop. Handled it by skipping “|” and “-” if they have been visited already.

    Part 2 is the same code as part 1 but I just check all the possible starting points.

    Code
    package main
    
    import (
    	"bufio"
    	"fmt"
    	"os"
    )
    
    type Direction int
    
    const (
    	UP    Direction = 0
    	DOWN  Direction = 1
    	LEFT  Direction = 2
    	RIGHT Direction = 3
    )
    
    type LightPoint struct {
    	row int
    	col int
    	dir Direction
    }
    
    func solve(A [][]rune, start LightPoint) int {
    	m := len(A)
    	n := len(A[0])
    	visited := make([]bool, m*n)
    	points := []LightPoint{}
    	points = append(points, start)
    
    	for len(points) > 0 {
    		current := points[0]
    		points = points[1:]
    		i := current.row
    		j := current.col
    		dir := current.dir
    
    		for {
    			if i < 0 || i >= m || j < 0 || j >= n {
    				break
    			}
    			if visited[i*n+j] && (A[i][j] == '-' || A[i][j] == '|') {
    				break
    			}
    
    			visited[i*n+j] = true
    
    			if A[i][j] == '.' ||
    				(A[i][j] == '-' && (dir == LEFT || dir == RIGHT)) ||
    				(A[i][j] == '|' && (dir == UP || dir == DOWN)) {
    				switch dir {
    				case UP:
    					i--
    				case DOWN:
    					i++
    				case LEFT:
    					j--
    				case RIGHT:
    					j++
    				}
    				continue
    			}
    
    			if A[i][j] == '\\' {
    				switch dir {
    				case UP:
    					dir = LEFT
    					j--
    				case DOWN:
    					dir = RIGHT
    					j++
    				case LEFT:
    					dir = UP
    					i--
    				case RIGHT:
    					dir = DOWN
    					i++
    				}
    				continue
    			}
    
    			if A[i][j] == '/' {
    				switch dir {
    				case UP:
    					dir = RIGHT
    					j++
    				case DOWN:
    					dir = LEFT
    					j--
    				case LEFT:
    					dir = DOWN
    					i++
    				case RIGHT:
    					dir = UP
    					i--
    				}
    				continue
    			}
    
    			if A[i][j] == '-' && (dir == UP || dir == DOWN) {
    				points = append(points, LightPoint{row: i, col: j + 1, dir: RIGHT})
    				dir = LEFT
    				j--
    				continue
    			}
    
    			if A[i][j] == '|' && (dir == LEFT || dir == RIGHT) {
    				points = append(points, LightPoint{row: i + 1, col: j, dir: DOWN})
    				dir = UP
    				i--
    			}
    		}
    	}
    
    	energized := 0
    	for _, v := range visited {
    		if v {
    			energized++
    		}
    	}
    	return energized
    }
    
    func part1(A [][]rune) {
    	start := LightPoint{row: 0, col: 0, dir: RIGHT}
    	energized := solve(A, start)
    	fmt.Println(energized)
    }
    
    func part2(A [][]rune) {
    	m := len(A)
    	n := len(A[0])
    	max := -1
    
    	for i := 0; i < m; i++ {
    		start := LightPoint{row: i, col: 0, dir: RIGHT}
    		energized := solve(A, start)
    		if energized > max {
    			max = energized
    		}
    		start = LightPoint{row: 0, col: n - 1, dir: LEFT}
    		energized = solve(A, start)
    		if energized > max {
    			max = energized
    		}
    	}
    
    	for j := 0; j < n; j++ {
    		start := LightPoint{row: 0, col: j, dir: DOWN}
    		energized := solve(A, start)
    		if energized > max {
    			max = energized
    		}
    		start = LightPoint{row: m - 1, col: j, dir: UP}
    		energized = solve(A, start)
    		if energized > max {
    			max = energized
    		}
    	}
    
    	fmt.Println(max)
    }
    
    func main() {
    	// file, _ := os.Open("sample.txt")
    	file, _ := os.Open("input.txt")
    	defer file.Close()
    
    	scanner := bufio.NewScanner(file)
    
    	var lines []string
    	for scanner.Scan() {
    		lines = append(lines, scanner.Text())
    	}
    
    	var A [][]rune
    	for _, line := range lines {
    		A = append(A, []rune(line))
    	}
    
    	// part1(A)
    	part2(A)
    }