Prolog. Developed and tested with SWI-Prolog 8.2.3.
line-size(91).
check_and_read(10, [] ,_):-
!.
check_and_read(13, [], _):-
!.
check_and_read(32, [], _):-
!.
check_and_read(end_of_file, [], _):-
!.
check_and_read(Char, [Char|Chars], Stream):-
get_code(Stream, NextChar),
check_and_read(NextChar, Chars, Stream).
read_data(Stream, []):-
at_end_of_stream(Stream).
read_data(Stream, [X|L]):-
\+ at_end_of_stream(Stream),
get_code(Stream, Char),
check_and_read(Char, Chars, Stream),
atom_codes(X, Chars),
read_data(Stream, L).
hashcount(List, HashCount):-
hashcount(List, 0, HashCount).
hashcount([], HashCount, HashCount).
hashcount([H|T], HashCountPartial, HashCount):-
H == 35,
HCP is HashCountPartial + 1,
hashcount(T, HCP, HashCount).
hashcount([H|T], HashCountPartial, HashCount):-
H \== 35,
hashcount(T, HashCountPartial, HashCount).
allseats(Records, AllSeats):-
allseats(Records, [], AllSeats).
allseats([], AllSeats, AllSeats).
allseats([H|T], AllSeatsAccum, AllSeats):-
string_codes(H, L),
append(AllSeatsAccum, L, Accum),
allseats(T, Accum, AllSeats).
adjacent_bottomleft(Seat, AllSeats, AdjacentSeat):-
line-size(LS),
LS1 is LS - 1,
S is Seat + LS1,
S > 0,
M0 is Seat mod LS,
M1 is S mod LS,
((M0 \== 0, M0 \==1,
M1 < M0);
(M0 == 0, M1 == LS1)),
nth1(S, AllSeats, BLeft),
((BLeft \== 46, AdjacentSeat = BLeft);
adjacent_bottomleft(S, AllSeats, AdjacentSeat)).
adjacent_bottomleft(_, _, AdjacentSeat):-
AdjacentSeat = null.
adjacent_left(Seat, AllSeats, AdjacentSeat):-
line-size(LS),
LS1 is LS - 1,
S is Seat - 1,
S > 0,
M0 is Seat mod LS,
M1 is S mod LS,
((M0 \== 0, M0 \==1,
M1 < M0);
(M0 == 0, M1 == LS1)),
nth1(S, AllSeats, Left),
((Left \== 46, AdjacentSeat = Left);
adjacent_left(S, AllSeats, AdjacentSeat)).
adjacent_left(_, _, AdjacentSeat):-
AdjacentSeat = null.
adjacent_topleft(Seat, AllSeats, AdjacentSeat):-
line-size(LS),
LS1 is LS - 1,
S is Seat - (LS + 1),
S > 0,
M0 is Seat mod LS,
M1 is S mod LS,
((M0 \== 0, M0 \==1,
M1 < M0);
(M0 == 0, M1 == LS1)),
nth1(S, AllSeats, TLeft),
((TLeft \== 46, AdjacentSeat = TLeft);
adjacent_topleft(S, AllSeats, AdjacentSeat)).
adjacent_topleft(_, _, AdjacentSeat):-
AdjacentSeat = null.
adjacent_bottomright(Seat, AllSeats, AdjacentSeat):-
line-size(LS),
LS1 is LS - 1,
S is Seat + (LS + 1),
S > 0,
M0 is Seat mod LS,
M1 is S mod LS,
((M1 > M0,
M0 \== 0);
(M1 == 0, M0 == LS1)),
nth1(S, AllSeats, BRight),
((BRight \== 46, AdjacentSeat = BRight);
adjacent_bottomright(S, AllSeats, AdjacentSeat)).
adjacent_bottomright(_, _, AdjacentSeat):-
AdjacentSeat = null.
adjacent_right(Seat, AllSeats, AdjacentSeat):-
line-size(LS),
LS1 is LS - 1,
S is Seat + 1,
S > 0,
M0 is Seat mod LS,
M1 is S mod LS,
((M1 > M0,
M0 \== 0);
(M1 == 0, M0 == LS1)),
nth1(S, AllSeats, Right),
((Right \== 46, AdjacentSeat = Right);
adjacent_right(S, AllSeats, AdjacentSeat)).
adjacent_right(_, _, AdjacentSeat):-
AdjacentSeat = null.
adjacent_topright(Seat, AllSeats, AdjacentSeat):-
line-size(LS),
LS1 is LS - 1,
S is Seat - LS1,
M0 is Seat mod LS,
M1 is S mod LS,
((M1 > M0,
M0 \== 0);
(M1 == 0, M0 == LS1)),
nth1(S, AllSeats, TRight),
((TRight \== 46, AdjacentSeat = TRight);
adjacent_topright(S, AllSeats, AdjacentSeat)).
adjacent_topright(_, _, AdjacentSeat):-
AdjacentSeat = null.
adjacent_up(Seat, AllSeats, AdjacentSeat):-
line-size(LS),
S is Seat - LS,
S > 0,
nth1(S, AllSeats, Up),
((Up \== 46, AdjacentSeat = Up);
adjacent_up(S, AllSeats, AdjacentSeat)).
adjacent_up(_, _, AdjacentSeat):-
AdjacentSeat = null.
adjacent_down(Seat, AllSeats, AdjacentSeat):-
line-size(LS),
S is Seat + LS,
S > 0,
nth1(S, AllSeats, Down),
((Down \== 46, AdjacentSeat = Down);
adjacent_down(S, AllSeats, AdjacentSeat)).
adjacent_down(_, _, AdjacentSeat):-
AdjacentSeat = null.
adjacent(Seat, AllSeats, AdjacentSeats):-
adjacent_left(Seat, AllSeats, AdjacentSeatLeft),
adjacent_right(Seat, AllSeats, AdjacentSeatRight),
adjacent_up(Seat, AllSeats, AdjacentSeatUp),
adjacent_down(Seat, AllSeats, AdjacentSeatDown),
adjacent_topleft(Seat, AllSeats, AdjacentSeatTopLeft),
adjacent_topright(Seat, AllSeats, AdjacentSeatTopRight),
adjacent_bottomleft(Seat, AllSeats, AdjacentSeatBottomLeft),
adjacent_bottomright(Seat, AllSeats, AdjacentSeatBottomRight),
AdjacentSeats = [AdjacentSeatLeft, AdjacentSeatRight, AdjacentSeatUp, AdjacentSeatDown,
AdjacentSeatTopLeft, AdjacentSeatTopRight, AdjacentSeatBottomLeft,
AdjacentSeatBottomRight],!.
round(AllSeats, UpdatedSeats):-
round(AllSeats, 0, AllSeats, [], UpdatedSeats).
round([], _, _, UpdatedSeats, UpdatedSeats).
round([H|T], Counter, AllSeats, UpdatedSeatsAccum, UpdatedSeats):-
C is Counter + 1,
atom_codes(A, [H]),
A == '.',
append(UpdatedSeatsAccum, [H], Accum),
round(T, C, AllSeats, Accum, UpdatedSeats).
round([H|T], Counter, AllSeats, UpdatedSeatsAccum, UpdatedSeats):-
C is Counter + 1,
atom_codes(A, [H]),
A == '#',
adjacent(C, AllSeats, AdjacentSeats),
hashcount(AdjacentSeats, HashCount),
HashCount >= 5,
H0 = 'L',
atom_codes(H0, [A0]),
append(UpdatedSeatsAccum, [A0], Accum),
round(T, C, AllSeats, Accum, UpdatedSeats).
round([H|T], Counter, AllSeats, UpdatedSeatsAccum, UpdatedSeats):-
C is Counter + 1,
atom_codes(A, [H]),
A == '#',
adjacent(C, AllSeats, AdjacentSeats),
hashcount(AdjacentSeats, HashCount),
HashCount \== 5,
append(UpdatedSeatsAccum, [H], Accum),
round(T, C, AllSeats, Accum, UpdatedSeats).
round([H|T], Counter, AllSeats, UpdatedSeatsAccum, UpdatedSeats):-
C is Counter + 1,
atom_codes(A, [H]),
A == 'L',
adjacent(C, AllSeats, AdjacentSeats),
\+ member(35, AdjacentSeats),
H0 = '#',
atom_codes(H0, [A0]),
append(UpdatedSeatsAccum, [A0], Accum),
round(T, C, AllSeats, Accum, UpdatedSeats).
round([H|T], Counter, AllSeats, UpdatedSeatsAccum, UpdatedSeats):-
C is Counter + 1,
atom_codes(A, [H]),
A == 'L',
adjacent(C, AllSeats, AdjacentSeats),
member(35, AdjacentSeats),
append(UpdatedSeatsAccum, [H], Accum),
round(T, C, AllSeats, Accum, UpdatedSeats).
rounds(AllSeats, OccupiedSeats):-
rounds(AllSeats, [], OccupiedSeats).
rounds([-1], _, _).
rounds(AllSeats, PreviousRound, OccupiedSeats):-
round(AllSeats, UpdatedRound),!,
write_seats(UpdatedRound), nl,
((
UpdatedRound == PreviousRound,
hashcount(UpdatedRound, OccupiedSeats),
rounds([-1], UpdatedRound, OccupiedSeats)
);
(
UpdatedRound \== PreviousRound,
rounds(UpdatedRound, UpdatedRound, OccupiedSeats)
)).
write_seats([H|T]):-
write_seats([H|T], 0).
write_seats([], _).
write_seats([H|T], Counter):-
line-size(LS),
C is Counter + 1,
M is C mod LS,
M \== 0,
atom_codes(A, [H]),
write(A),
write_seats(T, C).
write_seats([H|T], Counter):-
line-size(LS),
C is Counter + 1,
M is C mod LS,
M == 0,
atom_codes(A, [H]),
write(A),
nl,
write_seats(T, C).
main:-
open('data', read, Stream),
read_data(Stream, Records),
close(Stream),
allseats(Records, AllSeats),
rounds(AllSeats, OccupiedSeats),
write(OccupiedSeats), nl.