Next 3 Friday the 13th

Numbers around us
Numbers around us
Published in
2 min readOct 25, 2023

Excel BI’s Excel Challenge #310 — solved in R

Defining the Puzzle:

It was early Monday morning when hunt for Fridays come up. Of course new riddle about Fridays 13th.

Task was really short yet challenging: Find the next 3 Friday the 13th dates for dates given in column A.

Loading Data from Excel:

Let me get needed libraries, exercise dates and solution from our excercise file.

library(tidyverse)
library(lubridate)
library(readxl)
library(data.table)

input = read_excel(“Next 3 Friday the 13th.xlsx”, range = “A1:A10”)
test = read_excel(“next 3 friday the 13th.xlsx”, range = “B2:D10”,
col_names = c(“friday_13th_1”, “friday_13th_2”, “friday_13th_3”))

Approach 1: Tidyverse with purrr

get_3_f13_tv<- function(date) {
start_date <- as.Date(paste0(year(date), “-”, month(date), “-13”))
end_date <- start_date + years(3)
date_seq_13th <- seq.Date(from=start_date, to=end_date, by=”month”)

friday_13ths <- date_seq_13th[wday(date_seq_13th) == 6 & date_seq_13th > date]

head(friday_13ths, 3)
}

next_3_tv = input %>%
rowwise() %>%
mutate(friday_13th_1 = get_3_f13_tv(Date)[1] %>% as.character(),
friday_13th_2 = get_3_f13_tv(Date)[2] %>% as.character() ,
friday_13th_3 = get_3_f13_tv(Date)[3] %>% as.character()) %>%
ungroup() %>%
select(-Date)

Approach 2: Base R

get_3_f13_base <- function(date) {
start_date <- as.Date(paste0(format(as.Date(date), “%Y-%m”), “-13”))
end_date <- start_date + (365.25 * 3)
date_seq_13th <- seq(start_date, end_date, by=”month”)

weekday <- weekdays(date_seq_13th )
friday_13ths <- date_seq_13th[weekday == “Friday” & date_seq_13th > date]

head(friday_13ths, 3)
}

next_3_base <- tibble(
friday_13th_1 = character(nrow(input)),
friday_13th_2 = character(nrow(input)),
friday_13th_3 = character(nrow(input))
)

for (i in 1:nrow(input)) {
f13_dates <- get_3_f13_base(input$Date[i])
next_3_base$friday_13th_1[i] <- as.character(f13_dates[1])
next_3_base$friday_13th_2[i] <- as.character(f13_dates[2])
next_3_base$friday_13th_3[i] <- as.character(f13_dates[3])
}

Approach 3: Data.table

input_dt = setDT(input)

get_3_f13_dt <- function(date) {
start_date <- as.Date(paste0(year(date), “-”, month(date), “-13”))
end_date <- start_date + years(3)
date_seq_13th <- seq.Date(from=start_date, to=end_date, by=”month”)

friday_13ths <- date_seq_13th[wday(date_seq_13th) == 6 & date_seq_13th > date]

friday_13ths <- head(friday_13ths, 3)

c(friday_13ths, rep(NA, 3 — length(friday_13ths)))
}

input_dt[, c(“friday_13th_1”, “friday_13th_2”, “friday_13th_3”) :=
as.list(get_3_f13_dt(Date)), by = 1:nrow(input_dt)][
, `:=`(friday_13th_1 = as.character(friday_13th_1),
friday_13th_2 = as.character(friday_13th_2),
friday_13th_3 = as.character(friday_13th_3))][
, Date := NULL]

next_3_dt = as_tibble(as.data.frame(input_dt))

Validating Our Solutions:

identical(test, next_3_tv)
#> [1] TRUE

identical(test, next_3_base)
#> [1] TRUE

identical(test, next_3_dt)
#> [1] TRUE

If you like my publications or have your own ways to solve those puzzles in R, Python or whatever tool you choose, let me know.

--

--

Numbers around us
Numbers around us

Published in Numbers around us

Articles about data… Data science, BI, data management and many more…

Numbers around us
Numbers around us

Written by Numbers around us

Self developed analyst. BI Developer, R programmer. Delivers what you need, not what you asked for.

No responses yet