提问人:user22623213 提问时间:9/24/2023 最后编辑:Dave2euser22623213 更新时间:9/24/2023 访问量:73
Rstudio:序列的 for 循环
Rstudio: for-loop of a sequence
问:
我想找到数据形式的回溯序列(因为它来自 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
该函数将索引返回到序列增加的点,而不是序列值。has_backtrack
函数和灵感来自这个 R-bloggers 代码。next_collatz
collatz
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_backtrack
lapply
- 第 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
评论
df
collatz
has_backtrack(df$collatz)
i[1]
has_backtrack
dput(head(collatz_df))
考虑为第一个值之后的余数。id() 上的子集,看看它们是否是 。z
z
cumsum(z < x[1]) > 1
any
TRUE
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
评论
structure
评论