github.com/agrigoryan/aoc_2023_go@v0.0.0-20231216221323-4ace361ec685/day10/d10p1.go (about)

     1  package day10
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  )
     7  
     8  var pipeDirections = map[rune]struct {
     9  	u, r, d, l bool
    10  }{
    11  	'-': {
    12  		u: false,
    13  		r: true,
    14  		d: false,
    15  		l: true,
    16  	},
    17  	'|': {
    18  		u: true,
    19  		r: false,
    20  		d: true,
    21  		l: false,
    22  	},
    23  	'7': {
    24  		u: false,
    25  		r: false,
    26  		d: true,
    27  		l: true,
    28  	},
    29  	'L': {
    30  		u: true,
    31  		r: true,
    32  		d: false,
    33  		l: false,
    34  	},
    35  	'J': {
    36  		u: true,
    37  		r: false,
    38  		d: false,
    39  		l: true,
    40  	},
    41  	'F': {
    42  		u: false,
    43  		r: true,
    44  		d: true,
    45  		l: false,
    46  	},
    47  	'S': {
    48  		u: true,
    49  		r: true,
    50  		d: true,
    51  		l: true,
    52  	},
    53  }
    54  
    55  func d10p1(input string) int {
    56  	lines := strings.Split(input, "\n")
    57  	fmt.Println(lines)
    58  
    59  	type pos struct {
    60  		i, j int
    61  	}
    62  	type cell struct {
    63  		pos
    64  		d int
    65  		r rune
    66  	}
    67  
    68  	runes := make([][]rune, len(lines))
    69  
    70  	var startCell cell
    71  	for i, line := range lines {
    72  		runes[i] = []rune(line)
    73  		for j, r := range runes[i] {
    74  			if r == 'S' {
    75  				startCell = cell{pos{i, j}, 0, r}
    76  			}
    77  		}
    78  	}
    79  
    80  	visited := map[pos]*cell{}
    81  	toVisit := []cell{startCell}
    82  
    83  	addToVisit := func(n pos, d int) {
    84  		if visited[n] != nil {
    85  			visited[n].d = min(visited[n].d, d)
    86  		} else {
    87  			toVisit = append(toVisit, cell{
    88  				n, d, runes[n.i][n.j],
    89  			})
    90  		}
    91  	}
    92  
    93  	for len(toVisit) > 0 {
    94  		c := toVisit[0]
    95  		toVisit = toVisit[1:]
    96  		visited[c.pos] = &c
    97  		n := pos{c.i - 1, c.j}
    98  		if n.i >= 0 && pipeDirections[c.r].u && pipeDirections[runes[n.i][n.j]].d {
    99  			addToVisit(n, c.d+1)
   100  		}
   101  		n = pos{c.i, c.j - 1}
   102  		if n.j >= 0 && pipeDirections[c.r].l && pipeDirections[runes[n.i][n.j]].r {
   103  			addToVisit(n, c.d+1)
   104  		}
   105  		n = pos{c.i, c.j + 1}
   106  		if n.i < len(runes) && pipeDirections[c.r].r && pipeDirections[runes[n.i][n.j]].l {
   107  			addToVisit(n, c.d+1)
   108  		}
   109  		n = pos{c.i + 1, c.j}
   110  		if n.j < len(runes[0]) && pipeDirections[c.r].d && pipeDirections[runes[n.i][n.j]].u {
   111  			addToVisit(n, c.d+1)
   112  		}
   113  	}
   114  
   115  	m := startCell.d
   116  
   117  	for _, v := range visited {
   118  		if v.d > m {
   119  			m = v.d
   120  		}
   121  	}
   122  
   123  	fmt.Println(m)
   124  	return m
   125  }