March 2014 update
This commit is contained in:
parent
09687c4926
commit
a25938f123
1846 changed files with 21876 additions and 5203 deletions
|
|
@ -1,4 +1,4 @@
|
|||
[[wp:Hamming_numbers#Algorithms|Hamming numbers]] are numbers of the form
|
||||
'''[[wp:Hamming numbers|Hamming numbers]]''' are numbers of the form
|
||||
: <math>H = 2^i \cdot 3^j \cdot 5^k, \; \mathrm{where} \; i, j, k \geq 0</math>.
|
||||
''Hamming numbers'' are also known as ''ugly numbers'' and also ''5-smooth numbers'' (numbers whose prime divisors are less or equal to 5).
|
||||
|
||||
|
|
@ -7,6 +7,6 @@ Generate the sequence of Hamming numbers, ''in increasing order''. In particular
|
|||
# Show the 1691st Hamming number (the last one below <math>2^{31}</math>).
|
||||
# Show the one millionth Hamming number (if the language – or a convenient library – supports arbitrary-precision integers).
|
||||
'''References'''
|
||||
# [[wp:Hamming_numbers]]
|
||||
# [[wp:Smooth_number]]
|
||||
# [[wp:Hamming numbers|Hamming numbers]]
|
||||
# [[wp:Smooth number|Smooth number]]
|
||||
# [http://dobbscodetalk.com/index.php?option=com_content&task=view&id=913&Itemid=85 Hamming problem] from Dr. Dobb's CodeTalk (dead link as of Sep 2011; parts of the thread [http://drdobbs.com/blogs/architecture-and-design/228700538 here] and [http://www.jsoftware.com/jwiki/Essays/Hamming%20Number here]).
|
||||
|
|
|
|||
35
Task/Hamming-numbers/Bracmat/hamming-numbers.bracmat
Normal file
35
Task/Hamming-numbers/Bracmat/hamming-numbers.bracmat
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
( ( hamming
|
||||
= x2 x3 x5 n i j k min
|
||||
. tbl$(h,!arg) { This creates an array. Arrays are always global in Bracmat. }
|
||||
& 1:?(0$h)
|
||||
& 2:?x2
|
||||
& 3:?x3
|
||||
& 5:?x5
|
||||
& 0:?n:?i:?j:?k
|
||||
& whl
|
||||
' ( !n+1:<!arg:?n
|
||||
& !x2:?min
|
||||
& (!x3:<!min:?min|)
|
||||
& (!x5:<!min:?min|)
|
||||
& !min:?(!n$h) { !n is index into array h }
|
||||
& ( !x2:!min
|
||||
& 2*!((1+!i:?i)$h):?x2
|
||||
|
|
||||
)
|
||||
& ( !x3:!min
|
||||
& 3*!((1+!j:?j)$h):?x3
|
||||
|
|
||||
)
|
||||
& ( !x5:!min
|
||||
& 5*!((1+!k:?k)$h):?x5
|
||||
|
|
||||
)
|
||||
)
|
||||
& !((!arg+-1)$h) (tbl$(h,0)&) { We delete the array by setting its size to 0 }
|
||||
)
|
||||
& 0:?I
|
||||
& whl'(!I+1:~>20:?I&put$(hamming$!I " "))
|
||||
& out$
|
||||
& out$(hamming$1691)
|
||||
& out$(hamming$1000000)
|
||||
);
|
||||
25
Task/Hamming-numbers/Forth/hamming-numbers-2.fth
Normal file
25
Task/Hamming-numbers/Forth/hamming-numbers-2.fth
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
2000 cells constant /hamming
|
||||
create hamming /hamming allot
|
||||
( n1 n2 n3 n4 n5 n6 n7 -- n3 n4 n5 n6 n1 n2 n8)
|
||||
: min? >r dup r> min >r 2rot r> ;
|
||||
|
||||
: hit? ( n1 n2 n3 n4 n5 n6 n7 n8 -- n3 n4 n9 n10 n1 n2 n7)
|
||||
>r 2dup = \ compare number with found minimum
|
||||
if -rot drop 1+ hamming over cells + @ r@ * rot then
|
||||
r> drop >r 2rot r>
|
||||
; \ if so, increment and rotate
|
||||
|
||||
: hamming# ( n1 -- n2)
|
||||
1 hamming ! >r \ set first cell and initialize parms
|
||||
0 5 over 3 over 2
|
||||
r@ 1 ?do \ determine minimum and set cell
|
||||
dup min? min? min? dup hamming i cells + !
|
||||
2 hit? 5 hit? 3 hit? drop
|
||||
loop \ find if minimum equals value
|
||||
2drop 2drop 2drop hamming r> 1- cells + @
|
||||
; \ clean up stack and fetch hamming number
|
||||
|
||||
: test
|
||||
cr 21 1 ?do i . i hamming# . cr loop
|
||||
1691 hamming# . cr
|
||||
;
|
||||
111
Task/Hamming-numbers/Java/hamming-numbers-2.java
Normal file
111
Task/Hamming-numbers/Java/hamming-numbers-2.java
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
// ilkka.kokkarinen@gmail.com
|
||||
|
||||
public class HammingTriple implements Comparable<HammingTriple> {
|
||||
|
||||
// Precompute a couple of constants that we need all the time
|
||||
private static final BigInteger two = BigInteger.valueOf(2);
|
||||
private static final BigInteger three = BigInteger.valueOf(3);
|
||||
private static final BigInteger five = BigInteger.valueOf(5);
|
||||
private static final double logOf2 = Math.log(2);
|
||||
private static final double logOf3 = Math.log(3);
|
||||
private static final double logOf5 = Math.log(5);
|
||||
|
||||
// The powers of this triple
|
||||
private int a, b, c;
|
||||
|
||||
public HammingTriple(int a, int b, int c) {
|
||||
this.a = a; this.b = b; this.c = c;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[" + a + ", " + b + ", " + c + "]";
|
||||
}
|
||||
|
||||
public BigInteger getValue() {
|
||||
return two.pow(a).multiply(three.pow(b)).multiply(five.pow(c));
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if(other instanceof HammingTriple) {
|
||||
HammingTriple h = (HammingTriple) other;
|
||||
return this.a == h.a && this.b == h.b && this.c == h.c;
|
||||
}
|
||||
else { return false; }
|
||||
}
|
||||
|
||||
// Return 0 if this == other, +1 if this > other, and -1 if this < other
|
||||
public int compareTo(HammingTriple other) {
|
||||
// equality
|
||||
if(this.a == other.a && this.b == other.b && this.c == other.c) {
|
||||
return 0;
|
||||
}
|
||||
// this dominates
|
||||
if(this.a >= other.a && this.b >= other.b && this.c >= other.c) {
|
||||
return +1;
|
||||
}
|
||||
// other dominates
|
||||
if(this.a <= other.a && this.b <= other.b && this.c <= other.c) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// take the logarithms for comparison
|
||||
double log1 = this.a * logOf2 + this.b * logOf3 + this.c * logOf5;
|
||||
double log2 = other.a * logOf2 + other.b * logOf3 + other.c * logOf5;
|
||||
|
||||
// are these different enough to be reliable?
|
||||
if(Math.abs(log1 - log2) > 0.0000001) {
|
||||
return (log1 < log2) ? -1: +1;
|
||||
}
|
||||
|
||||
// oh well, looks like we have to do this the hard way
|
||||
return this.getValue().compareTo(other.getValue());
|
||||
// (getting this far should be pretty rare, though)
|
||||
}
|
||||
|
||||
public static BigInteger computeHamming(int n, boolean verbose) {
|
||||
if(verbose) {
|
||||
System.out.println("Hamming number #" + n);
|
||||
}
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
// The elements of the search frontier
|
||||
PriorityQueue<HammingTriple> frontierQ = new PriorityQueue<HammingTriple>();
|
||||
int maxFrontierSize = 1;
|
||||
|
||||
// Initialize the frontier
|
||||
frontierQ.offer(new HammingTriple(0, 0, 0)); // 1
|
||||
|
||||
while(true) {
|
||||
if(frontierQ.size() > maxFrontierSize) {
|
||||
maxFrontierSize = frontierQ.size();
|
||||
}
|
||||
// Pop out the next Hamming number from the frontier
|
||||
HammingTriple curr = frontierQ.poll();
|
||||
|
||||
if(--n == 0) {
|
||||
if(verbose) {
|
||||
System.out.println("Time: " + (System.currentTimeMillis() - startTime) + " ms");
|
||||
System.out.println("Frontier max size: " + maxFrontierSize);
|
||||
System.out.println("As powers: " + curr.toString());
|
||||
System.out.println("As value: " + curr.getValue());
|
||||
}
|
||||
return curr.getValue();
|
||||
}
|
||||
|
||||
// Current times five, if at origin in (a,b) plane
|
||||
if(curr.a == 0 && curr.b == 0) {
|
||||
frontierQ.offer(new HammingTriple(curr.a, curr.b, curr.c + 1));
|
||||
}
|
||||
// Current times three, if at line a == 0
|
||||
if(curr.a == 0) {
|
||||
frontierQ.offer(new HammingTriple(curr.a, curr.b + 1, curr.c));
|
||||
}
|
||||
// Current times two, unconditionally
|
||||
curr.a++;
|
||||
frontierQ.offer(curr); // reuse the current HammingTriple object
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Task/Hamming-numbers/Kotlin/hamming-numbers.kotlin
Normal file
32
Task/Hamming-numbers/Kotlin/hamming-numbers.kotlin
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import java.math.BigInteger;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
val Three = BigInteger.valueOf(3)
|
||||
val Five = BigInteger.valueOf(5)
|
||||
|
||||
fun updateFrontier(x : BigInteger, pq : PriorityQueue<BigInteger>) {
|
||||
pq add(x shiftLeft(1))
|
||||
pq add(x multiply(Three))
|
||||
pq add(x multiply(Five))
|
||||
}
|
||||
|
||||
fun hamming(n : Int) : BigInteger {
|
||||
val frontier = PriorityQueue<BigInteger>()
|
||||
updateFrontier(BigInteger.ONE, frontier)
|
||||
var lowest = BigInteger.ONE
|
||||
for (i in 1 .. n-1) {
|
||||
lowest = frontier.poll() ?: lowest
|
||||
while (frontier.peek() equals(lowest))
|
||||
frontier.poll()
|
||||
updateFrontier(lowest, frontier)
|
||||
}
|
||||
return lowest
|
||||
}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
System.out print("Hamming(1 .. 20) =")
|
||||
for (i in 1 .. 20)
|
||||
System.out print(" ${hamming(i)}")
|
||||
System.out println("\nHamming(1691) = ${hamming(1691)}")
|
||||
System.out println("Hamming(1000000) = ${hamming(1000000)}")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue