Description

两个迭代器的交叉迭代

  • R: expand.grid(),返回数据框
  • julia: [for in for in],返回 tuple 的迭代器
  • js: 自己写的 crossing() 函数,返回数组的数组

Solutions

Julia



using Test
using Printf


"""
通项公式为 1/k/(n+1)^(2k)  
对此公式交叉遍历 k 向量和 n 向量,求和
"""
#> "通项公式为 1/k/(n+1)^(2k)  \n对此公式交叉遍历 k 向量和 n 向量,求和\n"
function doubles(maxk::Int, maxn::Int)::Float64
    v(k, n) = 1 / k / (big(n) + 1)^(2k) # 不转换Float64或BigInt会数值越界
    [v(k, n) for k  1:maxk for n  1:maxn] |> sum
end
#> doubles (generic function with 1 method)

doubles(10, 1000)
#> 0.6921486500921955


function ifinrange(maxk::Int, maxn::Int, expect::Float64; tolerence=1e-6)::Bool
    # println("Expect $(round(expect, digits = 12))")
    @printf("Expect %.12f\n", expect)

    actual = doubles(maxk, maxn)
    @printf("Actual %.12f\n", actual)

    abs(actual - expect)  tolerence
end
#> ifinrange (generic function with 1 method)



@testset "fixed tests" begin
    @test ifinrange(1, 10, 0.5580321939764581) == true
    @test ifinrange(10, 1000, 0.6921486500921933) == true
end
#> Expect 0.558032193976
#> Actual 0.558032193976
#> Expect 0.692148650092
#> Actual 0.692148650092
#> Test Summary: | Pass  Total
#> fixed tests   |    2      2
#> Test.DefaultTestSet("fixed tests", Any[], 2, false, false)

R

library(tidyverse)
library(data.table)
library(magrittr)


doubles <- function(maxk, maxn) {
    iterator <- expand.grid(k = 1:maxk, n = 1:maxn) %>%
        as.data.table()
    iterator[, `:=`(v, 1/(k * (n + 1)^(2 * k)))][, v] %>%
        sum()
}

doubles(1, 10)
#> [1] 0.5580322
library(testthat)
dotest <- function(maxk, maxn, expected) {
    actual <- doubles(maxk, maxn)
    expect_equal(actual, expected, tol = 1e-06, scale = 1, info = "")
}
test_that("test doubles", {
    dotest(1, 10, 0.558032193976458)
    dotest(10, 1000, 0.692148650092193)
    dotest(10, 5000, 0.69294721240312)
})
#> Test passed 😀

JavaScript

const Vector = require("../src/JavaScript/toolkit/Vector");
const naturalSequence = Vector.naturalSequence;
const crossing = Vector.crossing;
const sum = require("../src/JavaScript/toolkit/Statistics").sum;


function doubles(K, N) {
  const v = (k, n) => 1 / (k * Math.pow(n + 1, 2 * k));
  const crossIterator = crossing(naturalSequence(K), naturalSequence(N));
  return sum(crossIterator.map(paras => v(paras[0], paras[1])));
}

console.log(doubles(1, 10));
console.log(doubles(10, 1000));
#> 0.5580321939764581
#> 0.6921486500921895