Rstudio:序列的 for 循环

Rstudio: for-loop of a sequence

提问人:user22623213 提问时间:9/24/2023 最后编辑:Dave2euser22623213 更新时间:9/24/2023 访问量:73

问:

我想找到数据形式的回溯序列(因为它来自 collatz 猜想 tibble 数据从 1 到 10,000)在某个点高于该序列的起始值。

这是我对数据帧的输出:

structure(list(start = 1:6, seq = list(1L, c(2, 1), c(3, 10, 
5, 16, 8, 4, 2, 1), c(4, 2, 1), c(5, 16, 8, 4, 2, 1), c(6, 3, 
10, 5, 16, 8, 4, 2, 1)), length = c(1, 2, 8, 3, 6, 9), parity = c("Odd", 
"Even", "Odd", "Even", "Odd", "Even"), max_val = c(1, 2, 16, 
4, 16, 16)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", 
"data.frame"))

我是这样做的:

has_backtrack <- function(seq) {
  length_seq <- length(seq)
  if (length_seq < 3) {
    return(FALSE)
  }
  for (i in 2:(length_seq - 1)) {
    if (seq[i] < seq[1] && seq[i + 1] > seq[i]) {
      return(TRUE)
    }
  }
}

但是,对于我当前的代码,它只显示序列是否增加,但不高于第一个值。

回溯 def:当序列达到小于起始整数的值,但随后再次增加到起始值/整数以上时,在达到 1 之前至少可以回溯一次。

R 数据帧 for-loop collatz

评论

0赞 Rui Barradas 9/24/2023
你能发布样本输入和预期输出吗?
0赞 user22623213 9/24/2023
样本输入:(i)整数 4,序列:C(4,2,1) (ii)整数 6,序列:C(6,3,10,5,16,8,4,2,1) 预期输出:整数 6

答:

1赞 Rui Barradas 9/24/2023 #1

我不确定以下内容是否是您想要的。它使用 R 的矢量化指令来获取输入序列在一条指令中增加的所有点,使代码更加简单,无需循环。for

该函数将索引返回到序列增加的点,而不是序列值。has_backtrack

函数和灵感来自这个 R-bloggers 代码next_collatzcollatz

next_collatz <- function(num) {
  if(num == 1L) {
    invisible(NULL)
  } else if(num %% 2L == 0L) {
    num / 2L
  } else 3L * num + 1L
}
collatz <- function(x) {
  result <- x
  while(x != 1L) {
    x <- next_collatz(x)
    result <- c(result, x)
  }
  result
}

has_backtrack <- function(x) which(diff(x) > 0L)

cltz_6 <- collatz(6)
has_backtrack(cltz_6)
#> [1] 2 4
i <- has_backtrack(cltz_6)
cltz_6[i]
#> [1] 3 5

创建于 2023-09-24 使用 reprex v2.0.2

另一个例子,使用严格递减的输入 Collatz 序列。

(cltz_16 <- collatz(16))
#> [1] 16  8  4  2  1
(i <- has_backtrack(cltz_16))
#> integer(0)
cltz_16[i]
#> numeric(0)

创建于 2023-09-24 使用 reprex v2.0.2


编辑

在问题中发布数据集后,Collatz 序列列是一个列表列,函数可以如下所示。
结果表明,
has_backtracklapply

  • 第 1、2、4 个 Collatz 序列为递减序列,没有递增点的指数;
  • 第 3 和第 6 序列有两个序列增加的点;
  • 第 5 个序列只有一个序列增加的点。
inx_list <- lapply(df1$seq, has_backtrack)
inx_list
#> [[1]]
#> integer(0)
#> 
#> [[2]]
#> integer(0)
#> 
#> [[3]]
#> [1] 1 3
#> 
#> [[4]]
#> integer(0)
#> 
#> [[5]]
#> [1] 1
#> 
#> [[6]]
#> [1] 2 4

创建于 2023-09-24 使用 reprex v2.0.2

要获取增加点之前的值,请使用 。Map

Map(\(x, i) x[i], df1$seq, inx_list)
#> [[1]]
#> integer(0)
#> 
#> [[2]]
#> numeric(0)
#> 
#> [[3]]
#> [1] 3 5
#> 
#> [[4]]
#> numeric(0)
#> 
#> [[5]]
#> [1] 5
#> 
#> [[6]]
#> [1] 3 5

创建于 2023-09-24 使用 reprex v2.0.2


数据

df1 <-
  structure(list(
    start = 1:6, 
    seq = list(1L, c(2, 1), c(3, 10, 5, 16, 8, 4, 2, 1), 
               c(4, 2, 1), c(5, 16, 8, 4, 2, 1), c(6, 3, 10, 5, 16, 8, 4, 2, 1)), 
    length = c(1, 2, 8, 3, 6, 9), 
    parity = c("Odd", "Even", "Odd", "Even", "Odd", "Even"), 
    max_val = c(1, 2, 16, 4, 16, 16)), 
    row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))

创建于 2023-09-24 使用 reprex v2.0.2

评论

0赞 user22623213 9/24/2023
谢谢,这是很好的代码,但是我已经有 collatz 猜想的数据,它是介于 1:10,000 整数之间的 tibble 形式,所以我想过滤 collatz 数据以使用给定的 def 创建新的回溯数据。对不起,如果我的问题不清楚。
0赞 Rui Barradas 9/24/2023
@user22623213 如果你的 tibble 被命名并且有一个名为 的列,那么你可以使用 和 只保留 。这是否回答了问题和评论?dfcollatzhas_backtrack(df$collatz)i[1]
0赞 user22623213 9/24/2023
我的 tibble 是 collatz_df,并且具有 start(integers)、sequences、parity、length 和 max_val 列。 所以我需要按照你的代码从?has_backtrack
0赞 Rui Barradas 9/24/2023
@user22623213 你能用 的输出编辑问题吗?我不明白如何在我的答案中应用该函数,并且使用实际数据会更容易为您提供帮助。dput(head(collatz_df))
0赞 user22623213 9/24/2023
好的,会的,谢谢sm...
0赞 jay.sf 9/24/2023 #2

考虑为第一个值之后的余数。id() 上的子集,看看它们是否是 。zzcumsum(z < x[1]) > 1anyTRUE

has_backtrack2 <- function(x) {
  if (length(x) < 3) FALSE
  else {
    z <- x[-1]
    any(z[cumsum(z < x[1]) > 1L] > x[1])
  }
}

sapply

sapply(df$seq, has_backtrack2)
# [1] FALSE FALSE FALSE FALSE FALSE  TRUE

或用于 conveniece d。Vectorize

has_backtrack2v <- Vectorize(has_backtrack2)

has_backtrack2v(df$seq)
# [1] FALSE FALSE FALSE FALSE FALSE  TRUE

假设所需的“整数 6”表示序列具有回溯,您可以相应地获取它:which

which(has_backtrack2v(df$seq))
# [1] 6

评论

0赞 user22623213 9/24/2023
我确实遵循了您的代码,但是,整数 7 有回溯,但您的代码输出给出了 false。.我会尝试调整你的代码,谢谢
0赞 jay.sf 9/24/2023
@user22623213指定“整数 7”的含义
0赞 user22623213 9/24/2023
好的,我的问题是检查哪些整数有回溯,对于整数 7,序列是 c(7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16 [...]),序列确实有多个回溯,因此整数 7 的结果应该是 True 而不是 False。
0赞 jay.sf 9/24/2023
@user22623213 不明白,在你显示中看不到任何“整数 7”。structure
0赞 user22623213 9/24/2023
忘记了“整数 7”,我的结果代码的解决方案必须是 8,229 行(在 1:10,000 之间),但使用您的代码我得到了 7,529 行......