diff --git a/config.json b/config.json index 13e33ecb..95f219b4 100644 --- a/config.json +++ b/config.json @@ -832,6 +832,38 @@ "practices": [], "prerequisites": [], "difficulty": 5 + }, + { + "slug": "dnd-character", + "name": "D&D Character", + "uuid": "8c617fa4-5c2f-4be3-b7dc-8f8bf8214326", + "practices": [], + "prerequisites": [], + "difficulty": 4 + }, + { + "slug": "binary-search", + "name": "Binary Search", + "uuid": "7b4e53cc-44c0-4be3-b036-1e08fb1ae507", + "practices": [], + "prerequisites": [], + "difficulty": 3 + }, + { + "slug": "robot-name", + "name": "Robot Name", + "uuid": "445bd3fd-011d-4a8f-aa83-5acc53225679", + "practices": [], + "prerequisites": [], + "difficulty": 4 + }, + { + "slug": "nth-prime", + "name": "Nth Prime", + "uuid": "e61c707d-eb0d-4c37-8c0f-014db4504d3d", + "practices": [], + "prerequisites": [], + "difficulty": 5 } ] }, diff --git a/exercises/practice/binary-search/.docs/instructions.md b/exercises/practice/binary-search/.docs/instructions.md new file mode 100644 index 00000000..12f4358e --- /dev/null +++ b/exercises/practice/binary-search/.docs/instructions.md @@ -0,0 +1,29 @@ +# Instructions + +Your task is to implement a binary search algorithm. + +A binary search algorithm finds an item in a list by repeatedly splitting it in half, only keeping the half which contains the item we're looking for. +It allows us to quickly narrow down the possible locations of our item until we find it, or until we've eliminated all possible locations. + +~~~~exercism/caution +Binary search only works when a list has been sorted. +~~~~ + +The algorithm looks like this: + +- Find the middle element of a _sorted_ list and compare it with the item we're looking for. +- If the middle element is our item, then we're done! +- If the middle element is greater than our item, we can eliminate that element and all the elements **after** it. +- If the middle element is less than our item, we can eliminate that element and all the elements **before** it. +- If every element of the list has been eliminated then the item is not in the list. +- Otherwise, repeat the process on the part of the list that has not been eliminated. + +Here's an example: + +Let's say we're looking for the number 23 in the following sorted list: `[4, 8, 12, 16, 23, 28, 32]`. + +- We start by comparing 23 with the middle element, 16. +- Since 23 is greater than 16, we can eliminate the left half of the list, leaving us with `[23, 28, 32]`. +- We then compare 23 with the new middle element, 28. +- Since 23 is less than 28, we can eliminate the right half of the list: `[23]`. +- We've found our item. diff --git a/exercises/practice/binary-search/.docs/introduction.md b/exercises/practice/binary-search/.docs/introduction.md new file mode 100644 index 00000000..03496599 --- /dev/null +++ b/exercises/practice/binary-search/.docs/introduction.md @@ -0,0 +1,13 @@ +# Introduction + +You have stumbled upon a group of mathematicians who are also singer-songwriters. +They have written a song for each of their favorite numbers, and, as you can imagine, they have a lot of favorite numbers (like [0][zero] or [73][seventy-three] or [6174][kaprekars-constant]). + +You are curious to hear the song for your favorite number, but with so many songs to wade through, finding the right song could take a while. +Fortunately, they have organized their songs in a playlist sorted by the title — which is simply the number that the song is about. + +You realize that you can use a binary search algorithm to quickly find a song given the title. + +[zero]: https://en.wikipedia.org/wiki/0 +[seventy-three]: https://en.wikipedia.org/wiki/73_(number) +[kaprekars-constant]: https://en.wikipedia.org/wiki/6174_(number) diff --git a/exercises/practice/binary-search/.meta/config.json b/exercises/practice/binary-search/.meta/config.json new file mode 100644 index 00000000..46e7be68 --- /dev/null +++ b/exercises/practice/binary-search/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "erikschierboom" + ], + "files": { + "solution": [ + "binary-search.R" + ], + "test": [ + "test_binary-search.R" + ], + "example": [ + ".meta/example.R" + ] + }, + "blurb": "Implement a binary search algorithm.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Binary_search_algorithm" +} diff --git a/exercises/practice/binary-search/.meta/example.R b/exercises/practice/binary-search/.meta/example.R new file mode 100644 index 00000000..d494ad2d --- /dev/null +++ b/exercises/practice/binary-search/.meta/example.R @@ -0,0 +1,15 @@ +find <- function(haystack, needle) { + left <- 1 + right <- length(haystack) + + while (left <= right) { + middle_idx <- (right + left) %/% 2 + middle <- haystack[middle_idx] + + if (middle == needle) return(middle_idx) + if (middle < needle) left <- middle_idx + 1 + else right <- middle_idx - 1 + } + + -1 +} diff --git a/exercises/practice/binary-search/.meta/tests.toml b/exercises/practice/binary-search/.meta/tests.toml new file mode 100644 index 00000000..61e2b068 --- /dev/null +++ b/exercises/practice/binary-search/.meta/tests.toml @@ -0,0 +1,43 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[b55c24a9-a98d-4379-a08c-2adcf8ebeee8] +description = "finds a value in an array with one element" + +[73469346-b0a0-4011-89bf-989e443d503d] +description = "finds a value in the middle of an array" + +[327bc482-ab85-424e-a724-fb4658e66ddb] +description = "finds a value at the beginning of an array" + +[f9f94b16-fe5e-472c-85ea-c513804c7d59] +description = "finds a value at the end of an array" + +[f0068905-26e3-4342-856d-ad153cadb338] +description = "finds a value in an array of odd length" + +[fc316b12-c8b3-4f5e-9e89-532b3389de8c] +description = "finds a value in an array of even length" + +[da7db20a-354f-49f7-a6a1-650a54998aa6] +description = "identifies that a value is not included in the array" + +[95d869ff-3daf-4c79-b622-6e805c675f97] +description = "a value smaller than the array's smallest value is not found" + +[8b24ef45-6e51-4a94-9eac-c2bf38fdb0ba] +description = "a value larger than the array's largest value is not found" + +[f439a0fa-cf42-4262-8ad1-64bf41ce566a] +description = "nothing is found in an empty array" + +[2c353967-b56d-40b8-acff-ce43115eed64] +description = "nothing is found when the left and right bounds cross" diff --git a/exercises/practice/binary-search/binary-search.R b/exercises/practice/binary-search/binary-search.R new file mode 100644 index 00000000..adb14263 --- /dev/null +++ b/exercises/practice/binary-search/binary-search.R @@ -0,0 +1,3 @@ +find <- function(haystack, needle) { + +} diff --git a/exercises/practice/binary-search/test_binary-search.R b/exercises/practice/binary-search/test_binary-search.R new file mode 100644 index 00000000..2f526306 --- /dev/null +++ b/exercises/practice/binary-search/test_binary-search.R @@ -0,0 +1,69 @@ +source("./binary-search.R") +library(testthat) + +test_that("Finds a needle in an haystack with one element", { + haystack <- c(6) + needle <- 6 + expect_equal(find(haystack, needle), 1) +}) + +test_that("Finds a needle in the middle of an haystack", { + haystack <- c(1, 3, 4, 6, 8, 9, 11) + needle <- 6 + expect_equal(find(haystack, needle), 4) +}) + +test_that("Finds a needle at the beginning of an haystack", { + haystack <- c(1, 3, 4, 6, 8, 9, 11) + needle <- 1 + expect_equal(find(haystack, needle), 1) +}) + +test_that("Finds a needle at the end of an haystack", { + haystack <- c(1, 3, 4, 6, 8, 9, 11) + needle <- 11 + expect_equal(find(haystack, needle), 7) +}) + +test_that("Finds a needle in an haystack of odd length", { + haystack <- c(1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634) + needle <- 144 + expect_equal(find(haystack, needle), 10) +}) + +test_that("Finds a needle in an haystack of even length", { + haystack <- c(1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377) + needle <- 21 + expect_equal(find(haystack, needle), 6) +}) + +test_that("Identifies that a needle is not included in the haystack", { + haystack <- c(1, 3, 4, 6, 8, 9, 11) + needle <- 7 + expect_equal(find(haystack, needle), -1) +}) + +test_that("A needle smaller than the haystack's smallest needle is not found", { + haystack <- c(1, 3, 4, 6, 8, 9, 11) + needle <- 0 + expect_equal(find(haystack, needle), -1) +}) + +test_that("A needle larger than the haystack's largest needle is not found", { + haystack <- c(1, 3, 4, 6, 8, 9, 11) + needle <- 13 + expect_equal(find(haystack, needle), -1) +}) + +test_that("Nothing is found in an empty haystack", { + haystack <- c() + needle <- 1 + expected <- -1 + expect_equal(find(haystack, needle), -1) +}) + +test_that("Nothing is found when the left and right bounds cross", { + haystack <- c(1, 2) + needle <- 0 + expect_equal(find(haystack, needle), -1) +}) diff --git a/exercises/practice/dnd-character/.docs/instructions.md b/exercises/practice/dnd-character/.docs/instructions.md new file mode 100644 index 00000000..e14e7949 --- /dev/null +++ b/exercises/practice/dnd-character/.docs/instructions.md @@ -0,0 +1,32 @@ +# Instructions + +For a game of [Dungeons & Dragons][dnd], each player starts by generating a character they can play with. +This character has, among other things, six abilities; strength, dexterity, constitution, intelligence, wisdom and charisma. +These six abilities have scores that are determined randomly. +You do this by rolling four 6-sided dice and recording the sum of the largest three dice. +You do this six times, once for each ability. + +Your character's initial hitpoints are 10 + your character's constitution modifier. +You find your character's constitution modifier by subtracting 10 from your character's constitution, divide by 2 and round down. + +Write a random character generator that follows the above rules. + +For example, the six throws of four dice may look like: + +- 5, 3, 1, 6: You discard the 1 and sum 5 + 3 + 6 = 14, which you assign to strength. +- 3, 2, 5, 3: You discard the 2 and sum 3 + 5 + 3 = 11, which you assign to dexterity. +- 1, 1, 1, 1: You discard the 1 and sum 1 + 1 + 1 = 3, which you assign to constitution. +- 2, 1, 6, 6: You discard the 1 and sum 2 + 6 + 6 = 14, which you assign to intelligence. +- 3, 5, 3, 4: You discard the 3 and sum 5 + 3 + 4 = 12, which you assign to wisdom. +- 6, 6, 6, 6: You discard the 6 and sum 6 + 6 + 6 = 18, which you assign to charisma. + +Because constitution is 3, the constitution modifier is -4 and the hitpoints are 6. + +~~~~exercism/note +Most programming languages feature (pseudo-)random generators, but few programming languages are designed to roll dice. +One such language is [Troll][troll]. + +[troll]: https://di.ku.dk/Ansatte/?pure=da%2Fpublications%2Ftroll-a-language-for-specifying-dicerolls(84a45ff0-068b-11df-825d-000ea68e967b)%2Fexport.html +~~~~ + +[dnd]: https://en.wikipedia.org/wiki/Dungeons_%26_Dragons diff --git a/exercises/practice/dnd-character/.docs/introduction.md b/exercises/practice/dnd-character/.docs/introduction.md new file mode 100644 index 00000000..5301f618 --- /dev/null +++ b/exercises/practice/dnd-character/.docs/introduction.md @@ -0,0 +1,10 @@ +# Introduction + +After weeks of anticipation, you and your friends get together for your very first game of [Dungeons & Dragons][dnd] (D&D). +Since this is the first session of the game, each player has to generate a character to play with. +The character's abilities are determined by rolling 6-sided dice, but where _are_ the dice? +With a shock, you realize that your friends are waiting for _you_ to produce the dice; after all it was your idea to play D&D! +Panicking, you realize you forgot to bring the dice, which would mean no D&D game. +As you have some basic coding skills, you quickly come up with a solution: you'll write a program to simulate dice rolls. + +[dnd]: https://en.wikipedia.org/wiki/Dungeons_%26_Dragons diff --git a/exercises/practice/dnd-character/.meta/config.json b/exercises/practice/dnd-character/.meta/config.json new file mode 100644 index 00000000..a292f918 --- /dev/null +++ b/exercises/practice/dnd-character/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "erikschierboom" + ], + "files": { + "solution": [ + "dnd-character.R" + ], + "test": [ + "test_dnd-character.R" + ], + "example": [ + ".meta/example.R" + ] + }, + "blurb": "Randomly generate Dungeons & Dragons characters.", + "source": "Simon Shine, Erik Schierboom", + "source_url": "https://github.com/exercism/problem-specifications/issues/616#issuecomment-437358945" +} diff --git a/exercises/practice/dnd-character/.meta/example.R b/exercises/practice/dnd-character/.meta/example.R new file mode 100644 index 00000000..503438ad --- /dev/null +++ b/exercises/practice/dnd-character/.meta/example.R @@ -0,0 +1,24 @@ +modifier <- function(score) { + (score - 10) %/% 2 +} + +ability <- function() { + sample(1:6, 4, replace = TRUE) |> sort() |> tail(n = 3) |> sum() +} + +new_character <- function() { + constitution <- ability() + + structure( + list( + strength = ability(), + dexterity = ability(), + intelligence = ability(), + wisdom = ability(), + charisma = ability(), + constitution = constitution, + hitpoints = 10 + modifier(constitution) + ), + class = "character" + ) +} diff --git a/exercises/practice/dnd-character/.meta/tests.toml b/exercises/practice/dnd-character/.meta/tests.toml new file mode 100644 index 00000000..719043b2 --- /dev/null +++ b/exercises/practice/dnd-character/.meta/tests.toml @@ -0,0 +1,72 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[1e9ae1dc-35bd-43ba-aa08-e4b94c20fa37] +description = "ability modifier -> ability modifier for score 3 is -4" + +[cc9bb24e-56b8-4e9e-989d-a0d1a29ebb9c] +description = "ability modifier -> ability modifier for score 4 is -3" + +[5b519fcd-6946-41ee-91fe-34b4f9808326] +description = "ability modifier -> ability modifier for score 5 is -3" + +[dc2913bd-6d7a-402e-b1e2-6d568b1cbe21] +description = "ability modifier -> ability modifier for score 6 is -2" + +[099440f5-0d66-4b1a-8a10-8f3a03cc499f] +description = "ability modifier -> ability modifier for score 7 is -2" + +[cfda6e5c-3489-42f0-b22b-4acb47084df0] +description = "ability modifier -> ability modifier for score 8 is -1" + +[c70f0507-fa7e-4228-8463-858bfbba1754] +description = "ability modifier -> ability modifier for score 9 is -1" + +[6f4e6c88-1cd9-46a0-92b8-db4a99b372f7] +description = "ability modifier -> ability modifier for score 10 is 0" + +[e00d9e5c-63c8-413f-879d-cd9be9697097] +description = "ability modifier -> ability modifier for score 11 is 0" + +[eea06f3c-8de0-45e7-9d9d-b8cab4179715] +description = "ability modifier -> ability modifier for score 12 is +1" + +[9c51f6be-db72-4af7-92ac-b293a02c0dcd] +description = "ability modifier -> ability modifier for score 13 is +1" + +[94053a5d-53b6-4efc-b669-a8b5098f7762] +description = "ability modifier -> ability modifier for score 14 is +2" + +[8c33e7ca-3f9f-4820-8ab3-65f2c9e2f0e2] +description = "ability modifier -> ability modifier for score 15 is +2" + +[c3ec871e-1791-44d0-b3cc-77e5fb4cd33d] +description = "ability modifier -> ability modifier for score 16 is +3" + +[3d053cee-2888-4616-b9fd-602a3b1efff4] +description = "ability modifier -> ability modifier for score 17 is +3" + +[bafd997a-e852-4e56-9f65-14b60261faee] +description = "ability modifier -> ability modifier for score 18 is +4" + +[4f28f19c-2e47-4453-a46a-c0d365259c14] +description = "random ability is within range" + +[385d7e72-864f-4e88-8279-81a7d75b04ad] +description = "random character is valid" + +[2ca77b9b-c099-46c3-a02c-0d0f68ffa0fe] +description = "each ability is only calculated once" +include = false + +[dca2b2ec-f729-4551-84b9-078876bb4808] +description = "each ability is only calculated once" +reimplements = "2ca77b9b-c099-46c3-a02c-0d0f68ffa0fe" diff --git a/exercises/practice/dnd-character/dnd-character.R b/exercises/practice/dnd-character/dnd-character.R new file mode 100644 index 00000000..b320863f --- /dev/null +++ b/exercises/practice/dnd-character/dnd-character.R @@ -0,0 +1,11 @@ +modifier <- function(score) { + +} + +ability <- function() { + +} + +new_character <- function() { + +} diff --git a/exercises/practice/dnd-character/test_dnd-character.R b/exercises/practice/dnd-character/test_dnd-character.R new file mode 100644 index 00000000..df39321f --- /dev/null +++ b/exercises/practice/dnd-character/test_dnd-character.R @@ -0,0 +1,99 @@ +source("./dnd-character.R") +library(testthat) + +test_that("Ability modifier for score 3 is -4", { + expect_equal(modifier(3), -4) +}) + +test_that("Ability modifier for score 4 is -3", { + expect_equal(modifier(4), -3) +}) + +test_that("Ability modifier for score 5 is -3", { + expect_equal(modifier(5), -3) +}) + +test_that("Ability modifier for score 6 is -2", { + expect_equal(modifier(6), -2) +}) + +test_that("Ability modifier for score 7 is -2", { + expect_equal(modifier(7), -2) +}) + +test_that("Ability modifier for score 8 is -1", { + expect_equal(modifier(8), -1) +}) + +test_that("Ability modifier for score 9 is -1", { + expect_equal(modifier(9), -1) +}) + +test_that("Ability modifier for score 10 is 0", { + expect_equal(modifier(10), 0) +}) + +test_that("Ability modifier for score 11 is 0", { + expect_equal(modifier(11), 0) +}) + +test_that("Ability modifier for score 12 is +1", { + expect_equal(modifier(12), 1) +}) + +test_that("Ability modifier for score 13 is +1", { + expect_equal(modifier(13), 1) +}) + +test_that("Ability modifier for score 14 is +2", { + expect_equal(modifier(14), 2) +}) + +test_that("Ability modifier for score 15 is +2", { + expect_equal(modifier(15), 2) +}) + +test_that("Ability modifier for score 16 is +3", { + expect_equal(modifier(16), 3) +}) + +test_that("Ability modifier for score 17 is +3", { + expect_equal(modifier(17), 3) +}) + +test_that("Ability modifier for score 18 is +4", { + expect_equal(modifier(18), 4) +}) + +test_that("Random ability is within range", { + for (i in 1:10) { + expect_true(ability() %in% 3:18) + } +}) + +test_that("Random character is valid", { + for (i in 1:10) { + character <- new_character() + expect_s3_class(character, "character") + expect_true(character$strength %in% 3:18) + expect_true(character$dexterity %in% 3:18) + expect_true(character$constitution %in% 3:18) + expect_true(character$intelligence %in% 3:18) + expect_true(character$wisdom %in% 3:18) + expect_true(character$charisma %in% 3:18) + expect_equal(character$hitpoints, 10 + modifier(character$constitution)) + } +}) + +test_that("Each ability is only calculated once", { + for (i in 1:10) { + character <- new_character() + expect_equal(character$strength, character$strength) + expect_equal(character$dexterity, character$dexterity) + expect_equal(character$constitution, character$constitution) + expect_equal(character$intelligence, character$intelligence) + expect_equal(character$wisdom, character$wisdom) + expect_equal(character$charisma, character$charisma) + expect_equal(character$hitpoints, character$hitpoints) + } +}) diff --git a/exercises/practice/nth-prime/.docs/instructions.md b/exercises/practice/nth-prime/.docs/instructions.md new file mode 100644 index 00000000..065e323a --- /dev/null +++ b/exercises/practice/nth-prime/.docs/instructions.md @@ -0,0 +1,7 @@ +# Instructions + +Given a number n, determine what the nth prime is. + +By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. + +If your language provides methods in the standard library to deal with prime numbers, pretend they don't exist and implement them yourself. diff --git a/exercises/practice/nth-prime/.meta/config.json b/exercises/practice/nth-prime/.meta/config.json new file mode 100644 index 00000000..76301631 --- /dev/null +++ b/exercises/practice/nth-prime/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "erikschierboom" + ], + "files": { + "solution": [ + "nth-prime.R" + ], + "test": [ + "test_nth-prime.R" + ], + "example": [ + ".meta/example.R" + ] + }, + "blurb": "Given a number n, determine what the nth prime is.", + "source": "A variation on Problem 7 at Project Euler", + "source_url": "https://projecteuler.net/problem=7" +} diff --git a/exercises/practice/nth-prime/.meta/example.R b/exercises/practice/nth-prime/.meta/example.R new file mode 100644 index 00000000..18210734 --- /dev/null +++ b/exercises/practice/nth-prime/.meta/example.R @@ -0,0 +1,23 @@ +prime <- function(n) { + stopifnot(n > 0) + + primes <- c(2, 3) + current <- 6 + + while (length(primes) < n) { + limit <- sqrt(current + 1) + prime_check <- primes[primes <= limit] + + if (all((current - 1) %% prime_check != 0)) { + primes <- c(primes, current - 1) + } + + if (all((current + 1) %% prime_check != 0)) { + primes <- c(primes, current + 1) + } + + current <- current + 6 + } + + primes[n] +} diff --git a/exercises/practice/nth-prime/.meta/tests.toml b/exercises/practice/nth-prime/.meta/tests.toml new file mode 100644 index 00000000..daccec42 --- /dev/null +++ b/exercises/practice/nth-prime/.meta/tests.toml @@ -0,0 +1,25 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[75c65189-8aef-471a-81de-0a90c728160c] +description = "first prime" + +[2c38804c-295f-4701-b728-56dea34fd1a0] +description = "second prime" + +[56692534-781e-4e8c-b1f9-3e82c1640259] +description = "sixth prime" + +[fce1e979-0edb-412d-93aa-2c744e8f50ff] +description = "big prime" + +[bd0a9eae-6df7-485b-a144-80e13c7d55b2] +description = "there is no zeroth prime" diff --git a/exercises/practice/nth-prime/nth-prime.R b/exercises/practice/nth-prime/nth-prime.R new file mode 100644 index 00000000..ccd0dfe3 --- /dev/null +++ b/exercises/practice/nth-prime/nth-prime.R @@ -0,0 +1,3 @@ +prime <- function(n) { + +} diff --git a/exercises/practice/nth-prime/test_nth-prime.R b/exercises/practice/nth-prime/test_nth-prime.R new file mode 100644 index 00000000..8c8862d6 --- /dev/null +++ b/exercises/practice/nth-prime/test_nth-prime.R @@ -0,0 +1,22 @@ +source("./nth-prime.R") +library(testthat) + +test_that("First prime", { + expect_equal(prime(1), 2) +}) + +test_that("Second prime", { + expect_equal(prime(2), 3) +}) + +test_that("Sixth prime", { + expect_equal(prime(6), 13) +}) + +test_that("Big prime", { + expect_equal(prime(10001), 104743) +}) + +test_that("There is no zeroth prime", { + expect_error(prime(0)) +}) diff --git a/exercises/practice/robot-name/.docs/instructions.md b/exercises/practice/robot-name/.docs/instructions.md new file mode 100644 index 00000000..fca3a41a --- /dev/null +++ b/exercises/practice/robot-name/.docs/instructions.md @@ -0,0 +1,14 @@ +# Instructions + +Manage robot factory settings. + +When a robot comes off the factory floor, it has no name. + +The first time you turn on a robot, a random name is generated in the format of two uppercase letters followed by three digits, such as RX837 or BC811. + +Every once in a while we need to reset a robot to its factory settings, which means that its name gets wiped. +The next time you ask, that robot will respond with a new random name. + +The names must be random: they should not follow a predictable sequence. +Using random names means a risk of collisions. +Your solution must ensure that every existing robot has a unique name. diff --git a/exercises/practice/robot-name/.meta/config.json b/exercises/practice/robot-name/.meta/config.json new file mode 100644 index 00000000..0867167e --- /dev/null +++ b/exercises/practice/robot-name/.meta/config.json @@ -0,0 +1,18 @@ +{ + "authors": [ + "erikschierboom" + ], + "files": { + "solution": [ + "robot-name.R" + ], + "test": [ + "test_robot-name.R" + ], + "example": [ + ".meta/example.R" + ] + }, + "blurb": "Manage robot factory settings.", + "source": "A debugging session with Paul Blackwell at gSchool." +} diff --git a/exercises/practice/robot-name/.meta/example.R b/exercises/practice/robot-name/.meta/example.R new file mode 100644 index 00000000..2166cdcf --- /dev/null +++ b/exercises/practice/robot-name/.meta/example.R @@ -0,0 +1,20 @@ +new_robot <- function() { + structure( + list( + name = random_name() + ), + class = "robot" + ) +} + +reset_robot <- function(robot) { + robot$name <- random_name() + robot +} + +random_name <- function() { + paste0( + c(sample(LETTERS, 2, replace = TRUE), sample(0:9, 3, replace = TRUE)), + collapse = "" + ) +} diff --git a/exercises/practice/robot-name/robot-name.R b/exercises/practice/robot-name/robot-name.R new file mode 100644 index 00000000..90781377 --- /dev/null +++ b/exercises/practice/robot-name/robot-name.R @@ -0,0 +1,7 @@ +new_robot <- function() { + +} + +reset_robot <- function(robot) { + +} diff --git a/exercises/practice/robot-name/test_robot-name.R b/exercises/practice/robot-name/test_robot-name.R new file mode 100644 index 00000000..40d5dc11 --- /dev/null +++ b/exercises/practice/robot-name/test_robot-name.R @@ -0,0 +1,29 @@ +source("./robot-name.R") +library(testthat) + +test_that("Robot has a class", { + robot <- new_robot() + expect_s3_class(robot, "robot") +}) + +test_that("Robot has a name", { + robot <- new_robot() + expect_match(robot$name, "^[A-Z]{2}\\d{3}$") +}) + +test_that("Name is the same each time", { + robot <- new_robot() + expect_equal(robot$name, robot$name) +}) + +test_that("Two different robots have different names", { + robot1 <- new_robot() + robot2 <- new_robot() + expect_true(robot1$name != robot2$name) +}) + +test_that("Can reset the name", { + robot <- new_robot() + reset_robot <- reset_robot(robot) + expect_true(robot$name != reset_robot$name) +})