implement day 17 rock falling logic
This commit is contained in:
parent
490696c63d
commit
9f1499a1d3
1
inputs/day17.tt
Normal file
1
inputs/day17.tt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
||||||
147
src/day17.ml
Normal file
147
src/day17.ml
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
open Containers
|
||||||
|
|
||||||
|
let example_lines = {|>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>|}
|
||||||
|
|
||||||
|
type shape =
|
||||||
|
| Row
|
||||||
|
| Plus
|
||||||
|
| Angle
|
||||||
|
| Col
|
||||||
|
| Square
|
||||||
|
|
||||||
|
let dir_of_char = function
|
||||||
|
| '<' -> Vec2.left
|
||||||
|
| '>' -> Vec2.right
|
||||||
|
| _ -> failwith "oof"
|
||||||
|
;;
|
||||||
|
|
||||||
|
let get_dir stream idx =
|
||||||
|
let idx = idx mod Array.length stream in
|
||||||
|
stream.(idx)
|
||||||
|
;;
|
||||||
|
|
||||||
|
(*[{
|
||||||
|
#
|
||||||
|
# # #
|
||||||
|
### # # ##
|
||||||
|
#### # ### # ##
|
||||||
|
|
||||||
|
row plus angle col square
|
||||||
|
|
||||||
|
}]*)
|
||||||
|
let shape_points shape pos =
|
||||||
|
let points =
|
||||||
|
match shape with
|
||||||
|
| Row -> [ 0, 0; 1, 0; 2, 0; 3, 0 ]
|
||||||
|
| Plus -> [ 0, 1; 1, 0; 1, 1; 1, 2; 2, 1 ]
|
||||||
|
| Angle -> [ 0, 0; 1, 0; 2, 0; 2, 1; 2, 2 ]
|
||||||
|
| Col -> [ 0, 0; 0, 1; 0, 2; 0, 3 ]
|
||||||
|
| Square -> [ 0, 0; 1, 0; 0, 1; 1, 1 ]
|
||||||
|
in
|
||||||
|
points |> List.map (fun point -> Vec2.(pos + of_tuple point))
|
||||||
|
;;
|
||||||
|
|
||||||
|
type cave =
|
||||||
|
{ grid : char Grid.t
|
||||||
|
; mutable height : int
|
||||||
|
; mutable rocks : (shape * Vec2.t) list
|
||||||
|
; mutable stream_idx : int
|
||||||
|
}
|
||||||
|
|
||||||
|
let init_cave max_height =
|
||||||
|
let grid = Grid.init ~width:7 ~height:max_height (Fun.const '.') in
|
||||||
|
{ grid; height = -1; rocks = []; stream_idx = 0 }
|
||||||
|
;;
|
||||||
|
|
||||||
|
let draw_cave cave = Grid.draw cave.grid ~rev_y:true (fun _ contents -> contents)
|
||||||
|
|
||||||
|
let place_shape cave shape pos =
|
||||||
|
cave.rocks <- (shape, pos) :: cave.rocks;
|
||||||
|
shape_points shape pos
|
||||||
|
|> List.iter (fun point ->
|
||||||
|
if cave.height < point.Vec2.y then cave.height <- point.y;
|
||||||
|
Grid.set_e cave.grid point '#')
|
||||||
|
;;
|
||||||
|
|
||||||
|
let can_place_shape cave shape pos =
|
||||||
|
shape_points shape pos
|
||||||
|
|> List.fold_while
|
||||||
|
(fun _ point ->
|
||||||
|
match cave.grid.Grid.%(point) with
|
||||||
|
| Some '.' -> true, `Continue
|
||||||
|
| _ -> false, `Stop)
|
||||||
|
false
|
||||||
|
;;
|
||||||
|
|
||||||
|
let drop_shape cave stream shape =
|
||||||
|
let rec drop pos =
|
||||||
|
let stream_pos = Vec2.(pos + get_dir stream cave.stream_idx) in
|
||||||
|
cave.stream_idx <- cave.stream_idx + 1;
|
||||||
|
let pos = if can_place_shape cave shape stream_pos then stream_pos else pos in
|
||||||
|
let drop_pos = Vec2.(pos + Vec2.up) in
|
||||||
|
if can_place_shape cave shape drop_pos
|
||||||
|
then drop drop_pos
|
||||||
|
else place_shape cave shape pos
|
||||||
|
in
|
||||||
|
drop Vec2.{ x = 2; y = Int.(cave.height + 4) }
|
||||||
|
;;
|
||||||
|
|
||||||
|
let%expect_test "Day 17" =
|
||||||
|
let stream = example_lines |> Iter.of_str |> Iter.map dir_of_char |> Iter.to_array in
|
||||||
|
let cave = init_cave 40 in
|
||||||
|
drop_shape cave stream Row;
|
||||||
|
drop_shape cave stream Plus;
|
||||||
|
drop_shape cave stream Angle;
|
||||||
|
drop_shape cave stream Col;
|
||||||
|
drop_shape cave stream Square;
|
||||||
|
drop_shape cave stream Row;
|
||||||
|
drop_shape cave stream Plus;
|
||||||
|
drop_shape cave stream Angle;
|
||||||
|
drop_shape cave stream Col;
|
||||||
|
drop_shape cave stream Square;
|
||||||
|
Printf.printf "height: %i\n" (cave.height + 1);
|
||||||
|
Printf.printf "%s" @@ draw_cave cave;
|
||||||
|
[%expect
|
||||||
|
{|
|
||||||
|
height: 17
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
.......
|
||||||
|
....#..
|
||||||
|
....#..
|
||||||
|
....##.
|
||||||
|
##..##.
|
||||||
|
######.
|
||||||
|
.###...
|
||||||
|
..#....
|
||||||
|
.####..
|
||||||
|
....##.
|
||||||
|
....##.
|
||||||
|
....#..
|
||||||
|
..#.#..
|
||||||
|
..#.#..
|
||||||
|
#####..
|
||||||
|
..###..
|
||||||
|
...#...
|
||||||
|
..####. |}]
|
||||||
|
;;
|
||||||
Loading…
Reference in New Issue
Block a user