Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
5
Task/Generator-Exponential/00-META.yaml
Normal file
5
Task/Generator-Exponential/00-META.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
category:
|
||||
- Non parametric generators
|
||||
- Stateful transactions
|
||||
from: http://rosettacode.org/wiki/Generator/Exponential
|
||||
23
Task/Generator-Exponential/00-TASK.txt
Normal file
23
Task/Generator-Exponential/00-TASK.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
A generator is an executable entity (like a function or procedure) that contains code that yields a sequence of values, one at a time, so that each time you call the generator, the next value in the sequence is provided.
|
||||
|
||||
Generators are often built on top of coroutines or objects so that the internal state of the object is handled “naturally”.
|
||||
|
||||
Generators are often used in situations where a sequence is potentially infinite, and where it is possible to construct the next value of the sequence with only minimal state.
|
||||
|
||||
|
||||
;Task:
|
||||
* Create a function that returns a generation of the m'th powers of the positive integers starting from zero, in order, and without obvious or simple upper limit. (Any upper limit to the generator should not be stated in the source but should be down to factors such as the languages natural integer size limit or computational time/size).
|
||||
* Use it to create a generator of:
|
||||
:::* Squares.
|
||||
:::* Cubes.
|
||||
* Create a new generator that filters all cubes from the generator of squares.
|
||||
* Drop the first 20 values from this last generator of filtered results, and then show the next 10 values.
|
||||
|
||||
|
||||
Note that this task ''requires'' the use of generators in the calculation of the result.
|
||||
|
||||
|
||||
;Also see:
|
||||
* [[wp:Generator (computer_science)|Generator]]
|
||||
<br><br>
|
||||
|
||||
41
Task/Generator-Exponential/11l/generator-exponential.11l
Normal file
41
Task/Generator-Exponential/11l/generator-exponential.11l
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
T Generator
|
||||
F.virtual.abstract next() -> Float
|
||||
|
||||
T PowersGenerator(Generator)
|
||||
i = 0.0
|
||||
Float e
|
||||
|
||||
F (e)
|
||||
.e = e
|
||||
|
||||
F.virtual.assign next() -> Float
|
||||
V r = .i ^ .e
|
||||
.i++
|
||||
R r
|
||||
|
||||
T Filter
|
||||
Generator gen, filter
|
||||
Float lastG, lastF
|
||||
|
||||
F (Generator gen, filter)
|
||||
.gen = gen
|
||||
.filter = filter
|
||||
.lastG = .gen.next()
|
||||
.lastF = .filter.next()
|
||||
|
||||
F ()()
|
||||
L .lastG >= .lastF
|
||||
I .lastG == .lastF
|
||||
.lastG = .gen.next()
|
||||
.lastF = .filter.next()
|
||||
|
||||
V out = .lastG
|
||||
.lastG = .gen.next()
|
||||
R out
|
||||
|
||||
V gen = Filter(PowersGenerator(2), PowersGenerator(3))
|
||||
|
||||
L 20
|
||||
gen()
|
||||
L 10
|
||||
print(gen(), end' ‘ ’)
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
MODE YIELDVALUE = PROC(VALUE)VOID;
|
||||
MODE GENVALUE = PROC(YIELDVALUE)VOID;
|
||||
|
||||
PROC gen filtered = (GENVALUE gen candidate, gen exclude, YIELDVALUE yield)VOID: (
|
||||
VALUE candidate; SEMA have next exclude = LEVEL 0;
|
||||
VALUE exclude; SEMA get next exclude = LEVEL 0;
|
||||
BOOL initialise exclude := TRUE;
|
||||
|
||||
PAR ( # run each generator in a different thread #
|
||||
# Thread 1 #
|
||||
# FOR VALUE next exclude IN # gen exclude( # ) DO #
|
||||
## (VALUE next exclude)VOID: (
|
||||
DOWN get next exclude; exclude := next exclude;
|
||||
IF candidate <= exclude THEN
|
||||
UP have next exclude
|
||||
ELSE
|
||||
UP get next exclude
|
||||
FI
|
||||
# OD #)),
|
||||
# Thread 2 #
|
||||
# FOR VALUE next candidate IN # gen candidate( # ) DO #
|
||||
## (VALUE next candidate)VOID: (
|
||||
candidate := next candidate;
|
||||
IF initialise exclude ORF candidate > exclude THEN
|
||||
UP get next exclude;
|
||||
DOWN have next exclude; # wait for result #
|
||||
initialise exclude := FALSE
|
||||
FI;
|
||||
IF candidate < exclude THEN
|
||||
yield(candidate)
|
||||
FI
|
||||
# OD #))
|
||||
)
|
||||
);
|
||||
|
||||
PROC gen slice = (GENVALUE t, VALUE start, stop, YIELDVALUE yield)VOID: (
|
||||
INT index := 0;
|
||||
# FOR VALUE i IN # t( # ) DO #
|
||||
## (VALUE i)VOID: (
|
||||
IF index >= stop THEN done
|
||||
ELIF index >= start THEN yield(i) FI;
|
||||
index +:= 1
|
||||
# OD # ));
|
||||
done: SKIP
|
||||
);
|
||||
|
||||
PROC get list = (GENVALUE gen)[]VALUE: (
|
||||
INT upb := 0;
|
||||
INT ups := 2;
|
||||
FLEX [ups]VALUE out;
|
||||
# FOR VALUE i IN # gen( # ) DO #
|
||||
## (VALUE i)VOID:(
|
||||
upb +:= 1;
|
||||
IF upb > ups THEN # dynamically grow the array 50% #
|
||||
[ups +:= ups OVER 2]VALUE append; append[:upb-1] := out; out := append
|
||||
FI;
|
||||
out[upb] := i
|
||||
# OD # ))
|
||||
out[:upb]
|
||||
);
|
||||
|
||||
PROC powers = (VALUE m, YIELDVALUE yield)VOID:
|
||||
FOR n FROM 0 DO yield(n ** m) OD;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/local/bin/a68g --script #
|
||||
|
||||
MODE VALUE = INT;
|
||||
PR READ "Template.Generator.a68" PR
|
||||
|
||||
GENVALUE squares = powers(2,), cubes = powers(3,);
|
||||
GENVALUE fil = gen filtered(squares, cubes,);
|
||||
|
||||
printf(($g(0)x$, get list(gen slice(fil, 20, 30, )) ))
|
||||
183
Task/Generator-Exponential/ATS/generator-exponential.ats
Normal file
183
Task/Generator-Exponential/ATS/generator-exponential.ats
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
(* "Generators" *)
|
||||
|
||||
(* I implement "generators" as non-linear closures. *)
|
||||
|
||||
#include "share/atspre_staload.hats"
|
||||
|
||||
#define NIL list_nil ()
|
||||
#define :: list_cons
|
||||
|
||||
(* Integer powers where base and power are of any unsigned integer
|
||||
types. *)
|
||||
fn {tk_b, tk_p : tkind}
|
||||
g1uint_ipow
|
||||
(base : g1uint tk_b,
|
||||
power : g1uint tk_p)
|
||||
:<> g1uint tk_b =
|
||||
let
|
||||
fun
|
||||
loop {p : nat}
|
||||
.<p>.
|
||||
(b : g1uint tk_b,
|
||||
p : g1uint (tk_p, p),
|
||||
accum : g1uint tk_b)
|
||||
:<> g1uint tk_b =
|
||||
let
|
||||
val ph = half p
|
||||
val accum = (if ph + ph = p then accum else accum * b)
|
||||
in
|
||||
if ph = g1i2u 0 then
|
||||
accum
|
||||
else
|
||||
loop (b * b, ph, accum)
|
||||
end
|
||||
|
||||
prval () = lemma_g1uint_param base
|
||||
prval () = lemma_g1uint_param power
|
||||
in
|
||||
loop (base, power, g1i2u 1)
|
||||
end
|
||||
|
||||
overload ipow with g1uint_ipow of 100
|
||||
|
||||
(* Some unit tests of ipow. *)
|
||||
val- 0U = ipow (0U, 100U)
|
||||
val- 1U = ipow (0U, 0U) (* Sometimes a convenient result. *)
|
||||
val- 9UL = ipow (3UL, 2ULL)
|
||||
val- 81ULL = ipow (3ULL, 4U)
|
||||
|
||||
typedef generator (tk : tkind) =
|
||||
() -<cloref1> g1uint tk
|
||||
|
||||
typedef option_generator (tk : tkind) =
|
||||
() -<cloref1> Option (g1uint tk)
|
||||
|
||||
fn {tk_b : tkind}
|
||||
{tk_p : tkind}
|
||||
make_powers_generator
|
||||
(power : g1uint tk_p)
|
||||
:<!wrt> generator tk_b =
|
||||
let
|
||||
val base : ref (g1uint tk_b) = ref (g1i2u 0)
|
||||
in
|
||||
lam () =>
|
||||
let
|
||||
val b = !base
|
||||
val result = ipow (b, power)
|
||||
in
|
||||
!base := succ b;
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
fn {tk : tkind}
|
||||
make_generator_of_1_that_are_not_also_2
|
||||
(gen1 : generator tk,
|
||||
gen2 : generator tk)
|
||||
:<!wrt> generator tk =
|
||||
let
|
||||
val initialized : ref bool = ref false
|
||||
val x2 : ref (g1uint tk) = ref (g1i2u 0)
|
||||
|
||||
fn
|
||||
check (x1 : g1uint tk)
|
||||
:<1> bool =
|
||||
let
|
||||
fun
|
||||
loop ()
|
||||
:<1> bool =
|
||||
if x1 <= !x2 then
|
||||
(x1 <> !x2)
|
||||
else
|
||||
begin
|
||||
!x2 := gen2 ();
|
||||
loop ()
|
||||
end
|
||||
in
|
||||
loop ()
|
||||
end
|
||||
in
|
||||
lam () =>
|
||||
let
|
||||
var result : g1uint tk = g1i2u 0
|
||||
var found_one : bool = false
|
||||
in
|
||||
if ~(!initialized) then
|
||||
begin
|
||||
!x2 := gen2 ();
|
||||
!initialized := true
|
||||
end;
|
||||
while (~found_one)
|
||||
let
|
||||
val next1 = gen1 ()
|
||||
in
|
||||
if check next1 then
|
||||
begin
|
||||
result := next1;
|
||||
found_one := true
|
||||
end
|
||||
end;
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
fn {tk : tkind}
|
||||
make_dropper
|
||||
(n : size_t,
|
||||
gen : generator tk)
|
||||
:<!wrt> generator tk =
|
||||
let
|
||||
val counter : ref size_t = ref n
|
||||
in
|
||||
lam () =>
|
||||
begin
|
||||
while (isneqz (!counter))
|
||||
let
|
||||
val _ = gen ()
|
||||
in
|
||||
!counter := pred (!counter)
|
||||
end;
|
||||
gen ()
|
||||
end
|
||||
end
|
||||
|
||||
fn {tk : tkind}
|
||||
make_taker
|
||||
(n : size_t,
|
||||
gen : generator tk)
|
||||
:<!wrt> option_generator tk =
|
||||
let
|
||||
val counter : ref size_t = ref n
|
||||
in
|
||||
lam () =>
|
||||
if iseqz (!counter) then
|
||||
None ()
|
||||
else
|
||||
begin
|
||||
!counter := pred (!counter);
|
||||
Some (gen ())
|
||||
end
|
||||
end
|
||||
|
||||
implement
|
||||
main0 () =
|
||||
let
|
||||
stadef tk = uintknd
|
||||
macdef filter = make_generator_of_1_that_are_not_also_2<tk>
|
||||
|
||||
val squares_generator = make_powers_generator<tk> 2U
|
||||
val cubes_generator = make_powers_generator<tk> 3U
|
||||
val gen = filter (squares_generator, cubes_generator)
|
||||
val gen = make_dropper<tk> (i2sz 20, gen)
|
||||
val gen = make_taker<tk> (i2sz 10, gen)
|
||||
|
||||
var done : bool = false
|
||||
in
|
||||
while (~done)
|
||||
begin
|
||||
case+ gen () of
|
||||
| None () => done := true
|
||||
| Some x => print! (" ", x)
|
||||
end;
|
||||
println! ()
|
||||
end
|
||||
23
Task/Generator-Exponential/Ada/generator-exponential-1.ada
Normal file
23
Task/Generator-Exponential/Ada/generator-exponential-1.ada
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
package Generator is
|
||||
|
||||
type Generator is tagged private;
|
||||
procedure Reset (Gen : in out Generator);
|
||||
function Get_Next (Gen : access Generator) return Natural;
|
||||
|
||||
type Generator_Function is access function (X : Natural) return Natural;
|
||||
procedure Set_Generator_Function (Gen : in out Generator;
|
||||
Func : Generator_Function);
|
||||
|
||||
procedure Skip (Gen : access Generator'Class; Count : Positive := 1);
|
||||
|
||||
private
|
||||
|
||||
function Identity (X : Natural) return Natural;
|
||||
|
||||
type Generator is tagged record
|
||||
Last_Source : Natural := 0;
|
||||
Last_Value : Natural := 0;
|
||||
Gen_Func : Generator_Function := Identity'Access;
|
||||
end record;
|
||||
|
||||
end Generator;
|
||||
19
Task/Generator-Exponential/Ada/generator-exponential-2.ada
Normal file
19
Task/Generator-Exponential/Ada/generator-exponential-2.ada
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package Generator.Filtered is
|
||||
|
||||
type Filtered_Generator is new Generator with private;
|
||||
procedure Reset (Gen : in out Filtered_Generator);
|
||||
function Get_Next (Gen : access Filtered_Generator) return Natural;
|
||||
|
||||
procedure Set_Source (Gen : in out Filtered_Generator;
|
||||
Source : access Generator);
|
||||
procedure Set_Filter (Gen : in out Filtered_Generator;
|
||||
Filter : access Generator);
|
||||
|
||||
private
|
||||
|
||||
type Filtered_Generator is new Generator with record
|
||||
Last_Filter : Natural := 0;
|
||||
Source, Filter : access Generator;
|
||||
end record;
|
||||
|
||||
end Generator.Filtered;
|
||||
62
Task/Generator-Exponential/Ada/generator-exponential-3.ada
Normal file
62
Task/Generator-Exponential/Ada/generator-exponential-3.ada
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
package body Generator is
|
||||
|
||||
--------------
|
||||
-- Identity --
|
||||
--------------
|
||||
|
||||
function Identity (X : Natural) return Natural is
|
||||
begin
|
||||
return X;
|
||||
end Identity;
|
||||
|
||||
----------
|
||||
-- Skip --
|
||||
----------
|
||||
|
||||
procedure Skip (Gen : access Generator'Class; Count : Positive := 1) is
|
||||
Val : Natural;
|
||||
pragma Unreferenced (Val);
|
||||
begin
|
||||
for I in 1 .. Count loop
|
||||
Val := Gen.Get_Next;
|
||||
end loop;
|
||||
end Skip;
|
||||
|
||||
-----------
|
||||
-- Reset --
|
||||
-----------
|
||||
|
||||
procedure Reset (Gen : in out Generator) is
|
||||
begin
|
||||
Gen.Last_Source := 0;
|
||||
Gen.Last_Value := 0;
|
||||
end Reset;
|
||||
|
||||
--------------
|
||||
-- Get_Next --
|
||||
--------------
|
||||
|
||||
function Get_Next (Gen : access Generator) return Natural is
|
||||
begin
|
||||
Gen.Last_Source := Gen.Last_Source + 1;
|
||||
Gen.Last_Value := Gen.Gen_Func (Gen.Last_Source);
|
||||
return Gen.Last_Value;
|
||||
end Get_Next;
|
||||
|
||||
----------------------------
|
||||
-- Set_Generator_Function --
|
||||
----------------------------
|
||||
|
||||
procedure Set_Generator_Function
|
||||
(Gen : in out Generator;
|
||||
Func : Generator_Function)
|
||||
is
|
||||
begin
|
||||
if Func = null then
|
||||
Gen.Gen_Func := Identity'Access;
|
||||
else
|
||||
Gen.Gen_Func := Func;
|
||||
end if;
|
||||
end Set_Generator_Function;
|
||||
|
||||
end Generator;
|
||||
59
Task/Generator-Exponential/Ada/generator-exponential-4.ada
Normal file
59
Task/Generator-Exponential/Ada/generator-exponential-4.ada
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
package body Generator.Filtered is
|
||||
|
||||
-----------
|
||||
-- Reset --
|
||||
-----------
|
||||
|
||||
procedure Reset (Gen : in out Filtered_Generator) is
|
||||
begin
|
||||
Reset (Generator (Gen));
|
||||
Gen.Source.Reset;
|
||||
Gen.Filter.Reset;
|
||||
Gen.Last_Filter := 0;
|
||||
end Reset;
|
||||
|
||||
--------------
|
||||
-- Get_Next --
|
||||
--------------
|
||||
|
||||
function Get_Next (Gen : access Filtered_Generator) return Natural is
|
||||
Next_Source : Natural := Gen.Source.Get_Next;
|
||||
Next_Filter : Natural := Gen.Last_Filter;
|
||||
begin
|
||||
loop
|
||||
if Next_Source > Next_Filter then
|
||||
Gen.Last_Filter := Gen.Filter.Get_Next;
|
||||
Next_Filter := Gen.Last_Filter;
|
||||
elsif Next_Source = Next_Filter then
|
||||
Next_Source := Gen.Source.Get_Next;
|
||||
else
|
||||
return Next_Source;
|
||||
end if;
|
||||
end loop;
|
||||
end Get_Next;
|
||||
|
||||
----------------
|
||||
-- Set_Source --
|
||||
----------------
|
||||
|
||||
procedure Set_Source
|
||||
(Gen : in out Filtered_Generator;
|
||||
Source : access Generator)
|
||||
is
|
||||
begin
|
||||
Gen.Source := Source;
|
||||
end Set_Source;
|
||||
|
||||
----------------
|
||||
-- Set_Filter --
|
||||
----------------
|
||||
|
||||
procedure Set_Filter
|
||||
(Gen : in out Filtered_Generator;
|
||||
Filter : access Generator)
|
||||
is
|
||||
begin
|
||||
Gen.Filter := Filter;
|
||||
end Set_Filter;
|
||||
|
||||
end Generator.Filtered;
|
||||
35
Task/Generator-Exponential/Ada/generator-exponential-5.ada
Normal file
35
Task/Generator-Exponential/Ada/generator-exponential-5.ada
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
with Ada.Text_IO;
|
||||
with Generator.Filtered;
|
||||
|
||||
procedure Generator_Test is
|
||||
|
||||
function Square (X : Natural) return Natural is
|
||||
begin
|
||||
return X * X;
|
||||
end Square;
|
||||
|
||||
function Cube (X : Natural) return Natural is
|
||||
begin
|
||||
return X * X * X;
|
||||
end Cube;
|
||||
|
||||
G1, G2 : aliased Generator.Generator;
|
||||
F : aliased Generator.Filtered.Filtered_Generator;
|
||||
|
||||
begin
|
||||
|
||||
G1.Set_Generator_Function (Func => Square'Unrestricted_Access);
|
||||
G2.Set_Generator_Function (Func => Cube'Unrestricted_Access);
|
||||
|
||||
F.Set_Source (G1'Unrestricted_Access);
|
||||
F.Set_Filter (G2'Unrestricted_Access);
|
||||
|
||||
F.Skip (20);
|
||||
|
||||
for I in 1 .. 10 loop
|
||||
Ada.Text_IO.Put ("I:" & Integer'Image (I));
|
||||
Ada.Text_IO.Put (", F:" & Integer'Image (F.Get_Next));
|
||||
Ada.Text_IO.New_Line;
|
||||
end loop;
|
||||
|
||||
end Generator_Test;
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
----------------- EXPONENTIAL / GENERATOR ----------------
|
||||
|
||||
-- powers :: Gen [Int]
|
||||
on powers(n)
|
||||
script f
|
||||
on |λ|(x)
|
||||
x ^ n as integer
|
||||
end |λ|
|
||||
end script
|
||||
fmapGen(f, enumFrom(0))
|
||||
end powers
|
||||
|
||||
|
||||
--------------------------- TEST -------------------------
|
||||
on run
|
||||
take(10, ¬
|
||||
drop(20, ¬
|
||||
differenceGen(powers(2), powers(3))))
|
||||
|
||||
--> {529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089}
|
||||
end run
|
||||
|
||||
|
||||
------------------------- GENERIC ------------------------
|
||||
|
||||
-- Just :: a -> Maybe a
|
||||
on Just(x)
|
||||
{type:"Maybe", Nothing:false, Just:x}
|
||||
end Just
|
||||
|
||||
|
||||
-- Nothing :: Maybe a
|
||||
on Nothing()
|
||||
{type:"Maybe", Nothing:true}
|
||||
end Nothing
|
||||
|
||||
|
||||
-- Tuple (,) :: a -> b -> (a, b)
|
||||
on Tuple(a, b)
|
||||
{type:"Tuple", |1|:a, |2|:b, length:2}
|
||||
end Tuple
|
||||
|
||||
|
||||
-- differenceGen :: Gen [a] -> Gen [a] -> Gen [a]
|
||||
on differenceGen(ga, gb)
|
||||
-- All values of ga except any
|
||||
-- already seen in gb.
|
||||
script
|
||||
property g : zipGen(ga, gb)
|
||||
property bs : {}
|
||||
property xy : missing value
|
||||
on |λ|()
|
||||
set xy to g's |λ|()
|
||||
if missing value is xy then
|
||||
xy
|
||||
else
|
||||
set x to |1| of xy
|
||||
set y to |2| of xy
|
||||
set bs to {y} & bs
|
||||
if bs contains x then
|
||||
|λ|() -- Next in series.
|
||||
else
|
||||
x
|
||||
end if
|
||||
end if
|
||||
end |λ|
|
||||
end script
|
||||
end differenceGen
|
||||
|
||||
|
||||
-- drop :: Int -> [a] -> [a]
|
||||
-- drop :: Int -> String -> String
|
||||
on drop(n, xs)
|
||||
set c to class of xs
|
||||
if script is not c then
|
||||
if string is not c then
|
||||
if n < length of xs then
|
||||
items (1 + n) thru -1 of xs
|
||||
else
|
||||
{}
|
||||
end if
|
||||
else
|
||||
if n < length of xs then
|
||||
text (1 + n) thru -1 of xs
|
||||
else
|
||||
""
|
||||
end if
|
||||
end if
|
||||
else
|
||||
take(n, xs) -- consumed
|
||||
return xs
|
||||
end if
|
||||
end drop
|
||||
|
||||
|
||||
-- enumFrom :: Int -> [Int]
|
||||
on enumFrom(x)
|
||||
script
|
||||
property v : missing value
|
||||
on |λ|()
|
||||
if missing value is not v then
|
||||
set v to 1 + v
|
||||
else
|
||||
set v to x
|
||||
end if
|
||||
return v
|
||||
end |λ|
|
||||
end script
|
||||
end enumFrom
|
||||
|
||||
|
||||
-- fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
|
||||
on fmapGen(f, gen)
|
||||
script
|
||||
property g : mReturn(f)
|
||||
on |λ|()
|
||||
set v to gen's |λ|()
|
||||
if v is missing value then
|
||||
v
|
||||
else
|
||||
g's |λ|(v)
|
||||
end if
|
||||
end |λ|
|
||||
end script
|
||||
end fmapGen
|
||||
|
||||
|
||||
-- length :: [a] -> Int
|
||||
on |length|(xs)
|
||||
set c to class of xs
|
||||
if list is c or string is c then
|
||||
length of xs
|
||||
else
|
||||
(2 ^ 29 - 1) -- (maxInt - simple proxy for non-finite)
|
||||
end if
|
||||
end |length|
|
||||
|
||||
|
||||
-- Lift 2nd class handler function into 1st class script wrapper
|
||||
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
|
||||
on mReturn(f)
|
||||
if script is class of f then
|
||||
f
|
||||
else
|
||||
script
|
||||
property |λ| : f
|
||||
end script
|
||||
end if
|
||||
end mReturn
|
||||
|
||||
|
||||
-- take :: Int -> [a] -> [a]
|
||||
-- take :: Int -> String -> String
|
||||
on take(n, xs)
|
||||
set c to class of xs
|
||||
if list is c then
|
||||
if 0 < n then
|
||||
items 1 thru min(n, length of xs) of xs
|
||||
else
|
||||
{}
|
||||
end if
|
||||
else if string is c then
|
||||
if 0 < n then
|
||||
text 1 thru min(n, length of xs) of xs
|
||||
else
|
||||
""
|
||||
end if
|
||||
else if script is c then
|
||||
set ys to {}
|
||||
repeat with i from 1 to n
|
||||
set v to xs's |λ|()
|
||||
if missing value is v then
|
||||
return ys
|
||||
else
|
||||
set end of ys to v
|
||||
end if
|
||||
end repeat
|
||||
return ys
|
||||
else
|
||||
missing value
|
||||
end if
|
||||
end take
|
||||
|
||||
|
||||
-- uncons :: [a] -> Maybe (a, [a])
|
||||
on uncons(xs)
|
||||
set lng to |length|(xs)
|
||||
if 0 = lng then
|
||||
Nothing()
|
||||
else
|
||||
if (2 ^ 29 - 1) as integer > lng then
|
||||
if class of xs is string then
|
||||
set cs to text items of xs
|
||||
Just(Tuple(item 1 of cs, rest of cs))
|
||||
else
|
||||
Just(Tuple(item 1 of xs, rest of xs))
|
||||
end if
|
||||
else
|
||||
set nxt to take(1, xs)
|
||||
if {} is nxt then
|
||||
Nothing()
|
||||
else
|
||||
Just(Tuple(item 1 of nxt, xs))
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
end uncons
|
||||
|
||||
|
||||
-- zipGen :: Gen [a] -> Gen [b] -> Gen [(a, b)]
|
||||
on zipGen(ga, gb)
|
||||
script
|
||||
property ma : missing value
|
||||
property mb : missing value
|
||||
on |λ|()
|
||||
if missing value is ma then
|
||||
set ma to uncons(ga)
|
||||
set mb to uncons(gb)
|
||||
end if
|
||||
if Nothing of ma or Nothing of mb then
|
||||
missing value
|
||||
else
|
||||
set ta to Just of ma
|
||||
set tb to Just of mb
|
||||
set x to Tuple(|1| of ta, |1| of tb)
|
||||
set ma to uncons(|2| of ta)
|
||||
set mb to uncons(|2| of tb)
|
||||
return x
|
||||
end if
|
||||
end |λ|
|
||||
end script
|
||||
end zipGen
|
||||
66
Task/Generator-Exponential/C++/generator-exponential.cpp
Normal file
66
Task/Generator-Exponential/C++/generator-exponential.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
template<class T>
|
||||
class Generator
|
||||
{
|
||||
public:
|
||||
virtual T operator()() = 0;
|
||||
};
|
||||
|
||||
// Does nothing unspecialized
|
||||
template<class T, T P>
|
||||
class PowersGenerator: Generator<T> {};
|
||||
|
||||
// Specialize with other types, or provide a generic version of pow
|
||||
template<int P>
|
||||
class PowersGenerator<int, P>: Generator<int>
|
||||
{
|
||||
public:
|
||||
int i;
|
||||
PowersGenerator() { i = 1; }
|
||||
virtual int operator()()
|
||||
{
|
||||
int o = 1;
|
||||
for(int j = 0; j < P; ++j) o *= i;
|
||||
++i;
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
// Only works with non-decreasing generators
|
||||
template<class T, class G, class F>
|
||||
class Filter: Generator<T>
|
||||
{
|
||||
public:
|
||||
G gen;
|
||||
F filter;
|
||||
T lastG, lastF;
|
||||
|
||||
Filter() { lastG = gen(); lastF = filter(); }
|
||||
|
||||
virtual T operator()()
|
||||
{
|
||||
while(lastG >= lastF)
|
||||
{
|
||||
if(lastG == lastF)
|
||||
lastG = gen();
|
||||
lastF = filter();
|
||||
}
|
||||
|
||||
T out = lastG;
|
||||
lastG = gen();
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Filter<int, PowersGenerator<int, 2>, PowersGenerator<int, 3>> gen;
|
||||
|
||||
for(int i = 0; i < 20; ++i)
|
||||
gen();
|
||||
|
||||
for(int i = 20; i < 30; ++i)
|
||||
cout << i << ": " << gen() << endl;
|
||||
}
|
||||
19
Task/Generator-Exponential/C-sharp/generator-exponential.cs
Normal file
19
Task/Generator-Exponential/C-sharp/generator-exponential.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
static class Program {
|
||||
static void Main() {
|
||||
Func<int, IEnumerable<int>> ms = m => Infinite().Select(i => (int)Math.Pow(i, m));
|
||||
var squares = ms(2);
|
||||
var cubes = ms(3);
|
||||
var filtered = squares.Where(square => cubes.First(cube => cube >= square) != square);
|
||||
var final = filtered.Skip(20).Take(10);
|
||||
foreach (var i in final) Console.WriteLine(i);
|
||||
}
|
||||
|
||||
static IEnumerable<int> Infinite() {
|
||||
var i = 0;
|
||||
while (true) yield return i++;
|
||||
}
|
||||
}
|
||||
162
Task/Generator-Exponential/C/generator-exponential-1.c
Normal file
162
Task/Generator-Exponential/C/generator-exponential-1.c
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
#include <inttypes.h> /* int64_t, PRId64 */
|
||||
#include <stdlib.h> /* exit() */
|
||||
#include <stdio.h> /* printf() */
|
||||
|
||||
#include <libco.h> /* co_{active,create,delete,switch}() */
|
||||
|
||||
|
||||
|
||||
/* A generator that yields values of type int64_t. */
|
||||
struct gen64 {
|
||||
cothread_t giver; /* this cothread calls yield64() */
|
||||
cothread_t taker; /* this cothread calls next64() */
|
||||
int64_t given;
|
||||
void (*free)(struct gen64 *);
|
||||
void *garbage;
|
||||
};
|
||||
|
||||
/* Yields a value. */
|
||||
inline void
|
||||
yield64(struct gen64 *gen, int64_t value)
|
||||
{
|
||||
gen->given = value;
|
||||
co_switch(gen->taker);
|
||||
}
|
||||
|
||||
/* Returns the next value that the generator yields. */
|
||||
inline int64_t
|
||||
next64(struct gen64 *gen)
|
||||
{
|
||||
gen->taker = co_active();
|
||||
co_switch(gen->giver);
|
||||
return gen->given;
|
||||
}
|
||||
|
||||
static void
|
||||
gen64_free(struct gen64 *gen)
|
||||
{
|
||||
co_delete(gen->giver);
|
||||
}
|
||||
|
||||
struct gen64 *entry64;
|
||||
|
||||
/*
|
||||
* Creates a cothread for the generator. The first call to next64(gen)
|
||||
* will enter the cothread; the entry function must copy the pointer
|
||||
* from the global variable struct gen64 *entry64.
|
||||
*
|
||||
* Use gen->free(gen) to free the cothread.
|
||||
*/
|
||||
inline void
|
||||
gen64_init(struct gen64 *gen, void (*entry)(void))
|
||||
{
|
||||
if ((gen->giver = co_create(4096, entry)) == NULL) {
|
||||
/* Perhaps malloc() failed */
|
||||
fputs("co_create: Cannot create cothread\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
gen->free = gen64_free;
|
||||
entry64 = gen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Generates the powers 0**m, 1**m, 2**m, ....
|
||||
*/
|
||||
void
|
||||
powers(struct gen64 *gen, int64_t m)
|
||||
{
|
||||
int64_t base, exponent, n, result;
|
||||
|
||||
for (n = 0;; n++) {
|
||||
/*
|
||||
* This computes result = base**exponent, where
|
||||
* exponent is a nonnegative integer. The result
|
||||
* is the product of repeated squares of base.
|
||||
*/
|
||||
base = n;
|
||||
exponent = m;
|
||||
for (result = 1; exponent != 0; exponent >>= 1) {
|
||||
if (exponent & 1) result *= base;
|
||||
base *= base;
|
||||
}
|
||||
yield64(gen, result);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* stuff for squares_without_cubes() */
|
||||
#define ENTRY(name, code) static void name(void) { code; }
|
||||
ENTRY(enter_squares, powers(entry64, 2))
|
||||
ENTRY(enter_cubes, powers(entry64, 3))
|
||||
|
||||
struct swc {
|
||||
struct gen64 cubes;
|
||||
struct gen64 squares;
|
||||
void (*old_free)(struct gen64 *);
|
||||
};
|
||||
|
||||
static void
|
||||
swc_free(struct gen64 *gen)
|
||||
{
|
||||
struct swc *f = gen->garbage;
|
||||
f->cubes.free(&f->cubes);
|
||||
f->squares.free(&f->squares);
|
||||
f->old_free(gen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates the squares 0**2, 1**2, 2**2, ..., but removes the squares
|
||||
* that equal the cubes 0**3, 1**3, 2**3, ....
|
||||
*/
|
||||
void
|
||||
squares_without_cubes(struct gen64 *gen)
|
||||
{
|
||||
struct swc f;
|
||||
int64_t c, s;
|
||||
|
||||
gen64_init(&f.cubes, enter_cubes);
|
||||
c = next64(&f.cubes);
|
||||
|
||||
gen64_init(&f.squares, enter_squares);
|
||||
s = next64(&f.squares);
|
||||
|
||||
/* Allow other cothread to free this generator. */
|
||||
f.old_free = gen->free;
|
||||
gen->garbage = &f;
|
||||
gen->free = swc_free;
|
||||
|
||||
for (;;) {
|
||||
while (c < s)
|
||||
c = next64(&f.cubes);
|
||||
if (c != s)
|
||||
yield64(gen, s);
|
||||
s = next64(&f.squares);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
ENTRY(enter_squares_without_cubes, squares_without_cubes(entry64))
|
||||
|
||||
/*
|
||||
* Look at the sequence of numbers that are squares but not cubes.
|
||||
* Drop the first 20 numbers, then print the next 10 numbers.
|
||||
*/
|
||||
int
|
||||
main()
|
||||
{
|
||||
struct gen64 gen;
|
||||
int i;
|
||||
|
||||
gen64_init(&gen, enter_squares_without_cubes);
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
next64(&gen);
|
||||
for (i = 0; i < 9; i++)
|
||||
printf("%" PRId64 ", ", next64(&gen));
|
||||
printf("%" PRId64 "\n", next64(&gen));
|
||||
|
||||
gen.free(&gen); /* Free memory. */
|
||||
return 0;
|
||||
}
|
||||
74
Task/Generator-Exponential/C/generator-exponential-2.c
Normal file
74
Task/Generator-Exponential/C/generator-exponential-2.c
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
typedef int (*seq_func)(void *);
|
||||
#define SEQ_BASE seq_func f; int output
|
||||
|
||||
/* sort of polymorphing data structure */
|
||||
typedef struct { SEQ_BASE; } gen_t;
|
||||
|
||||
int seq_next(void *state)
|
||||
{
|
||||
return ((gen_t*)state)->output = (*(seq_func*)state)(state);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
SEQ_BASE;
|
||||
int pos, n;
|
||||
} power_gen_t;
|
||||
|
||||
int power_next(void *s)
|
||||
{
|
||||
return (int)pow(++((power_gen_t*)s)->pos, ((power_gen_t*)s)->n);
|
||||
}
|
||||
|
||||
void *power_seq(int n)
|
||||
{
|
||||
power_gen_t *s = malloc(sizeof(power_gen_t));
|
||||
s->output = -1;
|
||||
s->f = power_next;
|
||||
s->n = n;
|
||||
s->pos = -1;
|
||||
return s;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
SEQ_BASE;
|
||||
void *in, *without;
|
||||
} filter_gen_t;
|
||||
|
||||
int filter_next(void *s)
|
||||
{
|
||||
gen_t *in = ((filter_gen_t*)s)->in, *wo = ((filter_gen_t*)s)->without;
|
||||
|
||||
do{
|
||||
seq_next(in);
|
||||
while (wo->output < in->output)
|
||||
seq_next(wo);
|
||||
} while(wo->output == in->output);
|
||||
|
||||
return in->output;
|
||||
}
|
||||
|
||||
void* filter_seq(gen_t *in, gen_t *without)
|
||||
{
|
||||
filter_gen_t *filt = malloc(sizeof(filter_gen_t));
|
||||
filt->in = in;
|
||||
filt->without = without;
|
||||
filt->f = filter_next;
|
||||
filt->output = -1;
|
||||
return filt;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
void *s = filter_seq(power_seq(2), power_seq(3));
|
||||
|
||||
for (i = 0; i < 20; i++) seq_next(s);
|
||||
for (i = 0; i < 10; i++)
|
||||
printf("%d\n", seq_next(s));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(defn powers [m] (for [n (iterate inc 1)] (reduce * (repeat m n)))))
|
||||
(def squares (powers 2))
|
||||
(take 5 squares) ; => (1 4 9 16 25)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
(defn squares-not-cubes
|
||||
([] (squares-not-cubes (powers 2) (powers 3)))
|
||||
([squares cubes]
|
||||
(loop [[p2first & p2rest :as p2s] squares, [p3first & p3rest :as p3s] cubes]
|
||||
(cond
|
||||
(= p2first p3first) (recur p2rest p3rest)
|
||||
(> p2first p3first) (recur p2s p3rest)
|
||||
:else (cons p2first (lazy-seq (squares-not-cubes p2rest p3s)))))))
|
||||
|
||||
(->> (squares-not-cubes) (drop 20) (take 10))
|
||||
; => (529 576 625 676 784 841 900 961 1024 1089)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
(defn seq->fn [sequence]
|
||||
(let [state (atom (cons nil sequence))]
|
||||
(fn [] (first (swap! state rest)))
|
||||
|
||||
(def f (seq->fn (squares-not-cubes)))
|
||||
[(f) (f) (f)] ; => [4 9 16]
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
(defun take (seq &optional (n 1))
|
||||
(values-list (loop repeat n collect (funcall seq))))
|
||||
|
||||
(defun power-seq (n)
|
||||
(let ((x 0))
|
||||
(lambda () (expt (incf x) n))))
|
||||
|
||||
(defun filter-seq (s1 s2) ;; remove s2 from s1
|
||||
(let ((x1 (take s1)) (x2 (take s2)))
|
||||
(lambda ()
|
||||
(tagbody g
|
||||
(if (= x1 x2)
|
||||
(progn (setf x1 (take s1) x2 (take s2)) (go g)))
|
||||
(if (> x1 x2)
|
||||
(progn (setf x2 (take s2)) (go g))))
|
||||
|
||||
(prog1 x1 (setf x1 (take s1))))))
|
||||
|
||||
(let ((2not3 (filter-seq (power-seq 2) (power-seq 3))))
|
||||
(take 2not3 20) ;; drop 20
|
||||
(princ (multiple-value-list (take 2not3 10))))
|
||||
8
Task/Generator-Exponential/D/generator-exponential-1.d
Normal file
8
Task/Generator-Exponential/D/generator-exponential-1.d
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
void main() {
|
||||
import std.stdio, std.bigint, std.range, std.algorithm;
|
||||
|
||||
auto squares = 0.sequence!"n".map!(i => i.BigInt ^^ 2);
|
||||
auto cubes = 0.sequence!"n".map!(i => i.BigInt ^^ 3);
|
||||
|
||||
squares.setDifference(cubes).drop(20).take(10).writeln;
|
||||
}
|
||||
12
Task/Generator-Exponential/D/generator-exponential-2.d
Normal file
12
Task/Generator-Exponential/D/generator-exponential-2.d
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
void main() {
|
||||
import std.stdio, std.bigint, std.range, std.algorithm;
|
||||
|
||||
auto squares = 0.sequence!"n".map!(i => i.BigInt ^^ 2);
|
||||
auto cubes = 0.sequence!"n".map!(i => i.BigInt ^^ 3);
|
||||
|
||||
squares
|
||||
.filter!(s => cubes.find!(c => c >= s).front != s)
|
||||
.drop(20)
|
||||
.take(10)
|
||||
.writeln;
|
||||
}
|
||||
47
Task/Generator-Exponential/D/generator-exponential-3.d
Normal file
47
Task/Generator-Exponential/D/generator-exponential-3.d
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import std.stdio, std.bigint, std.range, std.algorithm;
|
||||
|
||||
struct Filtered(R1, R2) if (is(ElementType!R1 == ElementType!R2)) {
|
||||
R1 s1;
|
||||
R2 s2;
|
||||
alias ElementType!R1 T;
|
||||
T front, source, filter;
|
||||
|
||||
this(R1 r1, R2 r2) {
|
||||
s1 = r1;
|
||||
s2 = r2;
|
||||
source = s1.front;
|
||||
filter = s2.front;
|
||||
popFront;
|
||||
}
|
||||
|
||||
static immutable empty = false;
|
||||
|
||||
void popFront() {
|
||||
while (true) {
|
||||
if (source > filter) {
|
||||
s2.popFront;
|
||||
filter = s2.front;
|
||||
continue;
|
||||
} else if (source < filter) {
|
||||
front = source;
|
||||
s1.popFront;
|
||||
source = s1.front;
|
||||
break;
|
||||
}
|
||||
s1.popFront;
|
||||
source = s1.front;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto filtered(R1, R2)(R1 r1, R2 r2) // Helper function.
|
||||
if (isInputRange!R1 && isInputRange!R2 &&
|
||||
is(ElementType!R1 == ElementType!R2)) {
|
||||
return Filtered!(R1, R2)(r1, r2);
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto squares = 0.sequence!"n".map!(i => i.BigInt ^^ 2);
|
||||
auto cubes = 0.sequence!"n".map!(i => i.BigInt ^^ 3);
|
||||
filtered(squares, cubes).drop(20).take(10).writeln;
|
||||
}
|
||||
34
Task/Generator-Exponential/D/generator-exponential-4.d
Normal file
34
Task/Generator-Exponential/D/generator-exponential-4.d
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import std.stdio;
|
||||
|
||||
auto powers(in double e) pure nothrow {
|
||||
double i = 0;
|
||||
return () => i++ ^^ e;
|
||||
}
|
||||
|
||||
auto filter2(D)(D af, D bf) {
|
||||
double a = af(), b = bf();
|
||||
|
||||
return {
|
||||
double r;
|
||||
while (true) {
|
||||
if (a < b) {
|
||||
r = a;
|
||||
a = af();
|
||||
break;
|
||||
}
|
||||
if (b == a)
|
||||
a = af();
|
||||
b = bf();
|
||||
}
|
||||
return r;
|
||||
};
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto fgen = filter2(2.powers, 3.powers);
|
||||
foreach (immutable i; 0 .. 20)
|
||||
fgen();
|
||||
foreach (immutable i; 0 .. 10)
|
||||
write(fgen(), " ");
|
||||
writeln;
|
||||
}
|
||||
28
Task/Generator-Exponential/D/generator-exponential-5.d
Normal file
28
Task/Generator-Exponential/D/generator-exponential-5.d
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import std.stdio, std.range, std.algorithm, std.concurrency, std.bigint;
|
||||
|
||||
auto powers(in uint m) pure nothrow @safe {
|
||||
return 0.sequence!"n".map!(i => i.BigInt ^^ m);
|
||||
}
|
||||
|
||||
auto filtered(R1, R2)(R1 r1, R2 r2) /*@safe*/
|
||||
if (isForwardRange!R1 && isForwardRange!R2 &&
|
||||
is(ElementType!R1 == ElementType!R2)) {
|
||||
return new Generator!(ElementType!R1)({
|
||||
auto v = r1.front; r1.popFront;
|
||||
auto f = r2.front; r2.popFront;
|
||||
|
||||
while (true) {
|
||||
if (v > f) {
|
||||
f = r2.front; r2.popFront;
|
||||
continue;
|
||||
} else if (v < f)
|
||||
yield(v);
|
||||
v = r1.front; r1.popFront;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto squares = 2.powers, cubes = 3.powers;
|
||||
filtered(squares, cubes).drop(20).take(10).writeln;
|
||||
}
|
||||
151
Task/Generator-Exponential/Delphi/generator-exponential.delphi
Normal file
151
Task/Generator-Exponential/Delphi/generator-exponential.delphi
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
{Custom object forms basic generator}
|
||||
|
||||
type TCustomGen = class(TObject)
|
||||
private
|
||||
FNumber: integer;
|
||||
FExponent: integer;
|
||||
FStart: integer;
|
||||
protected
|
||||
property Exponent: integer read FExponent write FExponent;
|
||||
public
|
||||
constructor Create; virtual;
|
||||
procedure Reset;
|
||||
function Next: integer; virtual;
|
||||
procedure Skip(Count: integer);
|
||||
property Start: integer read FStart write FStart;
|
||||
end;
|
||||
|
||||
{Child object specifically for generating Squares}
|
||||
|
||||
type TSquareGen = class(TCustomGen)
|
||||
public
|
||||
constructor Create; override;
|
||||
end;
|
||||
|
||||
|
||||
{Child object specifically for generating cubes}
|
||||
|
||||
type TCubeGen = class(TCustomGen)
|
||||
public
|
||||
constructor Create; override;
|
||||
end;
|
||||
|
||||
{Child object specifically for filtering squares}
|
||||
|
||||
type TFilterSquareGen = class(TSquareGen)
|
||||
private
|
||||
function IsCube(N: integer): boolean;
|
||||
public
|
||||
function Next: integer; override;
|
||||
end;
|
||||
|
||||
{ TCustomGen }
|
||||
|
||||
constructor TCustomGen.Create;
|
||||
begin
|
||||
Start:=0;
|
||||
{Default to returning X^1}
|
||||
Exponent:=1;
|
||||
Reset;
|
||||
end;
|
||||
|
||||
|
||||
function TCustomGen.Next: integer;
|
||||
{Find next number in sequence}
|
||||
var I: integer;
|
||||
begin
|
||||
Result:=FNumber;
|
||||
{Raise to specified power}
|
||||
for I:=1 to FExponent-1 do Result:=Result * Result;
|
||||
{Get next base}
|
||||
Inc(FNumber);
|
||||
end;
|
||||
|
||||
|
||||
procedure TCustomGen.Reset;
|
||||
begin
|
||||
FNumber:=Start;
|
||||
end;
|
||||
|
||||
|
||||
procedure TCustomGen.Skip(Count: integer);
|
||||
{Skip specified number of items}
|
||||
var I: integer;
|
||||
begin
|
||||
for I:=1 to Count do Next;
|
||||
end;
|
||||
|
||||
{ TSquareGen }
|
||||
|
||||
constructor TSquareGen.Create;
|
||||
begin
|
||||
inherited;
|
||||
Exponent:=2;
|
||||
end;
|
||||
|
||||
{ TCubeGen }
|
||||
|
||||
constructor TCubeGen.Create;
|
||||
begin
|
||||
inherited;
|
||||
Exponent:=3;
|
||||
end;
|
||||
|
||||
{ TFilterSquareGen }
|
||||
|
||||
function TFilterSquareGen.IsCube(N: integer): boolean;
|
||||
{Test if number is perfect cube}
|
||||
var I: integer;
|
||||
begin
|
||||
I:=Round(Power(N,1/3));
|
||||
Result:=I*I*I = N;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
function TFilterSquareGen.Next: integer;
|
||||
begin
|
||||
{Gets inherited next square, rejects cubes}
|
||||
repeat Result:=inherited Next
|
||||
until not IsCube(Result);
|
||||
end;
|
||||
|
||||
|
||||
{-----------------------------------------------------------}
|
||||
|
||||
procedure DoTest(Memo: TMemo; Gen: TCustomGen; SkipCnt: integer; Title: string);
|
||||
{Carry out TGenerators tests. "Gen" is a TCustomGen which is the parent of}
|
||||
{all generators. That means "DoTest" can work with any type of generator}
|
||||
var S: string;
|
||||
var I,V: integer;
|
||||
begin
|
||||
Gen.Reset;
|
||||
Gen.Skip(SkipCnt);
|
||||
Memo.Lines.Add(Title);
|
||||
S:='[';
|
||||
for I:=1 to 10 do S:=S+Format(' %d',[Gen.Next]);
|
||||
Memo.Lines.Add(S+']');
|
||||
end;
|
||||
|
||||
|
||||
|
||||
procedure TestGenerators(Memo: TMemo);
|
||||
{Tests all three types of generators}
|
||||
var SquareGen: TSquareGen;
|
||||
var CubeGen: TCubeGen;
|
||||
var Filtered: TFilterSquareGen;
|
||||
begin
|
||||
SquareGen:=TSquareGen.Create;
|
||||
try
|
||||
CubeGen:=TCubeGen.Create;
|
||||
try
|
||||
Filtered:=TFilterSquareGen.Create;
|
||||
try
|
||||
DoTest(Memo,SquareGen,0,'Testing Square Generator');
|
||||
DoTest(Memo,CubeGen,0,'Testing Cube Generator');
|
||||
DoTest(Memo,Filtered,20,'Testing Squares with cubes removed');
|
||||
|
||||
finally Filtered.Free; end;
|
||||
finally CubeGen.Free; end;
|
||||
finally SquareGen.Free; end;
|
||||
end;
|
||||
35
Task/Generator-Exponential/E/generator-exponential.e
Normal file
35
Task/Generator-Exponential/E/generator-exponential.e
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
def genPowers(exponent) {
|
||||
var i := -1
|
||||
return def powerGenerator() {
|
||||
return (i += 1) ** exponent
|
||||
}
|
||||
}
|
||||
|
||||
def filtered(source, filter) {
|
||||
var fval := filter()
|
||||
return def filterGenerator() {
|
||||
while (true) {
|
||||
def sval := source()
|
||||
while (sval > fval) {
|
||||
fval := filter()
|
||||
}
|
||||
if (sval < fval) {
|
||||
return sval
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def drop(n, gen) {
|
||||
for _ in 1..n { gen() }
|
||||
}
|
||||
|
||||
|
||||
def squares := genPowers(2)
|
||||
def cubes := genPowers(3)
|
||||
def squaresNotCubes := filtered(squares, cubes)
|
||||
drop(20, squaresNotCubes)
|
||||
for _ in 1..10 {
|
||||
print(`${squaresNotCubes()} `)
|
||||
}
|
||||
println()
|
||||
36
Task/Generator-Exponential/EchoLisp/generator-exponential.l
Normal file
36
Task/Generator-Exponential/EchoLisp/generator-exponential.l
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
(lib 'tasks) ;; for make-generator
|
||||
|
||||
;; generator of generators
|
||||
(define (gen-power power)
|
||||
(make-generator
|
||||
(lambda(n) (yield (expt n power)) (1+ n)) 1))
|
||||
|
||||
(define powers-2 (gen-power 2))
|
||||
(define powers-3 (gen-power 3))
|
||||
|
||||
(take powers-3 10)
|
||||
→ (1 8 27 64 125 216 343 512 729 1000)
|
||||
|
||||
;; generators substraction
|
||||
;; input : two generators ga, gb - Sequences must be increasing
|
||||
;; output : new generator = ga sequence minus gb sequence
|
||||
|
||||
(define (gen-substract ga gb)
|
||||
(define (substract b (a))
|
||||
(set! a (next ga))
|
||||
(while (>= a b) ; avance b until > a
|
||||
(when (= a b) (set! a (next ga)))
|
||||
(set! b (next gb)))
|
||||
(yield a)
|
||||
b ) ;; b := next state
|
||||
(make-generator substract (next gb)))
|
||||
|
||||
;; application
|
||||
(define task (gen-substract (gen-power 2) (gen-power 3)))
|
||||
|
||||
(drop task 20)
|
||||
(take task 10)
|
||||
→ (529 576 625 676 784 841 900 961 1024 1089)
|
||||
|
||||
; inspect
|
||||
task → #generator:state: 1331
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
defmodule Generator do
|
||||
def filter( source_pid, remove_pid ) do
|
||||
first_remove = next( remove_pid )
|
||||
spawn( fn -> filter_loop(source_pid, remove_pid, first_remove) end )
|
||||
end
|
||||
|
||||
def next( pid ) do
|
||||
send(pid, {:next, self})
|
||||
receive do
|
||||
x -> x
|
||||
end
|
||||
end
|
||||
|
||||
def power( m ), do: spawn( fn -> power_loop(m, 0) end )
|
||||
|
||||
def task do
|
||||
squares_pid = power( 2 )
|
||||
cubes_pid = power( 3 )
|
||||
filter_pid = filter( squares_pid, cubes_pid )
|
||||
for _x <- 1..20, do: next(filter_pid)
|
||||
for _x <- 1..10, do: next(filter_pid)
|
||||
end
|
||||
|
||||
defp filter_loop( pid1, pid2, n2 ) do
|
||||
receive do
|
||||
{:next, pid} ->
|
||||
{n, new_n2} = filter_loop_next( next(pid1), n2, pid1, pid2 )
|
||||
send( pid, n )
|
||||
filter_loop( pid1, pid2, new_n2 )
|
||||
end
|
||||
end
|
||||
|
||||
defp filter_loop_next( n1, n2, pid1, pid2 ) when n1 > n2, do:
|
||||
filter_loop_next( n1, next(pid2), pid1, pid2 )
|
||||
defp filter_loop_next( n, n, pid1, pid2 ), do:
|
||||
filter_loop_next( next(pid1), next(pid2), pid1, pid2 )
|
||||
defp filter_loop_next( n1, n2, _pid1, _pid2 ), do: {n1, n2}
|
||||
|
||||
defp power_loop( m, n ) do
|
||||
receive do
|
||||
{:next, pid} -> send( pid, round(:math.pow(n, m) ) )
|
||||
end
|
||||
power_loop( m, n + 1 )
|
||||
end
|
||||
end
|
||||
|
||||
IO.inspect Generator.task
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
;; lexical-binding: t
|
||||
(require 'generator)
|
||||
|
||||
(iter-defun exp-gen (pow)
|
||||
(let ((i -1))
|
||||
(while
|
||||
(setq i (1+ i))
|
||||
(iter-yield (expt i pow)))))
|
||||
|
||||
(iter-defun flt-gen ()
|
||||
(let* ((g (exp-gen 2))
|
||||
(f (exp-gen 3))
|
||||
(i (iter-next g))
|
||||
(j (iter-next f)))
|
||||
(while
|
||||
(setq i (iter-next g))
|
||||
(while (> i j)
|
||||
(setq j (iter-next f)))
|
||||
(unless (= i j)
|
||||
(iter-yield i)))))
|
||||
|
||||
|
||||
(let ((g (flt-gen))
|
||||
(o 'nil))
|
||||
(dotimes (i 29)
|
||||
(setq o (iter-next g))
|
||||
(when (>= i 20)
|
||||
(print o))))
|
||||
37
Task/Generator-Exponential/Erlang/generator-exponential.erl
Normal file
37
Task/Generator-Exponential/Erlang/generator-exponential.erl
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
-module( generator ).
|
||||
|
||||
-export( [filter/2, next/1, power/1, task/0] ).
|
||||
|
||||
filter( Source_pid, Remove_pid ) ->
|
||||
First_remove = next( Remove_pid ),
|
||||
erlang:spawn( fun() -> filter_loop(Source_pid, Remove_pid, First_remove) end ).
|
||||
|
||||
next( Pid ) ->
|
||||
Pid ! {next, erlang:self()},
|
||||
receive X -> X end.
|
||||
|
||||
power( M ) -> erlang:spawn( fun() -> power_loop(M, 0) end ).
|
||||
|
||||
task() ->
|
||||
Squares_pid = power( 2 ),
|
||||
Cubes_pid = power( 3 ),
|
||||
Filter_pid = filter( Squares_pid, Cubes_pid ),
|
||||
[next(Filter_pid) || _X <- lists:seq(1, 20)],
|
||||
[next(Filter_pid) || _X <- lists:seq(1, 10)].
|
||||
|
||||
|
||||
filter_loop( Pid1, Pid2, N2 ) ->
|
||||
receive
|
||||
{next, Pid} ->
|
||||
{N, New_N2} = filter_loop_next( next(Pid1), N2, Pid1, Pid2 ),
|
||||
Pid ! N
|
||||
end,
|
||||
filter_loop( Pid1, Pid2, New_N2 ).
|
||||
|
||||
filter_loop_next( N1, N2, Pid1, Pid2 ) when N1 > N2 -> filter_loop_next( N1, next(Pid2), Pid1, Pid2 );
|
||||
filter_loop_next( N, N, Pid1, Pid2 ) -> filter_loop_next( next(Pid1), next(Pid2), Pid1, Pid2 );
|
||||
filter_loop_next( N1, N2, _Pid1, _Pid2 ) -> {N1, N2}.
|
||||
|
||||
power_loop( M, N ) ->
|
||||
receive {next, Pid} -> Pid ! erlang:round(math:pow(N, M) ) end,
|
||||
power_loop( M, N + 1 ).
|
||||
11
Task/Generator-Exponential/F-Sharp/generator-exponential.fs
Normal file
11
Task/Generator-Exponential/F-Sharp/generator-exponential.fs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
let m n = Seq.unfold(fun i -> Some(bigint.Pow(i, n), i + 1I)) 0I
|
||||
|
||||
let squares = m 2
|
||||
let cubes = m 3
|
||||
|
||||
let (--) orig veto = Seq.where(fun n -> n <> (Seq.find(fun m -> m >= n) veto)) orig
|
||||
|
||||
let ``squares without cubes`` = squares -- cubes
|
||||
|
||||
Seq.take 10 (Seq.skip 20 (``squares without cubes``))
|
||||
|> Seq.toList |> printfn "%A"
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
USING: fry kernel lists lists.lazy math math.functions
|
||||
prettyprint ;
|
||||
IN: rosetta-code.generator-exponential
|
||||
|
||||
: mth-powers-generator ( m -- lazy-list )
|
||||
[ 0 lfrom ] dip [ ^ ] curry lmap-lazy ;
|
||||
|
||||
: lmember? ( elt list -- ? )
|
||||
over '[ unswons dup _ >= ] [ drop ] until nip = ;
|
||||
|
||||
: 2-not-3-generator ( -- lazy-list )
|
||||
2 mth-powers-generator
|
||||
[ 3 mth-powers-generator lmember? not ] <lazy-filter> ;
|
||||
|
||||
10 2-not-3-generator 20 [ cdr ] times ltake list>array .
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
class Main
|
||||
{
|
||||
// Create and return a function which generates mth powers when called
|
||||
|->Int| make_generator (Int m)
|
||||
{
|
||||
current := 0
|
||||
return |->Int|
|
||||
{
|
||||
current += 1
|
||||
return (current-1).pow (m)
|
||||
}
|
||||
}
|
||||
|
||||
|->Int| squares_without_cubes ()
|
||||
{
|
||||
squares := make_generator (2)
|
||||
cubes := make_generator (3)
|
||||
c := cubes.call
|
||||
return |->Int|
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
s := squares.call
|
||||
while (c < s) { c = cubes.call }
|
||||
if (c != s) return s
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
Void main ()
|
||||
{
|
||||
swc := squares_without_cubes ()
|
||||
20.times { swc.call } // drop 20 values
|
||||
10.times // display the next 10
|
||||
{
|
||||
echo (swc.call)
|
||||
}
|
||||
}
|
||||
}
|
||||
46
Task/Generator-Exponential/Forth/generator-exponential.fth
Normal file
46
Task/Generator-Exponential/Forth/generator-exponential.fth
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
\ genexp-rcode.fs Generator/Exponential for RosettaCode.org
|
||||
|
||||
\ Generator/filter implementation using return stack as continuations stack
|
||||
: ENTER ( cont.addr -- ;borrowed from M.L.Gasanenko papers)
|
||||
>R
|
||||
;
|
||||
: | ( f -- ;true->go ahead, false->return into generator )
|
||||
IF EXIT THEN R> DROP
|
||||
;
|
||||
: GEN ( -- ;generate forever what is between 'GEN' and ';' )
|
||||
BEGIN R@ ENTER AGAIN
|
||||
;
|
||||
: STOP ( f -- ;return to caller of word that contain 'GEN' )
|
||||
IF R> DROP R> DROP R> DROP THEN
|
||||
;
|
||||
|
||||
\ Problem at hand
|
||||
: square ( n -- n^2 ) dup * ;
|
||||
: cube ( n -- n^3 ) dup square * ;
|
||||
|
||||
\ Faster tests using info that tested numbers are monotonic growing
|
||||
VARIABLE Sqroot \ last square root
|
||||
VARIABLE Cbroot \ last cubic root
|
||||
: square? ( u -- f ;test U for square number)
|
||||
BEGIN
|
||||
Sqroot @ square over <
|
||||
WHILE
|
||||
1 Sqroot +!
|
||||
REPEAT
|
||||
Sqroot @ square =
|
||||
;
|
||||
: cube? ( u -- f ;test U for cubic number)
|
||||
BEGIN
|
||||
Cbroot @ cube over <
|
||||
WHILE
|
||||
1 Cbroot +!
|
||||
REPEAT
|
||||
Cbroot @ cube =
|
||||
;
|
||||
VARIABLE Counter
|
||||
: (go) ( u -- u' )
|
||||
GEN 1+ Counter @ 30 >= STOP
|
||||
dup square? | dup cube? 0= | Counter @ 20 >= 1 Counter +! | dup .
|
||||
;
|
||||
:noname 0 Counter ! 1 Sqroot ! 1 Cbroot ! 0 (go) drop ;
|
||||
execute cr bye
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
Dim Shared As Long lastsquare, nextsquare, lastcube, midcube, nextcube
|
||||
|
||||
Function squares() As Long
|
||||
lastsquare += nextsquare
|
||||
nextsquare += 2
|
||||
squares = lastsquare
|
||||
End Function
|
||||
|
||||
Function cubes() As Long
|
||||
lastcube += nextcube
|
||||
nextcube += midcube
|
||||
midcube += 6
|
||||
cubes = lastcube
|
||||
End Function
|
||||
|
||||
lastsquare = 1 : nextsquare = -1 : lastcube = -1 : midcube = 0 : nextcube = 1
|
||||
Dim As Long cube, square
|
||||
cube = cubes
|
||||
|
||||
For i As Byte = 1 To 30
|
||||
Do
|
||||
square = squares
|
||||
Do While cube < square
|
||||
cube = cubes
|
||||
Loop
|
||||
If square <> cube Then Exit Do
|
||||
Loop
|
||||
If i > 20 Then Print square;
|
||||
Next i
|
||||
Sleep
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
def powers( m ) = map( (^ m), 0.. )
|
||||
|
||||
def
|
||||
filtered( s@sh:_, ch:ct ) | sh > ch = filtered( s, ct )
|
||||
filtered( sh:st, c@ch:_ ) | sh < ch = sh # filtered( st, c )
|
||||
filtered( _:st, c ) = filtered( st, c )
|
||||
|
||||
println( filtered(powers(2), powers(3)).drop(20).take(10) )
|
||||
47
Task/Generator-Exponential/Go/generator-exponential-1.go
Normal file
47
Task/Generator-Exponential/Go/generator-exponential-1.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
// note: exponent not limited to ints
|
||||
func newPowGen(e float64) func() float64 {
|
||||
var i float64
|
||||
return func() (r float64) {
|
||||
r = math.Pow(i, e)
|
||||
i++
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// given two functions af, bf, both monotonically increasing, return a
|
||||
// new function that returns values of af not returned by bf.
|
||||
func newMonoIncA_NotMonoIncB_Gen(af, bf func() float64) func() float64 {
|
||||
a, b := af(), bf()
|
||||
return func() (r float64) {
|
||||
for {
|
||||
if a < b {
|
||||
r = a
|
||||
a = af()
|
||||
break
|
||||
}
|
||||
if b == a {
|
||||
a = af()
|
||||
}
|
||||
b = bf()
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fGen := newMonoIncA_NotMonoIncB_Gen(newPowGen(2), newPowGen(3))
|
||||
for i := 0; i < 20; i++ {
|
||||
fGen()
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
fmt.Print(fGen(), " ")
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
48
Task/Generator-Exponential/Go/generator-exponential-2.go
Normal file
48
Task/Generator-Exponential/Go/generator-exponential-2.go
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
func newPowGen(e float64) chan float64 {
|
||||
ch := make(chan float64)
|
||||
go func() {
|
||||
for i := 0.; ; i++ {
|
||||
ch <- math.Pow(i, e)
|
||||
}
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
// given two input channels, a and b, both known to return monotonically
|
||||
// increasing values, supply on channel c values of a not returned by b.
|
||||
func newMonoIncA_NotMonoIncB_Gen(a, b chan float64) chan float64 {
|
||||
ch := make(chan float64)
|
||||
go func() {
|
||||
for va, vb := <-a, <-b; ; {
|
||||
switch {
|
||||
case va < vb:
|
||||
ch <- va
|
||||
fallthrough
|
||||
case va == vb:
|
||||
va = <-a
|
||||
default:
|
||||
vb = <-b
|
||||
|
||||
}
|
||||
}
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
func main() {
|
||||
ch := newMonoIncA_NotMonoIncB_Gen(newPowGen(2), newPowGen(3))
|
||||
for i := 0; i < 20; i++ {
|
||||
<-ch
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
fmt.Print(<-ch, " ")
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
16
Task/Generator-Exponential/Haskell/generator-exponential.hs
Normal file
16
Task/Generator-Exponential/Haskell/generator-exponential.hs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import Data.List.Ordered
|
||||
|
||||
powers :: Int -> [Int]
|
||||
powers m = map (^ m) [0..]
|
||||
|
||||
squares :: [Int]
|
||||
squares = powers 2
|
||||
|
||||
cubes :: [Int]
|
||||
cubes = powers 3
|
||||
|
||||
foo :: [Int]
|
||||
foo = filter (not . has cubes) squares
|
||||
|
||||
main :: IO ()
|
||||
main = print $ take 10 $ drop 20 foo
|
||||
25
Task/Generator-Exponential/Icon/generator-exponential.icon
Normal file
25
Task/Generator-Exponential/Icon/generator-exponential.icon
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
procedure main()
|
||||
|
||||
write("Non-cube Squares (21st to 30th):")
|
||||
every (k := 0, s := noncubesquares()) do
|
||||
if(k +:= 1) > 30 then break
|
||||
else write(20 < k," : ",s)
|
||||
end
|
||||
|
||||
procedure mthpower(m) #: generate i^m for i = 0,1,...
|
||||
while (/i := 0) | (i +:= 1) do suspend i^m
|
||||
end
|
||||
|
||||
procedure noncubesquares() #: filter for squares that aren't cubes
|
||||
cu := create mthpower(3) # co-expressions so that we can
|
||||
sq := create mthpower(2) # ... get our results where we need
|
||||
|
||||
repeat {
|
||||
if c === s then ( c := @cu , s := @sq )
|
||||
else if s > c then c := @cu
|
||||
else {
|
||||
suspend s
|
||||
s := @sq
|
||||
}
|
||||
}
|
||||
end
|
||||
10
Task/Generator-Exponential/J/generator-exponential-1.j
Normal file
10
Task/Generator-Exponential/J/generator-exponential-1.j
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
coclass 'mthPower'
|
||||
N=: 0
|
||||
create=: 3 :0
|
||||
M=: y
|
||||
)
|
||||
next=: 3 :0
|
||||
n=. N
|
||||
N=: N+1
|
||||
n^M
|
||||
)
|
||||
2
Task/Generator-Exponential/J/generator-exponential-2.j
Normal file
2
Task/Generator-Exponential/J/generator-exponential-2.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
stateySquare=: 2 conew 'mthPower'
|
||||
stateyCube=: 3 conew 'mthPower'
|
||||
6
Task/Generator-Exponential/J/generator-exponential-3.j
Normal file
6
Task/Generator-Exponential/J/generator-exponential-3.j
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
coclass 'uncubicalSquares'
|
||||
N=: 0
|
||||
next=: 3 :0"0
|
||||
while. (-: <.) 3 %: *: n=. N do. N=: N+1 end. N=: N+1
|
||||
*: n
|
||||
)
|
||||
2
Task/Generator-Exponential/J/generator-exponential-4.j
Normal file
2
Task/Generator-Exponential/J/generator-exponential-4.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
next__g i.10 [ next__g i.20 [ g=: conew 'uncubicalSquares'
|
||||
529 576 625 676 784 841 900 961 1024 1089
|
||||
4
Task/Generator-Exponential/J/generator-exponential-5.j
Normal file
4
Task/Generator-Exponential/J/generator-exponential-5.j
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
mthPower=: 1 :'^&m@i.'
|
||||
squares=: 2 mthPower
|
||||
cubes=: 3 mthPower
|
||||
uncubicalSquares=: squares -. cubes
|
||||
1
Task/Generator-Exponential/J/generator-exponential-6.j
Normal file
1
Task/Generator-Exponential/J/generator-exponential-6.j
Normal file
|
|
@ -0,0 +1 @@
|
|||
uncubicalSquares=: {. squares@<.@p.~&3 1.1 -. cubes
|
||||
2
Task/Generator-Exponential/J/generator-exponential-7.j
Normal file
2
Task/Generator-Exponential/J/generator-exponential-7.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
20 }. uncubicalSquares 30 NB. the 21st through 30th uncubical square
|
||||
529 576 625 676 784 841 900 961 1024 1089
|
||||
53
Task/Generator-Exponential/Java/generator-exponential.java
Normal file
53
Task/Generator-Exponential/Java/generator-exponential.java
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import java.util.function.LongSupplier;
|
||||
import static java.util.stream.LongStream.generate;
|
||||
|
||||
public class GeneratorExponential implements LongSupplier {
|
||||
private LongSupplier source, filter;
|
||||
private long s, f;
|
||||
|
||||
public GeneratorExponential(LongSupplier source, LongSupplier filter) {
|
||||
this.source = source;
|
||||
this.filter = filter;
|
||||
f = filter.getAsLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAsLong() {
|
||||
s = source.getAsLong();
|
||||
|
||||
while (s == f) {
|
||||
s = source.getAsLong();
|
||||
f = filter.getAsLong();
|
||||
}
|
||||
|
||||
while (s > f) {
|
||||
f = filter.getAsLong();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
generate(new GeneratorExponential(new SquaresGen(), new CubesGen()))
|
||||
.skip(20).limit(10)
|
||||
.forEach(n -> System.out.printf("%d ", n));
|
||||
}
|
||||
}
|
||||
|
||||
class SquaresGen implements LongSupplier {
|
||||
private long n;
|
||||
|
||||
@Override
|
||||
public long getAsLong() {
|
||||
return n * n++;
|
||||
}
|
||||
}
|
||||
|
||||
class CubesGen implements LongSupplier {
|
||||
private long n;
|
||||
|
||||
@Override
|
||||
public long getAsLong() {
|
||||
return n * n * n++;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
function PowersGenerator(m) {
|
||||
var n=0;
|
||||
while(1) {
|
||||
yield Math.pow(n, m);
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
|
||||
function FilteredGenerator(g, f){
|
||||
var value = g.next();
|
||||
var filter = f.next();
|
||||
|
||||
while(1) {
|
||||
if( value < filter ) {
|
||||
yield value;
|
||||
value = g.next();
|
||||
} else if ( value > filter ) {
|
||||
filter = f.next();
|
||||
} else {
|
||||
value = g.next();
|
||||
filter = f.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
var squares = PowersGenerator(2);
|
||||
var cubes = PowersGenerator(3);
|
||||
|
||||
var filtered = FilteredGenerator(squares, cubes);
|
||||
|
||||
|
||||
|
||||
for( var x = 0; x < 20; x++ ) filtered.next()
|
||||
for( var x = 20; x < 30; x++ ) console.logfiltered.next());
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
function* nPowerGen(n) {
|
||||
let e = 0;
|
||||
while (1) { e++ && (yield Math.pow(e, n)); }
|
||||
}
|
||||
|
||||
function* filterGen(gS, gC, skip=0) {
|
||||
let s = 0; // The square value
|
||||
let c = 0; // The cube value
|
||||
let n = 0; // A skip counter
|
||||
|
||||
while(1) {
|
||||
s = gS.next().value;
|
||||
s > c && (c = gC.next().value);
|
||||
s == c ?
|
||||
c = gC.next().value :
|
||||
n++ && n > skip && (yield s);
|
||||
}
|
||||
}
|
||||
|
||||
const filtered = filterGen(nPowerGen(2), nPowerGen(3), skip=20);
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// Generate the first 10 values
|
||||
for (let n = 0; n < 10; n++) {
|
||||
console.log(filtered.next().value)
|
||||
}
|
||||
155
Task/Generator-Exponential/JavaScript/generator-exponential-4.js
Normal file
155
Task/Generator-Exponential/JavaScript/generator-exponential-4.js
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// main :: IO()
|
||||
const main = () => {
|
||||
|
||||
// powers :: Gen [Int]
|
||||
const powers = n =>
|
||||
fmapGen(
|
||||
x => Math.pow(x, n),
|
||||
enumFrom(0)
|
||||
);
|
||||
|
||||
// xs :: [Int]
|
||||
const xs = take(10, drop(20,
|
||||
differenceGen(
|
||||
powers(2),
|
||||
powers(3)
|
||||
)
|
||||
));
|
||||
|
||||
console.log(xs);
|
||||
// -> [529,576,625,676,784,841,900,961,1024,1089]
|
||||
};
|
||||
|
||||
|
||||
// GENERIC FUNCTIONS ----------------------------------
|
||||
|
||||
// Just :: a -> Maybe a
|
||||
const Just = x => ({
|
||||
type: 'Maybe',
|
||||
Nothing: false,
|
||||
Just: x
|
||||
});
|
||||
|
||||
// Nothing :: Maybe a
|
||||
const Nothing = () => ({
|
||||
type: 'Maybe',
|
||||
Nothing: true,
|
||||
});
|
||||
|
||||
// Tuple (,) :: a -> b -> (a, b)
|
||||
const Tuple = (a, b) => ({
|
||||
type: 'Tuple',
|
||||
'0': a,
|
||||
'1': b,
|
||||
length: 2
|
||||
});
|
||||
|
||||
// differenceGen :: Gen [a] -> Gen [a] -> Gen [a]
|
||||
function* differenceGen(ga, gb) {
|
||||
// All values of generator stream a except any
|
||||
// already seen in generator stream b.
|
||||
const
|
||||
stream = zipGen(ga, gb),
|
||||
sb = new Set([]);
|
||||
let xy = take(1, stream);
|
||||
while (0 < xy.length) {
|
||||
const [x, y] = Array.from(xy[0]);
|
||||
sb.add(y);
|
||||
if (!sb.has(x)) yield x;
|
||||
xy = take(1, stream);
|
||||
}
|
||||
};
|
||||
|
||||
// drop :: Int -> [a] -> [a]
|
||||
// drop :: Int -> Generator [a] -> Generator [a]
|
||||
// drop :: Int -> String -> String
|
||||
const drop = (n, xs) =>
|
||||
Infinity > length(xs) ? (
|
||||
xs.slice(n)
|
||||
) : (take(n, xs), xs);
|
||||
|
||||
// enumFrom :: Enum a => a -> [a]
|
||||
function* enumFrom(x) {
|
||||
let v = x;
|
||||
while (true) {
|
||||
yield v;
|
||||
v = 1 + v;
|
||||
}
|
||||
}
|
||||
|
||||
// fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
|
||||
function* fmapGen(f, gen) {
|
||||
let v = take(1, gen);
|
||||
while (0 < v.length) {
|
||||
yield(f(v[0]))
|
||||
v = take(1, gen)
|
||||
}
|
||||
}
|
||||
|
||||
// fst :: (a, b) -> a
|
||||
const fst = tpl => tpl[0];
|
||||
|
||||
// Returns Infinity over objects without finite length.
|
||||
// This enables zip and zipWith to choose the shorter
|
||||
// argument when one is non-finite, like cycle, repeat etc
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs =>
|
||||
(Array.isArray(xs) || 'string' === typeof xs) ? (
|
||||
xs.length
|
||||
) : Infinity;
|
||||
|
||||
// snd :: (a, b) -> b
|
||||
const snd = tpl => tpl[1];
|
||||
|
||||
// take :: Int -> [a] -> [a]
|
||||
// take :: Int -> String -> String
|
||||
const take = (n, xs) =>
|
||||
'GeneratorFunction' !== xs.constructor.constructor.name ? (
|
||||
xs.slice(0, n)
|
||||
) : [].concat.apply([], Array.from({
|
||||
length: n
|
||||
}, () => {
|
||||
const x = xs.next();
|
||||
return x.done ? [] : [x.value];
|
||||
}));
|
||||
|
||||
// uncons :: [a] -> Maybe (a, [a])
|
||||
const uncons = xs => {
|
||||
const lng = length(xs);
|
||||
return (0 < lng) ? (
|
||||
lng < Infinity ? (
|
||||
Just(Tuple(xs[0], xs.slice(1))) // Finite list
|
||||
) : (() => {
|
||||
const nxt = take(1, xs);
|
||||
return 0 < nxt.length ? (
|
||||
Just(Tuple(nxt[0], xs))
|
||||
) : Nothing();
|
||||
})() // Lazy generator
|
||||
) : Nothing();
|
||||
};
|
||||
|
||||
// zipGen :: Gen [a] -> Gen [b] -> Gen [(a, b)]
|
||||
const zipGen = (ga, gb) => {
|
||||
function* go(ma, mb) {
|
||||
let
|
||||
a = ma,
|
||||
b = mb;
|
||||
while (!a.Nothing && !b.Nothing) {
|
||||
let
|
||||
ta = a.Just,
|
||||
tb = b.Just
|
||||
yield(Tuple(fst(ta), fst(tb)));
|
||||
a = uncons(snd(ta));
|
||||
b = uncons(snd(tb));
|
||||
}
|
||||
}
|
||||
return go(uncons(ga), uncons(gb));
|
||||
};
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
5
Task/Generator-Exponential/Jq/generator-exponential-1.jq
Normal file
5
Task/Generator-Exponential/Jq/generator-exponential-1.jq
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Compute self^m where m is a non-negative integer:
|
||||
def pow(m): . as $in | reduce range(0;m) as $i (1; .*$in);
|
||||
|
||||
# state: [i, i^m]
|
||||
def next_power(m): .[0] + 1 | [., pow(m) ];
|
||||
7
Task/Generator-Exponential/Jq/generator-exponential-2.jq
Normal file
7
Task/Generator-Exponential/Jq/generator-exponential-2.jq
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# skip m states, and return the next state
|
||||
def skip(m; next):
|
||||
if m <= 0 then . else next | skip(m-1; next) end;
|
||||
|
||||
# emit m states including the initial state
|
||||
def emit(m; next):
|
||||
if m <= 0 then empty else ., (next | emit(m-1; next)) end;
|
||||
5
Task/Generator-Exponential/Jq/generator-exponential-3.jq
Normal file
5
Task/Generator-Exponential/Jq/generator-exponential-3.jq
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Generate the first 4 values in the sequence i^2:
|
||||
[0,0] | emit(4; next_power(2)) | .[1]
|
||||
|
||||
# Generate all the values in the sequence i^3 less than 100:
|
||||
[0,0] | recurse(next_power(3) | if .[1] < 100 then . else empty end) | .[1]
|
||||
27
Task/Generator-Exponential/Jq/generator-exponential-4.jq
Normal file
27
Task/Generator-Exponential/Jq/generator-exponential-4.jq
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Infrastructure:
|
||||
def last(f): reduce f as $i (null; $i);
|
||||
|
||||
# emit the last value that satisfies condition, or null
|
||||
def while(condition; next):
|
||||
def w: if condition then ., (next|w) else empty end;
|
||||
last(w);
|
||||
|
||||
# Powers of m1 that are not also powers of m2.
|
||||
# filtered_next_power(m1;m2) produces [[i, i^m1], [j, j^m1]] where i^m1
|
||||
# is not a power of m2 and j^m2 < i^m1
|
||||
#
|
||||
def filtered_next_power(m1; m2):
|
||||
if . then . else [[0,0],[0,0]] end
|
||||
| (.[0] | next_power(m1)) as $next1
|
||||
| (.[1] | while( .[1] <= $next1[1]; next_power(m2))) as $next2
|
||||
| if $next1[1] == $next2[1]
|
||||
then [$next1, $next2] | filtered_next_power(m1;m2)
|
||||
else [$next1, $next2]
|
||||
end ;
|
||||
|
||||
# Emit ten powers of 2 that are NOT powers of 3,
|
||||
# skipping the first 20 integers satisfying the condition, including 0.
|
||||
filtered_next_power(2;3)
|
||||
| skip(20; filtered_next_power(2;3))
|
||||
| emit(10; filtered_next_power(2;3))
|
||||
| .[0][1]
|
||||
11
Task/Generator-Exponential/Jq/generator-exponential-5.jq
Normal file
11
Task/Generator-Exponential/Jq/generator-exponential-5.jq
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
$ jq -n -f generators.jq
|
||||
529
|
||||
576
|
||||
625
|
||||
676
|
||||
784
|
||||
841
|
||||
900
|
||||
961
|
||||
1024
|
||||
1089
|
||||
20
Task/Generator-Exponential/Julia/generator-exponential.julia
Normal file
20
Task/Generator-Exponential/Julia/generator-exponential.julia
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
drop(gen::Function, n::Integer) = (for _ in 1:n gen() end; gen)
|
||||
take(gen::Function, n::Integer) = collect(gen() for _ in 1:n)
|
||||
|
||||
function pgen(n::Number)
|
||||
x = 0
|
||||
return () -> (x += 1) ^ n
|
||||
end
|
||||
|
||||
function genfilter(g1::Function, g2::Function)
|
||||
local r1
|
||||
local r2 = g2()
|
||||
return () -> begin
|
||||
r1 = g1()
|
||||
while r2 < r1 r2 = g2() end
|
||||
while r1 == r2 r1 = g1() end
|
||||
return r1
|
||||
end
|
||||
end
|
||||
|
||||
@show take(drop(genfilter(pgen(2), pgen(3)), 20), 10)
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// version 1.1.0
|
||||
// compiled with flag -Xcoroutines=enable to suppress 'experimental' warning
|
||||
|
||||
import kotlin.coroutines.experimental.buildSequence
|
||||
|
||||
fun generatePowers(m: Int) =
|
||||
buildSequence {
|
||||
var n = 0
|
||||
val mm = m.toDouble()
|
||||
while (true) yield(Math.pow((n++).toDouble(), mm).toLong())
|
||||
}
|
||||
|
||||
fun generateNonCubicSquares(squares: Sequence<Long>, cubes: Sequence<Long>) =
|
||||
buildSequence {
|
||||
val iter2 = squares.iterator()
|
||||
val iter3 = cubes.iterator()
|
||||
var square = iter2.next()
|
||||
var cube = iter3.next()
|
||||
while (true) {
|
||||
if (square > cube) {
|
||||
cube = iter3.next()
|
||||
continue
|
||||
} else if (square < cube) {
|
||||
yield(square)
|
||||
}
|
||||
square = iter2.next()
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val squares = generatePowers(2)
|
||||
val cubes = generatePowers(3)
|
||||
val ncs = generateNonCubicSquares(squares, cubes)
|
||||
print("Non-cubic squares (21st to 30th) : ")
|
||||
ncs.drop(20).take(10).forEach { print("$it ") } // print 21st to 30th items
|
||||
println()
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
squares = script("generator.power").new(2)
|
||||
cubes = script("generator.power").new(3)
|
||||
filter = script("generator.filter").new(squares, cubes)
|
||||
filter.skip(20)
|
||||
res = []
|
||||
i = 0
|
||||
repeat while filter.exec(res)
|
||||
i = i + 1
|
||||
if i>10 then exit repeat
|
||||
put res[1]
|
||||
end repeat
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
property _exp
|
||||
property _index
|
||||
|
||||
-- @constructor
|
||||
on new (me, e)
|
||||
me._exp = e
|
||||
me._index = 0
|
||||
return me
|
||||
end
|
||||
|
||||
on exec (me, input)
|
||||
me._index = me._index+1
|
||||
input[1] = integer(power(me._index, me._exp))
|
||||
return TRUE
|
||||
end
|
||||
|
||||
on skip (me, steps)
|
||||
me._index = me._index + steps
|
||||
end
|
||||
|
||||
on reset (me)
|
||||
me._index = 0
|
||||
end
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
property _genv
|
||||
property _genf
|
||||
|
||||
-- @constructor
|
||||
on new (me, genv, genf)
|
||||
me._genv = genv
|
||||
me._genf = genf
|
||||
return me
|
||||
end
|
||||
|
||||
on exec (me, input)
|
||||
repeat while TRUE
|
||||
me._genv.exec(input)
|
||||
v = input[1]
|
||||
ok = TRUE
|
||||
me._genf.reset() -- reset filter generator
|
||||
repeat while TRUE
|
||||
me._genf.exec(input)
|
||||
f = input[1]
|
||||
if f>v then exit repeat
|
||||
if f=v then
|
||||
ok=FALSE
|
||||
exit repeat
|
||||
end if
|
||||
end repeat
|
||||
if ok then
|
||||
input[1] = v
|
||||
exit repeat
|
||||
end if
|
||||
end repeat
|
||||
return TRUE
|
||||
end
|
||||
|
||||
on skip (me, steps)
|
||||
repeat with i = 1 to steps
|
||||
me.exec([])
|
||||
end repeat
|
||||
end
|
||||
|
||||
on reset (me)
|
||||
me._genv.reset()
|
||||
me._genf.reset()
|
||||
end
|
||||
38
Task/Generator-Exponential/Lua/generator-exponential.lua
Normal file
38
Task/Generator-Exponential/Lua/generator-exponential.lua
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
--could be done with a coroutine, but a simple closure works just as well.
|
||||
local function powgen(m)
|
||||
local count = 0
|
||||
return function()
|
||||
count = count + 1
|
||||
return count^m
|
||||
end
|
||||
end
|
||||
|
||||
local squares = powgen(2)
|
||||
local cubes = powgen(3)
|
||||
|
||||
local cowrap,coyield = coroutine.wrap, coroutine.yield
|
||||
|
||||
local function filter(f,g)
|
||||
return cowrap(function()
|
||||
local ff,gg = f(), g()
|
||||
while true do
|
||||
if ff == gg then
|
||||
ff,gg = f(), g()
|
||||
elseif ff < gg then
|
||||
coyield(ff)
|
||||
ff = f()
|
||||
else
|
||||
gg = g()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
filter = filter(squares,cubes)
|
||||
|
||||
for i = 1,30 do
|
||||
local result = filter()
|
||||
if i > 20 then
|
||||
print(result)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
Module Generator {
|
||||
PowGen = Lambda (e)
|
||||
-> {
|
||||
= Lambda
|
||||
i=0, // closure
|
||||
e // closure
|
||||
-> {
|
||||
i++
|
||||
= i**e
|
||||
}
|
||||
}
|
||||
Squares=Lambda
|
||||
PowGen=PowGen(2) // closure
|
||||
->{
|
||||
= PowGen()
|
||||
}
|
||||
Cubes=Lambda
|
||||
PowGen=PowGen(3) // closure
|
||||
-> {
|
||||
= PowGen()
|
||||
}
|
||||
Filter=Lambda
|
||||
z=Squares(), // closure
|
||||
Squares, // closure
|
||||
m, // closure
|
||||
Cubes // closure
|
||||
->{
|
||||
while m<z :m=cubes():end while
|
||||
if z=m then z=Squares()
|
||||
= z : z=Squares()
|
||||
}
|
||||
For i=1 to 20 : dropit=Filter() :Next i
|
||||
Document doc$="Non-cubic squares (21st to 30th)"
|
||||
Print doc$
|
||||
doc$={
|
||||
} \\ a new line to doc$
|
||||
For i=1 to 10
|
||||
f=Filter()
|
||||
Print Format$("I: {0::-2}, F: {1}",i+20, f)
|
||||
doc$=Format$("I: {0::-2}, F: {1}",i+20, f)+{
|
||||
}
|
||||
Next
|
||||
Clipboard doc$
|
||||
}
|
||||
Generator
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
lastsquare = 1;
|
||||
nextsquare = -1;
|
||||
lastcube = -1;
|
||||
midcube = 0;
|
||||
nextcube = 1;
|
||||
Gensquares[] := Module[{},
|
||||
lastsquare += nextsquare;
|
||||
nextsquare += 2;
|
||||
squares = lastsquare;
|
||||
squares
|
||||
]
|
||||
Gencubes[] := Module[{},
|
||||
lastcube += nextcube;
|
||||
nextcube += midcube;
|
||||
midcube += 6;
|
||||
cubes = lastcube
|
||||
]
|
||||
|
||||
|
||||
c = Gencubes[];
|
||||
Do[
|
||||
While[True,
|
||||
s = Gensquares[];
|
||||
While[c < s,
|
||||
c = Gencubes[];
|
||||
];
|
||||
If[s =!= c,
|
||||
Break[]
|
||||
];
|
||||
];
|
||||
If[i > 20,
|
||||
Print[s]
|
||||
]
|
||||
,
|
||||
{i, 30}
|
||||
]
|
||||
39
Task/Generator-Exponential/Nim/generator-exponential.nim
Normal file
39
Task/Generator-Exponential/Nim/generator-exponential.nim
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
type Iterator = iterator(): int
|
||||
|
||||
proc `^`*(base: Natural; exp: Natural): int =
|
||||
var (base, exp) = (base, exp)
|
||||
result = 1
|
||||
while exp != 0:
|
||||
if (exp and 1) != 0:
|
||||
result *= base
|
||||
exp = exp shr 1
|
||||
base *= base
|
||||
|
||||
proc next(s: Iterator): int =
|
||||
for n in s(): return n
|
||||
|
||||
proc powers(m: Natural): Iterator =
|
||||
iterator it(): int {.closure.} =
|
||||
for n in 0 ..< int.high:
|
||||
yield n ^ m
|
||||
result = it
|
||||
|
||||
iterator filtered(s1, s2: Iterator): int =
|
||||
var v = next(s1)
|
||||
var f = next(s2)
|
||||
while true:
|
||||
if v > f:
|
||||
f = next(s2)
|
||||
continue
|
||||
elif v < f:
|
||||
yield v
|
||||
v = next(s1)
|
||||
|
||||
var
|
||||
squares = powers(2)
|
||||
cubes = powers(3)
|
||||
i = 1
|
||||
for x in filtered(squares, cubes):
|
||||
if i > 20: echo x
|
||||
if i >= 30: break
|
||||
inc i
|
||||
90
Task/Generator-Exponential/OCaml/generator-exponential.ocaml
Normal file
90
Task/Generator-Exponential/OCaml/generator-exponential.ocaml
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
(* Task : Generator/Exponential
|
||||
|
||||
Version using the Seq module types, but transparently
|
||||
*)
|
||||
|
||||
(*** Helper functions ***)
|
||||
|
||||
(* Generator type *)
|
||||
type 'a gen = unit -> 'a node
|
||||
and 'a node = Nil | Cons of 'a * 'a gen
|
||||
|
||||
(* Power function on integers *)
|
||||
let power (base : int) (exp : int) : int =
|
||||
let rec helper exp acc =
|
||||
if exp = 0 then acc
|
||||
else helper (exp - 1) (base * acc)
|
||||
in
|
||||
helper exp 1
|
||||
|
||||
(* Take (at most) n from generator *)
|
||||
let rec take (n : int) (gen : 'a gen) : 'a list =
|
||||
if n = 0 then []
|
||||
else
|
||||
match gen () with
|
||||
| Nil -> []
|
||||
| Cons (x, tl) -> x :: take (n - 1) tl
|
||||
|
||||
(* Stop existing generator at a given condition *)
|
||||
let rec keep_while (p : 'a -> bool) (gen : 'a gen) : 'a gen = fun () ->
|
||||
match gen () with
|
||||
| Nil -> Nil
|
||||
| Cons (x, tl) ->
|
||||
if p x then Cons (x, keep_while p tl)
|
||||
else Nil
|
||||
|
||||
(* Drop the first n elements of a generator *)
|
||||
let rec drop (n : int) (gen : 'a gen) : 'a gen =
|
||||
if n = 0 then gen
|
||||
else
|
||||
match gen () with
|
||||
| Nil -> (fun () -> Nil)
|
||||
| Cons (_, tl) -> drop (n - 1) tl
|
||||
|
||||
(* Filter based on predicate, lazily *)
|
||||
let rec filter (p : 'a -> bool) (gen : 'a gen) : 'a gen = fun () ->
|
||||
match gen () with
|
||||
| Nil -> Nil
|
||||
| Cons (x, tl) ->
|
||||
if p x then Cons (x, filter p tl)
|
||||
else filter p tl ()
|
||||
|
||||
(* Is this value inside this generator? Does not terminate for infinite streams! *)
|
||||
let rec mem (val_ : 'a) (gen : 'a gen) : bool =
|
||||
match gen () with
|
||||
| Nil -> false
|
||||
| Cons (x, tl) ->
|
||||
if x = val_ then true
|
||||
else mem val_ tl
|
||||
|
||||
(*** Task at hand ***)
|
||||
|
||||
(* Create a function that returns a generation of the m'th powers of the positive integers
|
||||
starting from zero, in order, and without obvious or simple upper limit.
|
||||
(Any upper limit to the generator should not be stated in the source but should be down
|
||||
to factors such as the languages natural integer size limit or computational time/size).
|
||||
*)
|
||||
let power_gen k : int gen =
|
||||
let rec generator n () =
|
||||
Cons (power n k, generator (n + 1))
|
||||
in
|
||||
generator 0
|
||||
|
||||
(* Use it to create generators of squares and cubes *)
|
||||
let squares = power_gen 2
|
||||
let cubes = power_gen 3
|
||||
|
||||
(* Create a new generator that filters all cubes from the generator of squares. *)
|
||||
let squares_no_cubes =
|
||||
let filter_p square =
|
||||
(* Get all cubes up to square *)
|
||||
let cubes_up_to_n2 = keep_while ((>=) square) cubes in
|
||||
not (mem square cubes_up_to_n2)
|
||||
in
|
||||
filter filter_p squares
|
||||
|
||||
(*** Output ***)
|
||||
|
||||
(* Drop the first 20 values from this last generator of filtered results, and then show the next 10 values. *)
|
||||
let _ =
|
||||
squares_no_cubes |> drop 20 |> take 10
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
g = List(1); \\ generator stack
|
||||
|
||||
genpow(p) = my(a=g[1]++);listput(g,[0,p]);()->g[a][1]++^g[a][2];
|
||||
|
||||
genpowf(p,f) = my(a=g[1]++);listput(g,[0,p]);(s=0)->my(q);while(ispower(p=g[a][1]++^g[a][2],f)||(s&&q++<=s),);p;
|
||||
30
Task/Generator-Exponential/PHP/generator-exponential.php
Normal file
30
Task/Generator-Exponential/PHP/generator-exponential.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
function powers($m) {
|
||||
for ($n = 0; ; $n++) {
|
||||
yield pow($n, $m);
|
||||
}
|
||||
}
|
||||
|
||||
function filtered($s1, $s2) {
|
||||
while (true) {
|
||||
list($v, $f) = [$s1->current(), $s2->current()];
|
||||
if ($v > $f) {
|
||||
$s2->next();
|
||||
continue;
|
||||
} else if ($v < $f) {
|
||||
yield $v;
|
||||
}
|
||||
$s1->next();
|
||||
}
|
||||
}
|
||||
|
||||
list($squares, $cubes) = [powers(2), powers(3)];
|
||||
$f = filtered($squares, $cubes);
|
||||
foreach (range(0, 19) as $i) {
|
||||
$f->next();
|
||||
}
|
||||
foreach (range(20, 29) as $i) {
|
||||
echo $i, "\t", $f->current(), "\n";
|
||||
$f->next();
|
||||
}
|
||||
?>
|
||||
44
Task/Generator-Exponential/PL-I/generator-exponential.pli
Normal file
44
Task/Generator-Exponential/PL-I/generator-exponential.pli
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
Generate: procedure options (main); /* 27 October 2013 */
|
||||
declare j fixed binary;
|
||||
declare r fixed binary;
|
||||
|
||||
/* Ignore the first 20 values */
|
||||
do j = 1 to 20;
|
||||
/* put edit (filter() ) (f(6)); */
|
||||
r = filter ();
|
||||
end;
|
||||
put skip;
|
||||
do j = 1 to 10;
|
||||
put edit (filter() ) (f(6));
|
||||
end;
|
||||
|
||||
/* filters out cubes from the result of the square generator. */
|
||||
filter: procedure returns (fixed binary);
|
||||
declare n fixed binary static initial (-0);
|
||||
declare (i, j, m) fixed binary;
|
||||
|
||||
do while ('1'b);
|
||||
m = squares();
|
||||
r = 0;
|
||||
do j = 1 to m;
|
||||
if m = cubes() then go to ignore;
|
||||
end;
|
||||
return (m);
|
||||
ignore:
|
||||
end;
|
||||
end filter;
|
||||
|
||||
squares: procedure returns (fixed binary);
|
||||
declare i fixed binary static initial (-0);
|
||||
|
||||
i = i + 1;
|
||||
return (i**2);
|
||||
end squares;
|
||||
|
||||
cubes: procedure returns (fixed binary);
|
||||
|
||||
r = r + 1;
|
||||
return (r**3);
|
||||
end cubes;
|
||||
|
||||
end Generate;
|
||||
37
Task/Generator-Exponential/Perl/generator-exponential.pl
Normal file
37
Task/Generator-Exponential/Perl/generator-exponential.pl
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# gen_pow($m) creates and returns an anonymous subroutine that will
|
||||
# generate and return the powers 0**m, 1**m, 2**m, ...
|
||||
sub gen_pow {
|
||||
my $m = shift;
|
||||
my $e = 0;
|
||||
return sub { return $e++ ** $m; };
|
||||
}
|
||||
|
||||
# gen_filter($g1, $g2) generates everything returned from $g1 that
|
||||
# is not also returned from $g2. Both $g1 and $g2 must be references
|
||||
# to subroutines that generate numbers in increasing order. gen_filter
|
||||
# creates and returns an anonymous subroutine.
|
||||
sub gen_filter {
|
||||
my($g1, $g2) = @_;
|
||||
my $v1;
|
||||
my $v2 = $g2->();
|
||||
return sub {
|
||||
for (;;) {
|
||||
$v1 = $g1->();
|
||||
$v2 = $g2->() while $v1 > $v2;
|
||||
return $v1 unless $v1 == $v2;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
# Create generators.
|
||||
my $squares = gen_pow(2);
|
||||
my $cubes = gen_pow(3);
|
||||
my $squares_without_cubes = gen_filter($squares, $cubes);
|
||||
|
||||
# Drop 20 values.
|
||||
$squares_without_cubes->() for (1..20);
|
||||
|
||||
# Print 10 values.
|
||||
my @answer;
|
||||
push @answer, $squares_without_cubes->() for (1..10);
|
||||
print "[", join(", ", @answer), "]\n";
|
||||
47
Task/Generator-Exponential/Phix/generator-exponential.phix
Normal file
47
Task/Generator-Exponential/Phix/generator-exponential.phix
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
(notonline)-->
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- demo\rosetta\Generator_Exponential.exw
|
||||
-- ======================================
|
||||
--</span>
|
||||
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- tasks</span>
|
||||
<span style="color: #004080;">bool</span> <span style="color: #000000;">terminate</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
|
||||
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">res</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">powers</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #000000;">terminate</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">task_suspend</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_self</span><span style="color: #0000FF;">())</span>
|
||||
<span style="color: #000000;">task_yield</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">squares</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">task_create</span><span style="color: #0000FF;">(</span><span style="color: #000000;">powers</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}),</span>
|
||||
<span style="color: #000000;">cubes</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">task_create</span><span style="color: #0000FF;">(</span><span style="color: #000000;">powers</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">})</span>
|
||||
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">square</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cube</span>
|
||||
<span style="color: #000000;">task_schedule</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cubes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">task_yield</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">cube</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">30</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">task_schedule</span><span style="color: #0000FF;">(</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">task_yield</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">square</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">cube</span><span style="color: #0000FF;"><</span><span style="color: #000000;">square</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">task_schedule</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cubes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">task_yield</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">cube</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">square</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">cube</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">></span><span style="color: #000000;">20</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #0000FF;">?</span><span style="color: #000000;">square</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
|
||||
<span style="color: #000000;">terminate</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
|
||||
<!--
|
||||
16
Task/Generator-Exponential/PicoLisp/generator-exponential.l
Normal file
16
Task/Generator-Exponential/PicoLisp/generator-exponential.l
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
(de powers (M)
|
||||
(co (intern (pack 'powers M))
|
||||
(for (I 0 (inc 'I))
|
||||
(yield (** I M)) ) ) )
|
||||
|
||||
(de filtered (N M)
|
||||
(co 'filtered
|
||||
(let (V (powers N) F (powers M))
|
||||
(loop
|
||||
(if (> V F)
|
||||
(setq F (powers M))
|
||||
(and (> F V) (yield V))
|
||||
(setq V (powers N)) ) ) ) ) )
|
||||
|
||||
(do 20 (filtered 2 3))
|
||||
(do 10 (println (filtered 2 3)))
|
||||
19
Task/Generator-Exponential/Python/generator-exponential-1.py
Normal file
19
Task/Generator-Exponential/Python/generator-exponential-1.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from itertools import islice, count
|
||||
|
||||
def powers(m):
|
||||
for n in count():
|
||||
yield n ** m
|
||||
|
||||
def filtered(s1, s2):
|
||||
v, f = next(s1), next(s2)
|
||||
while True:
|
||||
if v > f:
|
||||
f = next(s2)
|
||||
continue
|
||||
elif v < f:
|
||||
yield v
|
||||
v = next(s1)
|
||||
|
||||
squares, cubes = powers(2), powers(3)
|
||||
f = filtered(squares, cubes)
|
||||
print(list(islice(f, 20, 30)))
|
||||
82
Task/Generator-Exponential/Python/generator-exponential-2.py
Normal file
82
Task/Generator-Exponential/Python/generator-exponential-2.py
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
'''Exponentials as generators'''
|
||||
|
||||
from itertools import count, islice
|
||||
|
||||
|
||||
# powers :: Gen [Int]
|
||||
def powers(n):
|
||||
'''A non-finite succession of integers,
|
||||
starting at zero,
|
||||
raised to the nth power.'''
|
||||
|
||||
def f(x):
|
||||
return pow(x, n)
|
||||
|
||||
return map(f, count(0))
|
||||
|
||||
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Taking the difference between two derived generators.'''
|
||||
print(
|
||||
take(10)(
|
||||
drop(20)(
|
||||
differenceGen(powers(2))(
|
||||
powers(3)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# GENERIC -------------------------------------------------
|
||||
|
||||
|
||||
# differenceGen :: Gen [a] -> Gen [a] -> Gen [a]
|
||||
def differenceGen(ga):
|
||||
'''All values of ga except any
|
||||
already seen in gb.'''
|
||||
def go(a, b):
|
||||
stream = zip(a, b)
|
||||
bs = set([])
|
||||
while True:
|
||||
xy = next(stream, None)
|
||||
if None is not xy:
|
||||
x, y = xy
|
||||
bs.add(y)
|
||||
if x not in bs:
|
||||
yield x
|
||||
else:
|
||||
return
|
||||
return lambda gb: go(ga, gb)
|
||||
|
||||
|
||||
# drop :: Int -> [a] -> [a]
|
||||
# drop :: Int -> String -> String
|
||||
def drop(n):
|
||||
'''The sublist of xs beginning at
|
||||
(zero-based) index n.'''
|
||||
def go(xs):
|
||||
if isinstance(xs, list):
|
||||
return xs[n:]
|
||||
else:
|
||||
take(n)(xs)
|
||||
return xs
|
||||
return lambda xs: go(xs)
|
||||
|
||||
|
||||
# take :: Int -> [a] -> [a]
|
||||
# take :: Int -> String -> String
|
||||
def take(n):
|
||||
'''The prefix of xs of length n,
|
||||
or xs itself if n > length xs.'''
|
||||
return lambda xs: (
|
||||
xs[0:n]
|
||||
if isinstance(xs, list)
|
||||
else list(islice(xs, n))
|
||||
)
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
[ ' [ this -1 peek
|
||||
this -2 peek **
|
||||
1 this tally
|
||||
done ]
|
||||
swap join
|
||||
0 join ] is expogen ( n --> [ )
|
||||
|
||||
[ ' [ this temp put
|
||||
temp share -3 peek do
|
||||
dup temp share share = iff
|
||||
[ drop
|
||||
temp share -2 peek do
|
||||
temp take replace ] again
|
||||
[ dup temp share share > iff
|
||||
[ temp share -2 peek do
|
||||
temp share replace ]
|
||||
again ]
|
||||
temp release
|
||||
done ]
|
||||
unrot
|
||||
dip nested
|
||||
dup dip nested
|
||||
do 3 times join ] is taskgen ( [ [ --> [ )
|
||||
|
||||
2 expogen
|
||||
3 expogen taskgen
|
||||
|
||||
20 times [ dup do drop ]
|
||||
10 times [ dup do echo sp ]
|
||||
drop
|
||||
25
Task/Generator-Exponential/R/generator-exponential.r
Normal file
25
Task/Generator-Exponential/R/generator-exponential.r
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
powers = function(m)
|
||||
{n = -1
|
||||
function()
|
||||
{n <<- n + 1
|
||||
n^m}}
|
||||
|
||||
noncubic.squares = local(
|
||||
{squares = powers(2)
|
||||
cubes = powers(3)
|
||||
cube = cubes()
|
||||
function()
|
||||
{square = squares()
|
||||
while (1)
|
||||
{if (square > cube)
|
||||
{cube <<- cubes()
|
||||
next}
|
||||
else if (square < cube)
|
||||
{return(square)}
|
||||
else
|
||||
{square = squares()}}}})
|
||||
|
||||
for (i in 1:20)
|
||||
noncubic.squares()
|
||||
for (i in 1:10)
|
||||
message(noncubic.squares())
|
||||
36
Task/Generator-Exponential/REXX/generator-exponential.rexx
Normal file
36
Task/Generator-Exponential/REXX/generator-exponential.rexx
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*REXX program demonstrates how to use a generator (also known as an iterator). */
|
||||
parse arg N .; if N=='' | N=="," then N=20 /*N not specified? Then use default.*/
|
||||
@.= /* [↓] calculate squares,cubes,pureSq.*/
|
||||
do i=1 for N; call Gsquare i
|
||||
call Gcube i
|
||||
call GpureSquare i /*these are cube─free square numbers.*/
|
||||
end /*i*/
|
||||
|
||||
do k=1 for N; @.pureSquare.k=; end /*k*/ /*this is used to drop 1st N values.*/
|
||||
|
||||
w=length(N+10); ps= 'pure square' /*the width of the numbers; a literal.*/
|
||||
|
||||
do m=N+1 for 10; say ps right(m, w)":" right(GpureSquare(m), 3*w)
|
||||
end /*m*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
Gpower: procedure expose @.; parse arg x,p; q=@.pow.x.p
|
||||
if q\=='' then return q; _=x**p; @.pow.x.p=_
|
||||
return _
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
Gsquare: procedure expose @.; parse arg x; q=@.square.x
|
||||
if q=='' then @.square.x=Gpower(x, 2)
|
||||
return @.square.x
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
Gcube: procedure expose @.; parse arg x; q=@.cube.x
|
||||
if q=='' then @.cube.x=Gpower(x, 3) _=@.cube.x; @.3pow._=1
|
||||
return @.cube.x
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
GpureSquare: procedure expose @.; parse arg x; q=@.pureSquare.x
|
||||
if q\=='' then return q
|
||||
#=0
|
||||
do j=1 until #==x; ?=Gpower(j, 2) /*search for pure square. */
|
||||
if @.3pow.?==1 then iterate /*is it a power of three? */
|
||||
#=#+1; @.pureSquare.#=? /*assign next pureSquare. */
|
||||
end /*j*/
|
||||
return @.pureSquare.x
|
||||
23
Task/Generator-Exponential/Racket/generator-exponential.rkt
Normal file
23
Task/Generator-Exponential/Racket/generator-exponential.rkt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#lang racket
|
||||
|
||||
(require racket/generator)
|
||||
|
||||
;; this is a function that returns a powers generator, not a generator
|
||||
(define (powers m)
|
||||
(generator ()
|
||||
(for ([n (in-naturals)]) (yield (expt n m)))))
|
||||
|
||||
(define squares (powers 2))
|
||||
(define cubes (powers 3))
|
||||
|
||||
;; same here
|
||||
(define (filtered g1 g2)
|
||||
(generator ()
|
||||
(let loop ([n1 (g1)] [n2 (g2)])
|
||||
(cond [(< n1 n2) (yield n1) (loop (g1) n2)]
|
||||
[(> n1 n2) (loop n1 (g2))]
|
||||
[else (loop (g1) (g2))]))))
|
||||
|
||||
(for/list ([x (in-producer (filtered squares cubes) (lambda (_) #f))]
|
||||
[i 30] #:when (>= i 20))
|
||||
x)
|
||||
13
Task/Generator-Exponential/Raku/generator-exponential.raku
Normal file
13
Task/Generator-Exponential/Raku/generator-exponential.raku
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
sub powers($m) { 0..* X** $m }
|
||||
|
||||
my @squares = powers(2);
|
||||
my @cubes = powers(3);
|
||||
|
||||
sub infix:<with-out> (@orig, @veto) {
|
||||
gather for @veto -> $veto {
|
||||
take @orig.shift while @orig[0] before $veto;
|
||||
@orig.shift if @orig[0] eqv $veto;
|
||||
}
|
||||
}
|
||||
|
||||
say (@squares with-out @cubes)[20 ..^ 20+10].join(', ');
|
||||
20
Task/Generator-Exponential/Ruby/generator-exponential-1.rb
Normal file
20
Task/Generator-Exponential/Ruby/generator-exponential-1.rb
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# This solution cheats and uses only one generator!
|
||||
|
||||
def powers(m)
|
||||
return enum_for(__method__, m) unless block_given?
|
||||
0.step{|n| yield n**m}
|
||||
end
|
||||
|
||||
def squares_without_cubes
|
||||
return enum_for(__method__) unless block_given?
|
||||
|
||||
cubes = powers(3)
|
||||
c = cubes.next
|
||||
powers(2) do |s|
|
||||
c = cubes.next while c < s
|
||||
yield s unless c == s
|
||||
end
|
||||
end
|
||||
|
||||
p squares_without_cubes.take(30).drop(20)
|
||||
# p squares_without_cubes.lazy.drop(20).first(10) # Ruby 2.0+
|
||||
23
Task/Generator-Exponential/Ruby/generator-exponential-2.rb
Normal file
23
Task/Generator-Exponential/Ruby/generator-exponential-2.rb
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# This solution uses three generators.
|
||||
|
||||
def powers(m)
|
||||
return enum_for(__method__, m) unless block_given?
|
||||
0.step{|n| yield n**m}
|
||||
end
|
||||
|
||||
def squares_without_cubes
|
||||
return enum_for(__method__) unless block_given?
|
||||
|
||||
cubes = powers(3) #no block, so this is the first generator
|
||||
c = cubes.next
|
||||
squares = powers(2) # second generator
|
||||
loop do
|
||||
s = squares.next
|
||||
c = cubes.next while c < s
|
||||
yield s unless c == s
|
||||
end
|
||||
end
|
||||
|
||||
answer = squares_without_cubes # third generator
|
||||
20.times { answer.next }
|
||||
p 10.times.map { answer.next }
|
||||
14
Task/Generator-Exponential/Ruby/generator-exponential-3.rb
Normal file
14
Task/Generator-Exponential/Ruby/generator-exponential-3.rb
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
def filtered(s1, s2)
|
||||
return enum_for(__method__, s1, s2) unless block_given?
|
||||
v, f = s1.next, s2.next
|
||||
loop do
|
||||
v > f and f = s2.next and next
|
||||
v < f and yield v
|
||||
v = s1.next
|
||||
end
|
||||
end
|
||||
|
||||
squares, cubes = powers(2), powers(3)
|
||||
f = filtered(squares, cubes)
|
||||
p f.take(30).last(10)
|
||||
# p f.lazy.drop(20).first(10) # Ruby 2.0+
|
||||
39
Task/Generator-Exponential/Rust/generator-exponential.rust
Normal file
39
Task/Generator-Exponential/Rust/generator-exponential.rust
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::iter::Peekable;
|
||||
|
||||
fn powers(m: u32) -> impl Iterator<Item = u64> {
|
||||
(0u64..).map(move |x| x.pow(m))
|
||||
}
|
||||
|
||||
fn noncubic_squares() -> impl Iterator<Item = u64> {
|
||||
NoncubicSquares {
|
||||
squares: powers(2).peekable(),
|
||||
cubes: powers(3).peekable(),
|
||||
}
|
||||
}
|
||||
|
||||
struct NoncubicSquares<T: Iterator<Item = u64>, U: Iterator<Item = u64>> {
|
||||
squares: Peekable<T>,
|
||||
cubes: Peekable<U>,
|
||||
}
|
||||
|
||||
impl<T: Iterator<Item = u64>, U: Iterator<Item = u64>> Iterator for NoncubicSquares<T, U> {
|
||||
type Item = u64;
|
||||
fn next(&mut self) -> Option<u64> {
|
||||
loop {
|
||||
match self.squares.peek()?.cmp(self.cubes.peek()?) {
|
||||
Ordering::Equal => self.squares.next(),
|
||||
Ordering::Greater => self.cubes.next(),
|
||||
Ordering::Less => return self.squares.next(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
noncubic_squares()
|
||||
.skip(20)
|
||||
.take(10)
|
||||
.for_each(|x| print!("{} ", x));
|
||||
println!();
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
object Generators {
|
||||
def main(args: Array[String]): Unit = {
|
||||
def squares(n:Int=0):Stream[Int]=(n*n) #:: squares(n+1)
|
||||
def cubes(n:Int=0):Stream[Int]=(n*n*n) #:: cubes(n+1)
|
||||
|
||||
def filtered(s:Stream[Int], c:Stream[Int]):Stream[Int]={
|
||||
if(s.head>c.head) filtered(s, c.tail)
|
||||
else if(s.head<c.head) Stream.cons(s.head, filtered(s.tail, c))
|
||||
else filtered(s.tail, c)
|
||||
}
|
||||
|
||||
filtered(squares(), cubes()) drop 20 take 10 print
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
def filtered2(s:Stream[Int], c:Stream[Int]):Stream[Int]=(s, c) match {
|
||||
case (sh#::_, ch#::ct) if (sh>ch) => filtered2(s, ct)
|
||||
case (sh#::st, ch#::_) if (sh<ch) => sh #:: filtered2(st, c)
|
||||
case (_#::st, _) => filtered2(st, c)
|
||||
}
|
||||
27
Task/Generator-Exponential/Scheme/generator-exponential-1.ss
Normal file
27
Task/Generator-Exponential/Scheme/generator-exponential-1.ss
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
(define (power-seq n)
|
||||
(let ((i 0))
|
||||
(lambda ()
|
||||
(set! i (+ 1 i))
|
||||
(expt i n))))
|
||||
|
||||
(define (filter-seq m n)
|
||||
(let* ((s1 (power-seq m)) (s2 (power-seq n))
|
||||
(a 0) (b 0))
|
||||
(lambda ()
|
||||
(set! a (s1))
|
||||
(let loop ()
|
||||
(if (>= a b) (begin
|
||||
(cond ((> a b) (set! b (s2)))
|
||||
((= a b) (set! a (s1))))
|
||||
(loop))))
|
||||
a)))
|
||||
|
||||
(let loop ((seq (filter-seq 2 3)) (i 0))
|
||||
(if (< i 30)
|
||||
(begin
|
||||
(if (> i 20)
|
||||
(begin
|
||||
(display (seq))
|
||||
(newline))
|
||||
(seq))
|
||||
(loop seq (+ 1 i)))))
|
||||
103
Task/Generator-Exponential/Scheme/generator-exponential-2.ss
Normal file
103
Task/Generator-Exponential/Scheme/generator-exponential-2.ss
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
;;; Generators using call/cc.
|
||||
|
||||
(cond-expand
|
||||
(r7rs)
|
||||
(chicken (import r7rs)))
|
||||
|
||||
(define-library (suspendable-procedures)
|
||||
(export suspend)
|
||||
(export make-generator-procedure)
|
||||
|
||||
(import (scheme base))
|
||||
|
||||
(begin
|
||||
|
||||
(define *suspend* (make-parameter (lambda (x) x)))
|
||||
(define (suspend v) ((*suspend*) v))
|
||||
|
||||
(define (make-generator-procedure thunk)
|
||||
;; This is for making a suspendable procedure that takes no
|
||||
;; arguments when resumed. The result is a simple generator of
|
||||
;; values.
|
||||
(define (next-run return)
|
||||
(define (my-suspend v)
|
||||
(set! return (call/cc (lambda (resumption-point)
|
||||
(set! next-run resumption-point)
|
||||
(return v)))))
|
||||
(parameterize ((*suspend* my-suspend))
|
||||
(suspend (thunk))))
|
||||
(lambda () (call/cc next-run)))
|
||||
|
||||
)) ;; end library (suspendable-procedures)
|
||||
|
||||
(import (scheme base))
|
||||
(import (scheme case-lambda))
|
||||
(import (scheme write))
|
||||
(import (suspendable-procedures))
|
||||
|
||||
(define (make-integers-generator i0)
|
||||
(make-generator-procedure
|
||||
(lambda ()
|
||||
(let loop ((i i0))
|
||||
(suspend i)
|
||||
(loop (+ i 1))))))
|
||||
|
||||
(define make-nth-powers-generator
|
||||
(case-lambda
|
||||
((n i0)
|
||||
(define next-int (make-integers-generator i0))
|
||||
(make-generator-procedure
|
||||
(lambda ()
|
||||
(let loop ()
|
||||
(suspend (expt (next-int) n))
|
||||
(loop)))))
|
||||
((n)
|
||||
(make-nth-powers-generator n 0))))
|
||||
|
||||
(define (make-filter-generator gen1 gen2)
|
||||
(make-generator-procedure
|
||||
(lambda ()
|
||||
(let loop ((x1 (gen1))
|
||||
(x2 (gen2)))
|
||||
(cond ((= x1 x2) (loop (gen1) x2)) ; Skip this x1.
|
||||
((< x1 x2) (begin ; Return this x1.
|
||||
(suspend x1)
|
||||
(loop (gen1) x2)))
|
||||
(else (loop x1 (gen2))))))))
|
||||
|
||||
(define (gen-drop n)
|
||||
(lambda (generator)
|
||||
(make-generator-procedure
|
||||
(lambda ()
|
||||
(do ((i 0 (+ i 1)))
|
||||
((= i n))
|
||||
(generator))
|
||||
(let loop ()
|
||||
(suspend (generator))
|
||||
(loop))))))
|
||||
|
||||
(define (gen-take n)
|
||||
(lambda (generator)
|
||||
(make-generator-procedure
|
||||
(lambda ()
|
||||
(do ((i 0 (+ i 1)))
|
||||
((= i n))
|
||||
(suspend (generator)))
|
||||
(let loop ()
|
||||
(suspend #f)
|
||||
(loop))))))
|
||||
|
||||
(define my-generator
|
||||
((gen-take 10)
|
||||
((gen-drop 20)
|
||||
(make-filter-generator
|
||||
(make-nth-powers-generator 2)
|
||||
(make-nth-powers-generator 3)))))
|
||||
|
||||
(let loop ()
|
||||
(let ((x (my-generator)))
|
||||
(when x
|
||||
(display " ")
|
||||
(display x)
|
||||
(loop))))
|
||||
(newline)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// ExponentialGenerator.script
|
||||
|
||||
to initialize
|
||||
set my base to 0
|
||||
if my exponent is empty then set my exponent to 1 -- default if not given
|
||||
end initialize
|
||||
|
||||
to handle nextValue
|
||||
add 1 to my base
|
||||
return my base to the power of my exponent
|
||||
end nextValue
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// FilteredGenerator.script
|
||||
|
||||
// Takes a source generator, and a filter generator, which must both produce increasing values
|
||||
// Produces values from the source generator that don't match values from the filter generator
|
||||
|
||||
to initialize
|
||||
set my nextFilteredValue to the nextValue of my filter
|
||||
end initialize
|
||||
|
||||
to handle nextValue
|
||||
put the nextValue of my source into value -- get a candidate value
|
||||
|
||||
-- advance the filter as needed if it is behind
|
||||
repeat while my nextFilteredValue is less than or equal to value
|
||||
-- advance value if it's equal to the next filtered value
|
||||
if my nextFilteredValue = value then set value to my source's nextValue
|
||||
set my nextFilteredValue to my filter's nextValue
|
||||
end repeat
|
||||
|
||||
return value
|
||||
end nextValue
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Main.script to use the generators
|
||||
|
||||
set squares to new ExponentialGenerator with {exponent:2}
|
||||
|
||||
set cubes to new ExponentialGenerator with {exponent:3}
|
||||
|
||||
put "First 10 Squares:"
|
||||
repeat 10 times
|
||||
put squares.nextValue
|
||||
end repeat
|
||||
|
||||
put "-" repeated 30 times
|
||||
|
||||
put "First 10 Cubes:"
|
||||
repeat 10 times
|
||||
put cubes.nextValue
|
||||
end repeat
|
||||
|
||||
put "-" repeated 30 times
|
||||
|
||||
set filteredSquares to new FilteredGenerator with {
|
||||
source: new ExponentialGenerator with {exponent:2},
|
||||
filter: new ExponentialGenerator with {exponent:3}
|
||||
}
|
||||
|
||||
repeat 20 times
|
||||
get filteredSquares.nextValue
|
||||
end repeat
|
||||
|
||||
put "Filtered Squares 21 to 30:"
|
||||
repeat with n=21 to 30
|
||||
put n & ":" && filteredSquares.nextValue
|
||||
end repeat
|
||||
28
Task/Generator-Exponential/Sidef/generator-exponential.sidef
Normal file
28
Task/Generator-Exponential/Sidef/generator-exponential.sidef
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
func gen_pow(m) {
|
||||
var e = 0;
|
||||
func { e++ ** m };
|
||||
}
|
||||
|
||||
func gen_filter(g1, g2) {
|
||||
var v2 = g2.run;
|
||||
func {
|
||||
loop {
|
||||
var v1 = g1.run;
|
||||
while (v1 > v2) { v2 = g2.run };
|
||||
v1 == v2 || return v1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create generators.
|
||||
var squares = gen_pow(2);
|
||||
var cubes = gen_pow(3);
|
||||
var squares_without_cubes = gen_filter(squares, cubes);
|
||||
|
||||
# Drop 20 values.
|
||||
20.times { squares_without_cubes() };
|
||||
|
||||
# Print 10 values.
|
||||
var answer = [];
|
||||
10.times { answer.append(squares_without_cubes()) };
|
||||
say answer;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
f = { |m| {:x, x<-(0..) } ** m };
|
||||
g = f.(2);
|
||||
g.nextN(10); // answers [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(
|
||||
f = Pseries(0, 1)
|
||||
g = f ** 2;
|
||||
g.asStream.nextN(10); // answers [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ]
|
||||
)
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
(
|
||||
var filter = { |a, b, func| // both streams are assumed to be ordered
|
||||
Prout {
|
||||
var astr, bstr;
|
||||
var aval, bval;
|
||||
astr = a.asStream;
|
||||
bstr = b.asStream;
|
||||
bval = bstr.next;
|
||||
while {
|
||||
aval = astr.next;
|
||||
aval.notNil
|
||||
} {
|
||||
while {
|
||||
bval.notNil and: { bval < aval }
|
||||
} {
|
||||
bval = bstr.next;
|
||||
};
|
||||
if(func.value(aval, bval)) { aval.yield };
|
||||
}
|
||||
}
|
||||
};
|
||||
var without = filter.(_, _, { |a, b| a != b }); // partially apply function
|
||||
|
||||
f = Pseries(0, 1);
|
||||
|
||||
g = without.(f ** 2, f ** 3);
|
||||
h = g.drop(20);
|
||||
h.asStream.nextN(10);
|
||||
)
|
||||
|
||||
answers: [ 529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089 ]
|
||||
47
Task/Generator-Exponential/Swift/generator-exponential.swift
Normal file
47
Task/Generator-Exponential/Swift/generator-exponential.swift
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
func powGen(m: Int) -> GeneratorOf<Int> {
|
||||
let power = Double(m)
|
||||
var cur: Double = 0
|
||||
return GeneratorOf { Int(pow(cur++, power)) }
|
||||
}
|
||||
|
||||
var squares = powGen(2)
|
||||
var cubes = powGen(3)
|
||||
|
||||
var nCube = cubes.next()
|
||||
|
||||
var filteredSqs = GeneratorOf<Int> {
|
||||
for var nSq = squares.next() ;; nCube = cubes.next() {
|
||||
if nCube > nSq {
|
||||
return nSq
|
||||
} else if nCube == nSq {
|
||||
nSq = squares.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension GeneratorOf {
|
||||
func drop(n: Int) -> GeneratorOf<T> {
|
||||
var g = self
|
||||
for _ in 0..<n {g.next()}
|
||||
return GeneratorOf{g.next()}
|
||||
}
|
||||
func take(n: Int) -> GeneratorOf<T> {
|
||||
var (i, g) = (0, self)
|
||||
return GeneratorOf{++i > n ? nil : g.next()}
|
||||
}
|
||||
}
|
||||
|
||||
for num in filteredSqs.drop(20).take(10) {
|
||||
print(num)
|
||||
}
|
||||
|
||||
//529
|
||||
//576
|
||||
//625
|
||||
//676
|
||||
//784
|
||||
//841
|
||||
//900
|
||||
//961
|
||||
//1024
|
||||
//1089
|
||||
31
Task/Generator-Exponential/Tcl/generator-exponential.tcl
Normal file
31
Task/Generator-Exponential/Tcl/generator-exponential.tcl
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package require Tcl 8.6
|
||||
|
||||
proc powers m {
|
||||
yield
|
||||
for {set n 0} true {incr n} {
|
||||
yield [expr {$n ** $m}]
|
||||
}
|
||||
}
|
||||
coroutine squares powers 2
|
||||
coroutine cubes powers 3
|
||||
coroutine filtered apply {{s1 s2} {
|
||||
yield
|
||||
set f [$s2]
|
||||
set v [$s1]
|
||||
while true {
|
||||
if {$v > $f} {
|
||||
set f [$s2]
|
||||
continue
|
||||
} elseif {$v < $f} {
|
||||
yield $v
|
||||
}
|
||||
set v [$s1]
|
||||
}
|
||||
}} squares cubes
|
||||
|
||||
# Drop 20
|
||||
for {set i 0} {$i<20} {incr i} {filtered}
|
||||
# Take/print 10
|
||||
for {} {$i<30} {incr i} {
|
||||
puts [filtered]
|
||||
}
|
||||
44
Task/Generator-Exponential/VBA/generator-exponential.vba
Normal file
44
Task/Generator-Exponential/VBA/generator-exponential.vba
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
Public lastsquare As Long
|
||||
Public nextsquare As Long
|
||||
Public lastcube As Long
|
||||
Public midcube As Long
|
||||
Public nextcube As Long
|
||||
Private Sub init()
|
||||
lastsquare = 1
|
||||
nextsquare = -1
|
||||
lastcube = -1
|
||||
midcube = 0
|
||||
nextcube = 1
|
||||
End Sub
|
||||
|
||||
Private Function squares() As Long
|
||||
lastsquare = lastsquare + nextsquare
|
||||
nextsquare = nextsquare + 2
|
||||
squares = lastsquare
|
||||
End Function
|
||||
|
||||
Private Function cubes() As Long
|
||||
lastcube = lastcube + nextcube
|
||||
nextcube = nextcube + midcube
|
||||
midcube = midcube + 6
|
||||
cubes = lastcube
|
||||
End Function
|
||||
|
||||
Public Sub main()
|
||||
init
|
||||
cube = cubes
|
||||
For i = 1 To 30
|
||||
Do While True
|
||||
square = squares
|
||||
Do While cube < square
|
||||
cube = cubes
|
||||
Loop
|
||||
If square <> cube Then
|
||||
Exit Do
|
||||
End If
|
||||
Loop
|
||||
If i > 20 Then
|
||||
Debug.Print square;
|
||||
End If
|
||||
Next i
|
||||
End Sub
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
Module Program
|
||||
Iterator Function IntegerPowers(exp As Integer) As IEnumerable(Of Integer)
|
||||
Dim i As Integer = 0
|
||||
Do
|
||||
Yield CInt(Math.Pow(i, exp))
|
||||
i += 1
|
||||
Loop
|
||||
End Function
|
||||
|
||||
Function Squares() As IEnumerable(Of Integer)
|
||||
Return IntegerPowers(2)
|
||||
End Function
|
||||
|
||||
Function Cubes() As IEnumerable(Of Integer)
|
||||
Return IntegerPowers(3)
|
||||
End Function
|
||||
|
||||
Iterator Function SquaresWithoutCubes() As IEnumerable(Of Integer)
|
||||
Dim cubeSequence = Cubes().GetEnumerator()
|
||||
Dim nextGreaterOrEqualCube As Integer = 0
|
||||
For Each curSquare In Squares()
|
||||
Do While nextGreaterOrEqualCube < curSquare
|
||||
cubeSequence.MoveNext()
|
||||
nextGreaterOrEqualCube = cubeSequence.Current
|
||||
Loop
|
||||
If nextGreaterOrEqualCube <> curSquare Then Yield curSquare
|
||||
Next
|
||||
End Function
|
||||
|
||||
Sub Main()
|
||||
For Each x In From i In SquaresWithoutCubes() Skip 20 Take 10
|
||||
Console.WriteLine(x)
|
||||
Next
|
||||
End Sub
|
||||
End Module
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue