Description:
Consider a sequence u
where u is defined as follows:
- The number
u(0) = 1
is the first one inu
. - For each
x
inu
, theny = 2 * x + 1
andz = 3 * x + 1
must be inu
too. - There are no other numbers in
u
.
Ex:u = [1, 3, 4, 7, 9, 10, 13, 15, 19, 21, 22, 27, ...]
1 gives 3 and 4, then 3 gives 7 and 10, 4 gives 9 and 13, then 7 gives 15 and 22 and so on…
Task:
Given parameter n
the function dbl_linear
(or dblLinear…) returns the element u(n)
of the ordered (with <) sequence u
(so, there are no duplicates).
Example:
dbl_linear(10) should return 22
Note:
Focus attention on efficiency
Test Cases:
testing <- function(n, expected) {
actual <- dblLinear(n)
#cat("actual ", actual, "\n")
#cat("expected ", expected, "\n")
expect_equal(actual, expected)
}
test_that("tests", {
testing(10, 22)
testing(20, 57)
testing(30, 91)
testing(50, 175)
testing(100, 447)
testing(500, 3355)
testing(600, 4377)
testing(700, 5247)
testing(800, 6238)
testing(1000, 8488)
testing(5000, 65857)
testing(10000, 157654)
})
dblLinear23 <- function (n) {
h <- 1; cnt <- 0; q2 <- c(); q3 <- c()
while (TRUE) {
if (cnt >= n)
return(h)
q2 <- c(q2, 2 * h + 1)
q3 <- c(q3, 3 * h + 1)
h <- min(q2[1], q3[1])
if (h == q2[1]) q2 <- tail(q2, n=-1)
if (h == q3[1]) q3 <- tail(q3, n=-1)
cnt <- cnt + 1
}
}
yTests <- function() {
i <- 0
while (i < 50) {
rn <- floor(runif(1, 500, 5000))
testing(rn, dblLinear23(rn))
i <- i + 1
}
}
test_that("Random tests selfieDiag2Counterclock", {
yTests()
})
我的思路与代码
思路
我的思路其实很简单,就是以已经得到的u
为x
计算x
和y
,然后拿x, y, u
取集合运算并排序。至于为什么while
的条件中是<= n*10
,主要是考虑到u
中数的2或3倍可能比max(u)
要小,这就导致下标为n
的数与实际的不一样。
代码
dblLinear <- function (n) {
u <- c(1)
while(length(u) <= n*10){
container <- c(u*2+1, u*3+1)
u <- sort(c(u, container[!(container%in%u)]))
}
u[n+1]
}
本来一直找取集合的函数没找到,所以就用了一个强行的办法——逻辑运算,但是后面突然找到了,为unique
函数,因此又把我的代码简化了一下,详情见下面:
dblLinear <- function (n) {
u <- c(1)
while(length(u) <= n*10){
u <- sort(unique(c(u, 2*u+1, 3*u+1)))
}
u[n+1]
}
我看了看其他人的代码,好像没有比我这个还要更加简洁的了,还行。