I want to find 5 digit numbers that have four 5s. I do the following:
data <- str_split(as.character(x = 10000:99999), pattern = "")
but when I try to find the number of lists that contain four 5s
sapply(data, function(x) c("5", "5", "5", "5") %in% data[[x]])
it gives me an error "Error in data[[x]] : no such index at level 1":
What am I doing wrong? any other more elegant solution?
CodePudding user response:
Try this?
> x <- 10000:99999
> x[nchar(gsub("[^5]", "", x)) == 4 & nchar(x)==5]
[1] 15555 25555 35555 45555 50555 51555 52555 53555 54555 55055 55155 55255
[13] 55355 55455 55505 55515 55525 55535 55545 55550 55551 55552 55553 55554
[25] 55556 55557 55558 55559 55565 55575 55585 55595 55655 55755 55855 55955
[37] 56555 57555 58555 59555 65555 75555 85555 95555
Or, you can generalize it like below
# number of digits
n <- 5
# number of 5s
m <- 4
# output
(x <- 10^(n - 1):(10^n - 1))[nchar(gsub("[^5]", "", x)) == m]
CodePudding user response:
grep('^(?=.{5}$).*?(5)(.*?\\1){3}', 10000:99999, value = TRUE, perl=TRUE)
[1] "15555" "25555" "35555" "45555" "50555" "51555" "52555" "53555"
[9] "54555" "55055" "55155" "55255" "55355" "55455" "55505" "55515"
[17] "55525" "55535" "55545" "55550" "55551" "55552" "55553" "55554"
[25] "55555" "55556" "55557" "55558" "55559" "55565" "55575" "55585"
[33] "55595" "55655" "55755" "55855" "55955" "56555" "57555" "58555"
[41] "59555" "65555" "75555" "85555" "95555"
Regex Explanation:
Use a lookahead to determine whether the number contains five digits. ie ^(?=.{5}$)
. Then determine whethere there are 4 5's .*?(5)(.*?\\1){3}
CodePudding user response:
This would be one way:
library(dplyr)
library(tibble)
enframe(10000:99999) %>%
mutate(
name = 10000:99999,
value = as.character(value),
value = str_split(value, '')
) %>%
unnest(value) %>%
filter(value == 5) %>%
count(name) %>%
filter(n == 4) %>%
select(-n)
# A tibble: 44 x 1
name
<int>
1 15555
2 25555
3 35555
4 45555
5 50555
6 51555
7 52555
8 53555
9 54555
10 55055
# ... with 34 more rows
CodePudding user response:
I think the simplest is
5*9-1
# 44
This works because out of the five digits, exactly one is not five (leaving four fives remaining). For each non-five digit it can take any one of 9 different values (i.e. 0 to 9, except 5). Then we subtract 1 because we don't allow 05555, which would be a four digit number.
CodePudding user response:
Would this be an alternative? Not sure if you explicitly need characters.
EDIT: Question states "has 4 5s", but not if exclusively. 55555 also has 4 5s. So giving both solutions here.
If 4 5s
c(10000:99999)[grep("5.555|55.55|555.5|5555", 10000:99999 )]
[1] 15555 25555 35555 45555 50555 51555 52555 53555 54555 55055 55155 55255
[13] 55355 55455 55505 55515 55525 55535 55545 55550 55551 55552 55553 55554
[25] 55555 55556 55557 55558 55559 55565 55575 55585 55595 55655 55755 55855
[37] 55955 56555 57555 58555 59555 65555 75555 85555 95555
If only 4 5s
c(10000:99999)[grep("5[^5]555|55[^5]55|555[^5]5|[^5]5555|5555[^5]",c(10000:99999)) ]
[1] 15555 25555 35555 45555 50555 51555 52555 53555 54555 55055 55155 55255
[13] 55355 55455 55505 55515 55525 55535 55545 55550 55551 55552 55553 55554
[25] 55556 55557 55558 55559 55565 55575 55585 55595 55655 55755 55855 55955
[37] 56555 57555 58555 59555 65555 75555 85555 95555
CodePudding user response:
This should get you started. It will extract all the 5's from an expression and then count them. Add na logic.
library(stringr)
y <- nchar(str_extract(data, "[5] " )) = 4