Given a year, report if it is a leap year.
The tricky thing here is that a leap year in the Gregorian calendar occurs:
on every year that is evenly divisible by 4
except every year that is evenly divisible by 100
unless the year is also evenly divisible by 400
For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap year, but 2000 is.
If your language provides a method in the standard library that does this look-up, pretend it doesn't exist and implement it yourself.
Though our exercise adopts some very simple rules, there is more to learn!
For a delightful, four minute explanation of the whole leap year phenomenon, go watch this youtube video.
Run the tests with:
bats leap_test.sh
After the first test(s) pass, continue by commenting out or removing the skip
annotations prepending other tests.
JavaRanch Cattle Drive, exercise 3 http://www.javaranch.com/leap.jsp
Bash
is a language to write scripts that works closely with various system utilities,
like sed
, awk
, date
and even other programming languages, like Python
.
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.
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
#!/usr/bin/env bash
@test 'year not divisible by 4: common year' {
#skip
run bash leap.sh 2015
[ "$status" -eq 0 ]
[ "$output" = 'false' ]
}
@test 'year divisible by 4, not divisible by 100: leap year' {
skip
run bash leap.sh 1996
[ "$status" -eq 0 ]
[ "$output" = 'true' ]
}
@test 'year divisible by 100, not divisible by 400: common year' {
skip
run bash leap.sh 2100
[ "$status" -eq 0 ]
[ "$output" = 'false' ]
}
@test 'year divisible by 400: leap year' {
skip
run bash leap.sh 2000
[ "$status" -eq 0 ]
[ "$output" = 'true' ]
}
@test 'No input should return an error' {
skip
run bash leap.sh
[ "$status" -eq 1 ]
[ "$output" = 'Usage: leap.sh <year>' ]
}
@test 'Too many arguments should return an error' {
skip
run bash leap.sh 2016 4562 4566
[ "$status" -eq 1 ]
[ "$output" = 'Usage: leap.sh <year>' ]
}
@test 'Float number input should return an error' {
skip
run bash leap.sh 2016.54
[ "$status" -eq 1 ]
[ "$output" = 'Usage: leap.sh <year>' ]
}
@test 'Alpha input should return an error' {
skip
run bash leap.sh 'abcd'
[ "$status" -eq 1 ]
[ "$output" = 'Usage: leap.sh <year>' ]
}
#!/usr/bin/env bash
# tivasyk <tivasyk@gmail.com>
show_help() {
local NAME
NAME=$(basename "$0")
cat <<EOF
Usage: $NAME <year>
EOF
}
main () {
# If not one argument only, or if the argument contains anything but digits...
if [[ "$#" -ne 1 || ! -z "${1//[0-9]/}" ]]; then
show_help
exit 1
fi
# Check for leapiness
if [[ $(( $1 % 400)) -eq 0 || ( $(( $1 % 4 )) -eq 0 && $(( $1 % 100 )) -ne 0 ) ]] ; then
echo "true"
else
echo "false"
fi
}
main "$@"
well, figuring out that test for "leapiness" line was definitely a pain =)
Level up your programming skills with 3,112 exercises across 52 languages, and insightful discussion with our volunteer team of welcoming mentors. Exercism is 100% free forever.
Sign up Learn More
Community comments