September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
108
Task/Hamming-numbers/360-Assembly/hamming-numbers.360
Normal file
108
Task/Hamming-numbers/360-Assembly/hamming-numbers.360
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
* Hamming numbers 12/03/2017
|
||||
HAM CSECT
|
||||
USING HAM,R13 base register
|
||||
B 72(R15) skip savearea
|
||||
DC 17F'0' savearea
|
||||
STM R14,R12,12(R13) save previous context
|
||||
ST R13,4(R15) link backward
|
||||
ST R15,8(R13) link forward
|
||||
LR R13,R15 set addressability
|
||||
LA R6,1 ii=1
|
||||
DO WHILE=(C,R6,LE,=F'20') do ii=1 to 20
|
||||
BAL R14,PRTHAM call prtham
|
||||
LA R6,1(R6) ii++
|
||||
ENDDO , enddo ii
|
||||
LA R6,1691 ii=1691
|
||||
BAL R14,PRTHAM call prtham
|
||||
L R13,4(0,R13) restore previous savearea pointer
|
||||
LM R14,R12,12(R13) restore previous context
|
||||
XR R15,R15 rc=0
|
||||
BR R14 exit
|
||||
PRTHAM EQU * ---- prtham
|
||||
ST R14,R14PRT save return addr
|
||||
LR R1,R6 ii
|
||||
XDECO R1,XDEC edit
|
||||
MVC PG+2(4),XDEC+8 output ii
|
||||
LR R1,R6 ii
|
||||
BAL R14,HAMMING call hamming(ii)
|
||||
XDECO R0,XDEC edit
|
||||
MVC PG+8(10),XDEC+2 output hamming(ii)
|
||||
XPRNT PG,L'PG print buffer
|
||||
L R14,R14PRT restore return addr
|
||||
BR R14 ---- return
|
||||
HAMMING EQU * ---- hamming(ll)
|
||||
ST R14,R14HAM save return addr
|
||||
ST R1,LL ll
|
||||
MVC HH,=F'1' h(1)=1
|
||||
SR R0,R0 0
|
||||
ST R0,I i=0
|
||||
ST R0,J j=0
|
||||
ST R0,K k=0
|
||||
MVC X2,=F'2' x2=2
|
||||
MVC X3,=F'3' x3=3
|
||||
MVC X5,=F'5' x5=5
|
||||
LA R7,1 n=1
|
||||
L R2,LL ll
|
||||
BCTR R2,0 -1
|
||||
ST R2,LLM1 ll-1
|
||||
DO WHILE=(C,R7,LE,LLM1) do n=1 to ll-1
|
||||
L R4,X2 m=x2
|
||||
IF C,R4,GT,X3 THEN if m>x3 then
|
||||
L R4,X3 m=x3
|
||||
ENDIF , endif
|
||||
IF C,R4,GT,X5 THEN if m>x5 then
|
||||
L R4,X5 m=x5
|
||||
ENDIF , endif
|
||||
LR R1,R7 n
|
||||
SLA R1,2 *4
|
||||
ST R4,HH(R1) h(n+1)=m
|
||||
IF C,R4,EQ,X2 THEN if m=x2 then
|
||||
L R1,I i
|
||||
LA R1,1(R1) i+1
|
||||
ST R1,I i=i+1
|
||||
SLA R1,2 *4
|
||||
L R2,HH(R1) h(i+1)
|
||||
MH R2,=H'2' *2
|
||||
ST R2,X2 x2=2*h(i+1)
|
||||
ENDIF , endif
|
||||
IF C,R4,EQ,X3 THEN if m=x3 then
|
||||
L R1,J j
|
||||
LA R1,1(R1) j+1
|
||||
ST R1,J j=j+1
|
||||
SLA R1,2 *4
|
||||
L R2,HH(R1) h(j+1)
|
||||
MH R2,=H'3' *3
|
||||
ST R2,X3 x3=3*h(j+1)
|
||||
ENDIF , endif
|
||||
IF C,R4,EQ,X5 THEN if m=x5 then
|
||||
L R1,K k
|
||||
LA R1,1(R1) k+1
|
||||
ST R1,K k=k+1
|
||||
SLA R1,2 *4
|
||||
L R2,HH(R1) h(k+1)
|
||||
MH R2,=H'5' *5
|
||||
ST R2,X5 x5=5*h(k+1)
|
||||
ENDIF , endif
|
||||
LA R7,1(R7) n++
|
||||
ENDDO , enddo n
|
||||
L R1,LL ll
|
||||
SLA R1,2 *4
|
||||
L R0,HH-4(R1) return h(ll)
|
||||
L R14,R14HAM restore return addr
|
||||
BR R14 ---- return
|
||||
R14HAM DS A return addr of hamming
|
||||
R14PRT DS A return addr of print
|
||||
LL DS F ll
|
||||
LLM1 DS F ll-1
|
||||
I DS F i
|
||||
J DS F j
|
||||
K DS F k
|
||||
X2 DS F x2
|
||||
X3 DS F x3
|
||||
X5 DS F x5
|
||||
PG DC CL80'H(xxxx)=xxxxxxxxxx'
|
||||
XDEC DS CL12 temp
|
||||
LTORG positioning literal pool
|
||||
HH DS 1691F array h(1691)
|
||||
YREGS
|
||||
END HAM
|
||||
41
Task/Hamming-numbers/ALGOL-W/hamming-numbers.alg
Normal file
41
Task/Hamming-numbers/ALGOL-W/hamming-numbers.alg
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
begin
|
||||
% returns the minimum of a and b %
|
||||
integer procedure min ( integer value a, b ) ; if a < b then a else b;
|
||||
% find and print Hamming Numbers %
|
||||
% Algol W only supports 32-bit integers so we just find %
|
||||
% the 1691 32-bit Hamming Numbers %
|
||||
integer MAX_HAMMING;
|
||||
MAX_HAMMING := 1691;
|
||||
begin
|
||||
integer array H( 1 :: MAX_HAMMING );
|
||||
integer p2, p3, p5, last2, last3, last5;
|
||||
H( 1 ) := 1;
|
||||
last2 := last3 := last5 := 1;
|
||||
p2 := 2;
|
||||
p3 := 3;
|
||||
p5 := 5;
|
||||
for hPos := 2 until MAX_HAMMING do begin
|
||||
integer m;
|
||||
% the next Hamming number is the lowest of the next multiple of 2, 3, and 5 %
|
||||
m := min( min( p2, p3 ), p5 );
|
||||
H( hPos ) := m;
|
||||
if m = p2 then begin
|
||||
last2 := last2 + 1;
|
||||
p2 := 2 * H( last2 )
|
||||
end if_used_power_of_2 ;
|
||||
if m = p3 then begin
|
||||
last3 := last3 + 1;
|
||||
p3 := 3 * H( last3 )
|
||||
end if_used_power_of_3 ;
|
||||
if m = p5 then begin
|
||||
last5 := last5 + 1;
|
||||
p5 := 5 * H( last5 )
|
||||
end if_used_power_of_5 ;
|
||||
end for_hPos ;
|
||||
i_w := 1;
|
||||
s_w := 1;
|
||||
write( H( 1 ) );
|
||||
for i := 2 until 20 do writeon( H( i ) );
|
||||
write( H( MAX_HAMMING ) )
|
||||
end
|
||||
end.
|
||||
30
Task/Hamming-numbers/Bc/hamming-numbers.bc
Normal file
30
Task/Hamming-numbers/Bc/hamming-numbers.bc
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
cat hamming_numbers.bc
|
||||
define min(x,y) {
|
||||
if (x < y) {
|
||||
return x
|
||||
} else {
|
||||
return y
|
||||
}
|
||||
}
|
||||
define hamming(limit) {
|
||||
i = 0
|
||||
j = 0
|
||||
k = 0
|
||||
h[0] = 1
|
||||
x2 = 2
|
||||
x3 = 3
|
||||
x5 = 5
|
||||
for (n=1; n<=limit; n++) {
|
||||
h[n] = min(x2,min(x3,x5))
|
||||
if (h[n] == x2) { x2 = 2 * h[++i] }
|
||||
if (h[n] == x3) { x3 = 3 * h[++j] }
|
||||
if (h[n] == x5) { x5 = 5 * h[++k] }
|
||||
}
|
||||
return (h[limit-1])
|
||||
}
|
||||
for (lab=1; lab<=20; lab++) {
|
||||
hamming(lab)
|
||||
}
|
||||
hamming(1691)
|
||||
hamming(1000000)
|
||||
quit
|
||||
96
Task/Hamming-numbers/C++/hamming-numbers-4.cpp
Normal file
96
Task/Hamming-numbers/C++/hamming-numbers-4.cpp
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <gmpxx.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
template<class T>
|
||||
class Lazy {
|
||||
public:
|
||||
T _v;
|
||||
private:
|
||||
std::function<T()> _f;
|
||||
|
||||
public:
|
||||
explicit Lazy(std::function<T()> thnk)
|
||||
: _v(T()), _f(thnk) {};
|
||||
T value() { // not thread safe!
|
||||
if (this->_f != nullptr) {
|
||||
this->_v = this->_f();
|
||||
this->_f = nullptr;
|
||||
}
|
||||
return this->_v;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class LazyList {
|
||||
public:
|
||||
T head;
|
||||
std::shared_ptr<Lazy<LazyList<T>>> tail;
|
||||
LazyList(): head(T()) {} // only used in initializing Lazy...
|
||||
LazyList(T head, std::function<LazyList<T>()> thnk)
|
||||
: head(head), tail(std::make_shared<Lazy<LazyList<T>>>(thnk)) {}
|
||||
// default Copy/Move constructors and assignment operators seem to work well enough
|
||||
bool isEmpty() { return this->tail == nullptr; }
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<mpz_class> PBI;
|
||||
typedef LazyList<PBI> LL;
|
||||
typedef std::function<LL(LL)> FLL2LL;
|
||||
|
||||
LL merge(LL a, LL b) {
|
||||
auto ha = a.head; auto hb = b.head;
|
||||
if (*ha < *hb) {
|
||||
return LL(ha, [=]() { return merge(a.tail->value(), b); });
|
||||
} else {
|
||||
return LL(hb, [=]() { return merge(a, b.tail->value()); });
|
||||
}
|
||||
}
|
||||
|
||||
LL smult(int m, LL s) {
|
||||
const auto im = mpz_class(m);
|
||||
const auto psmlt =
|
||||
std::make_shared<FLL2LL>([](LL ss) { return ss; });
|
||||
*psmlt = [=](LL ss) {
|
||||
return LL(std::make_shared<mpz_class>(*ss.head * im),
|
||||
[=]() { return (*psmlt)(ss.tail->value()); });
|
||||
};
|
||||
return (*psmlt)(s); // worker wrapper pattern with recursive closure as worker...
|
||||
}
|
||||
|
||||
LL u(LL s, int n) {
|
||||
const auto r = std::make_shared<LL>(LL()); // interior mutable...
|
||||
*r = smult(n, LL(std::make_shared<mpz_class>(1), [=]() { return *r; }));
|
||||
if (!s.isEmpty()) { *r = merge(s, *r); }
|
||||
return *r;
|
||||
}
|
||||
|
||||
LL hammings() {
|
||||
auto r = LL();
|
||||
for (auto pn : std::vector<int>({5, 3, 2})) {
|
||||
r = u(r, pn);
|
||||
}
|
||||
return LL(std::make_shared<mpz_class>(1), [=]() { return r; });
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto hmgs = hammings();
|
||||
for (auto i = 0; i < 20; ++i) {
|
||||
std::cout << *hmgs.head << " ";
|
||||
hmgs = hmgs.tail->value();
|
||||
}
|
||||
std::cout << "\n";
|
||||
|
||||
hmgs = hammings();
|
||||
for (auto i = 1; i < 1691; ++i) hmgs = hmgs.tail->value();
|
||||
std::cout << *hmgs.head << "\n";
|
||||
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
hmgs = hammings();
|
||||
for (auto i = 1; i < 1000000; ++i) hmgs = hmgs.tail->value();
|
||||
auto stop = std::chrono::steady_clock::now();
|
||||
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
|
||||
std::cout << *hmgs.head << " in " << ms.count() << "milliseconds.\n";
|
||||
}
|
||||
64
Task/Hamming-numbers/C++/hamming-numbers-5.cpp
Normal file
64
Task/Hamming-numbers/C++/hamming-numbers-5.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <gmpxx.h>
|
||||
|
||||
class Hammings {
|
||||
private:
|
||||
const mpz_class _two = 2, _three = 3, _five = 5;
|
||||
std::vector<mpz_class> _m = {}, _h = {1};
|
||||
mpz_class _x5 = 5, _x53 = 9, _mrg = 3, _x532 = 2;
|
||||
int _i = 1, _j = 0;
|
||||
public:
|
||||
Hammings() {_m.reserve(65536); _h.reserve(65536); };
|
||||
bool operator!=(const Hammings& other) const { return true; }
|
||||
Hammings begin() const { return *this; }
|
||||
Hammings end() const { return *this; }
|
||||
mpz_class operator*() { return _h.back(); }
|
||||
const Hammings& operator++() {
|
||||
if (_i > _h.capacity() / 2) {
|
||||
_h.erase(_h.begin(), _h.begin() + _i);
|
||||
_i = 0;
|
||||
}
|
||||
if (_x532 < _mrg) {
|
||||
_h.push_back(_x532);
|
||||
_x532 = _h[_i++] * _two;
|
||||
} else {
|
||||
_h.push_back(_mrg);
|
||||
if (_x53 < _x5) {
|
||||
_mrg = _x53;
|
||||
_x53 = _m[_j++] * _three;
|
||||
} else {
|
||||
_mrg = _x5;
|
||||
_x5 = _x5 * _five;
|
||||
}
|
||||
if (_j > _m.capacity() / 2) {
|
||||
_m.erase(_m.begin(), _m.begin() + _j);
|
||||
_j = 0;
|
||||
}
|
||||
_m.push_back(_mrg);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
auto cnt = 1;
|
||||
for (auto hmg : Hammings()) {
|
||||
if (cnt <= 20) std::cout << hmg << " ";
|
||||
if (cnt == 20) std::cout << "\n";
|
||||
if (cnt++ >= 1691) {
|
||||
std::cout << hmg << "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
hmgs = hammings();
|
||||
auto&& hmgitr = Hammings();
|
||||
for (auto i = 1; i < 1000000; ++i) ++hmgitr;
|
||||
auto stop = std::chrono::steady_clock::now();
|
||||
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
|
||||
std::cout << *hmgitr << " in " << ms.count() << "milliseconds.\n";
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
import java.math.BigInteger
|
||||
import java.util.PriorityQueue
|
||||
import java.util.*
|
||||
|
||||
val Three = BigInteger.valueOf(3)
|
||||
val Five = BigInteger.valueOf(5)
|
||||
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))
|
||||
pq.add(x.shiftLeft(1))
|
||||
pq.add(x.multiply(Three))
|
||||
pq.add(x.multiply(Five))
|
||||
}
|
||||
|
||||
fun hamming(n : Int) : BigInteger {
|
||||
|
|
@ -16,7 +16,7 @@ fun hamming(n : Int) : BigInteger {
|
|||
var lowest = BigInteger.ONE
|
||||
for (i in 1 .. n-1) {
|
||||
lowest = frontier.poll() ?: lowest
|
||||
while (frontier.peek() equals(lowest))
|
||||
while (frontier.peek() == lowest)
|
||||
frontier.poll()
|
||||
updateFrontier(lowest, frontier)
|
||||
}
|
||||
|
|
@ -24,9 +24,9 @@ fun hamming(n : Int) : BigInteger {
|
|||
}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
System.out print("Hamming(1 .. 20) =")
|
||||
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)}")
|
||||
System.out.print(" ${hamming(i)}")
|
||||
System.out.println("\nHamming(1691) = ${hamming(1691)}")
|
||||
System.out.println("Hamming(1000000) = ${hamming(1000000)}")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import java.math.BigInteger
|
||||
import java.util.PriorityQueue
|
||||
import java.util.*
|
||||
|
||||
val One = BigInteger.ONE
|
||||
val Three = BigInteger.valueOf(3)
|
||||
val Five = BigInteger.valueOf(5)
|
||||
val One = BigInteger.ONE!!
|
||||
val Three = BigInteger.valueOf(3)!!
|
||||
val Five = BigInteger.valueOf(5)!!
|
||||
|
||||
fun PriorityQueue<BigInteger>.update(x: BigInteger) : PriorityQueue<BigInteger> {
|
||||
add(x.shiftLeft(1))
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import java.math.BigInteger
|
||||
import java.util.PriorityQueue
|
||||
import java.util.*
|
||||
|
||||
val One = BigInteger.ONE
|
||||
val Three = BigInteger.valueOf(3)
|
||||
val Five = BigInteger.valueOf(5)
|
||||
val One = BigInteger.ONE!!
|
||||
val Three = BigInteger.valueOf(3)!!
|
||||
val Five = BigInteger.valueOf(5)!!
|
||||
|
||||
infix fun PriorityQueue<BigInteger>.update(x: BigInteger) : PriorityQueue<BigInteger> {
|
||||
add(x.shiftLeft(1))
|
||||
|
|
|
|||
|
|
@ -1,38 +1,38 @@
|
|||
import java.math.BigInteger as BI
|
||||
|
||||
data class LazyList<T>(val head: T, val lztail: Lazy<LazyList<T>?>) {
|
||||
fun toSequence() = generateSequence(this) { it.lztail.value }
|
||||
.map { it.head }
|
||||
fun toSequence() = generateSequence(this) { it.lztail.value }
|
||||
.map { it.head }
|
||||
}
|
||||
|
||||
fun hamming(): LazyList<BI> {
|
||||
fun merge(s1: LazyList<BI>, s2: LazyList<BI>): LazyList<BI> {
|
||||
val s1v = s1.head; val s2v = s2.head
|
||||
if (s1v < s2v) {
|
||||
return LazyList(s1v, lazy({->merge(s1.lztail.value!!, s2)}))
|
||||
} else {
|
||||
return LazyList(s2v, lazy({->merge(s1, s2.lztail.value!!)}))
|
||||
}
|
||||
}
|
||||
fun llmult(m: BI, s: LazyList<BI>): LazyList<BI> {
|
||||
fun llmlt(ss: LazyList<BI>): LazyList<BI> {
|
||||
return LazyList(m * ss.head, lazy({->llmlt(ss.lztail.value!!)}))
|
||||
}
|
||||
return llmlt(s)
|
||||
}
|
||||
fun u(s: LazyList<BI>?, n: Long): LazyList<BI> {
|
||||
var r: LazyList<BI>? = null // mutable nullable so can do the below
|
||||
if (s == null) { // recursively referenced variables are ugly!!!
|
||||
r = llmult(BI.valueOf(n), LazyList(BI.valueOf(1), lazy{ -> r }))
|
||||
} else { // recursively referenced variables only work with lazy
|
||||
r = merge(s, llmult(BI.valueOf(n), // or a loop race limit
|
||||
LazyList(BI.valueOf(1), lazy{ -> r })))
|
||||
}
|
||||
return r
|
||||
}
|
||||
val prms = arrayOf(5L, 3L, 2L)
|
||||
val thunk = {->prms.fold<Long,LazyList<BI>?>(null, {s, n -> u(s,n)})!!}
|
||||
return LazyList(BI.valueOf(1), lazy(thunk))
|
||||
fun merge(s1: LazyList<BI>, s2: LazyList<BI>): LazyList<BI> {
|
||||
val s1v = s1.head; val s2v = s2.head
|
||||
if (s1v < s2v) {
|
||||
return LazyList(s1v, lazy({->merge(s1.lztail.value!!, s2)}))
|
||||
} else {
|
||||
return LazyList(s2v, lazy({->merge(s1, s2.lztail.value!!)}))
|
||||
}
|
||||
}
|
||||
fun llmult(m: BI, s: LazyList<BI>): LazyList<BI> {
|
||||
fun llmlt(ss: LazyList<BI>): LazyList<BI> {
|
||||
return LazyList(m * ss.head, lazy({->llmlt(ss.lztail.value!!)}))
|
||||
}
|
||||
return llmlt(s)
|
||||
}
|
||||
fun u(s: LazyList<BI>?, n: Long): LazyList<BI> {
|
||||
var r: LazyList<BI>? = null // mutable nullable so can do the below
|
||||
if (s == null) { // recursively referenced variables are ugly!!!
|
||||
r = llmult(BI.valueOf(n), LazyList(BI.valueOf(1), lazy{ -> r }))
|
||||
} else { // recursively referenced variables only work with lazy
|
||||
r = merge(s, llmult(BI.valueOf(n), // or a loop race limit
|
||||
LazyList(BI.valueOf(1), lazy{ -> r })))
|
||||
}
|
||||
return r
|
||||
}
|
||||
val prms = arrayOf(5L, 3L, 2L)
|
||||
val thunk = {->prms.fold<Long,LazyList<BI>?>(null, {s, n -> u(s,n)})!!}
|
||||
return LazyList(BI.valueOf(1), lazy(thunk))
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
|
|
|||
44
Task/Hamming-numbers/Phix/hamming-numbers-1.phix
Normal file
44
Task/Hamming-numbers/Phix/hamming-numbers-1.phix
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
function hamming(integer N)
|
||||
sequence h = repeat(1,N)
|
||||
atom x2 = 2, x3 = 3, x5 = 5, hn
|
||||
integer i = 1, j = 1, k = 1
|
||||
for n=2 to N do
|
||||
hn = min(x2,min(x3,x5))
|
||||
h[n] = hn
|
||||
if hn=x2 then i += 1 x2 = 2*h[i] end if
|
||||
if hn=x3 then j += 1 x3 = 3*h[j] end if
|
||||
if hn=x5 then k += 1 x5 = 5*h[k] end if
|
||||
end for
|
||||
return h[N]
|
||||
end function
|
||||
|
||||
include builtins\bigatom.e
|
||||
|
||||
function ba_min(bigatom a, bigatom b)
|
||||
return iff(ba_compare(a,b)<0?a:b)
|
||||
end function
|
||||
|
||||
function ba_hamming(integer N)
|
||||
sequence h = repeat(ba_new(1),N)
|
||||
bigatom x2 = ba_new(2), x3 = ba_new(3), x5 = ba_new(5), hn
|
||||
integer i = 1, j = 1, k = 1
|
||||
for n=2 to N do
|
||||
hn = ba_min(x2,ba_min(x3,x5))
|
||||
h[n] = hn
|
||||
if ba_compare(hn,x2)=0 then i += 1 x2 = ba_multiply(2,h[i]) end if
|
||||
if ba_compare(hn,x3)=0 then j += 1 x3 = ba_multiply(3,h[j]) end if
|
||||
if ba_compare(hn,x5)=0 then k += 1 x5 = ba_multiply(5,h[k]) end if
|
||||
end for
|
||||
return h[N]
|
||||
end function
|
||||
|
||||
sequence s = {}
|
||||
for i=1 to 20 do
|
||||
s = append(s,hamming(i))
|
||||
end for
|
||||
?s
|
||||
?hamming(1691)
|
||||
?{hamming(1000000),"wrong!"}
|
||||
|
||||
?ba_sprintf("%B\n",ba_hamming(1691))
|
||||
?ba_sprintf("%B\n",ba_hamming(1000000))
|
||||
52
Task/Hamming-numbers/Phix/hamming-numbers-2.phix
Normal file
52
Task/Hamming-numbers/Phix/hamming-numbers-2.phix
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
-- numbers kept as {log,{pow2,pow3,pow5}},
|
||||
-- value is ~= exp(log), == (2^pow2)*(3^pow3)*(5^pow5)
|
||||
enum LOG, POWS
|
||||
enum POW2, POW3, POW5
|
||||
|
||||
function lnmin(sequence a, sequence b)
|
||||
return iff(a[LOG]<b[LOG]?a:b)
|
||||
end function
|
||||
|
||||
constant ln1 = log(1), ln2 = log(2), ln3 = log(3), ln5 = log(5)
|
||||
|
||||
function hamming(integer N)
|
||||
sequence h = repeat(0,N)
|
||||
sequence x2 = {ln2,{1,0,0}},
|
||||
x3 = {ln3,{0,1,0}},
|
||||
x5 = {ln5,{0,0,1}}
|
||||
integer i = 1, j = 1, k = 1
|
||||
h[1] = {ln1,{0,0,0}}
|
||||
for n=2 to N do
|
||||
h[n] = lnmin(x2,lnmin(x3,x5))
|
||||
sequence p = h[n][POWS]
|
||||
if p=x2[POWS] then i += 1 x2 = h[i] x2[LOG] += ln2 x2[POWS][POW2] += 1 end if
|
||||
if p=x3[POWS] then j += 1 x3 = h[j] x3[LOG] += ln3 x3[POWS][POW3] += 1 end if
|
||||
if p=x5[POWS] then k += 1 x5 = h[k] x5[LOG] += ln5 x5[POWS][POW5] += 1 end if
|
||||
end for
|
||||
return h[N]
|
||||
end function
|
||||
|
||||
function hint(sequence hm)
|
||||
-- (obviously not accurate above 53 bits on a 32-bit system, or 64 bits on a 64 bit system)
|
||||
sequence p = hm[POWS]
|
||||
return power(2,p[POW2])*power(3,p[POW3])*power(5,p[POW5])
|
||||
end function
|
||||
|
||||
sequence s = {}
|
||||
for i=1 to 20 do
|
||||
s = append(s,hint(hamming(i)))
|
||||
end for
|
||||
?s
|
||||
?hint(hamming(1691))
|
||||
?hint(hamming(1000000))
|
||||
printf(1," %d\n",hint(hamming(1000000)))
|
||||
|
||||
include builtins\bigatom.e
|
||||
|
||||
function ba_hint(sequence hm)
|
||||
-- (as accurate as you like)
|
||||
sequence p = hm[POWS]
|
||||
return ba_multiply(ba_power(2,p[POW2]),ba_multiply(ba_power(3,p[POW3]),ba_power(5,p[POW5])))
|
||||
end function
|
||||
|
||||
?ba_sprintf("%B",ba_hint(hamming(1000000)))
|
||||
29
Task/Hamming-numbers/PureBasic/hamming-numbers.purebasic
Normal file
29
Task/Hamming-numbers/PureBasic/hamming-numbers.purebasic
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#X2 = 2
|
||||
#X3 = 3
|
||||
#X5 = 5
|
||||
|
||||
Macro Ham(w)
|
||||
PrintN("H("+Str(w)+") = "+Str(Hamming(w)))
|
||||
EndMacro
|
||||
|
||||
Procedure.i Hamming(l.i)
|
||||
Define.i i,j,k,n,m,x=#X2,y=#X3,z=#X5
|
||||
Dim h.i(l) : h(0)=1
|
||||
For n=1 To l-1
|
||||
m=x
|
||||
If m>y : m=y : EndIf
|
||||
If m>z : m=z : EndIf
|
||||
h(n)=m
|
||||
If m=x : i+1 : x=#X2*h(i) : EndIf
|
||||
If m=y : j+1 : y=#X3*h(j) : EndIf
|
||||
If m=z : k+1 : z=#X5*h(k) : EndIf
|
||||
Next
|
||||
ProcedureReturn h(l-1)
|
||||
EndProcedure
|
||||
|
||||
OpenConsole("Hamming numbers")
|
||||
For h.i=1 To 20
|
||||
Ham(h)
|
||||
Next
|
||||
Ham(1691)
|
||||
Input()
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
start = Time.now
|
||||
|
||||
idx = 1
|
||||
hamming.each do |ham|
|
||||
case idx
|
||||
when (1..20), 1691
|
||||
p [idx, ham]
|
||||
when 1_000_000
|
||||
p [idx, ham]
|
||||
break
|
||||
end
|
||||
idx += 1
|
||||
end
|
||||
|
||||
puts "elapsed: #{Time.now - start} seconds"
|
||||
|
|
@ -1,21 +1,21 @@
|
|||
func ham_gen {
|
||||
var s = [[1], [1], [1]];
|
||||
var m = [2, 3, 5];
|
||||
|
||||
var s = [[1], [1], [1]]
|
||||
var m = [2, 3, 5]
|
||||
|
||||
func {
|
||||
var n = [s[0][0], s[1][0], s[2][0]].min;
|
||||
for i in (0..2) {
|
||||
s[i].shift if (s[i][0] == n);
|
||||
s[i].append(n * m[i]);
|
||||
}
|
||||
var n = [s[0][0], s[1][0], s[2][0]].min
|
||||
{ |i|
|
||||
s[i].shift if (s[i][0] == n)
|
||||
s[i].append(n * m[i])
|
||||
} << ^3
|
||||
return n
|
||||
}
|
||||
}
|
||||
|
||||
var h = ham_gen();
|
||||
var h = ham_gen()
|
||||
|
||||
var i = 20;
|
||||
say i.of { h() }.join(' ');
|
||||
say i.of { h() }.join(' ')
|
||||
|
||||
range(i+1, 1691-1).each { h() }
|
||||
say h();
|
||||
{ h() } << (i+1 ..^ 1691)
|
||||
say h()
|
||||
|
|
|
|||
19
Task/Hamming-numbers/Zkl/hamming-numbers-1.zkl
Normal file
19
Task/Hamming-numbers/Zkl/hamming-numbers-1.zkl
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
var BN=Import("zklBigNum"); // only needed for large N
|
||||
fcn hamming(N){
|
||||
h:=List.createLong(N+1); (0).pump(N+1,h.write,Void); // fill list with stuff
|
||||
h[0]=1;
|
||||
#if 1 // regular (64 bit) ints
|
||||
x2:=2; x3:=3; x5:=5; i:=j:=k:=0;
|
||||
#else // big ints
|
||||
x2:=BN(2); x3:=BN(3); x5:=BN(5); i:=j:=k:=0;
|
||||
#endif
|
||||
foreach n in ([1..N]){
|
||||
z:=(x2<x3) and x2 or x3; z=(z<x5) and z or x5; h[n]=z;
|
||||
if (h[n] == x2) { x2 = h[i+=1]*2 }
|
||||
if (h[n] == x3) { x3 = h[j+=1]*3 }
|
||||
if (h[n] == x5) { x5 = h[k+=1]*5 }
|
||||
}
|
||||
return(h[N-1])
|
||||
}
|
||||
[1..20].apply(hamming).println();
|
||||
hamming(1691).println();
|
||||
43
Task/Hamming-numbers/Zkl/hamming-numbers-2.zkl
Normal file
43
Task/Hamming-numbers/Zkl/hamming-numbers-2.zkl
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#-- directly find n-th Hamming number, in ~ O(n^{2/3}) time
|
||||
#-- by Will Ness, based on "top band" idea by Louis Klauder, from DDJ discussion
|
||||
#-- http://drdobbs.com/blogs/architecture-and-design/228700538
|
||||
|
||||
var BN=Import("zklBigNum");
|
||||
var lg3 = (3.0).log()/(2.0).log(), lg5 = (5.0).log()/(2.0).log();
|
||||
fcn logval(i,j,k){ lg5*k + lg3*j + i }
|
||||
fcn trival(i,j,k){ BN(2).pow(i) * BN(3).pow(j) * BN(5).pow(k) }
|
||||
fcn estval(n){ (6.0*lg3*lg5*n).pow(1.0/3) } #-- estimated logval, base 2
|
||||
fcn rngval(n){
|
||||
if(n > 500000) return(2.4496 , 0.0076); #-- empirical estimation
|
||||
if(n > 50000) return(2.4424 , 0.0146); #-- correction, base 2
|
||||
if(n > 500) return(2.3948 , 0.0723); #-- (dist,width)
|
||||
if(n > 1) return(2.2506 , 0.2887); #-- around (log $ sqrt 30),
|
||||
return(2.2506 , 0.5771); #-- says WP
|
||||
}
|
||||
|
||||
fcn nthHam(n){ // -> (Double, (Int, Int, Int)) #-- n: 1-based: 1,2,3...
|
||||
d,w := rngval(n); #-- correction dist, width
|
||||
hi := estval(n.toFloat()) - d; #-- hi > logval > hi-w
|
||||
c,b := band(hi,w); #-- total count, the band
|
||||
s := b.sort(fcn(a,b){ a[0]>b[0] }); #-- sorted decreasing, result
|
||||
m := c - n; #-- m 0-based from top
|
||||
nb := b.len(); #-- |band|
|
||||
res := s[m]; #-- result
|
||||
|
||||
if(w >= 1) throw(Exception.Generic("Breach of contract: (w < 1): " + w));
|
||||
if(m < 0) throw(Exception.Generic("Not enough triples generated: " +c+n));
|
||||
if(m >= nb)throw(Exception.Generic("Generated band is too narrow: " +m+nb));
|
||||
return(res);
|
||||
}
|
||||
|
||||
fcn band(hi,w){ //--> #-- total count, the band
|
||||
b := Sink(List); cnt := 0;
|
||||
foreach k in ([0 .. (hi/lg5).floor()]){ p := lg5*k;
|
||||
foreach j in ([0 .. ((hi-p)/lg3).floor()]){ q := lg3*j + p;
|
||||
i,frac := (hi-q).modf(); r := hi-frac; #-- r = i + q
|
||||
cnt+=(i+1); #-- total count
|
||||
if(frac<w) b.write(T(r,T(i,j,k))); #-- store it, if inside band
|
||||
}
|
||||
}
|
||||
return(cnt,b.close());
|
||||
}
|
||||
9
Task/Hamming-numbers/Zkl/hamming-numbers-3.zkl
Normal file
9
Task/Hamming-numbers/Zkl/hamming-numbers-3.zkl
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
fcn printHam(n){
|
||||
r,t:=nthHam(n); i,j,k:=t; h:=trival(i,j,k);
|
||||
println("Hamming(%,d)-->2^%d * 3^%d * 5^%d-->\n%s".fmt(n,i,j,k,h));
|
||||
}
|
||||
|
||||
printHam(1691); //(5,12,3), 10 digits
|
||||
printHam(0d1_000_000); //(55,47,64), 84 digits
|
||||
printHam(0d10_000_000); //(80,92,162), 182 digits, 80 zeros at end
|
||||
printHam(0d1_000_000_000); //(1334,335,404), 845 digits
|
||||
Loading…
Add table
Add a link
Reference in a new issue