# 2020 Advent Of Code Day 12 (Part 1)

Prolog. Developed and tested with SWI-Prolog 8.2.3.

right(0, east, east).
right(90, east, south).
right(180, east, west).
right(270, east, north).
right(360, east, east).
right(0, south, south).
right(90, south, west).
right(180, south, north).
right(270, south, east).
right(360, south, south).
right(0, west, west).
right(90, west, north).
right(180, west, east).
right(270, west, south).
right(360, west, west).
right(0, north, north).
right(90, north, east).
right(180, north, south).
right(270, north, west).
right(360, north, north).

left(Degree, Facing, NewFacing):-
D is 360 - Degree,
right(D, Facing, NewFacing).

!.
!.
!.
!.
get_code(Stream, NextChar),

at_end_of_stream(Stream).
\+ at_end_of_stream(Stream),
get_code(Stream, Char),
atom_codes(X, Chars),

execute_command(Command, Value, Position, Direction, NewDirection, UpdatedPosition):-
(Command == 'R',
right(Value, Direction, NewDirection),
UpdatedPosition = Position
);
(Command == 'L',
left(Value, Direction, NewDirection),
UpdatedPosition = Position);
(Command == 'N',
NewDirection = Direction,
[X0, Y0] = Position,
Y1 is Y0 + Value,
UpdatedPosition = [X0, Y1]);
(Command == 'S',
NewDirection = Direction,
[X0, Y0] = Position,
Y1 is Y0 - Value,
UpdatedPosition = [X0, Y1]);
(Command == 'E',
NewDirection = Direction,
[X0, Y0] = Position,
X1 is X0 + Value,
UpdatedPosition = [X1, Y0]);
(Command == 'W',
NewDirection = Direction,
[X0, Y0] = Position,
X1 is X0 - Value,
UpdatedPosition = [X1, Y0]);
(Command == 'F',
(Direction == east, execute_command('E', Value, Position, Direction, NewDirection, UpdatedPosition));
(Direction == south, execute_command('S', Value, Position, Direction, NewDirection, UpdatedPosition));
(Direction == west, execute_command('W', Value, Position, Direction, NewDirection, UpdatedPosition));
(Direction == north, execute_command('N', Value, Position, Direction, NewDirection, UpdatedPosition))
).

move_ship([]).
move_ship(Commands, FinalPosition):-
move_ship(Commands, east, [0, 0], FinalPosition).
move_ship([], _, FinalPosition, FinalPosition):-!.
move_ship([H|T], Direction, IntermediatePosition, FinalPosition):-
atom_chars(H, C),
[Command|Number] = C,
number_chars(Value, Number),
execute_command(Command, Value, IntermediatePosition, Direction, NewDirection, UpdatedPosition),
move_ship(T, NewDirection, UpdatedPosition, FinalPosition).

manhattan_distance(FinalPosition, ManhattanDistance):-
[X, Y] = FinalPosition,
ManhattanDistance is abs(X) + abs(Y).

main:-
close(Stream),
move_ship(Commands, FinalPosition),
manhattan_distance(FinalPosition, ManhattanDistance),
format("Manhattan Distance from starting point: ~d.~n", [ManhattanDistance]).

### Recent Posts from This Journal

• #### A Simple Binary Tree in Perl

This Binary Tree implementation uses Class::Struct and only defines find() and insert() operations, along with a simple print function for…

• #### The Weekly Challenge 127: Conflict Intervals (C++ Solutions)

Part 2 of The Weekly Challenge 127: You are given two sets with unique numbers. Write a script to figure out if they are disjoint. #include

• #### The Weekly Challenge 127: Disjoint Lists (C++ Solutions)

Part 1 of The Weekly Challenge 127: You are given two sets with unique numbers. Write a script to figure out if they are disjoint. #include

Comments for this post were disabled by the author