0

我正在尝试创建一个带有两个参数的函数。在我的情况下,它将重复调用第一个参数

f()

直到 f 连续 3 次返回相同的值。然后它将调用第二个参数

g()

如果 g 返回与之前返回的 f 相同的值,则函数必须返回该值。否则它将返回并再次调用第一个参数 f() 并重复循环。

这就是我到目前为止所拥有的。

call_until = function(f, g) {
    while(1) {
        n = f %>% chunk(3) %>% filter(f, function(v) length(unique(v)) == 1)
        x = n()[1]
        if (x == g()) {
            return(x)
        }
    }
}

例如,如果 f 连续 3 次返回 4,则转到 g。如果 g 等于 f 连续三次返回的值(在本例中为 4);所以如果 g == 4,那么 call_until 应该返回 4。

4

3 回答 3

0

这是如何实现的示例:

f <- function(){
  return(sample(1:10,1))
}
g <- f

call_until <- function(f, g){
  results <- c(f(), f(), f())
  test <- g()
  while(length(unique(results)) > 1 || test != results[3]){
    results <- c(results[2:3], f())
    test <- g()
  }
  return(test)
}

现在在这里我创建了一些简单的函数f;g,它们会随机选择1-10(甚至不需要参数作为输入)。所以这可能需要调整。以下是一些输出:

> call_until(f,g)
[1] 3
> call_until(f,g)
[1] 7
> call_until(f,g)
[1] 10
> call_until(f,g)
[1] 9
于 2018-03-28T16:30:09.577 回答
0

递归函数可能不是最佳选择,请将此答案视为一个选项。

f <- function(){
    sample(1:2, 1)
}

g <- function(){
    sample(1:2, 1)
}

fg <- function(f, g){
    res <- c(replicate(3, f()), g()) 
    message(paste("[-] f():", paste(res[1:3], collapse = ","), 
                  "g():", res[4], "\n"))
    if(var(res) == 0){
        message(paste("[+] Magic value is ", res[1]))
        return(invisible(res[1]))
    }
    return(fg(f, g))
}

fg(f,g)

[-] f(): 1,1,1 g(): 2 

[-] f(): 1,1,1 g(): 2 

[-] f(): 1,2,2 g(): 1 

[-] f(): 2,1,1 g(): 2 

[-] f(): 1,1,1 g(): 2 

[-] f(): 1,2,2 g(): 1 

[-] f(): 1,1,1 g(): 1 

[+] Magic value is  1
于 2018-03-28T16:49:25.763 回答
0

这是您如何执行此操作的另一个示例

call_until = function(f, g) {
  while(TRUE) {
    value <- f()
    seen <- 1
    while(seen < 3) {
      next_value <- f()
      if (next_value == value) {
        seen <- seen + 1
      } else {
        value <- next_value
        seen <- 1
      }
    }
    if (value == g()) {
        return(value)
    }
  }
}

尽管如果不匹配或仅绘制一个新值,则应该绘制三个新f值,这很重要。g

这里有一些有用的测试功能。它们只是按顺序从向量返回值,并根据需要重复。

cycler <- function(vals) {
  i <- 1
  function() {
    i<<-i+1
    vals[(i-2) %% length(vals)+1]
  }
}

f <- cycler(c(1,2,2,2,3,4,5,5,5,1,1))
g <- cycler(c(5,4))

有了这个,我们得到

call_until(f, g)
# [1] 5
于 2018-03-28T16:50:46.017 回答