Soluție R pentru puzzle-uri Excel

URMĂREȘTE-NE
16,065FaniÎmi place
1,142CititoriConectați-vă

Puzzle-uri nr. 559–563

Puzzle-uri

Autor: ExcelBI

Toate fișierele (xlsx cu puzzle și R cu soluție) pentru fiecare puzzle sunt disponibile pe Github-ul meu. Bucurați-vă.

Puzzle #559

Uneori trebuie să lucrăm pe coloane. Din punct de vedere tehnic, este exact ca să lucrezi la liste și uite ce trebuie să facem cu listele astăzi. Se numește alergare maximă. De obicei avem un anumit contact cu suma sau media curentă, dar maximul rulant este puțin mai puțin popular. Nu returnează o singură cifră, ci, în mod similar, ca în cumsum, toate secvența de numere în care pentru un anumit element trebuie să agregam într-un fel toate elementele precedente (în sumă – trebuie să le însumăm, în medie – medie și în maxim alege întotdeauna max dintre toate precedente). Este destul de ușor în R, așa că verificați-l.

Se încarcă biblioteci și date

library(tidyverse)
library(readxl)

path = "Excel/559 Max of first N elements.xlsx"
input = read_excel(path, range = "A2:D13")
test  = read_excel(path, range = "F2:I13")

Transformare

output = input %>% 
  mutate(across(everything(), ~cummax(.))) 

Validare

all.equal(output, test, check.attributes = FALSE)
#> (1) TRUE

Puzzle #560

Să ne gândim la cuvinte ca la sandvișuri… astăzi trebuie să găsim toate sandvișurile pe masa noastră. Oh, nu, reveniți la Excel… nu vă gândiți la sandvișurile cu pastramă. Trebuie să găsim fiecare combinație de una sau mai multe vocale între consoane. Am găsit un obstacol în această sarcină, dar și soluția cum să extrag și acele combinații care se suprapun cu alte combinații valide precum putrefața și tor în rotor.

Se încarcă biblioteci și date

library(tidyverse)
library(readxl)

path = "Excel/560 Vowels between Consonants.xlsx"
input = read_excel(path, range = "A1:A10")
test  = read_excel(path, range = "B1:B10") %>% replace_na(list(`Answer Expected` = ""))

Transformare

extract_cvc_overlap <- function(input_string) {
  pattern <- "(?=((^aeiou)(aeiou)+(^aeiou)))"
  str_match_all(input_string, pattern) %>%
    map_chr(~ paste(.(, 2), collapse = ", ")) %>%
    str_trim()
}

result = input %>%
  mutate(result = map_chr(Words, extract_cvc_overlap))

Validare

all.equal(result$result, test$`Answer Expected`, check.attributes = FALSE)
#> (1) TRUE

Puzzle #561

Astăzi vom juca tranzacții cu acțiuni la scară mică. Avem 9 active și prețuri de la 10 zile și tot ce trebuie să facem este să găsim cel mai profitabil scenariu când să cumpărăm și să vindem. Desigur, probabil că am face-o mai repede manual decât scrierea codului, dar suntem aici pentru a scrie cod. Și dacă este greu de rezolvat, este și mai satisfăcător. Verificați.

Se încarcă biblioteci și date

library(tidyverse)
library(readxl)

path = "Excel/561 Maximum Profit.xlsx"

input = read_excel(path, range = "A2:J11")
test  = read_excel(path, range = "K2:M11") %>%
  mutate(across(everything(), ~if_else(.x == "NP", NA_real_, as.numeric(.x))))

Transformare

process_row <- function(...){
  row <- c_across(everything())
  cell_list <- map(1:length(row), ~row(.x:length(row)))
  df_pairs <- map_dfr(1:length(cell_list), function(i) {
    tibble(
      from = rep(row(i), length(cell_list((i))) - 1),
      to = cell_list((i))(-1)
    )
  })
  df_pairs <- df_pairs %>%
    mutate(diff = to - from)
  max_pair <- df_pairs %>%
    slice_max(diff, with_ties = FALSE)
  return(list(
    max_diff = max_pair$diff,
    from_value = max_pair$from,
    to_value = max_pair$to
  ))
}

result <- input %>%
  rowwise() %>%
  mutate(result = list(process_row(across(everything())))) %>%
  mutate(
    Buy = result$from_value,
    Sell = result$to_value,
    Profit = result$max_diff
  ) %>%
  ungroup() %>%
  select(Buy, Sell, Profit) %>%
  mutate(across(everything(), ~if_else(Profit <= 0, NA_real_, .x)))

Validare

all.equal(result, test, check.attributes = FALSE)
# (1) TRUE

Puzzle #562

