Skip to content

Commit b1cd067

Browse files
annalyns-infiltration concept exercise (#169)
1 parent 9289a53 commit b1cd067

10 files changed

Lines changed: 250 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ bin/configlet.exe
44
bin/latest-configlet.tar.gz
55
bin/latest-configlet.zip
66
bin/configlet.zip
7+
test-exercises/

config.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@
3030
]
3131
},
3232
"exercises": {
33+
"concept": [
34+
{
35+
"slug": "annalyns-infiltration",
36+
"name": "Annalyns Infiltration",
37+
"uuid": "57a3408b-1c45-4860-9605-47eb6651fb81",
38+
"concepts": [
39+
"stack-effect"
40+
],
41+
"prerequisites": [],
42+
"status": "wip"
43+
}
44+
],
3345
"practice": [
3446
{
3547
"slug": "hello-world",
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Hints
2+
3+
## General
4+
5+
- The three boolean words — `and`, `or`, and `not` — all live in the
6+
`kernel` vocabulary and are already available without a `USING:` line.
7+
- Factor is concatenative: arguments are consumed from the stack in the
8+
order they were pushed. If you need to combine two values in the "wrong"
9+
order, use `swap`.
10+
11+
## 1. Fast attack
12+
13+
- `not` inverts a boolean, which is exactly what you need to turn
14+
"the knight is awake" into "the knight is asleep".
15+
16+
## 2. Spy
17+
18+
- `or` applied to two values is true when at least one is true.
19+
- `or` combines just two inputs at a time, but it composes: chaining
20+
two `or`s is fine when you need to check three values.
21+
22+
## 3. Signal prisoner
23+
24+
- You need `prisoner-awake AND (NOT archer-awake)`.
25+
- `archer-awake` sits deeper on the stack than `prisoner-awake` when the
26+
word is entered. Consider whether a `swap` helps you apply `not` to the
27+
right value.
28+
29+
## 4. Free prisoner
30+
31+
- The success condition is an `or` of two sub-expressions.
32+
- Each sub-expression is an `and` of several negated and/or plain
33+
booleans — you may find it clearest to write the word using
34+
locals (`::` and named parameters) rather than juggling the stack.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Instructions
2+
3+
In this exercise, you'll be writing some logic for a video game a friend is developing.
4+
The game's main character is Annalyn, a brave girl with a fierce and loyal pet dog.
5+
Unfortunately, disaster strikes, as her best friend is kidnapped while searching for berries in the forest.
6+
Annalyn will try to find and free her friend, optionally taking her dog with her on this quest.
7+
8+
Annalyn eventually finds the camp in which her friend is imprisoned and it turns out there are two kidnappers: a mighty knight and a cunning archer.
9+
10+
The player is presented with some options for what to do next.
11+
For each of the four possible options you need to write a word that tells the game whether it should show that option or not.
12+
13+
## 1. Check if the 'Fast Attack' option should be shown
14+
15+
If the knight is sleeping, then Annalyn will be able to make a quick attack into the camp before he can wake up properly and get his armour on.
16+
17+
Implement a word named `can-do-fast-attack` that takes a boolean value indicating whether the knight is awake.
18+
It returns `t` if the 'Fast Attack' action is available, otherwise `f`:
19+
20+
```factor
21+
t can-do-fast-attack .
22+
! => f
23+
```
24+
25+
## 2. Check if the 'Spy' option should be shown
26+
27+
The group can be spied upon if at least one of them is awake. Otherwise, spying is a waste of time.
28+
29+
Implement a word named `can-spy` that takes three boolean values, indicating whether the knight, archer and prisoner, respectively, are awake.
30+
It returns `t` if the 'Spy' action is available, otherwise `f`:
31+
32+
```factor
33+
f t f can-spy .
34+
! => t
35+
```
36+
37+
## 3. Check if the 'Signal Prisoner' option should be shown
38+
39+
The prisoner can be signalled using bird sounds if she is awake and the archer is sleeping.
40+
If the archer is awake then she can't be safely signaled because the archer is also trained in bird signalling.
41+
42+
Implement a word named `can-signal-prisoner` that takes two boolean values, indicating whether the archer and prisoner, respectively, are awake.
43+
It returns `t` if the 'Signal Prisoner' action is available, otherwise `f`:
44+
45+
```factor
46+
f t can-signal-prisoner .
47+
! => t
48+
```
49+
50+
## 4. Check if the 'Free Prisoner' option should be shown
51+
52+
Annalyn can try sneaking into the camp to free her friend. This is a risky thing to do and can only succeed in one of two ways:
53+
54+
- If Annalyn has her pet dog with her, she can rescue the prisoner if the archer is asleep.
55+
The knight is scared of the dog and the archer will not have time to get ready before Annalyn and her friend can escape.
56+
57+
- If Annalyn does not have her dog, then she and the prisoner must be very sneaky!
58+
Annalyn can free the prisoner if the prisoner is awake and the knight and archer are both sleeping.
59+
If the prisoner is sleeping, she can't be rescued: she would be startled by Annalyn's sudden appearance and wake up the knight and archer.
60+
61+
Implement a word named `can-free-prisoner` that takes four boolean values.
62+
The first three parameters indicate whether the knight, archer and prisoner, respectively, are awake.
63+
The last parameter indicates whether Annalyn's pet dog is present.
64+
It returns `t` if the 'Free Prisoner' action is available, otherwise `f`:
65+
66+
```factor
67+
f t f f can-free-prisoner .
68+
! => f
69+
```
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Introduction
2+
3+
## Booleans in Factor
4+
5+
True and false are written as the words `t` and `f`. `f` is Factor's only
6+
falsy value — everything else, including `0` and empty collections, is
7+
truthy.
8+
9+
```factor
10+
t .
11+
! => t
12+
13+
f .
14+
! => f
15+
```
16+
17+
## Boolean operators
18+
19+
Three words in the `kernel` vocabulary handle the common cases:
20+
21+
- `and` — returns truthy when both inputs are truthy.
22+
- `or` — returns truthy when either input is truthy.
23+
- `not` — inverts its argument.
24+
25+
```factor
26+
t t and . ! => t
27+
t f and . ! => f
28+
29+
f t or . ! => t
30+
31+
t not . ! => f
32+
```
33+
34+
Because Factor is concatenative, these words consume their arguments from
35+
the data stack. If your arguments are on the stack in the "wrong" order for
36+
a particular operator, use `swap` to flip them.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Source
2+
3+
Forked from the Julia track's ["Annalyn's Infiltration" exercise][julia-source], which is in turn based on the JavaScript track's ["Booleans" exercise][javascript-source], designed by [Rishi Kothari][rishiosaur] and [Derk-Jan Karrenbeld][sleepless].
4+
5+
[julia-source]: https://github.com/exercism/julia/tree/main/exercises/concept/annalyns-infiltration
6+
[javascript-source]: https://github.com/exercism/v3/tree/1b7c392e1cc576f3948ed55216611c42fabb19b1/languages/javascript/exercises/concept/booleans
7+
[rishiosaur]: https://github.com/rishiosaur
8+
[sleepless]: https://github.com/SleeplessByte
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"authors": [
3+
"keiravillekode"
4+
],
5+
"files": {
6+
"solution": [
7+
"annalyns-infiltration/annalyns-infiltration.factor"
8+
],
9+
"test": [
10+
"annalyns-infiltration/annalyns-infiltration-tests.factor"
11+
],
12+
"exemplar": [
13+
".meta/exemplar.factor"
14+
]
15+
},
16+
"forked_from": [
17+
"julia/annalyns-infiltration"
18+
],
19+
"icon": "annalyns-infiltration",
20+
"blurb": "Learn about boolean expressions by implementing the quest logic for a new RPG."
21+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
USING: kernel locals ;
2+
IN: annalyns-infiltration
3+
4+
: can-do-fast-attack ( knight-awake -- ? )
5+
not ;
6+
7+
: can-spy ( knight-awake archer-awake prisoner-awake -- ? )
8+
or or ;
9+
10+
: can-signal-prisoner ( archer-awake prisoner-awake -- ? )
11+
swap not and ;
12+
13+
:: can-free-prisoner ( knight-awake archer-awake prisoner-awake dog-present -- ? )
14+
dog-present archer-awake not and
15+
prisoner-awake knight-awake not and archer-awake not and
16+
or ;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
USING: annalyns-infiltration tools.test ;
2+
IN: annalyns-infiltration.tests
3+
4+
! TASK: 1 fast attack
5+
{ t } [ f can-do-fast-attack ] unit-test
6+
{ f } [ t can-do-fast-attack ] unit-test
7+
8+
! TASK: 2 spying
9+
{ f } [ f f f can-spy ] unit-test
10+
{ t } [ f f t can-spy ] unit-test
11+
{ t } [ f t f can-spy ] unit-test
12+
{ t } [ f t t can-spy ] unit-test
13+
{ t } [ t f f can-spy ] unit-test
14+
{ t } [ t f t can-spy ] unit-test
15+
{ t } [ t t t can-spy ] unit-test
16+
17+
! TASK: 3 signaling prisoner
18+
{ f } [ f f can-signal-prisoner ] unit-test
19+
{ t } [ f t can-signal-prisoner ] unit-test
20+
{ f } [ t f can-signal-prisoner ] unit-test
21+
{ f } [ t t can-signal-prisoner ] unit-test
22+
23+
! TASK: 4 freeing prisoner
24+
{ f } [ f f f f can-free-prisoner ] unit-test
25+
{ t } [ f f f t can-free-prisoner ] unit-test
26+
{ t } [ f f t f can-free-prisoner ] unit-test
27+
{ t } [ f f t t can-free-prisoner ] unit-test
28+
{ f } [ f t f f can-free-prisoner ] unit-test
29+
{ f } [ f t f t can-free-prisoner ] unit-test
30+
{ f } [ f t t f can-free-prisoner ] unit-test
31+
{ f } [ f t t t can-free-prisoner ] unit-test
32+
{ f } [ t f f f can-free-prisoner ] unit-test
33+
{ t } [ t f f t can-free-prisoner ] unit-test
34+
{ f } [ t f t f can-free-prisoner ] unit-test
35+
{ t } [ t f t t can-free-prisoner ] unit-test
36+
{ f } [ t t f f can-free-prisoner ] unit-test
37+
{ f } [ t t f t can-free-prisoner ] unit-test
38+
{ f } [ t t t f can-free-prisoner ] unit-test
39+
{ f } [ t t t t can-free-prisoner ] unit-test
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
USING: kernel ;
2+
IN: annalyns-infiltration
3+
4+
: can-do-fast-attack ( knight-awake -- ? )
5+
"unimplemented" throw ;
6+
7+
: can-spy ( knight-awake archer-awake prisoner-awake -- ? )
8+
"unimplemented" throw ;
9+
10+
: can-signal-prisoner ( archer-awake prisoner-awake -- ? )
11+
"unimplemented" throw ;
12+
13+
: can-free-prisoner ( knight-awake archer-awake prisoner-awake dog-present -- ? )
14+
"unimplemented" throw ;

0 commit comments

Comments
 (0)