8.bas (4450B)
1 REM QBasic/QuickBasic implementation of AOC2022 day 8 2 3 REM visibility reference constants; tree height is stored in forest%(x,y,HEIGHT) 4 const TOPV = 0 5 const LEFTV = 1 6 const BOTTOMV = 2 7 const RIGHTV = 3 8 const HEIGHT = 4 9 10 REM Open and read file 11 open "input" for input as #1 12 line input #1, line$ 13 let side% = len(line$) 14 15 REM Create array to store the forest and visibilities, assume square 16 dim forest%(side%, side%, 5) 17 let visible% = 0 18 19 REM Construct a matrix of the forest from file input and the top and left visibilities 20 for y% = 1 to side% 21 if y% > 1 then 22 line input #1, line$ 23 end if 24 for x% = 1 to side% 25 let tree$ = mid$(line$, x%, 1) 26 let forest%(x% - 1, y% - 1, HEIGHT) = asc(tree$) - 48 27 28 REM Determine visibility from the left 29 if x% = 1 then 30 forest%(0, y% - 1, LEFTV) = -1 31 elseif forest%(x% - 2, y% - 1, HEIGHT) > forest%(x% - 2, y% - 1, LEFTV) then 32 forest%(x% - 1, y% - 1, LEFTV) = forest%(x% - 2, y% - 1, HEIGHT) 33 else 34 forest%(x% - 1, y% - 1, LEFTV) = forest%(x% - 2, y% - 1, LEFTV) 35 end if 36 37 REM Determine visibility from the top 38 if y% = 1 then 39 forest%(x% - 1, 0, TOPV) = -1 40 elseif forest%(x% - 1, y% - 2, HEIGHT) > forest%(x% - 1, y% - 2, TOPV) then 41 forest%(x% - 1, y% - 1, TOPV) = forest%(x% - 1, y% - 2, HEIGHT) 42 else 43 forest%(x% - 1, y% - 1, TOPV) = forest%(x% - 1, y% - 2, TOPV) 44 end if 45 next x% 46 next y% 47 48 REM Close file 49 close #1 50 51 REM Go backward through the array and collect visibility in the opposite direction 52 REM and count visible trees 53 for y% = side% to 1 step - 1 54 for x% = side% to 1 step -1 55 REM Determine visibility from the right 56 if x% = side% then 57 forest%(side% - 1, y% - 1, RIGHTV) = -1 58 elseif forest%(x%, y% - 1, HEIGHT) > forest%(x%, y% - 1, RIGHTV) then 59 forest%(x% - 1, y% - 1, RIGHTV) = forest%(x%, y% - 1, HEIGHT) 60 else 61 forest%(x% - 1, y% - 1, RIGHTV) = forest%(x%, y% - 1, RIGHTV) 62 end if 63 64 REM Determine visibility from the bottom 65 if y% = side% then 66 forest%(x% - 1, side% - 1, BOTTOMV) = -1 67 elseif forest%(x% - 1, y%, HEIGHT) > forest%(x% - 1, y%, BOTTOMV) then 68 forest%(x% - 1, y% - 1, BOTTOMV) = forest%(x% - 1, y%, HEIGHT) 69 else 70 forest%(x% - 1, y% - 1, BOTTOMV) = forest%(x% - 1, y%, BOTTOMV) 71 end if 72 73 let treeheight% = forest%(x% - 1, y% - 1, HEIGHT) 74 if (forest%(x% - 1, y% - 1, LEFTV) < treeheight%) OR (forest%(x% - 1, y% - 1, TOPV) < treeheight%) OR (forest%(x% - 1, y% - 1, RIGHTV) < treeheight%) OR (forest%(x% - 1, y% - 1, BOTTOMV) < treeheight%) then 75 visible% = visible% + 1 76 end if 77 next x% 78 next y% 79 80 REM Loop over again and find the highest viewing distance 81 let maxsc = 0 82 for y% = side% to 1 step - 1 83 for x% = side% to 1 step -1 84 let treeheight% = forest%(x% - 1, y% - 1, HEIGHT) 85 let lv = 0 86 let tv = 0 87 let rv = 0 88 let bv = 0 89 90 REM Find left visibility 91 if x% = 1 then 92 lv = 0 93 else 94 lv = 0 95 do 96 lv = lv + 1 97 loop until (forest%(x% - (lv + 1), y% - 1, HEIGHT) >= treeheight%) or (x% - lv = 1) 98 end if 99 100 REM Find top visibility 101 if y% = 1 then 102 tv = 0 103 else 104 tv = 0 105 do 106 tv = tv + 1 107 loop until (forest%(x% - 1, y% - (tv + 1), HEIGHT) >= treeheight%) or (y% - tv = 1) 108 end if 109 110 REM Find right visibility 111 if x% = side% then 112 rv = 0 113 else 114 rv = 0 115 do 116 rv = rv + 1 117 loop until (forest%(x% + (rv - 1), y% - 1, HEIGHT) >= treeheight%) or (x% + rv = side%) 118 end if 119 120 REM Find bottom visibility 121 if y% = side% then 122 bv = 0 123 else 124 bv = 0 125 do 126 bv = bv + 1 127 loop until (forest%(x% - 1, y% + (bv - 1), HEIGHT) >= treeheight%) or (y% + bv = side%) 128 end if 129 130 let scenic = lv * tv * rv * bv 131 if scenic > maxsc then maxsc = scenic 132 next x% 133 next y% 134 135 print visible%; " visible trees" 136 print maxsc; " max scenic value" 137 end