Palindromuri, palindromuri… Cred că Vijay A. Verma nu va găsi sfârșitul tărâmului palindromurilor prea curând. Astăzi subiectul nostru este palindromul unui copil. Ce înseamnă că numărul are copil? Înseamnă că subșirul de număr este divizibil cu lungimea unui astfel de număr original. Deci, dacă vrem un număr cu un singur copil, trebuie să găsim unul care dintre toate subșirurile are doar unul care este divizibil prin lungimea numărului original. Dar trebuie să-l amestecăm și cu proprietățile palindromului și să găsim 1000 de primele numere cu toate acele proprietăți împreună.

Este o soluție destul de lentă, dar funcționează bine.

Se încarcă biblioteci și date

library(tidyverse)
library(readxl)

path = "Excel/562 One Child Palindromes.xlsx"
test = read_excel(path, range = "A1:A1001")

Transformare

has_one_child <- function(n) {
  nchar = nchar(n)
  if (nchar == 1) {
    return(FALSE)
  }
  grid_coord = expand.grid(1:nchar, 1:nchar)
  substrings = apply(grid_coord, 1, function(x) {
    substr(n, x(1), x(2))
  }) %>%
  as.numeric() %>%
  .(!is.na(.) & . != 0) %>%
  unique()
  
  substrings = substrings(substrings %% nchar == 0)
  return(length(substrings) == 1)
}

generate_all_palindromes <- function(num_digits) {
  if (num_digits < 1) {
    stop("Number of digits must be at least 1")
  }
  if (num_digits == 1) {
    return(0:9)
  }
  half_digits <- ceiling(num_digits / 2)
  start_num <- 10^(half_digits - 1)
  end_num <- 10^half_digits - 1
  palindromes <- vector("integer", length = 0)
  
  for (i in start_num:end_num) {
    num_str <- as.character(i)
    rev_str <- paste0(rev(strsplit(num_str, "")((1))), collapse = "")
    if (num_digits %% 2 == 0) {
      palindrome_str <- paste0(num_str, rev_str)
    } else {
      palindrome_str <- paste0(num_str, substring(rev_str, 2))
    }
    palindromes <- c(palindromes, as.integer(palindrome_str))
  }
  return(palindromes)
}


palindrome_df <- tibble(num_digits = 1:9) %>%
  mutate(palindromes = map(num_digits, generate_all_palindromes))
res = palindrome_df %>%
  unnest(cols = c(palindromes)) %>%
  mutate(palindromes = as.integer(palindromes),
         has_one_child = map_lgl(palindromes, has_one_child))
result = res %>%
  filter(has_one_child == TRUE, palindromes > 10) %>%
  head(1000) %>%
  select(palindromes)

Validare

all.equal(test$`Answer Expected`, result$palindromes, check.attributes = FALSE)
# (1) TRUE

Puzzle #563

Cu ceva timp în urmă am făcut lucruri similare, dar altfel. Când avem unele notații de interval, trebuia să le împărțim în numere din interval, dar de data aceasta trebuie să facem alt mod. Dacă găsim numere consecutive în grupuri, le restrângem în interval. Află cum am făcut-o.

Se încarcă biblioteci și date

library(tidyverse)
library(readxl)

path = "Excel/563 Bands of Numbers.xlsx"
input = read_excel(path, range = "A2:B17")
test  = read_excel(path, range = "D2:F6")

Transformare

result = input %>%
  mutate(Group = cumsum(c(1, diff(Numbers)) != 1), .by = Product) %>%
  mutate(Band = ifelse(n() == 1, paste0(Numbers), paste0(Numbers(1), "-", Numbers(n()))), 
         .by = c(Product, Group)) %>%
  summarise(Bands = paste0(unique(Band), collapse = ", "), 
            Count = n_distinct(Band), 
            .by = Product)

Validare

all.equal(result, test, check.attributes = FALSE)
# (1) TRUE

Simțiți-vă liber să comentați, să distribuiți și să mă contactați cu sfaturi, întrebări și ideile dvs. despre cum să îmbunătățiți orice. Contactați-mă și pe Linkedin dacă doriți.
Pe depozitul meu Github există și soluții pentru aceleași puzzle-uri în Python. Verifică!


R Solution for Excel Puzzles a fost publicat inițial în Numbers around us on Medium, unde oamenii continuă conversația evidențiind și răspunzând la această poveste.

Dominic Botezariu
Dominic Botezariuhttps://www.noobz.ro/
Creator de site și redactor-șef.

Cele mai noi știri

Pe același subiect

LĂSAȚI UN MESAJ

Vă rugăm să introduceți comentariul dvs.!
Introduceți aici numele dvs.