Skip to content

Instantly share code, notes, and snippets.

@diakopter
Created February 23, 2011 00:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diakopter/839752 to your computer and use it in GitHub Desktop.
Save diakopter/839752 to your computer and use it in GitHub Desktop.
sub getHammingNumbers(int $howMany, boolean $all --> List[BigInteger]) {
my $three = BigInteger.Parse("3");
my $five = BigInteger.Parse("5");
my $completedNumbers = List[BigInteger].new;
my $frontierSet = SortedSet[BigInteger].new;
$completedNumbers.Add(BigInteger.One);
$frontierSet.Add(BigInteger.op_LeftShift(BigInteger.One, 1));
$frontierSet.Add(BigInteger.One * $three);
$frontierSet.Add(BigInteger.One * $five);
loop (my $count = 1; $count < $howMany; $count++) {
my $lowestNumber = $frontierSet.Min;
$frontierSet.Remove($lowestNumber);
if ($all) {
$completedNumbers.Add($lowestNumber)
} else {
$completedNumbers[0] = $lowestNumber
}
$frontierSet.Add(BigInteger.op_LeftShift($lowestNumber, 1));
$frontierSet.Add($lowestNumber* $three);
$frontierSet.Add($lowestNumber* $five)
}
$completedNumbers
}
my $stopwatch = Diagnostics::Stopwatch.StartNew;
say "First 20 Hamming numbers: ";
my $twenty = getHammingNumbers(20, true);
loop (my $i=0;$i<$twenty.Count;++$i) { say $twenty[$i] }
say "1691st Hamming number: " ~ getHammingNumbers(1691, false)[0];
say "One millionth Hamming number: " + getHammingNumbers(1000000, false)[0];
say "Elapsed: " ~ $stopwatch.Elapsed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment