A-M baby
This commit is contained in:
parent
764da6cbbb
commit
db842d013d
19005 changed files with 197040 additions and 7 deletions
14
Task/Generator-Exponential/0DESCRIPTION
Normal file
14
Task/Generator-Exponential/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
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 description'''
|
||||
|
||||
# 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 then show the next 10 values
|
||||
Note that this task ''requires'' the use of generators in the calculation of the result.
|
||||
|
||||
'''See also'''
|
||||
* [[wp:Generator (computer_science)|Generator]]
|
||||
|
|
@ -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, )) ))
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace RosettaGenerator
|
||||
{
|
||||
class ClosureStyle
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Func<int> squaresGenerator = PowerGeneratorAsClosure(2);
|
||||
Func<int> cubesGenerator = PowerGeneratorAsClosure(3);
|
||||
|
||||
Func<int> filter = FilterAsClosure(squaresGenerator, cubesGenerator);
|
||||
|
||||
foreach (int i in Enumerable.Range(0, 20))
|
||||
filter();
|
||||
foreach (int i in Enumerable.Range(21, 10))
|
||||
Console.Write(filter() + " ");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
public static Func<int> PowerGeneratorAsClosure(int exponent)
|
||||
{
|
||||
int x = 0;
|
||||
return () => { return (int)Math.Pow(x++, exponent); };
|
||||
}
|
||||
|
||||
public static Func<int> FilterAsClosure(Func<int> squaresGenerator, Func<int> cubesGenerator)
|
||||
{
|
||||
int squareValue;
|
||||
int cubeValue = cubesGenerator();
|
||||
return () =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
squareValue = squaresGenerator();
|
||||
while (squareValue > cubeValue)
|
||||
cubeValue = cubesGenerator();
|
||||
if (squareValue < cubeValue)
|
||||
return squareValue;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace RosettaGenerator
|
||||
{
|
||||
class ListStyle
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
IEnumerator<int> squaresGenerator = PowerGeneratorAsList(2);
|
||||
IEnumerator<int> cubesGenerator = PowerGeneratorAsList(3);
|
||||
|
||||
IEnumerable<int> filter = FilterAsList(squaresGenerator, cubesGenerator);
|
||||
|
||||
foreach (int value in filter.Skip(20).Take(10))
|
||||
Console.Write(value + " ");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
public static IEnumerator<int> PowerGeneratorAsList(int exponent)
|
||||
{
|
||||
int x = 0;
|
||||
while (true)
|
||||
yield return (int)Math.Pow(x++, exponent);
|
||||
}
|
||||
|
||||
public static IEnumerable<int> FilterAsList(IEnumerator<int> squaresGenerator, IEnumerator<int> cubesGenerator)
|
||||
{
|
||||
int squareValue;
|
||||
int cubeValue = cubesGenerator.Current;
|
||||
while (true)
|
||||
{
|
||||
squareValue = squaresGenerator.Current;
|
||||
while (squareValue > cubeValue)
|
||||
{
|
||||
cubesGenerator.MoveNext();
|
||||
cubeValue = cubesGenerator.Current;
|
||||
}
|
||||
if (squareValue < cubeValue)
|
||||
yield return squareValue;
|
||||
squaresGenerator.MoveNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
10
Task/Generator-Exponential/C/generator-exponential-3.c
Normal file
10
Task/Generator-Exponential/C/generator-exponential-3.c
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
529
|
||||
576
|
||||
625
|
||||
676
|
||||
784
|
||||
841
|
||||
900
|
||||
961
|
||||
1024
|
||||
1089
|
||||
|
|
@ -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))))
|
||||
61
Task/Generator-Exponential/D/generator-exponential-1.d
Normal file
61
Task/Generator-Exponential/D/generator-exponential-1.d
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
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 current, source, filter;
|
||||
|
||||
this(R1 r1, R2 r2) {
|
||||
s1 = r1;
|
||||
s2 = r2;
|
||||
source = s1.front();
|
||||
filter = s2.front();
|
||||
_next();
|
||||
}
|
||||
|
||||
const bool empty = false;
|
||||
@property T front() { return current; }
|
||||
void popFront() { _next(); }
|
||||
|
||||
private void _next() {
|
||||
while (true) {
|
||||
if (source > filter) {
|
||||
s2.popFront();
|
||||
filter = s2.front();
|
||||
continue;
|
||||
} else if (source < filter) {
|
||||
current = source;
|
||||
s1.popFront();
|
||||
source = s1.front();
|
||||
break;
|
||||
}
|
||||
s1.popFront();
|
||||
source = s1.front();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto filtered(R1, R2)(R1 r1, R2 r2)
|
||||
if (is(ElementType!R1 == ElementType!R2)) {
|
||||
return Filtered!(R1, R2)(r1, r2);
|
||||
}
|
||||
|
||||
struct Count(T) {
|
||||
T n;
|
||||
const bool empty = false;
|
||||
@property T front() { return n; }
|
||||
void popFront() { /* n++; */ n += 1; }
|
||||
}
|
||||
|
||||
Count!T count(T)(T start) { return Count!T(start); }
|
||||
Count!T count(T)() { return Count!T(cast(T)0); }
|
||||
|
||||
void main() {
|
||||
auto squares = count!BigInt().map!q{a ^^ 2}();
|
||||
auto cubes = count!BigInt().map!q{a ^^ 3}();
|
||||
auto f = filtered(squares, cubes);
|
||||
|
||||
popFrontN(f, 20);
|
||||
writeln(take(f, 10));
|
||||
}
|
||||
33
Task/Generator-Exponential/D/generator-exponential-2.d
Normal file
33
Task/Generator-Exponential/D/generator-exponential-2.d
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import std.stdio, std.traits;
|
||||
|
||||
auto powers(in double e) pure nothrow {
|
||||
double i = 0.0;
|
||||
return () => i++ ^^ e;
|
||||
}
|
||||
|
||||
auto filter(D)(D af, D bf) if (isCallable!D) {
|
||||
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 = filter(powers(2), powers(3));
|
||||
foreach (i; 0 .. 20)
|
||||
fgen();
|
||||
foreach (i; 0 .. 10)
|
||||
write(fgen(), " ");
|
||||
writeln();
|
||||
}
|
||||
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()
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
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()
|
||||
}
|
||||
12
Task/Generator-Exponential/Haskell/generator-exponential.hs
Normal file
12
Task/Generator-Exponential/Haskell/generator-exponential.hs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
powers m = map (^ m) [0..]
|
||||
|
||||
filtered (x:xs) (y:ys) | x > y = filtered (x:xs) ys
|
||||
| x < y = x : filtered xs (y:ys)
|
||||
| otherwise = filtered xs (y:ys)
|
||||
|
||||
squares = powers 2
|
||||
cubes = powers 3
|
||||
f = filtered squares cubes
|
||||
|
||||
main :: IO ()
|
||||
main = print $ take 10 $ drop 20 $ f
|
||||
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
|
||||
|
|
@ -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());
|
||||
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
|
||||
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";
|
||||
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.py
Normal file
19
Task/Generator-Exponential/Python/generator-exponential.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)))
|
||||
47
Task/Generator-Exponential/REXX/generator-exponential.rexx
Normal file
47
Task/Generator-Exponential/REXX/generator-exponential.rexx
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*REXX program to show how to use a generator (also known as iterators).*/
|
||||
numeric digits 10000 /*just in case we need big 'uns. */
|
||||
parse arg show; show = word(show 0, 1) /*show this many.*/
|
||||
@gen.= /*generators start from scratch. */
|
||||
do j=1 to show; call tell 'squares' ,gen_squares(j) ; end
|
||||
do j=1 to show; call tell 'cubes' ,gen_cubes(j) ; end
|
||||
do j=1 to show; call tell 'sq¬cubes',gen_sqNcubes(j) ; end
|
||||
if show>0 then say 'dropping 1st ──► 20th values.'
|
||||
do j=1 to 20; drop @gen.sqNcubes.j ; end
|
||||
do j=20+1 for 10 ; call tell 'sq¬cubes',gen_sqNcubes(j) ; end
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*─────────────────────────────────────gen_powers iterator──────────────*/
|
||||
gen_powers: procedure expose @gen.; parse arg x,p; if x=='' then return
|
||||
if @gen.powers.x.p=='' then @gen.powers.x.p=x**p; return @gen.powers.x.p
|
||||
/*─────────────────────────────────────gen_squares iterator─────────────*/
|
||||
gen_squares: procedure expose @gen.; parse arg x; if x=='' then return
|
||||
if @gen.squares.x=='' then do; call gen_powers x,2
|
||||
@gen.squares.x=@gen.powers.x.2
|
||||
end
|
||||
return @gen.squares.x
|
||||
/*─────────────────────────────────────gen_cubes iterator───────────────*/
|
||||
gen_cubes: procedure expose @gen.; parse arg x; if x=='' then return
|
||||
if @gen.cubes.j=='' then do; call gen_powers x,3
|
||||
@gen.cubes.x=@gen.powers.x.3
|
||||
end
|
||||
return @gen.cubes.x
|
||||
/*─────────────────────────────────────gen_squares not cubes iterator───*/
|
||||
gen_sqNcubes: procedure expose @gen.; parse arg x; if x=='' then return
|
||||
s=0
|
||||
if @gen.sqNcubes.x=='' then do j=1 to x
|
||||
if @gen.sqNcubes\=='' then do; sq=sq+1
|
||||
iterate
|
||||
end
|
||||
do s=s+1 /*slow way to weed out cubes*/
|
||||
?=gen_squares(s)
|
||||
do c=1 until gen_cubes(c)>?
|
||||
if gen_cubes(c)==? then iterate s
|
||||
end /*c*/
|
||||
leave
|
||||
end /*s*/
|
||||
@gen.sqNcubes.x=?
|
||||
@gen.sqNcubes.x=@gen.squares.s
|
||||
end /*j*/
|
||||
return @gen.sqNcubes.x
|
||||
/*──────────────────────────────────TELL subroutine─────────────────────*/
|
||||
tell: if j==1 then say /* [↓] format args to be aligned.*/
|
||||
say right(arg(1),20) right(j,5) right(arg(2),20); return
|
||||
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)
|
||||
21
Task/Generator-Exponential/Ruby/generator-exponential-1.rb
Normal file
21
Task/Generator-Exponential/Ruby/generator-exponential-1.rb
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# This solution cheats and uses only one generator!
|
||||
|
||||
def powers(m)
|
||||
return enum_for(:powers, m) unless block_given?
|
||||
|
||||
n = 0
|
||||
loop { yield n ** m; n += 1 }
|
||||
end
|
||||
|
||||
def squares_without_cubes
|
||||
return enum_for(:squares_without_cubes) unless block_given?
|
||||
|
||||
cubes = powers(3)
|
||||
c = cubes.next
|
||||
powers(2) do |s|
|
||||
(c = cubes.next) until c >= s
|
||||
yield s unless c == s
|
||||
end
|
||||
end
|
||||
|
||||
p squares_without_cubes.take(30).drop(20)
|
||||
25
Task/Generator-Exponential/Ruby/generator-exponential-2.rb
Normal file
25
Task/Generator-Exponential/Ruby/generator-exponential-2.rb
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# This solution uses three generators.
|
||||
|
||||
def powers(m)
|
||||
return enum_for(:powers, m) unless block_given?
|
||||
|
||||
n = 0
|
||||
loop { yield n ** m; n += 1 }
|
||||
end
|
||||
|
||||
def squares_without_cubes
|
||||
return enum_for(:squares_without_cubes) unless block_given?
|
||||
|
||||
cubes = powers(3)
|
||||
c = cubes.next
|
||||
squares = powers(2)
|
||||
loop do
|
||||
s = squares.next
|
||||
(c = cubes.next) until c >= s
|
||||
yield s unless c == s
|
||||
end
|
||||
end
|
||||
|
||||
answer = squares_without_cubes
|
||||
20.times { answer.next }
|
||||
p (1..10).map { answer.next }
|
||||
|
|
@ -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)))))
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
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]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue