Я все еще преподаю немного R главным образом для себя (и для моих учеников).
Вот реализация последовательности Коллатца в R:
f <- function(n)
{
# construct the entire Collatz path starting from n
if (n==1) return(1)
if (n %% 2 == 0) return(c(n, f(n/2)))
return(c(n, f(3*n + 1)))
}
При вызове f (13) я получаю 13, 40, 20, 10, 5, 16, 8, 4, 2,1
Однако обратите внимание, что вектор здесь динамически увеличивается в размере.Такие шаги, как правило, являются рецептом для неэффективного кода.Есть ли более эффективная версия?
В Python я бы использовал
def collatz(n):
assert isinstance(n, int)
assert n >= 1
def __colla(n):
while n > 1:
yield n
if n % 2 == 0:
n = int(n / 2)
else:
n = int(3 * n + 1)
yield 1
return list([x for x in __colla(n)])
Я нашел способ записи в векторы без указания их размерности априори.Поэтому решение может быть
collatz <-function(n)
{
stopifnot(n >= 1)
# define a vector without specifying the length
x = c()
i = 1
while (n > 1)
{
x[i] = n
i = i + 1
n = ifelse(n %% 2, 3*n + 1, n/2)
}
x[i] = 1
# now "cut" the vector
dim(x) = c(i)
return(x)
}