Home > database >  How to Find the Second Highest digit in a string R
How to Find the Second Highest digit in a string R

Time:03-25

Question:

Write a function that accepts a string and returns the second highest numerical digit in the input as an integer.

The following rules should apply:

Inputs with no numerical digits should return -1 Inputs with only one numerical digit should return -1 Non-numeric characters should be ignored Each numerical input should be treated individually, meaning in the event of a joint highest digit then the second highest digit will also be the highest digit For example:

 "abc:1231234" returns 3
 "123123" returns 3

[execution time limit] 5 seconds (r)

[input] string input

The input string

[output] integer

The second-highest digit

I can convert the string into a numeric vector with strsplit and as.numeric and get rid of NAs (letters). But not sure where to go from here.

Clarification: Ideally base R solution.

I've got this code so far which, while messy, deals with all but the case where there are joint highest numbers:

solution <- function(input) {
  d <- as.integer(strsplit(input,"")[[1]])
  if (any(is.na(d))) {
    d <- d[-which(is.na(d))]
  }
  if(all(is.na(d))) {
    return(-1)
  }
  if (length(is.na(d)) == length(d)-1) {
    return(-1)
  }
  sort(d,TRUE)[2]
}

CodePudding user response:

A stringr::str_count solution:

secondHighest <- function(str) {
  ans <- 10L - match(TRUE, cumsum(stringr::str_count(str, paste0(9:0))) > 1L)
  if (is.na(ans)) -1L else ans
}

A base R solution:

secondHighest <- function(str) {
  suppressWarnings(ans <- 10L - match(TRUE, cumsum(tabulate(10L - as.integer(strsplit(str, "")[[1]]))) > 1L))
  if (is.na(ans)) -1L else ans
}

CodePudding user response:

As a one-liner

string <- "abc:1231234"

sort(unique(suppressWarnings(as.integer(strsplit(string, "", fixed = TRUE)[[1]]))), decreasing = TRUE)[2]
#> [1] 3

Or using the magrittr pipe:

library(magrittr)
suppressWarnings(
  strsplit(string, "", fixed = TRUE)[[1]] %>% 
    as.integer()  %>% 
    unique()  %>%  
    sort(decreasing = TRUE)  %>% 
    .[2]
)
#> [1] 3

Created on 2022-03-25 by the reprex package (v2.0.1)

CodePudding user response:

You can also do something like this to convert to ASCII integers.

solution <- function(input) {
  # ASCII codes for 0:9 are 48:57
  ints <- (intersect(57:48, utf8ToInt(input)) - 48)[2]
  if (is.na(ints)) -1L else ints  
}

Testing a few strings...

str1 <- "abc:1231234"
str2 <- "987654321"
str3 <- "abcdefg4"

solution(str1)
# [1] 3
solution(str2)
# [1] 8
solution(str3)
# [1] -1
  • Related