mirror of
https://github.com/zebrajr/coding-challenges.git
synced 2025-12-06 12:20:53 +01:00
add solver for part b
This commit is contained in:
parent
62374f15c9
commit
d2d508ca48
|
|
@ -9,12 +9,13 @@ import (
|
|||
)
|
||||
|
||||
var puzzle_file_name = "puzzle_input.txt"
|
||||
var level [][] string
|
||||
var guard_pos struct {
|
||||
type level [][] string
|
||||
type guard_info struct {
|
||||
col int
|
||||
row int
|
||||
direction int
|
||||
}
|
||||
var infinite_loop_count = 0
|
||||
|
||||
// { -1, 0 }
|
||||
// { 0, -1} { 0, +1 }
|
||||
|
|
@ -26,14 +27,13 @@ var directions = [][]int {
|
|||
{0, -1},
|
||||
}
|
||||
|
||||
func load_puzzle_from_file(target_file_name string){
|
||||
file, err := os.Open(target_file_name)
|
||||
if err != nil{
|
||||
return
|
||||
}
|
||||
func load_puzzle_from_file(target_file_name string) (level, guard_info){
|
||||
file, _ := os.Open(target_file_name)
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
var new_level level
|
||||
var new_guard guard_info
|
||||
|
||||
line_counter := 0
|
||||
for scanner.Scan(){
|
||||
|
|
@ -47,9 +47,9 @@ func load_puzzle_from_file(target_file_name string){
|
|||
}
|
||||
|
||||
if stringified == "^"{
|
||||
guard_pos.col = idx
|
||||
guard_pos.row = line_counter
|
||||
guard_pos.direction = 0
|
||||
new_guard.col = idx
|
||||
new_guard.row = line_counter
|
||||
new_guard.direction = 0
|
||||
line_array = append(line_array, stringified)
|
||||
}
|
||||
|
||||
|
|
@ -57,72 +57,79 @@ func load_puzzle_from_file(target_file_name string){
|
|||
line_array = append(line_array, stringified)
|
||||
}
|
||||
}
|
||||
level = append(level, line_array)
|
||||
new_level = append(new_level, line_array)
|
||||
line_counter++
|
||||
}
|
||||
return new_level, new_guard
|
||||
}
|
||||
|
||||
|
||||
func solve_movement(){
|
||||
fmt.Println("Map Size: ", len(level) -1, len(level[0]) -1)
|
||||
fmt.Println("Guard Starting Position: ", guard_pos.row, guard_pos.col, guard_pos.direction)
|
||||
|
||||
func solve_movement(test_level level, test_guard guard_info) (int){
|
||||
// create an indetic sized map to track places that were visited
|
||||
var visited [][]int
|
||||
for range level{
|
||||
for range test_level{
|
||||
var row []int
|
||||
for range level[0] {
|
||||
for range test_level[0] {
|
||||
row = append(row, 0)
|
||||
}
|
||||
visited = append(visited, row)
|
||||
}
|
||||
|
||||
// mark starting position as visited
|
||||
visited[guard_pos.row][guard_pos.col] = 1
|
||||
visited[test_guard.row][test_guard.col] = 1
|
||||
left_map := false
|
||||
max_visits_assume_infinite_loop := 10
|
||||
max_visits_seen := 0
|
||||
|
||||
for {
|
||||
if left_map {
|
||||
break
|
||||
}
|
||||
|
||||
next_row := guard_pos.row + directions[guard_pos.direction][0]
|
||||
next_col := guard_pos.col + directions[guard_pos.direction][1]
|
||||
next_row := test_guard.row + directions[test_guard.direction][0]
|
||||
next_col := test_guard.col + directions[test_guard.direction][1]
|
||||
// check for out of bounds
|
||||
is_row_negative := next_row < 0
|
||||
is_col_negative := next_col < 0
|
||||
is_row_oob := next_row > (len(level) -1)
|
||||
is_col_oob := next_col > (len(level[0]) -1)
|
||||
is_row_oob := next_row > (len(test_level) -1)
|
||||
is_col_oob := next_col > (len(test_level[0]) -1)
|
||||
if is_col_negative || is_row_negative || is_row_oob || is_col_oob {
|
||||
left_map = true
|
||||
continue
|
||||
}
|
||||
|
||||
if level[next_row][next_col] == "#"{
|
||||
guard_pos.direction++
|
||||
if guard_pos.direction > len(directions) -1 {
|
||||
guard_pos.direction = 0
|
||||
if test_level[next_row][next_col] == "#"{
|
||||
test_guard.direction++
|
||||
if test_guard.direction > len(directions) -1 {
|
||||
test_guard.direction = 0
|
||||
}
|
||||
}
|
||||
|
||||
if level[next_row][next_col] != "#" {
|
||||
guard_pos.row = next_row
|
||||
guard_pos.col = next_col
|
||||
visited[next_row][next_col] = 1
|
||||
if test_level[next_row][next_col] != "#" {
|
||||
test_guard.row = next_row
|
||||
test_guard.col = next_col
|
||||
visited[next_row][next_col]++
|
||||
if visited[next_row][next_col] > max_visits_seen{
|
||||
max_visits_seen++
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if max_visits_seen > max_visits_assume_infinite_loop {
|
||||
infinite_loop_count++
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
places_visited := 0
|
||||
for row := range visited{
|
||||
for col := range visited[row]{
|
||||
if visited[row][col] == 1 {
|
||||
if visited[row][col] >= 1 {
|
||||
places_visited++
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println("Visited Places: ", places_visited)
|
||||
|
||||
return places_visited
|
||||
}
|
||||
|
||||
func time_track(start time.Time, name string){
|
||||
|
|
@ -130,9 +137,39 @@ func time_track(start time.Time, name string){
|
|||
log.Printf("%s took %s", name, elapsed)
|
||||
}
|
||||
|
||||
func clone_level(origin level)(level){
|
||||
new_level := make(level, len(origin))
|
||||
for i := range origin{
|
||||
new_level[i] = make([]string, len(origin[i]))
|
||||
copy(new_level[i], origin[i])
|
||||
}
|
||||
return new_level
|
||||
}
|
||||
|
||||
func test_for_infinite_loop(base_level level, test_guard guard_info){
|
||||
for row := range base_level {
|
||||
for col := range base_level[row] {
|
||||
if test_guard.row == row && test_guard.col == col {
|
||||
continue
|
||||
}
|
||||
|
||||
if base_level[row][col] == "#"{
|
||||
continue
|
||||
}
|
||||
|
||||
isolated_level := clone_level(base_level)
|
||||
isolated_level[row][col] = "#"
|
||||
|
||||
solve_movement(isolated_level, test_guard)
|
||||
}
|
||||
}
|
||||
fmt.Println("Total Infinite Loops Found: ", infinite_loop_count)
|
||||
}
|
||||
|
||||
func main(){
|
||||
defer time_track(time.Now(), "main")
|
||||
load_puzzle_from_file(puzzle_file_name)
|
||||
solve_movement()
|
||||
level, guard := load_puzzle_from_file(puzzle_file_name)
|
||||
places_visited := solve_movement(level, guard)
|
||||
fmt.Println("Total Places Visited: ", places_visited)
|
||||
test_for_infinite_loop(level, guard)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user