Executable library: Difference between revisions
m
→{{header|Wren}}: Minor tidy
m (inserted omition for Haskell) |
m (→{{header|Wren}}: Minor tidy) |
||
(7 intermediate revisions by 4 users not shown) | |||
Line 42:
To overcome the first obstacle, we implement a very simplistic parameter passing mechanism in a package Parameter (''parameter.ads''): The global variable Parameter.X will hold the ingoing parameter, the other global variable Parameter.Y will take the return value. To overcome the second obstacle, we ensure that Parameter.X is 0 by default.
<
X: Natural := 0;
Y: Natural;
end Parameter;</
Now comes our parameterless procedure Hailstone (''hailstone.adb''). Note that we are
Line 51:
[[Hailstone sequence#Alternative method]] to perform the real computation.
<
procedure Hailstone is
Line 99:
end;
end if;
end Hailstone;</
If we compile this and run it, we get the following output:
Line 109:
that essentially repeats the parameter profile. As our procedure is actually parameterless, this specification is more than trivial.
<syntaxhighlight lang
Finally, we write another parameterless procedure (''hailstone_test.adb''), that will call the procedure Hailstone. Note that we '''must''' change the Parameter.X to a value > 0 before calling Hailstone, otherwise, Hailstone would act as if it where the main program.
<
procedure Hailstone_Test is
Line 147:
Ada.Text_IO.Put_Line("The first such sequence: Hailstone("
& Integer'Image(Sample) & " ).");
end Hailstone_Test;</
Compiling and running this gives the following output:
Line 161:
{{works with|AutoHotkey_L}}
First we create the library, hailstone.ahk:
<
SetBatchLines, -1
Line 188:
until n=1
return out
}</
Running this directly gives the output:
<pre>Length of hailstone 27: 112
Line 197:
Then we can create a file (test.ahk) that uses the library (note the #Include line):
<
#Include %A_ScriptDir%\hailstone.ahk
SetBatchLines -1
Line 213:
if (count > highestCount)
highestCount := count, highestN := length
MsgBox % "the most common length was " highestN "; it occurred " highestCount " times."</
Running this '''does not''' trigger the output of the hailstone.ahk,
instead it outputs this:
Line 227:
This must be saved as the file HAILSTONE.BBC.
It may be used as a library (see below) or executed directly.
<
PRINT "Sequence length for 27 is "; seqlen%
maxlen% = 0
Line 247:
L% += 1
ENDWHILE
= L% + 1</
{{out}}
<pre>
Line 257:
===Client===
This uses the above program as a library:
<
DIM freq%(351)
Line 274:
PRINT "The most common sequence length is " ; mostcommon%
PRINT "It occurs " ; max% " times"
END</
{{out}}
<pre>
Line 283:
=={{header|C}}==
Solution for Linux/GCC. First, header file hailstone.h:
<
#define HAILSTONE
Line 289:
void free_sequence(long *);
#endif/*HAILSTONE*/</
Then the lib source code hailstone.c (actual name doesn't matter):
<
#include <stdlib.h>
Line 334:
exit(0);
}</
A program to use the lib (I call it test.c):
<
#include "hailstone.h"
Line 355:
return 0;
}</
Building the lib: <code>gcc -Wall -W -fPIC -shared -o libhail.so hailstone.c -lc -Wl,-e,hail_main</code>
Line 382:
</pre>
The file <code>hailstone_sequence.clj</code> is an executable library:
<
(defn next-in-hailstone
Line 409:
(range 100000)))]
(printf "The number %s has the longest Hailstone sequence under 100000, of length %s.\n"
number length))))</
You can run it from the command line (<code>clojure.jar</code> is [https://clojure.org/community/downloads the jar that contains the Clojure language]):
<pre>$ java -cp clojure.jar clojure.main -m rosetta-code.hailstone-sequence
Line 417:
</pre>
You can also use its functions from other programs. The file <code>frequent_hailstone_lengths.clj</code>:
<
(:require [rosetta-code.hailstone-sequence
:refer [hailstone-seq]]))
Line 429:
(printf (str "The most frequent Hailstone sequence length for numbers under 100000 is %s,"
" with a frequency of %s.\n")
most-frequent-length frequency)))</
You can run it from the command line:
<pre>$ java -cp clojure.jar clojure.main -m rosetta-code.frequent-hailstone-lengths
Line 438:
The library, named <code>hailstone.deja</code>:
<
swap [ over ]
while < 1 dup:
Line 473:
!print( "number: " to-str max ", length: " to-str maxlen )
else:
@hailstone</
The client:
<
local :counts {}
Line 488:
set :maxlen counts! k
!print( "Maximum length: " to-str maxlen )
</syntaxhighlight>
=={{header|Factor}}==
Line 495:
This vocabulary, ''rosetta.hailstone'', exports the word ''hailstone'', but also uses ''MAIN:'' to declare a main entry point.
<
USING: arrays io kernel math math.ranges prettyprint sequences vectors ;
IN: rosetta.hailstone
Line 525:
PRIVATE>
MAIN: main</
There are two ways to run this program:
Line 542:
Any other Factor program can also use ''rosetta.hailstone'' as a regular vocabulary. This program only uses the word ''hailstone'' from that vocabulary, and never calls the main entry point of ''rosetta.hailstone''.
<
USING: assocs kernel io math math.ranges prettyprint
rosetta.hailstone sequences ;
Line 568:
PRIVATE>
MAIN: main</
<pre>$ ./factor -run=rosetta.hailstone.length
Line 595:
To complete the task, first create these two files in the 'modulino' directory:
<
package main
Line 631:
}
fmt.Printf("\n%d has the longest Hailstone sequence, its length being %d.\n", longest, length)
}</
<
package main
func main() {
libMain()
}</
To emulate an executable library:
Line 655:
Now create this file in the 'hailstone' directory:
<
package main
Line 673:
}
fmt.Printf("\nThe Hailstone length returned most is %d, which occurs %d times.\n", mk, mv)
}</
and copy modulino.go to the 'hailstone' directory. The library can then be used in the 'normal' way:
Line 686:
'''HailStone.io'''
<
HailStone sequence := method(n,
if(n < 1, Exception raise("hailstone: expect n >= 1 not #{n}" interpolate))
Line 715:
writeln("For numbers < 100,000, ", maxN,
" has the longest sequence of ", maxSize, " elements.")
)</
'''client.io'''
<
for(n, 1, 100000-1,
out := HailStone sequence(n)
Line 736:
writeln("The most frequent sequence lengths for n < 100,000 are:\n",
lengths join(",")," occurring ",maxCount," times each.")
)</
'''Terminal Session'''
<pre>$ io HailStone.io
Line 756:
This is the executable library:
<syntaxhighlight lang="j">#!/usr/bin/ijconsole
hailseq=: -:`(1 3&p.)@.(2&|) ^:(1 ~: ]) ^:a:"0
9!:29]1
9!:27'main 0'
Line 766 ⟶ 767:
smoutput 'less than 100000 (and finding that sequence length):'
smoutput (I.@(= >./),>./) #@hailseq i.1e5
)</
Running it might look like this:
<
Hailstone sequence for the number 27
27 82 41 124 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 ...
Finding number with longest hailstone sequence which is
less than 100000 (and finding that sequence length):
77031 351</
This is the program which uses the library part of that executable library:
<
9!:29]1
9!:27'main 0'
Line 787 ⟶ 788:
smoutput {:{.\:~ (#/.~,.~.) #@hailseq }.i.1e5
)
</syntaxhighlight>
Running it might look like this:
<
Finding most frequent hailstone sequence length for
Hailstone sequences for whole numbers less than 100000
72</
Notes: <code>9!:29]1</code> tells the interpeter to run a phrase. <code>9!:27'phrase'</code> tells the interpeter the phrase to execute. (<code>9!:</code> means, in essence: standard library number 9, and <code>9!:29</code> identifies a specific entry point in that library.)
Line 804 ⟶ 805:
===Library===
<
import java.util.ArrayList;
import java.util.List;
Line 849 ⟶ 850:
}
</syntaxhighlight>
{{out}}
<pre>
Line 858 ⟶ 859:
===Client===
<
import java.util.HashMap;
import java.util.Map;
Line 879 ⟶ 880:
}
</syntaxhighlight>
{{out}}
<pre>
Line 887 ⟶ 888:
=={{header|Julia}}==
A Julia module can check to see if it is also the file run from the command lime by checking the PROGRAM_NAME variable.
<
############### in file hailstone.jl ###############
module Hailstone
Line 941 ⟶ 942:
print("The most common hailstone sequence length for hailstone(n) for 1 <= n < 100000 is $nlen, which occurs $cnt times.")
</syntaxhighlight>
{{output}}<pre>
Running hailstone.jl standalone:
Line 959 ⟶ 960:
First, <code>execlib.b</code> looks like this:
<
include "sys.m"; sys: Sys;
Line 1,012 ⟶ 1,013:
return i :: hailstone(big 3 * i + big 1);
}
</syntaxhighlight>
And <code>execsexeclib.b</code> (which executes <code>execlib</code>) looks like this:
<
include "sys.m"; sys: Sys;
Line 1,061 ⟶ 1,062:
raise "fail:errors";
}
</syntaxhighlight>
{{out}}
Line 1,076 ⟶ 1,077:
=={{header|Lua}}==
The library is called hailstone.lua:
<
bit32=bit32 or bit
local lib={
Line 1,100 ⟶ 1,101:
return lib
end
</syntaxhighlight>
The executable is called hailtest.lua:
<
local lib=require"hailstone"
local longest,longest_i=0,0
Line 1,115 ⟶ 1,116:
end
print("Longest sequence at "..longest_i..", length "..longest)
</syntaxhighlight>
{{out}}
Line 1,127 ⟶ 1,128:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
===Library===
<
hailstone[n_] :=
hailstone[n] = Prepend[hailstone[If[EvenQ[n], n/2, 3 n + 1]], n];
Line 1,136 ⟶ 1,137:
val = MaximalBy[Range[99999], Length@*hailstone][[1]];
Print[val, " has the longest hailstone sequence with length ",
Length[hailstone[val]], "."]];</
{{out}}
<pre>hailstone(27) starts with {27, 82, 41, 124}, ends with {8, 4, 2, 1}, and has length 112.
Line 1,142 ⟶ 1,143:
===Client===
This assumes that the library is named <tt>hailstone.m</tt>.
<
Print["The most common hailstone length is ",
Commonest[Length@*hailstone /@ Range[99999]][[1]], "."];</
{{out}}
<pre>The most common hailstone length is 72.</pre>
Line 1,150 ⟶ 1,151:
=={{header|Nanoquery}}==
The global boolean value 'main' is true is the program is being executed directly and false if it is being imported as a library.
<
seq = list()
Line 1,183 ⟶ 1,184:
print "\nThe number less than 100,000 with the longest sequence is "
println maxLoc + " with a length of " + max
end</
=={{header|NetRexx}}==
Line 1,207 ⟶ 1,208:
Using this JAR file as a library, the following program can use the <tt>hailstone(N)</tt> method to complete the task:
<
options replace format comments java crossref symbols nobinary
Line 1,242 ⟶ 1,243:
say 'The length of hailstone sequence that is most common in the range' beginNum '<= N <' endNum 'is' mostOftenNum'. It occurs' mostOftenCount 'times.'
return
</syntaxhighlight>
The program can then be launched with the <tt>java</tt> command. In this sample the JAR file is included via the <tt>-cp</tt> switch:
Line 1,250 ⟶ 1,251:
=={{header|Nim}}==
<
result = @[n]
var n = n
Line 1,269 ⟶ 1,270:
m = n
mi = i
echo "Maximum length ", m, " was found for hailstone(", mi, ") for numbers <100,000"</
In Nim the value <code>isMainModule</code> is set at compiletime, and we can use it with <code>when</code> (a compiletime if).
'''Library Importing Example'''
<
var t = initCountTable[int]()
Line 1,283 ⟶ 1,284:
let (val, cnt) = t.largest()
echo "The length of hailstone sequence that is most common for"
echo "hailstone(n) where 1<=n<100000, is ", val, ". It occurs ", cnt, " times."</
{{out}}
Line 1,293 ⟶ 1,294:
Library file hailstone.c:
<
#define HAILSTONE1 "n=1;print1(%d,\": \");apply(x->while(x!=1,if(x/2==x\\2,x/=2,x=x*3+1);n++;print1(x,\", \")),%d);print(\"(\",n,\")\n\")"
Line 1,336 ⟶ 1,337:
exit(0);
}</
Compile hailstone.c: ''gcc -O2 -Wall hailstone.c -fPIC -shared -o libhailstone.so -lpari -Wl,-e,main''
Line 1,345 ⟶ 1,346:
----
Main program linking libhailstone.so... main.c:
<
int main(void)
Line 1,352 ⟶ 1,353:
return 0;
}</
Compile main.c: ''gcc -O2 -Wall main.c -o main -L. libhailstone.so''
Execute main program: ''LD_LIBRARY_PATH=. ./main'' :
<pre>27: 82, 41, 124, 62, 31, 94, 47, 142, 71, 214, 107, 322, 161, 484, 242, 121, 364, 182, 91, 274, 137, 412, 206, 103, 310, 155, 466, 233, 700, 350, 175, 526, 263, 790, 395, 1186, 593, 1780, 890, 445, 1336, 668, 334, 167, 502, 251, 754, 377, 1132, 566, 283, 850, 425, 1276, 638, 319, 958, 479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288, 3644, 1822, 911, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308, 1154, 577, 1732, 866, 433, 1300, 650, 325, 976, 488, 244, 122, 61, 184, 92, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1, (112)</pre>
=={{header|Pascal}}==
{{works with|FPC}}
Library:
<syntaxhighlight lang="pascal">
uses
DynLibs;
type
THailSeq = record
Data: PCardinal;
Count: Longint;
end;
var
Buffer: array[0..511] of Cardinal;
function Hailstone(aValue: Cardinal): THailSeq;
var
I: Longint;
begin
Hailstone.Count := 0;
Hailstone.Data := nil;
if (aValue <> 0) and (aValue <= 200000) then begin
Buffer[0] := aValue;
I := 1;
repeat
if Odd(aValue) then
aValue := Succ((3 * aValue))
else
aValue := aValue div 2;
Buffer[I] := aValue;
Inc(I);
until aValue = 1;
Hailstone.Count := I;
Hailstone.Data := @Buffer;
end;
end;
procedure PrintArray(const Prefix: string; const a: array of Cardinal);
var
I: Longint;
begin
Write(Prefix, '[');
for I := 0 to High(a) - 1 do Write(a[I], ', ');
WriteLn(a[High(a)], ']');
end;
exports
Hailstone;
var
hs: THailSeq;
I, Value: Cardinal;
MaxLen: Longint;
begin
hs := Hailstone(27);
WriteLn('Length of Hailstone(27) is ', hs.Count, ',');
PrintArray('it starts with ', hs.Data[0..3]);
PrintArray('and ends with ', hs.Data[hs.Count-4..hs.Count-1]);
Value := 0;
MaxLen := 0;
for I := 1 to 100000 do begin
hs := Hailstone(I);
if hs.Count > MaxLen then begin
MaxLen := hs.Count;
Value := I;
end;
end;
WriteLn('Maximum length ', MaxLen, ' was found for Hailstone(', Value, ')');
end.
</syntaxhighlight>
build
<syntaxhighlight lang="shell">
Linux64: fpc <source file name> -Cg -k-pie -oexec_lib
Win64: fpc <source file name> -Cg -oexec_lib.exe
</syntaxhighlight>
when run as executable:
{{out}}
<pre>
Length of Hailstone(27) is 112,
it starts with [27, 82, 41, 124]
and ends with [8, 4, 2, 1]
Maximum length 351 was found for Hailstone(77031)
</pre>
Client:
<syntaxhighlight lang="pascal">
{$h+}
uses
SysUtils, DynLibs;
const
LIB_NAME = {$ifdef windows}'exec_lib.exe'{$else}'exec_lib'{$endif};
type
THailSeq = record
Data: PCardinal;
Count: Longint;
end;
THailstone = function(aValue: Cardinal): THailSeq;
TCounts = array[0..511] of Longint;
var
LibName: string;
hLib: TLibHandle;
Fun: THailstone;
I, Len, Count, c: Longint;
Counts: TCounts;
begin
LibName := ExtractFilePath(ParamStr(0))+LIB_NAME;
hLib := LoadLibrary(LibName);
if hLib = NilHandle then begin
WriteLn('Can not load library ', LibName); Halt(1);
end;
Pointer(Fun) := GetProcAddress(hLib, 'Hailstone');
if Pointer(Fun) = nil then begin
WriteLn('Can not find Hailstone() function'); Halt(2);
end;
Counts := Default(TCounts);
Count := 0;
Len := 0;
for I := 1 to 100000 do begin
c := Fun(I).Count;
Inc(Counts[c]);
if Counts[c] > Count then begin
Count := Counts[c];
Len := c;
end;
end;
UnloadLibrary(hLib);
WriteLn('The most common Hailstone sequence length in the specified range is ',
Len, ', it occurs ', Count, ' times.');
end.
</syntaxhighlight>
Both executables must be placed in the same folder.
{{out}}
<pre>
The most common Hailstone sequence length in the specified range is 72, it occurs 1467 times.
</pre>
=={{header|Perl}}==
Lib package in file <code>Hailstone.pm</code>:
<
sub seq {
Line 1,385 ⟶ 1,519:
}
1;</
Main program in file <code>test.pl</code>:<
use strict;
use warnings;
Line 1,396 ⟶ 1,530:
my ($most_frequent) = sort {$seqs{$b} <=> $seqs{$a}} keys %seqs;
print "Most frequent length: $most_frequent ($seqs{$most_frequent} occurrences)\n";</
Running the lib: <pre>% perl Hailstone.pm
seq of 27 - 112 elements: 27 82 41 124 62 31 94 47 142 ... 10 5 16 8 4 2 1
Line 1,405 ⟶ 1,539:
=={{header|Phix}}==
Simply test whether include_file() returns 1. hail.exw:
<
function hailstone(atom n)
sequence s = {n}
Line 1,451 ⟶ 1,585:
printf(1,"The longest hailstone sequence under 100,000 is %d with %d elements.\n",{imax,hmax})
end if</
{{out}}
<pre>
Line 1,460 ⟶ 1,594:
</pre>
test.exw:
<
sequence counts = {}
Line 1,470 ⟶ 1,604:
counts[l] += 1
end for
printf(1,"The hailstone length returned most often between 1 and 100,000 is %d.\n",{largest(counts,1)})</
{{out}}
<pre>
Line 1,482 ⟶ 1,616:
by prefixing it with '-'.
Create an executable file (chmod +x) "hailstone.l":
<
(de hailstone (N)
Line 1,501 ⟶ 1,635:
(test 351 (length (hailstone N))) )
(println 'OK)
(bye) )</
and an executable file (chmod +x) "test.l":
<
(load "hailstone.l")
Line 1,513 ⟶ 1,647:
(prinl "The hailstone length returned most often is " (car M))
(prinl "It is returned " (cdr M) " times") ) )
(bye)</
Test:
<pre>$ ./hailstone.l -hailtest
Line 1,532 ⟶ 1,666:
both can be used as an executable.
<
int next(int n)
Line 1,570 ⟶ 1,704:
}
write("longest sequence starting at %d has %d elements\n", longest->start, longest->length);
}</
if run directly we get:
Line 1,580 ⟶ 1,714:
note that the . in .HailStone only signifies calling a class or module from the current directory.
the analyze function is identical in both examples:
<
{
.HailStone HailStone = .HailStone();
Line 1,604 ⟶ 1,738:
}
write("most common length %d appears %d times\n", max->length, max->count);
}</
a module is already instantiated so we can use it directly.
like above the initial . in .Hailstone.hailstone only signifies the current directory, the second . is a member reference resolved at compile time.
<
{
mapping long = ([]);
Line 1,630 ⟶ 1,764:
}
write("most common length %d appears %d times\n", max->length, max->count);
}</
{{out}} for both examples:
Line 1,641 ⟶ 1,775:
The entry is copied below and, for this task needs to be in a file called <code>hailstone.py</code>:
<
seq = [n]
while n>1:
Line 1,652 ⟶ 1,786:
assert len(h)==112 and h[:4]==[27, 82, 41, 124] and h[-4:]==[8, 4, 2, 1]
print("Maximum length %i was found for hailstone(%i) for numbers <100,000" %
max((len(hailstone(i)), i) for i in range(1,100000)))</
In the case of the Python language the interpreter maintains a module level variable called __name__. If the file hailstone.py is ''imported'' (as <code>import hailstone</code>), then the __name__ variable is set to the import name of 'hailstone' and the <code>if __name__ == '__main__'</code> expression would then be false, and only the hailstone function is available to the importer.
Line 1,661 ⟶ 1,795:
The second executable is the file <code>common_hailstone_length.py</code> with this content:
<
def function_length_frequency(func, hrange):
Line 1,673 ⟶ 1,807:
print("The length of hailstone sequence that is most common for\n"
"hailstone(n) where 1<=n<%i, is %i. It occurs %i times."
% (upto, hlen, freq))</
Both files could be in the same directory. (That is the easiest way to make the library known to its importer for this example)
Line 1,704 ⟶ 1,838:
function is now provided, and the demonstration printout is pushed into a
<tt>main</tt> submodule:
<syntaxhighlight lang="racket">
#lang racket
Line 1,726 ⟶ 1,860:
(printf "for x<=~s, ~s has the longest sequence with ~s items\n"
N (car longest) (cdr longest)))
</syntaxhighlight>
Running it directly produces the same output as [[Hailstone sequence#Racket]]:
Line 1,738 ⟶ 1,872:
And now this can be used from a second source file, "<tt>hsfreq.rkt</tt>" as a
library:
<syntaxhighlight lang="racket">
#lang racket
(require "hs.rkt")
Line 1,751 ⟶ 1,885:
(printf "Most frequent sequence length for x<=~s: ~s, appearing ~s times\n" N
(cdr best) (car best))
</syntaxhighlight>
<pre>
Line 1,761 ⟶ 1,895:
(formerly Perl 6)
The library can be written as a module:
<syntaxhighlight lang="raku"
our sub hailstone($n) is export {
$n, { $_ %% 2 ?? $_ div 2 !! $_ * 3 + 1 } ... 1
Line 1,769 ⟶ 1,903:
sub MAIN {
say "hailstone(27) = {.[^4]} [...] {.[*-4 .. *-1]}" given Hailstone::hailstone 27;
}</
It can be run with:
<syntaxhighlight lang
{{out}}
<pre>hailstone(27) = 27 82 41 124 [...] 8 4 2 1</pre>
It can then be used with a program such as:
<syntaxhighlight lang="raku"
my %score;
(1 .. 100_000).race.map: { %score{hailstone($_).elems}++ };
say "Most common length is {.key}, occurring {.value} times." given max :by(*.value), %score;</
Called with a command line as:
Line 1,798 ⟶ 1,932:
<br>The following program (function) is named: '''HAILSTONE.REX''' (the case doesn't matter for Microsoft Windows systems).
<br>All REXX interpreters support subroutines/functions being on the current drive ('''CD'''), default disk (or MDISK in the case of CMS), or the equivalent.
<
numeric digits 20 /*ensure enough digits for mult. */
parse arg n 1 s /*N & S assigned to the first arg*/
Line 1,806 ⟶ 1,940:
s=s n /*build a sequence list (append).*/
end /*while*/
return s</
===task 2, 3===
The following program is named: : '''HAIL_PGM.REX''' and is stored in the current directory.
<
parse arg x .; if x=='' then x=27 /*get the optional first argument*/
Line 1,825 ⟶ 1,959:
say '(between 1──►99,999) ' bigJ 'has the longest hailstone sequence:' w
/*stick a fork in it, we're done.*/</
{{out}}
<pre>
Line 1,835 ⟶ 1,969:
===task 4===
The following program is named: '''HAIL_POP.REX''' and is stored in the current directory.
<
parse arg z .; if z=='' then z=99999 /*get the optional first argument*/
!.=0
Line 1,849 ⟶ 1,983:
say '(between 1──►'z") " p,
' is the most common hailstone sequence length (with' occ "occurrences)."
/*stick a fork in it, we're done.*/</
{{out}}
<pre>
Line 1,881 ⟶ 2,015:
{{works with|Ruby|1.8.7}}
<
module Hailstone
module_function
Line 1,906 ⟶ 2,040:
puts "#{n} has a hailstone sequence length of #{len}"
puts "the largest number in that sequence is #{hailstone(n).max}"
end</
{{out|It runs like any Ruby program}}
Line 1,916 ⟶ 2,050:
This is ''hsfreq.rb'', which requires ''hailstone.rb'' as a library.
<
require 'hailstone'
Line 1,926 ⟶ 2,060:
puts "Given the hailstone sequences from 1 to #{last},"
puts "the most common sequence length is #{length},"
puts "with #{count} such sequences."</
As with any library, ''hailstone.rb'' must be in <code>$:</code>, the search path for libraries.
Line 1,941 ⟶ 2,075:
In Scala it is possible to combine several "main"s
(mixed-in by the App trait) in one file (e.g. HailstoneSequence.scala):
<syntaxhighlight lang="scala">
object HailstoneSequence extends App { // Show it all, default number is 27.
def hailstone(n: Int): LazyList[Int] =
Line 1,968 ⟶ 2,102:
println(s"Longest hailstone sequence length= $len occurring with number $n.")
}
</syntaxhighlight>
Steps:
Line 2,000 ⟶ 2,134:
=={{header|Sidef}}==
Library saved as '''Hailstone.sm'''
<
gather {
while (n > 1) {
take(n)
n = (n.is_even ? (n/2) : (take(3*n + 1)/2))
}
take(1)
}
}
if (__FILE__ == __MAIN__) { # true when not imported
var seq = hailstone(27)
say "hailstone(27) - #{seq.len} elements: #{seq.
var n = 0
var max = 0
Line 2,023 ⟶ 2,157:
}
}
say "Longest sequence is for #{n}: #{max}"
}</
It can be run with:
<syntaxhighlight lang
It can then be used with a program such as:
<
var score = Hash()
Line 2,037 ⟶ 2,171:
var k = score.keys.max_by {|k| score{k} }
say "Most common length is #{k}, occurring #{score{k}} times"</
Called with a command line as:
<syntaxhighlight lang
The library is searched in the directories specified in the '''SIDEF_INC''' environment variable, which defaults to the current directory.
Line 2,046 ⟶ 2,180:
=={{header|Tcl}}==
The standard idiom for detecting whether a script is being loaded as a library or run directly is to compare the result of <code>info script</code> (which describes the name of the currently sourced script file) and the global <code>argv0</code> variable (which holds the name of the main script).
<
package provide hailstone 1.0
Line 2,070 ⟶ 2,204:
}
puts "max is $max, with length $maxlen"
}</
To make the package locatable, run this Tcl script
in the same directory which builds the index file:
<syntaxhighlight lang
Using the above code as a library then just requires that we tell the script the location of the additional library directory by adding it to the global <code>auto_path</code> variable; it is unnecessary if the script is installed in one of the standard locations (a fairly long list that depends on the installation):
<
package require Tcl 8.6 ;# For [lsort -stride] option
lappend auto_path . ;# Or wherever it is located
Line 2,092 ⟶ 2,226:
lassign $sortedHist mostCommonLength freq
puts "most common length is $mostCommonLength, with frequency $freq"</
=={{header|Wren}}==
Line 2,102 ⟶ 2,236:
The strategy here is check whether the main module is the same as the library module and to treat is as executable if it is but as a library otherwise.
<
var Hailstone = Fn.new { |n|
Line 2,138 ⟶ 2,272:
// Check if it's being used as a library or not.
import "os" for Process
if (Process.allArguments[1] == "
libMain_.call()
}</
{{out}}
If we run this directly, we get the expected output:
<pre>
$ wren
For the Hailstone sequence starting with n = 27:
Line 2,158 ⟶ 2,292:
If we now create a second module which imports the above and calls its Hailstone function:
<
import "./
var freq = {}
Line 2,177 ⟶ 2,311:
}
}
System.print("The Hailstone length returned most is %(mk), which occurs %(mv) times.")</
{{out}}
We can now run this to check that the executable code in hailstone.wren has been suppressed, giving us:
<pre>
$ wren
The Hailstone length returned most is 72, which occurs 1467 times.
Line 2,191 ⟶ 2,325:
File hailstone.zkl:
<
if(n.isEven) return(self.fcn(n/2,z)); return(self.fcn(n*3+1,z)) }
Line 2,202 ⟶ 2,336:
fcn(c,n){ // if new longest sequence, save length/C, return longest
if(c.len()>n[0]) n.clear(c.len(),c[0]); n}.fp1(L(0,0)))
.println();</
File hailstone2.zkl:
<
collatz:=Import("hailstone",False,False,False).collatz; // don't run constructor
d:=Dictionary();
Line 2,215 ⟶ 2,349:
mostFreqLen:=d.filter1('wrap([(k,v)]){ v==longest })[0];
println("Most frequent length: %d; %d sequences of that length."
.fmt(mostFreqLen,longest));</
{{out}}
<pre>
|