Skip to content

Commit

Permalink
Add robot-name exercise
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikSchierboom committed Mar 21, 2024
1 parent 63b8cfd commit 95984b1
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,14 @@
"practices": [],
"prerequisites": [],
"difficulty": 1
},
{
"slug": "robot-name",
"name": "Robot Name",
"uuid": "54eb5f14-2b7c-4201-b38d-a25ce2cdae97",
"practices": [],
"prerequisites": [],
"difficulty": 1
}
],
"foregone": [
Expand Down
8 changes: 8 additions & 0 deletions exercises/practice/robot-name/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Hints

## General

- Use the [setarg] predicate to mutate data.
- The [setarg] predicate uses **1-based indexing**, so the first element is at index 1.

[setarg]: https://www.swi-prolog.org/pldoc/doc_for?object=setarg/3
9 changes: 9 additions & 0 deletions exercises/practice/robot-name/.docs/instructions.append.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Instructions append

## Mutable data in Prolog

By default, values in Prolog are _immutable_, which means that values never change (you'll have to introduce a new variable for each new value).
While this is great for the vast majority of use cases, this exercise _does_ require mutating values.
To mutate data in Prolog, you can use the [setarg] predicate.

[setarg]: https://www.swi-prolog.org/pldoc/doc_for?object=setarg/3
14 changes: 14 additions & 0 deletions exercises/practice/robot-name/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Instructions

Manage robot factory settings.

When a robot comes off the factory floor, it has no name.

The first time you turn on a robot, a random name is generated in the format of two uppercase letters followed by three digits, such as RX837 or BC811.

Every once in a while we need to reset a robot to its factory settings, which means that its name gets wiped.
The next time you ask, that robot will respond with a new random name.

The names must be random: they should not follow a predictable sequence.
Using random names means a risk of collisions.
Your solution must ensure that every existing robot has a unique name.
18 changes: 18 additions & 0 deletions exercises/practice/robot-name/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"authors": [
"erikschierboom"
],
"files": {
"solution": [
"robot_name.pl"
],
"test": [
"robot_name_tests.plt"
],
"example": [
".meta/robot_name.example.pl"
]
},
"blurb": "Manage robot factory settings.",
"source": "A debugging session with Paul Blackwell at gSchool."
}
19 changes: 19 additions & 0 deletions exercises/practice/robot-name/.meta/robot_name.example.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
letters(Letters) :- string_chars("ABCDEFGHIJKLMNOPQRSTUVWXZY", Letters).
digits(Digits) :- string_chars("0123456789", Digits).

generate_name(Name) :-
letters(Letters),
digits(Digits),
random_member(L1, Letters), random_member(L2, Letters),
random_member(D1, Digits), random_member(D2, Digits), random_member(D3, Digits),
string_chars(Name, [L1,L2,D1,D2,D3]).

create_robot(Robot) :-
generate_name(Name),
Robot = robot(Name).

robot_name(robot(Name), Name).

reset_name(Robot) :-
generate_name(Name),
setarg(1, Robot, Name).
3 changes: 3 additions & 0 deletions exercises/practice/robot-name/robot_name.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
create_robot(Robot).
robot_name(Robot, Name).
reset_name(Robot).
41 changes: 41 additions & 0 deletions exercises/practice/robot-name/robot_name_tests.plt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
pending :-
current_prolog_flag(argv, ['--all'|_]).
pending :-
write('\nA TEST IS PENDING!\n'),
fail.

:- begin_tests(robot_name).

test(has_name, condition(true)) :-
create_robot(Robot),
robot_name(Robot, Name),
string_concat(Letters, Digits, Name),
string_length(Letters, 2),
string_length(Digits, 3),
string_chars(Letters, LettersChars),
string_chars(Digits, DigitsChars),
maplist([C]>>char_type(C, upper), LettersChars),
maplist([C]>>char_type(C, digit), DigitsChars),
!.

test(name_sticks, condition(pending)) :-
create_robot(Robot),
robot_name(Robot, Name1),
robot_name(Robot, Name2),
Name1 == Name2.

test(different_robots_have_different_names, condition(pending)) :-
create_robot(Robot1),
create_robot(Robot2),
robot_name(Robot1, Name1),
robot_name(Robot2, Name2),
Name1 \== Name2.

test(reset_name, condition(pending)) :-
create_robot(Robot),
robot_name(Robot, Name1),
reset_name(Robot),
robot_name(Robot, Name2),
Name1 \== Name2.

:- end_tests(robot_name).

0 comments on commit 95984b1

Please sign in to comment.