Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
37
Task/Hamming-numbers/Java/hamming-numbers-1.java
Normal file
37
Task/Hamming-numbers/Java/hamming-numbers-1.java
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import java.math.BigInteger;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
final class Hamming {
|
||||
private static BigInteger THREE = BigInteger.valueOf(3);
|
||||
private static BigInteger FIVE = BigInteger.valueOf(5);
|
||||
|
||||
private static void updateFrontier(BigInteger x,
|
||||
PriorityQueue<BigInteger> pq) {
|
||||
pq.offer(x.shiftLeft(1));
|
||||
pq.offer(x.multiply(THREE));
|
||||
pq.offer(x.multiply(FIVE));
|
||||
}
|
||||
|
||||
public static BigInteger hamming(int n) {
|
||||
if (n <= 0)
|
||||
throw new IllegalArgumentException("Invalid parameter");
|
||||
PriorityQueue<BigInteger> frontier = new PriorityQueue<BigInteger>();
|
||||
updateFrontier(BigInteger.ONE, frontier);
|
||||
BigInteger lowest = BigInteger.ONE;
|
||||
for (int i = 1; i < n; i++) {
|
||||
lowest = frontier.poll();
|
||||
while (frontier.peek().equals(lowest))
|
||||
frontier.poll();
|
||||
updateFrontier(lowest, frontier);
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.print("Hamming(1 .. 20) =");
|
||||
for (int i = 1; i < 21; i++)
|
||||
System.out.print(" " + hamming(i));
|
||||
System.out.println("\nHamming(1691) = " + hamming(1691));
|
||||
System.out.println("Hamming(1000000) = " + hamming(1000000));
|
||||
}
|
||||
}
|
||||
110
Task/Hamming-numbers/Java/hamming-numbers-2.java
Normal file
110
Task/Hamming-numbers/Java/hamming-numbers-2.java
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
110
Task/Hamming-numbers/Java/hamming-numbers-3.java
Normal file
110
Task/Hamming-numbers/Java/hamming-numbers-3.java
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
import java.math.BigInteger;
|
||||
|
||||
public class Hamming
|
||||
{
|
||||
public static void main(String args[])
|
||||
{
|
||||
Stream hamming = makeHamming();
|
||||
System.out.print("H[1..20] ");
|
||||
for (int i=0; i<20; i++) {
|
||||
System.out.print(hamming.value());
|
||||
System.out.print(" ");
|
||||
hamming = hamming.advance();
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
System.out.print("H[1691] ");
|
||||
hamming = makeHamming();
|
||||
for (int i=1; i<1691; i++) {
|
||||
hamming = hamming.advance();
|
||||
}
|
||||
System.out.println(hamming.value());
|
||||
|
||||
hamming = makeHamming();
|
||||
System.out.print("H[10^6] ");
|
||||
for (int i=1; i<1000000; i++) {
|
||||
hamming = hamming.advance();
|
||||
}
|
||||
System.out.println(hamming.value());
|
||||
}
|
||||
|
||||
public interface Stream
|
||||
{
|
||||
BigInteger value();
|
||||
Stream advance();
|
||||
}
|
||||
|
||||
public static class MultStream implements Stream
|
||||
{
|
||||
MultStream(int mult)
|
||||
{ m_mult = BigInteger.valueOf(mult); }
|
||||
MultStream setBase(Stream s)
|
||||
{ m_base = s; return this; }
|
||||
public BigInteger value()
|
||||
{ return m_mult.multiply(m_base.value()); }
|
||||
public Stream advance()
|
||||
{ return setBase(m_base.advance()); }
|
||||
|
||||
private final BigInteger m_mult;
|
||||
private Stream m_base;
|
||||
}
|
||||
|
||||
private final static class RegularStream implements Stream
|
||||
{
|
||||
RegularStream(Stream[] streams, BigInteger val)
|
||||
{
|
||||
m_streams = streams;
|
||||
m_val = val;
|
||||
}
|
||||
public BigInteger value()
|
||||
{ return m_val; }
|
||||
|
||||
public Stream advance()
|
||||
{
|
||||
// memoized value for the next stream instance.
|
||||
if (m_advance != null) { return m_advance; }
|
||||
|
||||
int minidx = 0 ;
|
||||
BigInteger next = nextStreamValue(0);
|
||||
for (int i=1; i<m_streams.length; i++) {
|
||||
BigInteger v = nextStreamValue(i);
|
||||
if (v.compareTo(next) < 0) {
|
||||
next = v;
|
||||
minidx = i;
|
||||
}
|
||||
}
|
||||
RegularStream ret = new RegularStream(m_streams, next);
|
||||
// memoize the value!
|
||||
m_advance = ret;
|
||||
m_streams[minidx].advance();
|
||||
return ret;
|
||||
}
|
||||
private BigInteger nextStreamValue(int streamidx)
|
||||
{
|
||||
// skip past duplicates in the streams we're merging.
|
||||
BigInteger ret = m_streams[streamidx].value();
|
||||
while (ret.equals(m_val)) {
|
||||
m_streams[streamidx] = m_streams[streamidx].advance();
|
||||
ret = m_streams[streamidx].value();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
private final Stream[] m_streams;
|
||||
private final BigInteger m_val;
|
||||
private RegularStream m_advance = null;
|
||||
}
|
||||
|
||||
private final static Stream makeHamming()
|
||||
{
|
||||
MultStream nums[] = new MultStream[] {
|
||||
new MultStream(2),
|
||||
new MultStream(3),
|
||||
new MultStream(5)
|
||||
};
|
||||
Stream ret = new RegularStream(nums, BigInteger.ONE);
|
||||
for (int i=0; i<nums.length; i++) {
|
||||
nums[i].setBase(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue