我正在为学习目的而努力,我已经使用递归解决了Collatz
。如果您在下面看到我使用@_
和$_
来保持for
活着。
#!/usr/bin/env perl
sub collatz {
my ($num, $count) = @_;
$count++;
if ($num == 1) {
return $count;
} elsif ($num % 2 == 0) {
return collatz($num/2, $count);
} else {
return collatz($num*3 + 1, $count);
}
}
my $max = 0;
my $saved = 0;
for (1..1000) {
my $length = collatz($_, 0);
print "Num: " . $_ . " Length: " . $length . "\n";
if ($length > $max) {
$max = $length;
$saved = $_;
}
}
print "The longest sequence starts with " . $saved . "\n";
我正在尝试使用迭代而不是递归,但我想不出如何解决这个问题。我不是在问题中的代码之后,我只是想要一些关于如何解决这个问题的提示/提示以获得相同的结果。
我怀疑我需要使用while
或until
字段。
任何帮助将不胜感激,我再也不想要确切的答案。
更新
这是我的第二次尝试,它给了我一个错误
Can't return outside a subroutine at answer2.pl line 38.
my $number = 0;
my $counter = 0;
while ($number != 1000) {
$counter++;
if ($number == 1) {
return $counter;
}
elsif ($number % 2 == 0) {
return ($number / 2, $counter);
}
else {
return ($number * 3 + 1, $counter);
}
$number++;
}
print "number" . $number . "counter" . $counter . "\n";
答案 0 :(得分:0)
考虑添加在while中满足条件时返回的逻辑。
扰流:
我的$ iter = 0; while($ num!= 1){#do stuff; $ iter ++}
答案 1 :(得分:0)
只需使用for
或while
循环,其结束条件为您的数字== 1.
剧透:
use strict; use warnings; my $max_num = 0; my $max_steps = 0; for my $num (1..1000) { my $steps = 0; for (my $i = $num; $i != 1; $steps++) { $i = $i % 2 ? 3 * $i + 1 : $i / 2; } print "Num: " . $num . " Length: " . $steps . "\n"; if ($steps > $max_steps) { $max_num = $num; $max_steps = $steps; } } print "The longest sequence starts with " . $max_num . "\n";
答案 2 :(得分:0)
基本上你有tail recursion,这很容易消除。
而不是collatz
调用自身来生成序列中的下一步,而只是简单地更改变量并循环回到顶部。
最粗糙的形式是
sub collatz2 {
my ($num, $count) = @_;
NEXT:
$count++;
if ($num == 1) {
return $count;
}
elsif ($num % 2 == 0) {
$num = $num / 2;
}
else {
$num = $num * 3 + 1;
}
goto NEXT;
}
但它应该写得比那更好。
我最终得到了这个
sub collatz {
my ($num) = @_;
my $count = 1;
while ($num > 1) {
$num = $num % 2 ? $num * 3 + 1 : $num / 2;
++$count;
}
$count;
}