Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

port: allergies #280

Merged
merged 5 commits into from
May 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,17 @@
"math",
"transforming"
]
},
{
"slug": "allergies",
"uuid": "b572a9d9-859d-43bd-a8e1-8d6f7566b685",
"core": false,
"unlocked_by": "luhn",
"difficulty": 2,
"topics": [
"bitwise_operations",
"arrays"
]
}
]
}
1 change: 1 addition & 0 deletions exercises/allergies/.meta/version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.0.0
56 changes: 56 additions & 0 deletions exercises/allergies/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Allergies

Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.

An allergy test produces a single numeric score which contains the
information about all the allergies the person has (that they were
tested for).

The list of items (and their value) that were tested are:

* eggs (1)
* peanuts (2)
* shellfish (4)
* strawberries (8)
* tomatoes (16)
* chocolate (32)
* pollen (64)
* cats (128)

So if Tom is allergic to peanuts and chocolate, he gets a score of 34.

Now, given just that score of 34, your program should be able to say:

- Whether Tom is allergic to any one of those allergens listed above.
- All the allergens Tom is allergic to.

Note: a given score may include allergens **not** listed above (i.e.
allergens that score 256, 512, 1024, etc.). Your program should
ignore those components of the score. For example, if the allergy
score is 257, your program should only report the eggs (1) allergy.


Run the tests with:

```bash
bats allergies_test.sh
```

After the first test(s) pass, continue by commenting out or removing the `skip` annotations prepending other tests.

## Source

Jumpstart Lab Warm-up [http://jumpstartlab.com](http://jumpstartlab.com)


## External utilities
`Bash` is a language to write scripts that works closely with various system utilities,
like [`sed`](https://www.gnu.org/software/sed/), [`awk`](https://www.gnu.org/software/gawk/), [`date`](https://www.gnu.org/software/coreutils/manual/html_node/date-invocation.html) and even other programming languages, like [`Python`](https://www.python.org/).
This track does not restrict the usage of these utilities, and as long as your solution is portable
between systems and does not require installing third party applications, feel free to use them to solve the exercise.

For an extra challenge, if you would like to have a better understanding of the language,
try to re-implement the solution in pure `Bash`, without using any external tools.

## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
113 changes: 113 additions & 0 deletions exercises/allergies/allergies_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env bash

@test 'no_allergies_means_not_allergic' {
#skip
run bash allergies.sh 0 allergic_to peanuts
[[ $status -eq 0 ]]
[[ $output = "false" ]]
run bash allergies.sh 0 allergic_to cats
[[ $status -eq 0 ]]
[[ $output = "false" ]]
run bash allergies.sh 0 allergic_to strawberries
[[ $status -eq 0 ]]
[[ $output = "false" ]]
}

@test 'is_allergic_to_eggs' {
skip
run bash allergies.sh 1 allergic_to eggs
[[ $status -eq 0 ]]
[[ $output = "true" ]]
}

@test 'allergic_to_eggs_in_addition_to_other_stuff' {
skip
run bash allergies.sh 5 allergic_to eggs
[[ $status -eq 0 ]]
[[ $output = "true" ]]
run bash allergies.sh 5 allergic_to shellfish
[[ $status -eq 0 ]]
[[ $output = "true" ]]
run bash allergies.sh 5 allergic_to strawberries
[[ $status -eq 0 ]]
[[ $output = "false" ]]
}

@test 'allergic_to_strawberries_but_not_peanuts' {
skip
run bash allergies.sh 9 allergic_to eggs
[[ $status -eq 0 ]]
[[ $output = "true" ]]
run bash allergies.sh 9 allergic_to peanuts
[[ $status -eq 0 ]]
[[ $output = "false" ]]
run bash allergies.sh 9 allergic_to shellfish
[[ $status -eq 0 ]]
[[ $output = "false" ]]
run bash allergies.sh 9 allergic_to strawberries
[[ $status -eq 0 ]]
[[ $output = "true" ]]
}

@test 'no_allergies_at_all' {
skip
run bash allergies.sh 0 list
[[ $status -eq 0 ]]
[[ $output == "" ]]
}

@test 'allergic_to_just_eggs' {
skip
run bash allergies.sh 1 list
[[ $status -eq 0 ]]
[[ $output == "eggs" ]]
}

@test 'allergic_to_just_peanuts' {
skip
run bash allergies.sh 2 list
[[ $status -eq 0 ]]
[[ $output == "peanuts" ]]
}

@test 'allergic_to_just_strawberries' {
skip
run bash allergies.sh 8 list
[[ $status -eq 0 ]]
[[ $output == "strawberries" ]]
}

@test 'allergic_to_eggs_and_peanuts' {
skip
run bash allergies.sh 3 list
[[ $status -eq 0 ]]
[[ $output == "eggs peanuts" ]]
}

@test 'allergic_to_more_than_eggs_but_not_peanuts' {
skip
run bash allergies.sh 5 list
[[ $status -eq 0 ]]
[[ $output == "eggs shellfish" ]]
}

@test 'allergic_to_lots_of_stuff' {
skip
run bash allergies.sh 248 list
[[ $status -eq 0 ]]
[[ $output == "strawberries tomatoes chocolate pollen cats" ]]
}

@test 'allergic_to_everything' {
skip
run bash allergies.sh 255 list
[[ $status -eq 0 ]]
[[ $output == "eggs peanuts shellfish strawberries tomatoes chocolate pollen cats" ]]
}

@test 'ignore_non_allergen_score_parts' {
skip
run bash allergies.sh 509 list
[[ $status -eq 0 ]]
[[ $output == "eggs shellfish strawberries tomatoes chocolate pollen cats" ]]
}
72 changes: 72 additions & 0 deletions exercises/allergies/example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/bash

allergens=(
eggs peanuts shellfish strawberries
tomatoes chocolate pollen cats
)

main() {
if (( $# < 2 )); then
echo "usage: ${0##*/} <code> list" >&2
echo "usage: ${0##*/} <code> allergic_to <allergen>" >&2
exit 255
fi

local code=$1
local cmd=$2

case $cmd in
list)
list_allergies "$code"
;;
allergic_to)
if [[ -z "$3" ]]; then
echo "error: missing argument" >&2
exit 1
fi
is_allergic_to "$code" "$3"
;;
esac
}

# returns a 0/1 exit status
index_test() {
local code=$1 idx=$2
(( (code & (1 << idx)) != 0 ))
}

# print a space-separated list of allergens encoded by
# the allergy code
list_allergies() {
local code=$1
local allergies=()
local i
# iterate over the array _indices_
for i in "${!allergens[@]}"; do
if index_test "$code" "$i"; then
allergies+=( "${allergens[i]}" )
fi
done
echo "${allergies[*]}"
}

# print "true" if the allergy code includes the given allergen,
# print "false" otherwise
is_allergic_to() {
local code=$1
local allergen=$2
local i
# iterate over the array _indices_
for i in "${!allergens[@]}"; do
if [[ ${allergens[i]} == "$allergen" ]] &&
index_test "$code" "$i"
then
echo "true"
exit
fi

done
echo "false"
}

main "$@"