# Advent of Code 2022 Day 8 - Discussions

This topic is about Day 8 of the Advent of Code 2022 .

The entry code is:
`370884-a6a71927`

Good luck!

2 Likes

Re-used some of the code from previous year to parse numerical grid into a map:

``````main(File) ->
Data = [ [ X - \$0 || X <- binary_to_list(Line) ]
|| Line <- binary:split(RawData, <<"\n">>, [global, trim]) ],
io:format("part 1: ~p~n", [solve1(Map)]),
io:format("part 2: ~p~n", [solve2(Map)]).

maps:from_list([ {{X, Y}, N} || {Y, Line} <- enum(Data),
{X, N}    <- enum(Line) ]).

enum(List) ->
lists:zip(lists:seq(1, length(List)), List).

solve1(Data) ->
MaxC  = {MaxX, MaxY} = lists:max(maps:keys(Data)),
Edges = 2 * MaxX + 2 * MaxY - 4,
length([ true || X <- lists:seq(2, MaxX - 1),
Y <- lists:seq(2, MaxY - 1),
is_visible({X, Y}, MaxC, Data) ])
+ Edges.

is_visible(Coord, MaxC, Map) ->
Height = maps:get(Coord, Map),
lists:any(fun (D) -> all_shorter(Height, Map, enum_direction(D, Coord, MaxC)) end,
[left, right, up, down]).

all_shorter(Height, Map, Coords) ->
lists:all(fun (C) -> maps:get(C, Map) < Height end, Coords).

enum_direction(left,  {X0, Y0}, _        ) -> [ {X,  Y0} || X <- lists:seq(X0 - 1, 1, -1) ];
enum_direction(right, {X0, Y0}, {MaxX, _}) -> [ {X,  Y0} || X <- lists:seq(X0 + 1, MaxX)  ];
enum_direction(up,    {X0, Y0}, _        ) -> [ {X0, Y } || Y <- lists:seq(Y0 - 1, 1, -1) ];
enum_direction(down,  {X0, Y0}, {_, MaxY}) -> [ {X0, Y } || Y <- lists:seq(Y0 + 1, MaxY)  ].

solve2(Data) ->
MaxC = {MaxX, MaxY} = lists:max(maps:keys(Data)),
lists:max([ scenic_score({X, Y}, MaxC, Data) || X <- lists:seq(2, MaxX - 1),
Y <- lists:seq(2, MaxY - 1) ]).

scenic_score(Coord, MaxC, Map) ->
Height = maps:get(Coord, Map),
lists:foldl(fun (D, Acc) -> Acc * view_distance(Height, Map, enum_direction(D, Coord, MaxC)) end,
1,
[left, right, up, down]).

view_distance(Height, Map, [C|Rest]) ->
case maps:get(C, Map) >= Height of
true  -> 1;
false -> 1 + view_distance(Height, Map, Rest)
end;
view_distance(_, _, []) ->
0.
``````
2 Likes

I didnâ€™t know what I was doing last night but I solved it using Clojure. Nastiest Clojure I wrote, having transposed and reverted and reverted transposed matrices and comparing with originalâ€¦ arghhh.

I attempted to do the same for Erlang, after having enough hammock time. I am proud of the code (Although I took ample inspiration from your code at Part 2 especially, thank you). Especially I liked the way I regained my `[Head | Tail]` fluency (the `list -> map` function).

Did this at 5AM, took ~40 minutes (like I said, reading your code helped).

``````-module(day_8).

-export([solve/0]).

input() ->
RawHeights.

parse(RawHeights) ->
TreeList =
[[X - \$0 || X <- binary_to_list(Line)]
|| Line <- binary:split(RawHeights, <<"\n">>, [global, trim])],
Length = length(TreeList),
Edges = 2 * Length + 2 * Breadth - 4,
TreeMap = tree_list_to_tree_map(TreeList),

solve() ->
RawHeights = input(),
{TreeMap, Edges, Length, Breadth} = parse(RawHeights),
Solve1 = solve1(TreeMap, Edges, Length, Breadth),
{Solve1, Solve2}.

Interior =
length([true
|| X <- lists:seq(2, Length - 1),
Y <- lists:seq(2, Breadth - 1),
Edges + Interior.

|| X <- lists:seq(2, Length - 1), Y <- lists:seq(2, Breadth - 1)]).

tree_list_to_tree_map(TreeList) ->
tree_list_to_tree_map(TreeList, 1, 1, []).

tree_list_to_tree_map([], _, _, TreeList) ->
maps:from_list(TreeList);
tree_list_to_tree_map([[] | Lengths], X, _, TreeList) ->
tree_list_to_tree_map(Lengths, X + 1, 1, TreeList);
tree_list_to_tree_map([[Height | Breadths] | Lengths], X, Y, TreeList) ->
tree_list_to_tree_map([Breadths | Lengths], X, Y + 1, [{{X, Y}, Height} | TreeList]).

seen_from(top, {XX, YY}, _) ->
[{X, YY} || X <- lists:seq(XX - 1, 1, -1)];
seen_from(bottom, {XX, YY}, {Length, _}) ->
[{X, YY} || X <- lists:seq(XX + 1, Length)];
seen_from(left, {XX, YY}, _) ->
[{XX, Y} || Y <- lists:seq(YY - 1, 1, -1)];
seen_from(right, {XX, YY}, {_, Breadth}) ->
[{XX, Y} || Y <- lists:seq(YY + 1, Breadth)].

is_visible(Coord, Dims, Map) ->
lists:any(fun(Dir) -> is_tallest(maps:get(Coord, Map), Map, seen_from(Dir, Coord, Dims))
end,
[top, bottom, left, right]).

is_tallest(Height, Map, Coords) ->
lists:all(fun(C) -> maps:get(C, Map) < Height end, Coords).

scenic_score(Coord, Dims, Map) ->
Height = maps:get(Coord, Map),
Reducer =
fun(Dir, Acc) -> Acc * view_distance(Height, Map, seen_from(Dir, Coord, Dims)) end,
lists:foldl(Reducer, 1, [top, bottom, left, right]).

view_distance(Height, TreeMap, [C | Rest]) ->
case maps:get(C, TreeMap) >= Height of
true ->
1;
false ->
1 + view_distance(Height, TreeMap, Rest)
end;
view_distance(_, _, []) ->
0.
``````
2 Likes

Hah! That `TreeMap` and `TreeList` naming was intentionalâ€¦ a tribute to Java if you will.

2 Likes