R语言Codewars实战——Fibo akin(5kyu)

Description:

Be u(n) a sequence beginning with:

u[1]  = 1,  u[2]  = 1,  u[3]  = 2,  u[4]  = 3,  u[5]  = 3,  u[6] = 4,

u[7]  = 5,  u[8]  = 5,  u[9]  = 6,  u[10] = 6,  u[11] = 6,  u[12] = 8,

u[13] = 8,  u[14] = 8,  u[15] = 10, u[16] = 9,  u[17] = 10, u[18] = 11,

u[19] = 11, u[20] = 12, u[21] = 12, u[22] = 12, u[23] = 12 etc...
  • How is u[8] calculated?

We have u[7] = 5 and u[6] = 4. These numbers tell us that we have to go backwards from index 8 to index 8 - 5 = 3 and to index 8 - 4 = 4 so to index 3 and 4.

u[3] = 2 and u[4] = 3 hence u[8] = u[3] + u[4] = 2 + 3 = 5.

  • Another example: let us calculate u[13]. At indexes 12 and 11 we have 8 and 6. Going backwards of 8 and 6 from 13 we get indexes 13 - 8 = 5 and 13 - 6 = 7. u[5] = 3 and u[7] = 5 so u[13] = u[5] + u[7] = 3 + 5 = 8 .

Task

  1. Express u(n) as a function of n, u[n - 1], u[n - 2]. (not tested).
  2. Given two numbers n, k (integers > 2) write the function length_sup_u_k(n, k) or lengthSupUK or length-sup-u-k returning the number of terms u[i] >= k with 1 <= i <= n. If we look above we can see that between u[1] and u[23] we have fouru[i] greater or equal to 12: length_sup_u_k(23, 12) => 4
  3. Given n (integer > 2) write the function comp(n) returning the number of times where a term of u is less than its predecessor up to and including u[n].

Examples:

u(900) => 455 (not tested)
u(90000) => 44337 (not tested)

length_sup_u_k(23, 12) => 4
length_sup_u_k(50, 10) => 35
length_sup_u_k(500, 100) => 304

comp(23) => 1 (since only u(16) < u(15))
comp(100) => 22
comp(200) => 63

Note: Shell

Shell tests only lengthSupUk

Test Cases:

dotest1 <- function(n, k, expected) {
    actual <- lengthSupUK(n, k)
    expect_equal(actual, expected)
}

test_that("test lengthSupUK", {
    dotest1(50, 25, 2);
    dotest1(3332, 973, 1391);
    dotest1(2941, 862, 1246);
    dotest1(3177, 573, 2047);
    dotest1(1745, 645, 474);
    dotest1(4451, 663, 3135);
    dotest1(1956, 602, 770);
    dotest1(1971, 547, 883);
    dotest1(1881, 975, 7);
    dotest1(1138, 821, 0);
    
    dotest1(1774, 581, 624);
    dotest1(1361, 655, 66);
    dotest1(3501, 940, 1627);
    dotest1(2642, 945, 753);
    dotest1(3137, 775, 1571);
    dotest1(4903, 557, 3803);
    dotest1(3270, 679, 1912);
    dotest1(3030, 825, 1393);
    dotest1(2936, 655, 1637);
    dotest1(2592, 734, 1119);
    
    dotest1(18230, 9181, 201);
    dotest1(25071, 6290, 12391);
    dotest1(19309, 9486, 457);
    dotest1(23165, 8277, 6627);
    dotest1(22859, 5283, 12339);
    dotest1(30951, 9048, 12876);
    dotest1(12862, 7384, 0);
    dotest1(48320, 7209, 33898);
    dotest1(31984, 8901, 14194);
    dotest1(17971, 7807, 2349);
})

dotest2 <- function(n, expected) {
    actual <- comp(n)
    expect_equal(actual, expected)
}

test_that("test comp", {
    dotest2(74626, 37128);
    dotest2(71749, 35692);
    dotest2(56890, 28281);
    dotest2(60441, 30054);
    dotest2(21361, 10581);
    dotest2(39298, 19536);
    dotest2(55599, 27646);
    dotest2(11567, 5683);
    dotest2(32970, 16347);
    dotest2(41250, 20511);
    
    dotest2(44964, 22372);
    dotest2(77129, 38415);
    dotest2(59973, 29826);
    dotest2(47936, 23859);
    dotest2(50748, 25211);
    dotest2(91785, 45789);
    dotest2(37132, 18442);
    dotest2(34236, 16987);
    dotest2(23933, 11856);
    dotest2(44130, 21953);
})

u1777 <- function(n) {
    memu <- rep(1, n)
    memu[3] <- 2
    i <- 3
    while (i <= n) {
        memu[i] <- memu[i - memu[i - 1]] + memu[i - memu[i - 2]]
        i <- i + 1
    }
    memu
}

comp777 <- function(n) {
    memu <- u1777(n)
    prev <- 1; cnt <- 0; i = 2;
    while (i <= n) {
        cur <- memu[i]
        if (cur < prev)
            cnt <- cnt + 1
        prev <- cur
        i <- i + 1
    }
    cnt
}

yTests <- function() {
    i <- 0
    while (i < 50) {
        n <- floor(runif(1, 10000, 25000))
        dotest2(n, comp777(n))
        i <- i + 1
    }
}
test_that("Random tests comp", {
    yTests()
})

我的思路与代码

思路

我的思路很简单,先写一个函数,只需要输入n,就可以得到这种类型的数列的前n个数,有了这些数,剩下的需要写的两个函数就变得异常简单了。

对于函数lengthSupUK函数,直接逻辑运算再对逻辑值求和就行了;对于comp函数,也是算出来之后逻辑运算就行了,不再多说,直接上代码。

代码

fib <- function(n){
  u <- c(1,1)
  for(i in 3:n) u[i] <- u[i-u[i-2]]+u[i-u[i-1]]
  u
}
lengthSupUK <- function(n, k) {
  sum(fib(n) >= k)
}

comp <- function(n) {
  fibnums <- fib(n)
  sum(fibnums[2:n]<fibnums[1:(n-1)])
}

这道题的代码我觉得是蛮简单的,看来看去好像没啥要说明的,如果还有啥疑问,评论区提或者私信我吧。

做一点点补充,我看到有人在写comp函数的时候,用到了diff函数,然后判断diff后的结果是否大于0并做逻辑运算就得到了结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三只佩奇不结义

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值