ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# katrinleinweber's solution

## to Tournament in the R Track

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

Tally the results of a small football competition.

Based on an input file containing which team played against which and what the outcome was, create a file with a table like this:

``````Team                           | MP |  W |  D |  L |  P
Devastating Donkeys            |  3 |  2 |  1 |  0 |  7
Allegoric Alaskans             |  3 |  2 |  0 |  1 |  6
Blithering Badgers             |  3 |  1 |  0 |  2 |  3
Courageous Californians        |  3 |  0 |  1 |  2 |  1
``````

What do those abbreviations mean?

• MP: Matches Played
• W: Matches Won
• D: Matches Drawn (Tied)
• L: Matches Lost
• P: Points

A win earns a team 3 points. A draw earns 1. A loss earns 0.

The outcome should be ordered by points, descending. In case of a tie, teams are ordered alphabetically.

Input

Your tallying program will receive input that looks like:

``````Allegoric Alaskans;Blithering Badgers;win
Devastating Donkeys;Courageous Californians;draw
``````

The result of the match refers to the first team listed. So this line

``````Allegoric Alaskans;Blithering Badgers;win
``````

Means that the Allegoric Alaskans beat the Blithering Badgers.

This line:

``````Courageous Californians;Blithering Badgers;loss
``````

Means that the Blithering Badgers beat the Courageous Californians.

And this line:

``````Devastating Donkeys;Courageous Californians;draw
``````

Means that the Devastating Donkeys and Courageous Californians tied.

## 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`.

## Submitting Incomplete Solutions

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

### test_tournament.R

``````source("./tournament.R")
library(testthat)

context("tournament")

options(stringsAsFactors = FALSE)

test_that("typical input", {
input <- c(
"Devastating Donkeys;Courageous Californians;draw",
)
expect_equal(tournament(input),
data.frame(
Team = c(
"Devastating Donkeys",
"Courageous Californians"
),
MP = c(3, 3, 3, 3),
W = c(2, 2, 1, 0),
D = c(1, 0, 0, 1),
L = c(0, 1, 2, 2),
P = c(7, 6, 3, 1)
))
})

test_that("incomplete competition (not all pairs have played)", {
input <- c(
)
expect_equal(tournament(input),
data.frame(
Team = c(
"Courageous Californians",
"Devastating Donkeys"
),
MP = c(3, 2, 2, 1),
W = c(2, 1, 0, 0),
D = c(0, 1, 1, 0),
L = c(1, 0, 1, 1),
P = c(6, 4, 1, 0)
))
})

test_that("ties broken alphabetically", {
input <- c(
"Courageous Californians;Devastating Donkeys;win",
)
expect_equal(tournament(input),
data.frame(
Team = c(
"Courageous Californians",
"Devastating Donkeys"
),
MP = c(3, 3, 3, 3),
W = c(2, 2, 0, 0),
D = c(1, 1, 1, 1),
L = c(0, 0, 2, 2),
P = c(7, 7, 1, 1)
))
})

test_that("an empty line", {
input <- c(
"",
)
expect_equal(tournament(input),
data.frame(
Team = c(
"Courageous Californians",
"Devastating Donkeys"
),
MP = c(3, 2, 2, 1),
W = c(2, 1, 0, 0),
D = c(0, 1, 1, 0),
L = c(1, 0, 1, 1),
P = c(6, 4, 1, 0)
))
})

test_that("wrong separator used", {
input <- c(
"Devastating Donkeys@Courageous Californians;draw",
)
expect_equal(tournament(input),
data.frame(
Team = c(
"Courageous Californians",
"Devastating Donkeys"
),
MP = c(3, 2, 2, 1),
W = c(2, 1, 0, 0),
D = c(0, 1, 1, 0),
L = c(1, 0, 1, 1),
P = c(6, 4, 1, 0)
))
})

test_that("too many separators", {
input <- c(
"Devastating Donkeys;Courageous Californians;draw;5",
)
expect_equal(tournament(input),
data.frame(
Team = c(
"Courageous Californians",
"Devastating Donkeys"
),
MP = c(3, 2, 2, 1),
W = c(2, 1, 0, 0),
D = c(0, 1, 1, 0),
L = c(1, 0, 1, 1),
P = c(6, 4, 1, 0)
))
})

test_that("invalid match result", {
input <- c(
)
expect_equal(tournament(input),
data.frame(
Team = c(
"Courageous Californians",
"Devastating Donkeys"
),
MP = c(3, 2, 2, 1),
W = c(2, 1, 0, 0),
D = c(0, 1, 1, 0),
L = c(1, 0, 1, 1),
P = c(6, 4, 1, 0)
))
})

message("All tests passed for exercise: tournament")``````
``````library(dplyr)
library(magrittr)

tournament <- function(input) {

# clean input data (oust empty rows) & parse
input[lapply(input, nchar) > 0] %>%
stringi::stri_split_fixed(";") ->
input

# oust lines with incorrect number of cells
input <- input[lapply(input, length) == 3]

df <- data.frame()
for (r in 1:length(input))
for (c in 1:length(input[[r]]))
df[r, c] <- input[[r]][c]
names(df) <- c("Team", "Team2", "Result")

# separate team pairs, marking invalid result strings
df\$Result %>%
purrr::map_chr(function(x) case_when(x == "loss" ~ "win",
x == "win" ~ "loss",
x == "draw" ~ "draw",
x != "draw" ~ "NA")) %>%
data.frame(df\$Team2, .) ->
df2
names(df2) <- c("Team", "Result")

# oust rows with invalid results/cells
df2 <- df2[df2\$Result != "NA",]

# calculate values & output data frame
df\$Team2 <- NULL
df %>%
rbind(df2) %>%
mutate(W = ifelse(Result == "win", 1, 0),
D = ifelse(Result == "draw", 1, 0),
L = ifelse(Result == "loss", 1, 0),
MP = W + D + L,
P = 3 * W + D) %>%
select(-Result) %>%
group_by(Team) %>%
summarise_all(sum) %>%
select(Team, MP, W:P) %>%
arrange(desc(P))
}``````