-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrobot_simulator.gleam
96 lines (85 loc) · 2.12 KB
/
robot_simulator.gleam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import gleam/string
pub type Robot {
Robot(direction: Direction, position: Position)
}
pub type Direction {
North
East
South
West
}
pub type Position {
Position(x: Int, y: Int)
}
pub fn create(direction: Direction, position: Position) -> Robot {
Robot(direction: direction, position: position)
}
pub fn move(
direction: Direction,
position: Position,
instructions: String,
) -> Robot {
case string.first(instructions) {
Ok("R") -> move(
change_and_return_direction(direction, "R"),
position,
return_string_without_first_char(instructions)
)
Ok("L") -> move(
change_and_return_direction(direction, "L"),
position,
return_string_without_first_char(instructions)
)
Ok("A") -> move(
direction,
change_and_return_position(direction, position),
return_string_without_first_char(instructions)
)
Ok(_) -> Robot(direction: direction, position: position)
Error(Nil) -> Robot(direction: direction, position: position)
}
}
fn change_and_return_direction(direction: Direction, instruction: String) -> Direction {
case determine_orientation(instruction) {
1 -> return_next_direction(direction)
-1 -> return_previous_direction(direction)
_ -> panic
}
}
fn determine_orientation(instruction: String) -> Int {
case instruction {
"R" -> 1
"L" -> -1
_ -> 0
}
}
fn return_previous_direction(direction: Direction) -> Direction {
case direction {
North -> West
East -> North
South -> East
West -> South
}
}
fn return_next_direction(direction: Direction) -> Direction {
case direction {
North -> East
East -> South
South -> West
West -> North
}
}
fn change_and_return_position(direction: Direction, position: Position) -> Position {
case direction {
North -> Position(position.x, position.y + 1)
East -> Position(position.x + 1, position.y)
South -> Position(position.x, position.y - 1)
West -> Position(position.x - 1, position.y)
}
}
fn return_string_without_first_char(string: String) -> String {
case string.pop_grapheme(string) {
Ok(#(_, tail)) -> tail
_ -> ""
}
}