R Solution for Excel Puzzles

[This article was first published on Numbers around us - Medium, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Puzzles no. 484–488

Puzzles

Author: ExcelBI

All files (xlsx with puzzle and R with solution) for each and every puzzle are available on my Github. Enjoy.

Puzzle #484

I think we all know what Pythageorean Theorem is. Or at least I hope so… And today we need to use properties of right triangle to solve our challenge. We need to find groups of 3 numbers (called Pythagorean triplets), that are about two things. Sum of a squared and b squared are equal c squared, but also sum of a, b and c (means circumference) is equal to given number. There is possibility that given number has more then one triplet, and it is true for one case.

Loading libraries and data

library(tidyverse)
library(readxl)
library(gmp)

path = "Excel/484 Pythagorean Triplets for a Sum.xlsx"
input = read_xlsx(path, range = "A2:A10")
test  = read_xlsx(path, range = "B2:D10") %>% 
  mutate(across(everything(), as.numeric))

Transformation

find_pythagorean_triplet <- function(P) {
  m_max <- floor(sqrt(P / 2))
  
  possible_values <- expand_grid(m = 2:m_max, n = 1:(m_max - 1)) %>%
    filter(m > n, m %% 2 != n %% 2, gcd(m, n) == 1)
  
  triplets <- possible_values %>%
    pmap(function(m, n) {
      k <- P / (2 * m * (m + n))
      if (k == floor(k)) {
        a <- k * (m^2 - n^2)
        b <- k * 2 * m * n
        c <- k * (m^2 + n^2)
        return(c(a, b, c))
      } else {
        return(NULL)
      }
    })
  
  triplet <- triplets %>%
    compact() %>%
    keep(~ sum(.x) == P)
  
  if (length(triplet) > 0) {
    result <- triplet[[1]]
  } else {
    result <- c(NA_real_, NA_real_, NA_real_)
  }
  
  tibble(a = result[1], b = result[2], c = result[3])
}

result = input %>%
  pmap_dfr(~ find_pythagorean_triplet(..1))

Validation

# in one case (for 132) I get another but correct result

Puzzle #485

Sequences, world is full of them, and some have even their name and well researched properties. It is the case with Padovan sequence, which is similar to Fibonacci’s but has little bit bigger step and another initial elements. Check it out.
PS. To run it efficiently and save some time I also use memoise.

Loading libraries and data

library(purrr)
library(memoise)
library(readxl)
library(tidyverse)

path = "Excel/485 Pandovan Sequence.xlsx"
input = read_excel(path, range = "A1:A10")
test  = read_excel(path, range = "B1:B10")

Transformation

padovan <- function(n) {
  if (n <= 2) {
    return(1)
  } else {
    return(padovan_memo(n - 2) + padovan_memo(n - 3))
  }
}
padovan_memo = memoise(padovan)

result = input %>%
  mutate(`Answer Expectecd` = map_dbl(n, padovan_memo))

Validation

identical(result$`Answer Expectecd`, test$`Answer Expectecd`)
# [1] TRUE

Puzzle #486

When we are measuring thing like ranges and distances, sometimes for better and more readable notes, we are shortening down sequences of consecutive numbers using hyphenated range notation. And that is our task today. Let’s get party started.

Loading libraries and data

library(tidyverse)
library(readxl)

path = "Excel/486 Create Integer Intervals.xlsx"
input = read_excel(path, range = "A1:A8")
test  = read_excel(path, range = "B1:B8")

Transformation

group_consecutive = function(number_string) {
  numbers <- str_split(number_string, ",") %>%
    unlist() %>%
    as.numeric()
  
  tibble(numbers = sort(numbers)) %>%
    mutate(group = cumsum(c(TRUE, diff(numbers) != 1))) %>%
    summarise(range = if_else(n() > 1, 
                              paste0(min(numbers), "-", max(numbers)), 
                              as.character(numbers[1])), .by = group) %>%
    pull(range) %>%
    paste(collapse = ", ")
}

result = input %>%
  mutate(`Answer Expected` = map_chr(Problem, group_consecutive))

Validation

identical(result$`Answer Expected`, test$`Answer Expected`)
#> [1] TRUE

Puzzle #487

In this puzzle we need to find most frequent characters in given strings. It was like warm up before warm up. With no further words, lets do it.

Loading libraries and data

library(tidyverse)
library(readxl)

path = "Excel/487 Maximum Frequency Characters.xlsx"
input = read_xlsx(path, range = "A2:A11")
test  = read_xlsx(path, range = "B2:C11")

Transformation

find_most_freq_char = function(input) {
  result = input %>% 
    strsplit("") %>% 
    unlist() %>% 
    table()
  df = data.frame(
    Characters = names(result),
    Frequency = as.numeric(result)) %>% 
    filter(Frequency == max(Frequency)) %>%
    summarise(Characters = paste(sort(Characters), collapse = ", "), .by = Frequency) %>%
    select(Characters, Frequency)
  return(df)
}

result = input$Strings %>%
  map(find_most_freq_char) %>%
  bind_rows()

Validation:

# Validation on eye, all correct. In three cases there is different sorting than
#  in provided example but with the same characters.

Puzzle #488

Combinations, possible inputs to given output. I am sure we all love it. Today we are given bunch of numbers and one output. We need to find all combinations of this numbers that will sum up to given target. Code is quite long, but I think also easy to understand. Let me show it.

Loading libraries and data

library(gtools)
library(tidyverse)
library(readxl)

path = "Excel/488 Numbers to Meet Target Sum.xlsx"
input = read_excel(path, range = "A1:A10")
target = read_excel(path, range = "B1:B2") %>% pull()
test = read_excel(path, range = "C1:C5")

Transformation

find_combinations <- function(numbers, target) {
  combs <- map(1:length(numbers), ~combinations(length(numbers), ., v = numbers))
  valid_combs <- combs %>%
     map(as_tibble) %>%
    bind_rows() %>%
    mutate(sum = rowSums(., na.rm = TRUE)) %>%
    filter(sum == target)
  
  return(valid_combs)
}

combinations <- find_combinations(input$Numbers, target) %>%
  unite("Combination", - sum, sep = ", ", remove = T, na.rm = T) 

sort_numbers <- function(numbers) {
  paste(sort(as.numeric(strsplit(numbers, ",")[[1]])), collapse = ", ")
}

test <- test %>%
  mutate(Combination = map_chr(`Answer Expected`, sort_numbers))

Validation

identical(sort(combinations$Combination), sort(test$Combination))
# [1] TRUE

Feel free to comment, share and contact me with advices, questions and your ideas how to improve anything. Contact me on Linkedin if you wish as well.
On my Github repo there are also solutions for the same puzzles in Python. Check it out!


R Solution for Excel Puzzles was originally published in Numbers around us on Medium, where people are continuing the conversation by highlighting and responding to this story.

To leave a comment for the author, please follow the link and comment on their blog: Numbers around us - Medium.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)