然而,我真的不认为计划是解决这个问题的正确工具,而且由于很多人已经决定这是家庭作业而不是一个合法的问题,我将在 c 中提供我的解决方案,
inline unsigned int step(unsigned int i)
{
return (i&0x1)*(i*3+1)+((i+1)&0x1)*(i>>1);
}
这将在数字上迈出一步(没有分支!!!)。 整个计算的方法如下:
unsigned int collatz(unsigned int i)
{
unsigned int cur = i;
unsigned steps = 0;
while((cur=step(cur))!=1) steps++;
return steps;
}
我认为不可能完全删除分支。 这是数论问题,因此它适合极端(并且可能不必要)优化。 享受
i believe this is a great unsolved question of number theory. There is a hypothesis that every number when it goes through this operation enough times will reduce to one.
However i don't really think scheme is the right tool for this, plus since a lot of people have decided that this is homework and not a legit question I will provide my solution in c
inline unsigned int step(unsigned int i)
{
return (i&0x1)*(i*3+1)+((i+1)&0x1)*(i>>1);
}
this will do one step on the number (with no branches!!!). Heres how you do the whole calculation:
unsigned int collatz(unsigned int i)
{
unsigned int cur = i;
unsigned steps = 0;
while((cur=step(cur))!=1) steps++;
return steps;
}
I don't think its possible to remove the branch entirely. this is number theory problem and thus it is suited to extreme (and possibly unnecessary) optimization. enjoy
(define (listfrom a b)
(if (= a b)
(cons a empty)
(cons a (listfrom (+ 1 a) b))))
(define (max-collatz a b)
(foldl max 0 (map collatz-loop (listfrom a b))))
(define (max-collatz-num a b)
(foldl (lambda (c r)
(if (> (collatz-loop c) (collatz-loop r)) c r))
a
(listfrom a b)))
For the other two functions, using foldl:
(define (listfrom a b)
(if (= a b)
(cons a empty)
(cons a (listfrom (+ 1 a) b))))
(define (max-collatz a b)
(foldl max 0 (map collatz-loop (listfrom a b))))
(define (max-collatz-num a b)
(foldl (lambda (c r)
(if (> (collatz-loop c) (collatz-loop r)) c r))
a
(listfrom a b)))
(define (collatz-loop x)
(define (internal x counter)
(if (= x 1) counter
(internal (collatz x) (+ counter 1))))
(internal x 1))
该函数采用一个范围并返回需要最多步数到达末尾的数字以及步数:
(define (collatz-range a b)
(if (= a b)
(cons a (collatz-loop a))
(let ((this (collatz-loop a))
(rest (collatz-range (+ a 1) b)))
(if (< this (cdr rest)) rest
(cons a this)))))
(collatz-range 1 20) ; returns (18 . 21), which means that (collatz-loop 18) returns 21
这是 collatz-range,尾递归:
(define (collatz-range a b)
(define (internal a best)
(if (< b a) best
(internal (+ a 1)
(let ((x (collatz-loop a)))
(if (< x (cdr best))
best
(cons a x))))))
(internal a (cons -1 -1)))
A function that performs one iteration:
(define (collatz x)
(if (even? x)
(/ x 2)
(+ (* x 3) 1)))
This function takes an input and loops until it reaches 1. The function returns the number of iterations required to get to that state (try graphing this - it looks pretty cool):
As requested, here's a tail-recursive version of collatz-loop:
(define (collatz-loop x)
(define (internal x counter)
(if (= x 1) counter
(internal (collatz x) (+ counter 1))))
(internal x 1))
This function takes a range and returns the number that takes the most number of steps to reach the end along with the number of steps:
(define (collatz-range a b)
(if (= a b)
(cons a (collatz-loop a))
(let ((this (collatz-loop a))
(rest (collatz-range (+ a 1) b)))
(if (< this (cdr rest)) rest
(cons a this)))))
(collatz-range 1 20) ; returns (18 . 21), which means that (collatz-loop 18) returns 21
This is collatz-range, tail recursive:
(define (collatz-range a b)
(define (internal a best)
(if (< b a) best
(internal (+ a 1)
(let ((x (collatz-loop a)))
(if (< x (cdr best))
best
(cons a x))))))
(internal a (cons -1 -1)))
发布评论
评论(3)
我相信这是数论中一个尚未解决的重大问题。 有一个假设,每个数字经过此操作足够多的次数后都会减少到一。
然而,我真的不认为计划是解决这个问题的正确工具,而且由于很多人已经决定这是家庭作业而不是一个合法的问题,我将在 c 中提供我的解决方案,
这将在数字上迈出一步(没有分支!!!)。 整个计算的方法如下:
我认为不可能完全删除分支。 这是数论问题,因此它适合极端(并且可能不必要)优化。 享受
i believe this is a great unsolved question of number theory. There is a hypothesis that every number when it goes through this operation enough times will reduce to one.
However i don't really think scheme is the right tool for this, plus since a lot of people have decided that this is homework and not a legit question I will provide my solution in c
this will do one step on the number (with no branches!!!). Heres how you do the whole calculation:
I don't think its possible to remove the branch entirely. this is number theory problem and thus it is suited to extreme (and possibly unnecessary) optimization. enjoy
对于其他两个函数,使用foldl:
For the other two functions, using foldl:
执行一次迭代的函数:
该函数接受一个输入并循环直到达到 1。该函数返回达到该状态所需的迭代次数(尝试绘制此图 - 它看起来很酷):
根据要求,这里有一个尾部 - collatz-loop 的递归版本:
该函数采用一个范围并返回需要最多步数到达末尾的数字以及步数:
这是 collatz-range,尾递归:
A function that performs one iteration:
This function takes an input and loops until it reaches 1. The function returns the number of iterations required to get to that state (try graphing this - it looks pretty cool):
As requested, here's a tail-recursive version of collatz-loop:
This function takes a range and returns the number that takes the most number of steps to reach the end along with the number of steps:
This is collatz-range, tail recursive: