🎉 Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io 🎉
Avatar of katrinleinweber

katrinleinweber's solution

to Leap in the R Track

Published at Jul 13 2018 · 4 comments
Instructions
Test suite
Solution

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.

Notes

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.

Installation

See this guide for instructions on how to setup your local R environment.

How to implement your solution

In each problem folder, there is a file named <exercise_name>.R containing a function that returns a NULL value. Place your implementation inside the body of the function.

How to run tests

Inside of RStudio, simply execute the test_<exercise_name>.R script. This can be conveniently done with testthat's auto_test function. Because exercism code and tests are in the same folder, use this same path for both code_path and test_path parameters. On the command-line, you can also run Rscript test_<exercise_name>.R.

Source

JavaRanch Cattle Drive, exercise 3 http://www.javaranch.com/leap.jsp

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

test_leap.R

source("./leap.R")
library(testthat)

context("leap")

test_that("year not divisible by 4: common year", {
  year <- 2015
  expect_equal(leap(year), FALSE)
})

test_that("year divisible by 4, not divisible by 100: leap year", {
  year <- 2016
  expect_equal(leap(year), TRUE)
})

test_that("year divisible by 100, not divisible by 400: common year", {
  year <- 2100
  expect_equal(leap(year), FALSE)
})

test_that("year divisible by 400: leap year", {
  year <- 2000
  expect_equal(leap(year), TRUE)
})

message("All tests passed for exercise: leap")
leap <- function(year) {
  
  dplyr::case_when(
    year %% 400 == 0 ~ TRUE,
    year %% 100 == 0 ~ FALSE, 
    year %% 4 == 0 ~ TRUE,
    TRUE ~ FALSE
  )
}

Community comments

Find this solution interesting? Ask the author a question to learn more.
Avatar of jucikisistok

Your solution is super nice, dplyr is such a useful package :)

Avatar of katrinleinweber

Thank you! I wouldn't have been motivated to keep on learning R without dplyr and other tidyverse packages :-)

Avatar of jucikisistok

@katrinleinweber commented:

Thank you! I wouldn't have been motivated to keep on learning R without dplyr and other tidyverse packages :-)

Yeah, I can totally understand that :D Once I get tired of Python, these will be the first things that I wanna master :'D

Avatar of katrinleinweber

This solution now seems to be a local optimum to me. Nicely readable & logical in the context of using dplyr particularly. However, besides the fact that a dependency is not really needed, it's also a bit inefficient, because it:

  1. turns the =='s T or F results into a T or F return values (this duplicates implicit R behavior in order to make it explicit), and
  2. doesn't use the mathematical optimal order of comparisons (I encourage readers of this to search for a better order!).

A 1-liner with & & | would solve both these issues. Please have a look at other community solutions as well :-)

(edited over 2 years ago)

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?