initial commit
This commit is contained in:
64
bash/darts/README.md
Normal file
64
bash/darts/README.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Darts
|
||||
|
||||
Write a function that returns the earned points in a single toss of a Darts game.
|
||||
|
||||
[Darts](https://en.wikipedia.org/wiki/Darts) is a game where players
|
||||
throw darts to a [target](https://en.wikipedia.org/wiki/Darts#/media/File:Darts_in_a_dartboard.jpg).
|
||||
|
||||
In our particular instance of the game, the target rewards with 4 different amounts of points, depending on where the dart lands:
|
||||
|
||||
* If the dart lands outside the target, player earns no points (0 points).
|
||||
* If the dart lands in the outer circle of the target, player earns 1 point.
|
||||
* If the dart lands in the middle circle of the target, player earns 5 points.
|
||||
* If the dart lands in the inner circle of the target, player earns 10 points.
|
||||
|
||||
The outer circle has a radius of 10 units (This is equivalent to the total radius for the entire target), the middle circle a radius of 5 units, and the inner circle a radius of 1. Of course, they are all centered to the same point (That is, the circles are [concentric](http://mathworld.wolfram.com/ConcentricCircles.html)) defined by the coordinates (0, 0).
|
||||
|
||||
Write a function that given a point in the target (defined by its `real` cartesian coordinates `x` and `y`), returns the correct amount earned by a dart landing in that point.
|
||||
|
||||
This particular exercise, since it deals with floating point arithmetic, is natural to rely on external tools (see below). As an extra challenging challenge, find a way to implement this with plain bash.
|
||||
|
||||
Run the tests with:
|
||||
|
||||
```bash
|
||||
bats darts_test.sh
|
||||
```
|
||||
|
||||
After the first test(s) pass, continue by commenting out or removing the
|
||||
`[[ $BATS_RUN_SKIPPED == true ]] || skip`
|
||||
annotations prepending other tests.
|
||||
|
||||
To run all tests, including the ones with `skip` annotations, run:
|
||||
|
||||
```bash
|
||||
BATS_RUN_SKIPPED=true bats darts_test.sh
|
||||
```
|
||||
|
||||
## Source
|
||||
|
||||
Inspired by an exercise created by a professor Della Paolera in Argentina
|
||||
|
||||
|
||||
## External utilities
|
||||
`Bash` is a language to write "scripts" -- programs that can call
|
||||
external tools, such as
|
||||
[`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 programs written in 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
|
||||
installation of 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. Note that there are some types of
|
||||
problems that bash cannot solve, such as performing floating point
|
||||
arithmetic and manipulating dates: for those, you must call out to an
|
||||
external tool.
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others
|
||||
have completed the exercise.
|
82
bash/darts/darts.sh
Executable file
82
bash/darts/darts.sh
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# external tools: none (only integer operations).
|
||||
#
|
||||
# V1 : Initial version.
|
||||
# V2 : Using reference instead of subshell, as of
|
||||
# https://stackoverflow.com/questions/540298
|
||||
# moved valid numbers in parseval function.
|
||||
# V3/4 : added some quotes following suggestions
|
||||
|
||||
# set to mask to enable logs. 0: none, 255: all
|
||||
#((DEBUG=2#00001111))
|
||||
((DEBUG=2#00000000))
|
||||
|
||||
# $1: log level (mask), then strings to display.
|
||||
debug () {
|
||||
(( DEBUG & $1 )) && shift && echo "${@}" >&2
|
||||
}
|
||||
|
||||
usage () {
|
||||
echo "usage: darts x y" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
shopt -s extglob
|
||||
|
||||
# To be able to use bash only, all numbers will be miltiplied by 1,000.
|
||||
# Could be higher if we want more precision.
|
||||
#
|
||||
# So: 0.1 will be 100, 1 will be 1,000, 10 will br 10000, etc...
|
||||
|
||||
# circles. as we will use Pythagoras' theorem, so square value calc here
|
||||
outer=$(( (10 * 1000 ) ** 2 ))
|
||||
middle=$(( ( 5 * 1000 ) ** 2 ))
|
||||
inner=$(( ( 1 * 1000 ) ** 2 ))
|
||||
|
||||
debug 1 outer=$outer middle=$middle inner=$inner
|
||||
|
||||
# basic args check: 2 args, and decimal numbers, which are:
|
||||
# optional +- sign, optional digits, optional . and optional digits
|
||||
(( ${#} != 2 )) && usage
|
||||
|
||||
parseval() {
|
||||
# integer and decimal parts, final value by ref
|
||||
local int dec
|
||||
local -n calc=$1
|
||||
|
||||
# check for valid decimal number
|
||||
[[ ${2} != ?([-+])+([0-9])?(.*([0-9])) ]] && usage
|
||||
|
||||
IFS=. read int dec <<< "$2"
|
||||
debug 2 ${int} ${dec}
|
||||
|
||||
# we accept up to 3 decimals: add 3 zeroes to dec, then keep 3 first digits
|
||||
# So a decimal part of "1" will become 100, 01 will become 10, etc...
|
||||
# we also take care of leadings 0 (octal notation), and remove leading "-".
|
||||
dec="$dec"000
|
||||
dec="10#"${dec:0:3}
|
||||
int="10#"${int#-}
|
||||
|
||||
debug 2 mult ${int} ${dec}
|
||||
calc=$(( (int*1000 + dec) ** 2 ))
|
||||
}
|
||||
|
||||
parseval x "$1"
|
||||
parseval y "$2"
|
||||
total=$(( x+y ))
|
||||
debug 1 x=$x y=$y x+y=$total
|
||||
|
||||
(( total <= inner )) && echo 10 && exit 0
|
||||
(( total <= middle )) && echo 5 && exit 0
|
||||
(( total <= outer )) && echo 1 && exit 0
|
||||
echo 0 && exit 0
|
||||
|
||||
# emacs/vim settings.
|
||||
# Local Variables:
|
||||
# sh-basic-offset: 4
|
||||
# indent-tabs-mode: nil
|
||||
# comment-column: 60
|
||||
# fill-column: 80
|
||||
# End:
|
||||
# vim: set tabstop=4 expandtab:
|
Reference in New Issue
Block a user