This commit is contained in:
Ingy döt Net 2013-10-27 22:24:23 +00:00
parent 6f050a029e
commit 776bba907c
3887 changed files with 59894 additions and 7280 deletions

View file

@ -1,6 +1,6 @@
import std.stdio, std.algorithm, std.range, std.typecons;
auto hailstone(int n) pure nothrow {
auto hailstone(uint n) pure nothrow {
auto result = [n];
while (n != 1) {
n = n & 1 ? n*3 + 1 : n/2;
@ -11,12 +11,13 @@ auto hailstone(int n) pure nothrow {
void main() {
enum M = 27;
auto h = hailstone(M);
writeln("hailstone(", M, ")= ", h[0 .. 4], " ... " , h[$-4 .. $]);
writeln("length hailstone(", M, ")= ", h.length);
immutable h = M.hailstone;
writeln("hailstone(", M, ")= ", h[0 .. 4], " ... " , h[$ - 4 .. $]);
writeln("Length hailstone(", M, ")= ", h.length);
enum N = 100_000;
auto s = iota(1, N).map!(i => tuple(hailstone(i).length, i))();
auto p = reduce!max(s);
immutable p = iota(1, N)
.map!(i => tuple(i.hailstone.length, i))
.reduce!max;
writeln("Longest sequence in [1,", N, "]= ",p[1]," with len ",p[0]);
}

View file

@ -1,20 +1,23 @@
import std.stdio, std.algorithm, std.range, std.typecons;
struct Hail {
int n;
bool empty() { return n == 0; }
int front() { return n; }
void popFront() { n = n == 1 ? 0 : (n & 1 ? n*3 + 1 : n/2); }
struct Hailstone {
uint n;
bool empty() const pure nothrow { return n == 0; }
uint front() const pure nothrow { return n; }
void popFront() pure nothrow {
n = n == 1 ? 0 : (n & 1 ? n*3 + 1 : n/2);
}
}
void main() {
enum M = 27;
auto h = array(Hail(M));
writeln("hailstone(", M, ")= ", h[0 .. 4], " ... " , h[$-4 .. $]);
writeln("length hailstone(", M, ")= ", h.length);
immutable h = M.Hailstone.array;
writeln("hailstone(", M, ")= ", h[0 .. 4], " ... " , h[$ - 4 .. $]);
writeln("Length hailstone(", M, ")= ", h.length);
enum N = 100_000;
auto s = map!(i => tuple(walkLength(Hail(i)), i))(iota(1, N));
auto p = reduce!max(s);
immutable p = iota(1, N)
.map!(i => tuple(i.Hailstone.walkLength, i))
.reduce!max;
writeln("Longest sequence in [1,", N, "]= ",p[1]," with len ",p[0]);
}

View file

@ -0,0 +1,33 @@
import std.stdio, std.algorithm, std.range, std.typecons;
struct Hailstone(size_t cacheSize = 500_000) {
size_t n;
__gshared static size_t[cacheSize] cache;
bool empty() const pure nothrow { return n == 0; }
size_t front() const pure nothrow { return n; }
void popFront() nothrow {
if (n >= cacheSize) {
n = n == 1 ? 0 : (n & 1 ? n*3 + 1 : n/2);
} else if (cache[n]) {
n = cache[n];
} else {
immutable n2 = n == 1 ? 0 : (n & 1 ? n*3 + 1 : n/2);
n = cache[n] = n2;
}
}
}
void main() {
enum M = 27;
const h = M.Hailstone!().array;
writeln("hailstone(", M, ")= ", h[0 .. 4], " ... " , h[$ - 4 .. $]);
writeln("Length hailstone(", M, ")= ", h.length);
enum N = 100_000;
immutable p = iota(1, N)
.map!(i => tuple(i.Hailstone!().walkLength, i))
.reduce!max;
writeln("Longest sequence in [1,", N, "]= ",p[1]," with len ",p[0]);
}

View file

@ -0,0 +1,34 @@
hailstone:
swap [ over ]
while < 1 dup:
if % over 2:
#odd
++ * 3
else:
#even
/ swap 2
swap push-through rot dup
drop
local :h27 hailstone 27
. = 112 len h27
. = 27 h27! 0
. = 82 h27! 1
. = 41 h27! 2
. = 124 h27! 3
. = 8 h27! 108
. = 4 h27! 109
. = 2 h27! 110
. = 1 h27! 111
local :max 0
local :maxlen 0
for i range 1 99999:
dup len hailstone i
if < maxlen:
set :maxlen
set :max i
else:
drop
print( "number: " max ", length: " maxlen )

View file

@ -0,0 +1,22 @@
defmodule Hailstone do
def step(1), do: 0
def step(n) when Integer.even?(n), do: div(n,2)
def step(n) when Integer.odd?(n), do: n*3 + 1
def sequence(n) do
Enum.to_list(Stream.take_while(Stream.iterate(n, &step/1), &(&1 > 0)))
end
def run do
seq27 = Hailstone.sequence(27)
len27 = length(seq27)
repr = String.replace(inspect(seq27, limit: 4), "]",
String.replace(inspect(Enum.drop(seq27,len27-4)), "[", ", "))
IO.puts("Hailstone(27) has #{len27} elements: #{repr}")
{start, len} = Enum.max_by( Enum.map(1..100_000, fn(n) -> {n, length(Hailstone.sequence(n))} end),
fn({_,len}) -> len end )
IO.puts("Longest sequence starting under 100000 begins with #{start} and has #{len} elements.")
end
end
Hailstone.run

View file

@ -0,0 +1,12 @@
hailstone := proc( N )
local n := N, HS := Array([n]);
while n > 1 do
if type(n,even) then
n := n/2;
else
n := 3*n+1;
end if;
HS(numelems(HS)+1) := n;
end do;
HS;
end proc;

View file

@ -0,0 +1,7 @@
> r := hailstone(27):
[ 1..112 1-D Array ]
r := [ Data Type: anything ]
[ Storage: rectangular ]
[ Order: Fortran_order ]
> r(1..4) ... r(-4..);
[27, 82, 41, 124] .. [8, 4, 2, 1]

View file

@ -0,0 +1,9 @@
longest := 0; n := 0;
for i from 1 to 100000 do
len := numelems(hailstone(i));
if len > longest then
longest := len;
n := i;
end if;
od:
printf("The longest Hailstone sequence in the first 100k is n=%d, with %d terms\n",n,longest);

View file

@ -0,0 +1,27 @@
/*REXX pgm tests a number and a range for hailstone (Collatz) sequences.*/
parse arg x y . /*get optional arguments from CL.*/
if x=='' | x==',' then x=27 /*Any 1st argument? Use default.*/
if y=='' | y==',' then y=100000-1 /*Any 2nd argument? Use default.*/
numeric digits 20; @.=0 /*handle big #s; initialize array*/
$=hailstone(x) /*═══════════════════task 1═════════════════════════*/
say x ' has a hailstone sequence of ' words($)
say ' and starts with: ' subword($, 1, 4) " ∙∙∙"
say ' and ends with: ' subword($, max(1, words($)-3))
say
if y==0 then exit /*═══════════════════task 2═════════════════════════*/
w=0; do j=1 for y /*traipse through the numbers. */
call hailstone j /*compute the hailstone sequence.*/
if #hs<=w then iterate /*Not big 'nuff? Then keep going.*/
bigJ=j; w=#hs /*remember what # has biggest HS.*/
end /*j*/
say '(between 1'y") " bigJ ' has the longest hailstone sequence:' w
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────HAILSTONE subroutine────────────────*/
hailstone: procedure expose #hs; parse arg n 1 s /*N & S set to 1st arg*/
do #hs=1 while n\==1 /*loop while N isn't unity. */
if n//2 then n=n*3+1 /*if N is odd, calc: 3*n +1 */
else n=n%2 /* " " " even, perform fast ÷ */
s=s n /*build a sequence list (append).*/
end /*#hs*/
return s

View file

@ -0,0 +1,31 @@
/*REXX pgm tests a number and a range for hailstone (Collatz) sequences.*/
parse arg x y . /*get optional arguments from CL.*/
if x=='' | x==',' then x=27 /*Any 1st argument? Use default.*/
if y=='' | y==',' then y=99999 /*Any 2nd argument? Use default.*/
numeric digits 20; @.=0 /*handle big #s; initialize array*/
$=hailstone(x) /*═══════════════════task 1═════════════════════════*/
say x ' has a hailstone sequence of ' words($)
say ' and starts with: ' subword($, 1, 4) " ∙∙∙"
say ' and ends with: ' subword($, max(1, words($)-3))
say
if y==0 then exit /*═══════════════════task 2═════════════════════════*/
w=0; do j=1 for y /*loop through all numbers <100k.*/
$=hailstone(j) /*compute the hailstone sequence.*/
#hs=words($) /*find the length of the sequence*/
if #hs<=w then iterate /*Not big 'nuff? Then keep going.*/
bigJ=j; w=#hs /*remember what # has biggest HS.*/
end /*j*/
say '(between 1'y") " bigJ ' has the longest hailstone sequence:' w
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────HAILSTONE subroutine────────────────*/
hailstone: procedure expose @.; parse arg n 1 s 1 o /*N,S,O = 1st arg.*/
@.1= /*special case for unity. */
do forever /*loop while N isn't unity. */
if @.n\==0 then do; s=s @.n; leave; end /*been here before?*/
if n//2 then n=n*3+1 /*if N is odd, calc: 3*n +1 */
else n=n%2 /* " " " even, perform fast ÷ */
s=s n /*build a sequence list (append).*/
end /*forever*/
@.o=s /*memoization for this hailstone.*/
@.o=subword(s,2)
return s

View file

@ -1,11 +1,15 @@
object HailstoneSequence extends App {
def hailstone(n: Int): Stream[Int] =
n #:: {
if (n == 1) Stream.empty
else hailstone(if (n % 2 == 0) n / 2 else n * 3 + 1)
}
n #:: (if (n == 1) Stream.empty else hailstone(if (n % 2 == 0) n / 2 else n * 3 + 1))
def main(args: Array[String]) {
println(hailstone(27).toList)
val (n, len) = (1 to 100000).map(n => (n, hailstone(n).length)).maxBy(_._2)
println("value=" + n + " len=" + len)
}
val nr = args.headOption.map(_.toInt).getOrElse(27)
val collatz = hailstone(nr)
println(s"Use the routine to show that the hailstone sequence for the number: $nr.")
println(collatz.toList)
println(s"It has ${collatz.length} elements.")
println
println(
"Compute the number < 100,000, which has the longest hailstone sequence with that sequence's length.")
val (n, len) = (1 until 100000).map(n => (n, hailstone(n).length)).maxBy(_._2)
println(s"Longest hailstone sequence length= $len occurring with number $n.")
}