Can a convolution function written in tail recursive form?

和自甴很熟 提交于 2019-12-06 03:10:13

sapply isn't in continuation-passing style, so you have to replace it.

Here's a translation to continuation-passing style in Python (another language that does not have proper tail calls):

def sum_ways_cps(n_times, k_sum, s_side, ctn):
    """Compute the number of ways to get the sum k by rolling an s-sided die
    n times. Then pass the answer to ctn."""

    if k_sum < n_times or k_sum > n_times * s_side:
        return ctn(0)
    elif n_times == 1:
        return ctn(1)
    else:
        f = lambda j, ctn: sum_ways_cps(n_times - 1, k_sum - j, s_side, ctn)
        return sum_cps(1, s_side + 1, 0, f, ctn)

def sum_cps(j, j_max, total_so_far, f, ctn):
    """Compute the sum of f(x) for x=j to j_max.
    Then pass the answer to ctn."""

    if j > j_max:
        return ctn(total_so_far)
    else:
        return f(j, lambda result: sum_cps(j + 1, j_max, total_so_far + result, f, ctn))


sum_ways_cps(2, 7, 6, print)  # 6

Try this (with recursion, we need to think of a linear recurrence relation if we want a tail recursive version):

f <- function(n, k) {
  if (n == 1) {                 # base case
    return(ifelse(k<=6, 1, 0))
  } else if (k > n*6 | k < n) { # some validation
    return(0)
  } 
  else {
    # recursive calls, f(1,j)=1, 1<=j<=6, otherwise 0  
    return(sum(sapply(1:min(k-n+1, 6), function(j) f(n-1,k-j))))  
  }
}

sapply(1:13, function(k) f(2, k))
# [1] 0 1 2 3 4 5 6 5 4 3 2 1 0
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!