Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Intersecting-number-wheels/00-META.yaml
Normal file
2
Task/Intersecting-number-wheels/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Intersecting_number_wheels
|
||||
61
Task/Intersecting-number-wheels/00-TASK.txt
Normal file
61
Task/Intersecting-number-wheels/00-TASK.txt
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
A number wheel has:
|
||||
* A ''name'' which is an uppercase letter.
|
||||
* A set of ordered ''values'' which are either ''numbers'' or ''names''.
|
||||
|
||||
<br>A ''number'' is generated/yielded from a named wheel by:
|
||||
:1. Starting at the first value of the named wheel and advancing through subsequent values and wrapping around to the first value to form a "wheel":
|
||||
::1.a If the value is a number, yield it.
|
||||
::1.b If the value is a name, yield the next value from the named wheel
|
||||
::1.c Advance the position of this wheel.
|
||||
|
||||
Given the wheel
|
||||
: <code>A: 1 2 3</code>
|
||||
the number 1 is first generated, then 2, then 3, 1, 2, 3, 1, ...
|
||||
|
||||
'''Note:''' When more than one wheel is defined as a set of intersecting wheels then the
|
||||
first named wheel is assumed to be the one that values are generated from.
|
||||
|
||||
;Examples:
|
||||
Given the wheels:
|
||||
A: 1 B 2
|
||||
B: 3 4
|
||||
The series of numbers generated starts:
|
||||
1, 3, 2, 1, 4, 2, 1, 3, 2, 1, 4, 2, 1, 3, 2...
|
||||
|
||||
The intersections of number wheels can be more complex, (and might loop forever),
|
||||
and wheels may be multiply connected. <br>
|
||||
|
||||
'''Note:''' If a named wheel is referenced more than
|
||||
once by one or many other wheels, then there is only one position of the wheel
|
||||
that is advanced by each and all references to it.
|
||||
|
||||
E.g.
|
||||
A: 1 D D
|
||||
D: 6 7 8
|
||||
Generates:
|
||||
1 6 7 1 8 6 1 7 8 1 6 7 1 8 6 1 7 8 1 6 ...
|
||||
|
||||
;Task:
|
||||
Generate and show the first twenty terms of the sequence of numbers generated
|
||||
from these groups:
|
||||
|
||||
Intersecting Number Wheel group:
|
||||
A: 1 2 3
|
||||
|
||||
Intersecting Number Wheel group:
|
||||
A: 1 B 2
|
||||
B: 3 4
|
||||
|
||||
Intersecting Number Wheel group:
|
||||
A: 1 D D
|
||||
D: 6 7 8
|
||||
|
||||
Intersecting Number Wheel group:
|
||||
A: 1 B C
|
||||
B: 3 4
|
||||
C: 5 B
|
||||
|
||||
Show your output here, on this page.
|
||||
|
||||
<br>
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
F nextfrom(&w, =name)
|
||||
L
|
||||
V nxt = w[name][0]
|
||||
w[name] = w[name][1..] + w[name][0.<1]
|
||||
I nxt[0] C ‘0’..‘9’
|
||||
R nxt
|
||||
name = nxt
|
||||
|
||||
L(group) |‘A: 1 2 3
|
||||
A: 1 B 2; B: 3 4
|
||||
A: 1 D D; D: 6 7 8
|
||||
A: 1 B C; B: 3 4; C: 5 B’.split("\n")
|
||||
print("Intersecting Number Wheel group:\n "group)
|
||||
[String = [String]] wheel
|
||||
V first = ‘’
|
||||
L(w) group.split(‘;’)
|
||||
V s = w.trim(‘ ’).split(‘ ’)
|
||||
V name = s[0]
|
||||
wheel[name[0 .< (len)-1]] = s[1..]
|
||||
first = I first == ‘’ {name[0 .< (len)-1]} E first
|
||||
V gen = (0.<20).map(i -> nextfrom(&@wheel, @first)).join(‘ ’)
|
||||
print(" Generates:\n "gen" ...\n")
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
BEGIN
|
||||
# a number wheel element #
|
||||
MODE NWELEMENT = UNION( CHAR # wheel name #, INT # wheel value # );
|
||||
# a number wheel #
|
||||
MODE NW = STRUCT( CHAR name, REF INT position, FLEX[ 1 : 0 ]NWELEMENT values );
|
||||
# get the next value from a number wheel in an array of number wheels #
|
||||
# note: invalid wheel names will cause subscript range errors #
|
||||
OP NEXT = ( []NW wheels )INT:
|
||||
BEGIN
|
||||
INT result;
|
||||
BOOL found := FALSE;
|
||||
INT w := LWB wheels; # start with the first wheel #
|
||||
WHILE NOT found DO
|
||||
IF position OF wheels[ w ] > UPB values OF wheels[ w ] THEN
|
||||
# passed the end of the wheel, go back to the start #
|
||||
position OF wheels[ w ] := LWB values OF wheels[ w ]
|
||||
FI;
|
||||
NWELEMENT e = ( values OF wheels[ w ] )[ position OF wheels[ w ] ];
|
||||
position OF wheels[ w ] +:= 1;
|
||||
CASE e
|
||||
IN ( INT n ): BEGIN result := n; found := TRUE END
|
||||
, ( CHAR c ): BEGIN
|
||||
w := LWB wheels;
|
||||
WHILE name OF wheels[ w ] /= c DO w +:= 1 OD
|
||||
END
|
||||
ESAC
|
||||
OD;
|
||||
result
|
||||
END # NEXT # ;
|
||||
# prints the first n values from an array of wheels #
|
||||
PROC show = ( INT n, []NW wheels )VOID:
|
||||
BEGIN
|
||||
print( ( "First ", whole( n, 0 ), " values from the Intersecting Number Wheels:" ) );
|
||||
FOR i FROM LWB wheels TO UPB wheels DO
|
||||
print( ( newline, " ", name OF wheels[ i ], ":" ) );
|
||||
FOR v FROM LWB values OF wheels[ i ] TO UPB values OF wheels[ i ] DO
|
||||
CASE ( values OF wheels[ i ] )[ v ]
|
||||
IN ( INT n ): print( ( " ", whole( n, 0 ) ) )
|
||||
, ( CHAR c ): print( ( " ", c ) )
|
||||
ESAC
|
||||
OD
|
||||
OD;
|
||||
print( ( newline, " " ) );
|
||||
FOR i TO n DO print( ( " ", whole( NEXT wheels, 0 ) ) ) OD;
|
||||
print( ( newline, newline ) )
|
||||
END # show # ;
|
||||
# show some wheels in action #
|
||||
show( 20, ( NW( "A", LOC INT := 1, ( 1, 2, 3 ) ) ) );
|
||||
show( 20, ( NW( "A", LOC INT := 1, ( 1, "B", 2 ) )
|
||||
, NW( "B", LOC INT := 1, ( 3, 4 ) ) ) );
|
||||
show( 20, ( NW( "A", LOC INT := 1, ( 1, "D", "D" ) )
|
||||
, NW( "D", LOC INT := 1, ( 6, 7, 8 ) ) ) );
|
||||
show( 20, ( NW( "A", LOC INT := 1, ( 1, "B", "C" ) )
|
||||
, NW( "B", LOC INT := 1, ( 3, 4 ) )
|
||||
, NW( "C", LOC INT := 1, ( 5, "B" ) ) ) )
|
||||
END
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
obj1 := {"A":[1, 2, 3]}
|
||||
obj2 := {"A":[1, "B", 2] , "B":[3, 4]}
|
||||
obj3 := {"A":[1, "D", "D"] , "D":[6, 7, 8]}
|
||||
obj4 := {"A":[1, "B", "C"] , "B":[3, 4] , "C":[5, "B"]}
|
||||
|
||||
loop 4
|
||||
{
|
||||
str := ""
|
||||
for k, v in obj%A_Index% {
|
||||
str .= "{" k " : "
|
||||
for i, t in v
|
||||
str .= t ","
|
||||
str := Trim(str, ",") "}, "
|
||||
}
|
||||
str := Trim(str, ", ")
|
||||
x := INW(obj%A_Index%)
|
||||
result .= str "`n" x.1 "`n" x.2 "`n------`n"
|
||||
}
|
||||
MsgBox % result
|
||||
return
|
||||
|
||||
INW(obj, num:=20){
|
||||
sets := [], ptr := []
|
||||
for k, v in obj {
|
||||
if A_Index=1
|
||||
s := k, s1 := k
|
||||
%k% := v, sets.Push(k), ptr[k] := 0
|
||||
}
|
||||
loop % num {
|
||||
ptr[s]++
|
||||
while !((v := %s%[ptr[s]]) ~= "\d") {
|
||||
s := %s%[ptr[s]]
|
||||
ptr[s]++
|
||||
}
|
||||
key .= s "." ptr[s] ", "
|
||||
result .= %s%[ptr[s]] " "
|
||||
s := s1
|
||||
for i, set in sets
|
||||
ptr[set] := ptr[set] = %set%.count() ? 0 : ptr[set]
|
||||
}
|
||||
return [key, result]
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
#include <initializer_list>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
struct Wheel {
|
||||
private:
|
||||
std::vector<char> values;
|
||||
size_t index;
|
||||
|
||||
public:
|
||||
Wheel() : index(0) {
|
||||
// empty
|
||||
}
|
||||
|
||||
Wheel(std::initializer_list<char> data) : values(data), index(0) {
|
||||
//values.assign(data);
|
||||
if (values.size() < 1) {
|
||||
throw new std::runtime_error("Not enough elements");
|
||||
}
|
||||
}
|
||||
|
||||
char front() {
|
||||
return values[index];
|
||||
}
|
||||
|
||||
void popFront() {
|
||||
index = (index + 1) % values.size();
|
||||
}
|
||||
};
|
||||
|
||||
struct NamedWheel {
|
||||
private:
|
||||
std::map<char, Wheel> wheels;
|
||||
|
||||
public:
|
||||
void put(char c, Wheel w) {
|
||||
wheels[c] = w;
|
||||
}
|
||||
|
||||
char front(char c) {
|
||||
char v = wheels[c].front();
|
||||
while ('A' <= v && v <= 'Z') {
|
||||
v = wheels[v].front();
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
void popFront(char c) {
|
||||
auto v = wheels[c].front();
|
||||
wheels[c].popFront();
|
||||
|
||||
while ('A' <= v && v <= 'Z') {
|
||||
auto d = wheels[v].front();
|
||||
wheels[v].popFront();
|
||||
v = d;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void group1() {
|
||||
Wheel w({ '1', '2', '3' });
|
||||
for (size_t i = 0; i < 20; i++) {
|
||||
std::cout << ' ' << w.front();
|
||||
w.popFront();
|
||||
}
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
void group2() {
|
||||
Wheel a({ '1', 'B', '2' });
|
||||
Wheel b({ '3', '4' });
|
||||
|
||||
NamedWheel n;
|
||||
n.put('A', a);
|
||||
n.put('B', b);
|
||||
|
||||
for (size_t i = 0; i < 20; i++) {
|
||||
std::cout << ' ' << n.front('A');
|
||||
n.popFront('A');
|
||||
}
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
void group3() {
|
||||
Wheel a({ '1', 'D', 'D' });
|
||||
Wheel d({ '6', '7', '8' });
|
||||
|
||||
NamedWheel n;
|
||||
n.put('A', a);
|
||||
n.put('D', d);
|
||||
|
||||
for (size_t i = 0; i < 20; i++) {
|
||||
std::cout << ' ' << n.front('A');
|
||||
n.popFront('A');
|
||||
}
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
void group4() {
|
||||
Wheel a({ '1', 'B', 'C' });
|
||||
Wheel b({ '3', '4' });
|
||||
Wheel c({ '5', 'B' });
|
||||
|
||||
NamedWheel n;
|
||||
n.put('A', a);
|
||||
n.put('B', b);
|
||||
n.put('C', c);
|
||||
|
||||
for (size_t i = 0; i < 20; i++) {
|
||||
std::cout << ' ' << n.front('A');
|
||||
n.popFront('A');
|
||||
}
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
int main() {
|
||||
group1();
|
||||
group2();
|
||||
group3();
|
||||
group4();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
public static class IntersectingNumberWheels
|
||||
{
|
||||
public static void Main() {
|
||||
TurnWheels(('A', "123")).Take(20).Print();
|
||||
TurnWheels(('A', "1B2"), ('B', "34")).Take(20).Print();
|
||||
TurnWheels(('A', "1DD"), ('D', "678")).Take(20).Print();
|
||||
TurnWheels(('A', "1BC"), ('B', "34"), ('C', "5B")).Take(20).Print();
|
||||
}
|
||||
|
||||
static IEnumerable<char> TurnWheels(params (char name, string values)[] wheels) {
|
||||
var data = wheels.ToDictionary(wheel => wheel.name, wheel => wheel.values.Loop().GetEnumerator());
|
||||
var primary = data[wheels[0].name];
|
||||
while (true) {
|
||||
yield return Turn(primary);
|
||||
}
|
||||
|
||||
char Turn(IEnumerator<char> sequence) {
|
||||
sequence.MoveNext();
|
||||
char c = sequence.Current;
|
||||
return char.IsDigit(c) ? c : Turn(data[c]);
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable<T> Loop<T>(this IEnumerable<T> seq) {
|
||||
while (true) {
|
||||
foreach (T element in seq) yield return element;
|
||||
}
|
||||
}
|
||||
|
||||
static void Print(this IEnumerable<char> sequence) => Console.WriteLine(string.Join(" ", sequence));
|
||||
}
|
||||
141
Task/Intersecting-number-wheels/C/intersecting-number-wheels.c
Normal file
141
Task/Intersecting-number-wheels/C/intersecting-number-wheels.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct Wheel {
|
||||
char *seq;
|
||||
int len;
|
||||
int pos;
|
||||
};
|
||||
|
||||
struct Wheel *create(char *seq) {
|
||||
struct Wheel *w = malloc(sizeof(struct Wheel));
|
||||
if (w == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
w->seq = seq;
|
||||
w->len = strlen(seq);
|
||||
w->pos = 0;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
char cycle(struct Wheel *w) {
|
||||
char c = w->seq[w->pos];
|
||||
w->pos = (w->pos + 1) % w->len;
|
||||
return c;
|
||||
}
|
||||
|
||||
struct Map {
|
||||
struct Wheel *v;
|
||||
struct Map *next;
|
||||
char k;
|
||||
};
|
||||
|
||||
struct Map *insert(char k, struct Wheel *v, struct Map *head) {
|
||||
struct Map *m = malloc(sizeof(struct Map));
|
||||
if (m == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m->k = k;
|
||||
m->v = v;
|
||||
m->next = head;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
struct Wheel *find(char k, struct Map *m) {
|
||||
struct Map *ptr = m;
|
||||
|
||||
while (ptr != NULL) {
|
||||
if (ptr->k == k) {
|
||||
return ptr->v;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void printOne(char k, struct Map *m) {
|
||||
struct Wheel *w = find(k, m);
|
||||
char c;
|
||||
|
||||
if (w == NULL) {
|
||||
printf("Missing the wheel for: %c\n", k);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = cycle(w);
|
||||
if ('0' <= c && c <= '9') {
|
||||
printf(" %c", c);
|
||||
} else {
|
||||
printOne(c, m);
|
||||
}
|
||||
}
|
||||
|
||||
void exec(char start, struct Map *m) {
|
||||
struct Wheel *w;
|
||||
int i;
|
||||
|
||||
if (m == NULL) {
|
||||
printf("Unable to proceed.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 20; i++) {
|
||||
printOne(start, m);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void group1() {
|
||||
struct Wheel *a = create("123");
|
||||
|
||||
struct Map *m = insert('A', a, NULL);
|
||||
|
||||
exec('A', m);
|
||||
}
|
||||
|
||||
void group2() {
|
||||
struct Wheel *a = create("1B2");
|
||||
struct Wheel *b = create("34");
|
||||
|
||||
struct Map *m = insert('A', a, NULL);
|
||||
m = insert('B', b, m);
|
||||
|
||||
exec('A', m);
|
||||
}
|
||||
|
||||
void group3() {
|
||||
struct Wheel *a = create("1DD");
|
||||
struct Wheel *d = create("678");
|
||||
|
||||
struct Map *m = insert('A', a, NULL);
|
||||
m = insert('D', d, m);
|
||||
|
||||
exec('A', m);
|
||||
}
|
||||
|
||||
void group4() {
|
||||
struct Wheel *a = create("1BC");
|
||||
struct Wheel *b = create("34");
|
||||
struct Wheel *c = create("5B");
|
||||
|
||||
struct Map *m = insert('A', a, NULL);
|
||||
m = insert('B', b, m);
|
||||
m = insert('C', c, m);
|
||||
|
||||
exec('A', m);
|
||||
}
|
||||
|
||||
int main() {
|
||||
group1();
|
||||
group2();
|
||||
group3();
|
||||
group4();
|
||||
|
||||
return 0;
|
||||
}
|
||||
110
Task/Intersecting-number-wheels/D/intersecting-number-wheels.d
Normal file
110
Task/Intersecting-number-wheels/D/intersecting-number-wheels.d
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
import std.exception;
|
||||
import std.range;
|
||||
import std.stdio;
|
||||
|
||||
struct Wheel {
|
||||
private string[] values;
|
||||
private uint index;
|
||||
|
||||
invariant {
|
||||
enforce(index < values.length, "index out of range");
|
||||
}
|
||||
|
||||
this(string[] value...) in {
|
||||
enforce(value.length > 0, "Cannot create a wheel with no elements");
|
||||
} body {
|
||||
values = value;
|
||||
}
|
||||
|
||||
enum empty = false;
|
||||
|
||||
auto front() {
|
||||
return values[index];
|
||||
}
|
||||
|
||||
void popFront() {
|
||||
index = (index + 1) % values.length;
|
||||
}
|
||||
}
|
||||
|
||||
struct NamedWheel {
|
||||
private Wheel[char] wheels;
|
||||
char m;
|
||||
|
||||
this(char c, Wheel w) {
|
||||
add(c, w);
|
||||
m = c;
|
||||
}
|
||||
|
||||
void add(char c, Wheel w) {
|
||||
wheels[c] = w;
|
||||
}
|
||||
|
||||
enum empty = false;
|
||||
|
||||
auto front() {
|
||||
auto v = wheels[m].front;
|
||||
char c = v[0];
|
||||
while ('A' <= c && c <= 'Z') {
|
||||
v = wheels[c].front;
|
||||
c = v[0];
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
void popFront() {
|
||||
auto v = wheels[m].front;
|
||||
wheels[m].popFront;
|
||||
|
||||
char c = v[0];
|
||||
while ('A' <= c && c <= 'Z') {
|
||||
auto d = wheels[c].front;
|
||||
wheels[c].popFront;
|
||||
c = d[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void group1() {
|
||||
auto a = Wheel("1", "2", "3");
|
||||
a.take(20).writeln;
|
||||
}
|
||||
|
||||
void group2() {
|
||||
auto a = Wheel("1", "B", "2");
|
||||
auto b = Wheel("3", "4");
|
||||
|
||||
auto n = NamedWheel('A', a);
|
||||
n.add('B', b);
|
||||
|
||||
n.take(20).writeln;
|
||||
}
|
||||
|
||||
void group3() {
|
||||
auto a = Wheel("1", "D", "D");
|
||||
auto d = Wheel("6", "7", "8");
|
||||
|
||||
auto n = NamedWheel('A', a);
|
||||
n.add('D', d);
|
||||
|
||||
n.take(20).writeln;
|
||||
}
|
||||
|
||||
void group4() {
|
||||
auto a = Wheel("1", "B", "C");
|
||||
auto b = Wheel("3", "4");
|
||||
auto c = Wheel("5", "B");
|
||||
|
||||
auto n = NamedWheel('A', a);
|
||||
n.add('B', b);
|
||||
n.add('C', c);
|
||||
|
||||
n.take(20).writeln;
|
||||
}
|
||||
|
||||
void main() {
|
||||
group1();
|
||||
group2();
|
||||
group3();
|
||||
group4();
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Wheels within wheels. Nigel Galloway: September 30th., 2019.
|
||||
let N(n)=fun()->n
|
||||
let wheel(n:(unit->int)[])=let mutable g= -1 in (fun()->g<-(g+1)%n.Length; n.[g]())
|
||||
let A1=wheel[|N(1);N(2);N(3)|]
|
||||
for n in 0..20 do printf "%d " (A1())
|
||||
printfn ""
|
||||
let B2=wheel[|N(3);N(4)|]
|
||||
let A2=wheel[|N(1);B2;N(2)|]
|
||||
for n in 0..20 do printf "%d " (A2())
|
||||
printfn ""
|
||||
let D3=wheel[|N(6);N(7);N(8)|]
|
||||
let A3=wheel[|N(1);D3;D3|]
|
||||
for n in 0..20 do printf "%d " (A3())
|
||||
printfn ""
|
||||
let B4=wheel[|N(3);N(4)|]
|
||||
let C4=wheel[|N(5);B4|]
|
||||
let A4=wheel[|N(1);B4;C4|]
|
||||
for n in 0..20 do printf "%d " (A4())
|
||||
printfn ""
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
USING: accessors assocs circular io kernel lists lists.lazy math
|
||||
math.parser multiline peg.ebnf prettyprint prettyprint.custom
|
||||
sequences strings ;
|
||||
IN: rosetta-code.number-wheels
|
||||
|
||||
TUPLE: group pretty list ;
|
||||
|
||||
C: <group> group
|
||||
|
||||
M: group pprint* pretty>> write ;
|
||||
|
||||
TUPLE: number-wheel seq i ;
|
||||
|
||||
: <number-wheel> ( seq -- number-wheel )
|
||||
<circular> 0 number-wheel boa ;
|
||||
|
||||
: yield ( assoc -- n )
|
||||
dup first first [ dup integer? ]
|
||||
[ dupd of [ i>> ] [ [ 1 + ] change-i seq>> nth ] bi ] until
|
||||
nip ;
|
||||
|
||||
: number-wheel>lazy ( assoc -- list )
|
||||
0 lfrom swap [ yield nip ] curry lmap-lazy ;
|
||||
|
||||
EBNF: nw-parser [=[
|
||||
num = [0-9]+ => [[ >string string>number ]]
|
||||
name = [a-zA-Z]+ => [[ >string ]]
|
||||
wheel = (" "~ (num | name))+ "\n"?
|
||||
=> [[ but-last first <number-wheel> ]]
|
||||
group = (name ":"~ wheel)+ => [[ number-wheel>lazy ]]
|
||||
]=]
|
||||
|
||||
SYNTAX: NUMBER-WHEELS: parse-here dup nw-parser <group> suffix! ;
|
||||
|
||||
: .take ( n group -- )
|
||||
list>> ltake list>array [ pprint bl ] each "..." print ;
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
USING: generalizations io kernel prettyprint
|
||||
rosetta-code.number-wheels ;
|
||||
|
||||
NUMBER-WHEELS:
|
||||
A: 1 2 3
|
||||
;
|
||||
|
||||
NUMBER-WHEELS:
|
||||
A: 1 B 2
|
||||
B: 3 4
|
||||
;
|
||||
|
||||
NUMBER-WHEELS:
|
||||
A: 1 D D
|
||||
D: 6 7 8
|
||||
;
|
||||
|
||||
NUMBER-WHEELS:
|
||||
A: 1 B C
|
||||
B: 3 4
|
||||
C: 5 B
|
||||
;
|
||||
|
||||
[
|
||||
"Intersecting number wheel group:" print
|
||||
[ . ] [ "Generates:" print 20 swap .take nl ] bi
|
||||
] 4 napply
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type wheel struct {
|
||||
next int
|
||||
values []string
|
||||
}
|
||||
|
||||
type wheelMap = map[string]wheel
|
||||
|
||||
func generate(wheels wheelMap, start string, maxCount int) {
|
||||
count := 0
|
||||
w := wheels[start]
|
||||
for {
|
||||
s := w.values[w.next]
|
||||
v, err := strconv.Atoi(s)
|
||||
w.next = (w.next + 1) % len(w.values)
|
||||
wheels[start] = w
|
||||
if err == nil {
|
||||
fmt.Printf("%d ", v)
|
||||
count++
|
||||
if count == maxCount {
|
||||
fmt.Println("...\n")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
for {
|
||||
w2 := wheels[s]
|
||||
ss := s
|
||||
s = w2.values[w2.next]
|
||||
w2.next = (w2.next + 1) % len(w2.values)
|
||||
wheels[ss] = w2
|
||||
v, err = strconv.Atoi(s)
|
||||
if err == nil {
|
||||
fmt.Printf("%d ", v)
|
||||
count++
|
||||
if count == maxCount {
|
||||
fmt.Println("...\n")
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printWheels(wheels wheelMap) {
|
||||
var names []string
|
||||
for name := range wheels {
|
||||
names = append(names, name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
fmt.Println("Intersecting Number Wheel group:")
|
||||
for _, name := range names {
|
||||
fmt.Printf(" %s: %v\n", name, wheels[name].values)
|
||||
}
|
||||
fmt.Print(" Generates:\n ")
|
||||
}
|
||||
|
||||
func main() {
|
||||
wheelMaps := []wheelMap{
|
||||
{
|
||||
"A": {0, []string{"1", "2", "3"}},
|
||||
},
|
||||
{
|
||||
"A": {0, []string{"1", "B", "2"}},
|
||||
"B": {0, []string{"3", "4"}},
|
||||
},
|
||||
{
|
||||
"A": {0, []string{"1", "D", "D"}},
|
||||
"D": {0, []string{"6", "7", "8"}},
|
||||
},
|
||||
{
|
||||
"A": {0, []string{"1", "B", "C"}},
|
||||
"B": {0, []string{"3", "4"}},
|
||||
"C": {0, []string{"5", "B"}},
|
||||
},
|
||||
}
|
||||
for _, wheels := range wheelMaps {
|
||||
printWheels(wheels)
|
||||
generate(wheels, "A", 20)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import Data.Char (isDigit)
|
||||
import Data.List (mapAccumL)
|
||||
import qualified Data.Map.Strict as M
|
||||
import Data.Maybe (fromMaybe)
|
||||
|
||||
---------------- INTERSECTING NUMBER WHEELS --------------
|
||||
|
||||
clockWorkTick ::
|
||||
M.Map Char String ->
|
||||
(M.Map Char String, Char)
|
||||
clockWorkTick = flip click 'A'
|
||||
where
|
||||
click wheels name
|
||||
| isDigit name = (wheels, name)
|
||||
| otherwise =
|
||||
( click
|
||||
. flip
|
||||
(M.insert name . leftRotate)
|
||||
wheels
|
||||
<*> head
|
||||
)
|
||||
$ fromMaybe ['?'] $ M.lookup name wheels
|
||||
|
||||
leftRotate :: [a] -> [a]
|
||||
leftRotate = take . length <*> (tail . cycle)
|
||||
|
||||
--------------------------- TEST -------------------------
|
||||
main :: IO ()
|
||||
main = do
|
||||
let wheelSets =
|
||||
[ [('A', "123")],
|
||||
[('A', "1B2"), ('B', "34")],
|
||||
[('A', "1DD"), ('D', "678")],
|
||||
[('A', "1BC"), ('B', "34"), ('C', "5B")]
|
||||
]
|
||||
putStrLn "State of each wheel-set after 20 clicks:\n"
|
||||
mapM_ print $
|
||||
fmap
|
||||
( flip
|
||||
(mapAccumL (const . clockWorkTick))
|
||||
(replicate 20 undefined)
|
||||
. M.fromList
|
||||
)
|
||||
wheelSets
|
||||
putStrLn "\nInitial state of the wheel-sets:\n"
|
||||
mapM_ print wheelSets
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
wheelgroup=:{{
|
||||
yield_wheelgroup_=: {{
|
||||
i=. wheels i.<;y
|
||||
j=. i{inds
|
||||
k=. ".;y
|
||||
l=. j{k
|
||||
inds=: ((#k)|1+j) i} inds
|
||||
if. l e. wheels
|
||||
do.yield l
|
||||
else.{.".;l
|
||||
end.
|
||||
}}
|
||||
gen_wheelgroup_=: {{
|
||||
yield wheel
|
||||
}}
|
||||
grp=. cocreate ''
|
||||
coinsert__grp 'wheelgroup'
|
||||
specs__grp=: cut each boxopen m
|
||||
wheel__grp=: ;{.wheels__grp=: {.every specs__grp
|
||||
init__grp=: {{('inds';wheels)=:(0#~#specs);}.each specs}}
|
||||
init__grp''
|
||||
('gen_',(;grp),'_')~
|
||||
}}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
task=: {{y wheelgroup^:(1+i.20)_}}
|
||||
task 'A 1 2 3'
|
||||
1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2
|
||||
task 'A 1 B 2';'B 3 4'
|
||||
1 3 2 1 4 2 1 3 2 1 4 2 1 3 2 1 4 2 1 3
|
||||
task 'A 1 D D';'D 6 7 8'
|
||||
1 6 7 1 8 6 1 7 8 1 6 7 1 8 6 1 7 8 1 6
|
||||
task 'A 1 B C';'B 3 4';'C 5 B'
|
||||
1 3 5 1 4 3 1 4 5 1 3 4 1 3 5 1 4 3 1 4
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package intersectingNumberWheels;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class WheelController {
|
||||
private static final String IS_NUMBER = "[0-9]";
|
||||
private static final int TWENTY = 20;
|
||||
private static Map<String, WheelModel> wheelMap;
|
||||
|
||||
public static void advance(String wheel) {
|
||||
WheelModel w = wheelMap.get(wheel);
|
||||
if (w.list.get(w.position).matches(IS_NUMBER)) {
|
||||
w.printThePosition();
|
||||
w.advanceThePosition();
|
||||
} else {
|
||||
String wheelName = w.list.get(w.position);
|
||||
advance(wheelName);
|
||||
w.advanceThePosition();
|
||||
}
|
||||
}
|
||||
|
||||
public static void run() {
|
||||
System.out.println(wheelMap);
|
||||
IntStream.rangeClosed(1, TWENTY).forEach(i -> advance("A"));
|
||||
System.out.println();
|
||||
wheelMap.clear();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
wheelMap = new HashMap<>();
|
||||
wheelMap.put("A", new WheelModel("A", "1", "2", "3"));
|
||||
run();
|
||||
wheelMap.put("A", new WheelModel("A", "1", "B", "2"));
|
||||
wheelMap.put("B", new WheelModel("B", "3", "4"));
|
||||
run();
|
||||
wheelMap.put("A", new WheelModel("A", "1", "D", "D"));
|
||||
wheelMap.put("D", new WheelModel("D", "6", "7", "8"));
|
||||
run();
|
||||
wheelMap.put("A", new WheelModel("A", "1", "B", "C"));
|
||||
wheelMap.put("B", new WheelModel("B", "3", "4"));
|
||||
wheelMap.put("C", new WheelModel("C", "5", "B"));
|
||||
run();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WheelModel {
|
||||
String name;
|
||||
List<String> list;
|
||||
int position;
|
||||
int endPosition;
|
||||
private static final int INITIAL = 0;
|
||||
|
||||
public WheelModel(String name, String... values) {
|
||||
super();
|
||||
|
||||
this.name = name.toUpperCase();
|
||||
this.list = new ArrayList<>();
|
||||
for (String value : values) {
|
||||
list.add(value);
|
||||
}
|
||||
this.position = INITIAL;
|
||||
this.endPosition = this.list.size() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return list.toString();
|
||||
}
|
||||
|
||||
public void advanceThePosition() {
|
||||
if (this.position == this.endPosition) {
|
||||
this.position = INITIAL;// new beginning
|
||||
} else {
|
||||
this.position++;// advance position
|
||||
}
|
||||
}
|
||||
|
||||
public void printThePosition() {
|
||||
System.out.print(" " + this.list.get(position));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// main :: IO ()
|
||||
const main = () => {
|
||||
|
||||
// clockWorkTick :: Dict -> (Dict, Char)
|
||||
const clockWorkTick = wheelMap => {
|
||||
// The new configuration of the wheels, tupled with
|
||||
// a digit found by recursive descent from a single
|
||||
// click of the first wheel.
|
||||
const click = wheels => wheelName => {
|
||||
const
|
||||
wheel = wheels[wheelName] || ['?'],
|
||||
v = wheel[0];
|
||||
return bool(click)(Tuple)(isDigit(v) || '?' === v)(
|
||||
insertDict(wheelName)(
|
||||
leftRotate(wheel)
|
||||
)(wheels)
|
||||
)(v);
|
||||
};
|
||||
return click(wheelMap)('A');
|
||||
};
|
||||
|
||||
// leftRotate ::[a] -> [a]
|
||||
const leftRotate = xs =>
|
||||
// The head of the list appended
|
||||
// to the tail of of the list.
|
||||
0 < xs.length ? (
|
||||
xs.slice(1).concat(xs[0])
|
||||
) : [];
|
||||
|
||||
|
||||
// TEST -------------------------------------------
|
||||
// State of each wheel-set after 20 clicks,
|
||||
// paired with the resulting series of characters.
|
||||
|
||||
const tuple = uncurry(Tuple);
|
||||
const wheelLists = [
|
||||
[tuple('A', '123')],
|
||||
[tuple('A', '1B2'), tuple('B', '34')],
|
||||
[tuple('A', '1DD'), tuple('D', '678')],
|
||||
[tuple('A', '1BC'), tuple('B', '34'), tuple('C', '5B')]
|
||||
];
|
||||
|
||||
console.log([
|
||||
'Series and state of each wheel-set after 20 clicks:\n',
|
||||
unlines(
|
||||
map(tuples => showWheels(
|
||||
mapAccumL(
|
||||
compose(constant, clockWorkTick)
|
||||
)(dictFromList(tuples))(replicate(20)(''))
|
||||
))(wheelLists)
|
||||
),
|
||||
'\nInitial state of each wheel-set:\n',
|
||||
map(map(compose(
|
||||
JSON.stringify,
|
||||
dictFromList,
|
||||
x => [Array.from(x)]
|
||||
)))(wheelLists).join('\n')
|
||||
].join('\n'));
|
||||
};
|
||||
|
||||
// DISPLAY FORMATTING ---------------------------------
|
||||
|
||||
// showWheels :: (Dict, [Char]) -> String
|
||||
const showWheels = tpl =>
|
||||
JSON.stringify(
|
||||
Array.from(secondArrow(concat)(tpl))
|
||||
);
|
||||
|
||||
// GENERIC FUNCTIONS ----------------------------------
|
||||
|
||||
// Tuple (,) :: a -> b -> (a, b)
|
||||
const Tuple = a => b => ({
|
||||
type: 'Tuple',
|
||||
'0': a,
|
||||
'1': b,
|
||||
length: 2
|
||||
});
|
||||
|
||||
// bool :: a -> a -> Bool -> a
|
||||
const bool = f => t => p =>
|
||||
p ? t : f;
|
||||
|
||||
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
||||
const compose = (...fs) =>
|
||||
x => fs.reduceRight((a, f) => f(a), x);
|
||||
|
||||
// concat :: [[a]] -> [a]
|
||||
// concat :: [String] -> String
|
||||
const concat = xs =>
|
||||
0 < xs.length ? (() => {
|
||||
const unit = 'string' !== typeof xs[0] ? (
|
||||
[]
|
||||
) : '';
|
||||
return unit.concat.apply(unit, xs);
|
||||
})() : [];
|
||||
|
||||
// constant :: a -> b -> a
|
||||
const constant = k => _ => k;
|
||||
|
||||
// dictFromList :: [(k, v)] -> Dict
|
||||
const dictFromList = kvs =>
|
||||
Object.fromEntries(kvs);
|
||||
|
||||
// secondArrow :: (a -> b) -> ((c, a) -> (c, b))
|
||||
const secondArrow = f => xy =>
|
||||
// A function over a simple value lifted
|
||||
// to a function over a tuple.
|
||||
// f (a, b) -> (a, f(b))
|
||||
Tuple(xy[0])(
|
||||
f(xy[1])
|
||||
);
|
||||
|
||||
// insertDict :: String -> a -> Dict -> Dict
|
||||
const insertDict = k => v => dct =>
|
||||
Object.assign({}, dct, {
|
||||
[k]: v
|
||||
});
|
||||
|
||||
// isDigit :: Char -> Bool
|
||||
const isDigit = c => {
|
||||
const n = c.codePointAt(0);
|
||||
return 48 <= n && 57 >= n;
|
||||
};
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = f => xs =>
|
||||
(Array.isArray(xs) ? (
|
||||
xs
|
||||
) : xs.split('')).map(f);
|
||||
|
||||
// Map-accumulation is a combination of map and a catamorphism;
|
||||
// it applies a function to each element of a list, passing an
|
||||
// accumulating parameter from left to right, and returning a final
|
||||
// value of this accumulator together with the new list.
|
||||
|
||||
// mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
|
||||
const mapAccumL = f => acc => xs =>
|
||||
xs.reduce((a, x) => {
|
||||
const pair = f(a[0])(x);
|
||||
return Tuple(pair[0])(a[1].concat(pair[1]));
|
||||
}, Tuple(acc)([]));
|
||||
|
||||
// replicate :: Int -> a -> [a]
|
||||
const replicate = n => x =>
|
||||
Array.from({
|
||||
length: n
|
||||
}, () => x);
|
||||
|
||||
// uncurry :: (a -> b -> c) -> ((a, b) -> c)
|
||||
const uncurry = f =>
|
||||
(x, y) => f(x)(y);
|
||||
|
||||
// unlines :: [String] -> String
|
||||
const unlines = xs => xs.join('\n');
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
const d1 = Dict("A" => [["1", "2", "3"], 1])
|
||||
const d2 = Dict("A" => [["1", "B", "2"], 1], "B" => [["3", "4"], 1])
|
||||
const d3 = Dict("A" => [["1", "D", "D"], 1], "D" => [["6", "7", "8"], 1])
|
||||
const d4 = Dict("A" => [["1", "B", "C"], 1], "B" => [["3", "4"], 1],
|
||||
"C" => [["5", "B"], 1])
|
||||
|
||||
function getvalue!(wheelname, allwheels)
|
||||
wheel = allwheels[wheelname]
|
||||
s = wheel[1][wheel[2]]
|
||||
wheel[2] = mod1(wheel[2] + 1, length(wheel[1]))
|
||||
return haskey(allwheels, s) ? getvalue!(s, allwheels) : s
|
||||
end
|
||||
|
||||
function testwheels(wheels, numterms = 20, firstwheel = "A")
|
||||
println("\nNumber Wheels:")
|
||||
for k in sort(collect(keys(wheels)))
|
||||
print("$k: [")
|
||||
for s in wheels[k][1]
|
||||
print(s, " ")
|
||||
end
|
||||
println("\b]")
|
||||
end
|
||||
print("Output: ")
|
||||
for _ in 1:numterms
|
||||
print(getvalue!(firstwheel, wheels), " ")
|
||||
end
|
||||
println("...")
|
||||
end
|
||||
|
||||
foreach(testwheels, [d1, d2, d3, d4])
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
import java.util.Collections
|
||||
import java.util.stream.IntStream
|
||||
|
||||
object WheelController {
|
||||
private val IS_NUMBER = "[0-9]".toRegex()
|
||||
private const val TWENTY = 20
|
||||
private var wheelMap = mutableMapOf<String, WheelModel>()
|
||||
|
||||
private fun advance(wheel: String) {
|
||||
val w = wheelMap[wheel]
|
||||
if (w!!.list[w.position].matches(IS_NUMBER)) {
|
||||
w.printThePosition()
|
||||
} else {
|
||||
val wheelName = w.list[w.position]
|
||||
advance(wheelName)
|
||||
}
|
||||
w.advanceThePosition()
|
||||
}
|
||||
|
||||
private fun run() {
|
||||
println(wheelMap)
|
||||
IntStream.rangeClosed(1, TWENTY)
|
||||
.forEach { advance("A") }
|
||||
println()
|
||||
wheelMap.clear()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
wheelMap["A"] = WheelModel("1", "2", "3")
|
||||
run()
|
||||
wheelMap["A"] = WheelModel("1", "B", "2")
|
||||
wheelMap["B"] = WheelModel("3", "4")
|
||||
run()
|
||||
wheelMap["A"] = WheelModel("1", "D", "D")
|
||||
wheelMap["D"] = WheelModel("6", "7", "8")
|
||||
run()
|
||||
wheelMap["A"] = WheelModel("1", "B", "C")
|
||||
wheelMap["B"] = WheelModel("3", "4")
|
||||
wheelMap["C"] = WheelModel("5", "B")
|
||||
run()
|
||||
}
|
||||
}
|
||||
|
||||
internal class WheelModel(vararg values: String?) {
|
||||
var list = mutableListOf<String>()
|
||||
var position: Int
|
||||
private var endPosition: Int
|
||||
|
||||
override fun toString(): String {
|
||||
return list.toString()
|
||||
}
|
||||
|
||||
fun advanceThePosition() {
|
||||
if (position == endPosition) {
|
||||
position = INITIAL // new beginning
|
||||
} else {
|
||||
position++ // advance position
|
||||
}
|
||||
}
|
||||
|
||||
fun printThePosition() {
|
||||
print(" ${list[position]}")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val INITIAL = 0
|
||||
}
|
||||
|
||||
init {
|
||||
Collections.addAll<String>(list, *values)
|
||||
position = INITIAL
|
||||
endPosition = list.size - 1
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
with(ArrayTools):
|
||||
|
||||
module Wheel()
|
||||
option object;
|
||||
local spokes := Array([1,2,3]);
|
||||
local currentSpoke := 1;
|
||||
|
||||
export currentValue::static := proc(self::Wheel)
|
||||
local valueOut;
|
||||
if type(self:-spokes[self:-currentSpoke], integer) then
|
||||
valueOut := self:-spokes[self:-currentSpoke]:
|
||||
else
|
||||
valueOut := currentValue(self:-spokes[self:-currentSpoke]):
|
||||
end if:
|
||||
rotate(self):
|
||||
return valueOut;
|
||||
end proc:
|
||||
|
||||
export rotate::static := proc(self::Wheel)
|
||||
if self:-currentSpoke = ArrayNumElems(self:-spokes) then self:-currentSpoke := 1:
|
||||
else self:-currentSpoke += 1: end if:
|
||||
end proc:
|
||||
|
||||
export ModuleApply::static := proc()
|
||||
Object(Wheel, _passed);
|
||||
end proc:
|
||||
|
||||
export ModuleCopy::static := proc(new::Wheel, proto::Wheel, spo::Array, curr::integer, $)
|
||||
new:-spokes := spo:
|
||||
new:-currentSpoke := curr:
|
||||
end proc:
|
||||
end module:
|
||||
|
||||
A := Wheel(Array([1,2,3]), 1):
|
||||
|
||||
seq(currentValue(A), 1..20);
|
||||
|
||||
A := Wheel(Array([1,B,2]), 1):
|
||||
B := Wheel(Array([3,4]), 1):
|
||||
|
||||
seq(currentValue(A), 1..20);
|
||||
|
||||
A := Wheel(Array([1,d,d]), 1):
|
||||
d := Wheel(Array([6,7,8]), 1):
|
||||
|
||||
seq(currentValue(A), 1..20);
|
||||
|
||||
A := Wheel(Array([1,b,C]), 1):
|
||||
b := Wheel(Array([3,4]), 1):
|
||||
C := Wheel(Array([5,b]), 1):
|
||||
|
||||
seq(currentValue(A), 1..20);
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import strutils, tables
|
||||
|
||||
type
|
||||
|
||||
ElemKind = enum eValue, eWheel
|
||||
|
||||
Elem = object
|
||||
case kind: ElemKind
|
||||
of eValue:
|
||||
value: Natural
|
||||
of eWheel:
|
||||
name: char
|
||||
|
||||
Wheel = ref object
|
||||
elems: seq[Elem]
|
||||
index: Natural
|
||||
|
||||
Wheels = Table[char, Wheel]
|
||||
|
||||
WheelDescription = tuple[name: char; elems: string]
|
||||
|
||||
|
||||
func initWheels(wheels: openArray[WheelDescription]): Wheels =
|
||||
## Initialize a table of wheels from an array of wheel descriptions.
|
||||
|
||||
for (name, elems) in wheels:
|
||||
let wheel = new(Wheel)
|
||||
for e in elems.splitWhitespace():
|
||||
if e[0].isUpperAscii():
|
||||
wheel.elems.add Elem(kind: eWheel, name: e[0])
|
||||
else:
|
||||
wheel.elems.add Elem(kind: eValue, value: e.parseInt())
|
||||
result[name] = wheel
|
||||
|
||||
|
||||
func next(wheels: Wheels; name: char): Natural =
|
||||
## Return the next element from a wheel.
|
||||
|
||||
let wheel = wheels[name]
|
||||
let elem = wheel.elems[wheel.index]
|
||||
wheel.index = (wheel.index + 1) mod wheel.elems.len
|
||||
result = case elem.kind
|
||||
of eValue: elem.value
|
||||
of eWheel: wheels.next(elem.name)
|
||||
|
||||
|
||||
when isMainModule:
|
||||
|
||||
proc generate(wheelList: openArray[WheelDescription]; count: Positive) =
|
||||
## Create the wheels from their description, then display
|
||||
## the first "count" values generated by wheel 'A'.
|
||||
|
||||
let wheels = wheelList.initWheels()
|
||||
for (name, elems) in wheelList:
|
||||
echo name, ": ", elems
|
||||
echo "generates:"
|
||||
for _ in 1..count:
|
||||
stdout.write ' ', wheels.next('A')
|
||||
echo '\n'
|
||||
|
||||
|
||||
{'A': "1 2 3"}.generate(20)
|
||||
{'A': "1 B 2", 'B': "3 4"}.generate(20)
|
||||
{'A': "1 D D", 'D': "6 7 8"}.generate(20)
|
||||
{'A': "1 B C", 'B': "3 4", 'C': "5 B"}.generate(20)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use feature 'say';
|
||||
|
||||
sub get_next {
|
||||
my($w,%wheels) = @_;
|
||||
my $wh = \@{$wheels{$w}}; # reference, not a copy
|
||||
my $value = $$wh[0][$$wh[1]];
|
||||
$$wh[1] = ($$wh[1]+1) % @{$$wh[0]};
|
||||
defined $wheels{$value} ? get_next($value,%wheels) : $value;
|
||||
}
|
||||
|
||||
sub spin_wheels {
|
||||
my(%wheels) = @_;
|
||||
say "$_: " . join ', ', @{${$wheels{$_}}[0]} for sort keys %wheels;
|
||||
print get_next('A', %wheels) . ' ' for 1..20; print "\n\n";
|
||||
}
|
||||
|
||||
spin_wheels(%$_) for
|
||||
(
|
||||
{'A' => [['1', '2', '3'], 0]},
|
||||
{'A' => [['1', 'B', '2'], 0], 'B' => [['3', '4'], 0]},
|
||||
{'A' => [['1', 'D', 'D'], 0], 'D' => [['6', '7', '8'], 0]},
|
||||
{'A' => [['1', 'B', 'C'], 0], 'B' => [['3', '4'], 0], 'C' => [['5', 'B'], 0]},
|
||||
);
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">terms</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">wheels</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">wheels</span><span style="color: #0000FF;">)),</span>
|
||||
<span style="color: #000000;">wvs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">vslice</span><span style="color: #0000FF;">(</span><span style="color: #000000;">wheels</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">wheel</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rdx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">rdx</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">wheel</span><span style="color: #0000FF;">],</span>
|
||||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">wheels</span><span style="color: #0000FF;">[</span><span style="color: #000000;">wheel</span><span style="color: #0000FF;">][</span><span style="color: #000000;">p</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">wheels</span><span style="color: #0000FF;">[</span><span style="color: #000000;">wheel</span><span style="color: #0000FF;">])?</span><span style="color: #000000;">2</span><span style="color: #0000FF;">:</span><span style="color: #000000;">p</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">pos</span><span style="color: #0000FF;">[</span><span style="color: #000000;">wheel</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">p</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">></span><span style="color: #008000;">'9'</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">wheel</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wvs</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rdx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span>
|
||||
<span style="color: #000000;">rdx</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">wheel</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</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;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">wheels</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">"A123"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"A1B2"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"B34"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"A1DD"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D678"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"A1BC"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"B34"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"C5B"</span><span style="color: #0000FF;">}}</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: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">wheels</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #0000FF;">?</span><span style="color: #000000;">terms</span><span style="color: #0000FF;">(</span><span style="color: #000000;">wheels</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
from itertools import islice
|
||||
|
||||
class INW():
|
||||
"""
|
||||
Intersecting Number Wheels
|
||||
represented as a dict mapping
|
||||
name to tuple of values.
|
||||
"""
|
||||
|
||||
def __init__(self, **wheels):
|
||||
self._wheels = wheels
|
||||
self.isect = {name: self._wstate(name, wheel)
|
||||
for name, wheel in wheels.items()}
|
||||
|
||||
def _wstate(self, name, wheel):
|
||||
"Wheel state holder"
|
||||
assert all(val in self._wheels for val in wheel if type(val) == str), \
|
||||
f"ERROR: Interconnected wheel not found in {name}: {wheel}"
|
||||
pos = 0
|
||||
ln = len(wheel)
|
||||
while True:
|
||||
nxt, pos = wheel[pos % ln], pos + 1
|
||||
yield next(self.isect[nxt]) if type(nxt) == str else nxt
|
||||
|
||||
def __iter__(self):
|
||||
base_wheel_name = next(self.isect.__iter__())
|
||||
yield from self.isect[base_wheel_name]
|
||||
|
||||
def __repr__(self):
|
||||
return f"{self.__class__.__name__}({self._wheels})"
|
||||
|
||||
def __str__(self):
|
||||
txt = "Intersecting Number Wheel group:"
|
||||
for name, wheel in self._wheels.items():
|
||||
txt += f"\n {name+':':4}" + ' '.join(str(v) for v in wheel)
|
||||
return txt
|
||||
|
||||
def first(iter, n):
|
||||
"Pretty print first few terms"
|
||||
return ' '.join(f"{nxt}" for nxt in islice(iter, n))
|
||||
|
||||
if __name__ == '__main__':
|
||||
for group in[
|
||||
{'A': (1, 2, 3)},
|
||||
{'A': (1, 'B', 2),
|
||||
'B': (3, 4)},
|
||||
{'A': (1, 'D', 'D'),
|
||||
'D': (6, 7, 8)},
|
||||
{'A': (1, 'B', 'C'),
|
||||
'B': (3, 4),
|
||||
'C': (5, 'B')}, # 135143145...
|
||||
]:
|
||||
w = INW(**group)
|
||||
print(f"{w}\n Generates:\n {first(w, 20)} ...\n")
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
def nextfrom(w, name):
|
||||
while True:
|
||||
nxt, w[name] = w[name][0], w[name][1:] + w[name][:1]
|
||||
if '0' <= nxt[0] <= '9':
|
||||
return nxt
|
||||
name = nxt
|
||||
|
||||
if __name__ == '__main__':
|
||||
for group in '''
|
||||
A: 1 2 3
|
||||
A: 1 B 2; B: 3 4
|
||||
A: 1 D D; D: 6 7 8
|
||||
A: 1 B C; B: 3 4; C: 5 B'''.strip().split('\n'):
|
||||
print(f"Intersecting Number Wheel group:\n {group}")
|
||||
wheel, first = {}, None
|
||||
for w in group.strip().split(';'):
|
||||
name, *values = w.strip().split()
|
||||
wheel[name[:-1]] = values
|
||||
first = name[:-1] if first is None else first
|
||||
gen = ' '.join(nextfrom(wheel, first) for i in range(20))
|
||||
print(f" Generates:\n {gen} ...\n")
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
def nextfromr(w, name):
|
||||
nxt, w[name] = w[name][0], w[name][1:] + w[name][:1]
|
||||
return nxt if '0' <= nxt[0] <= '9' else nextfromr(w, nxt)
|
||||
|
||||
if __name__ == '__main__':
|
||||
for group in [{'A': '123'},
|
||||
{'A': '1B2', 'B': '34'},
|
||||
{'A': '1DD', 'D': '678'},
|
||||
{'A': '1BC', 'B': '34', 'C': '5B'},]:
|
||||
print(f"Intersecting Number Wheel group:\n {group}")
|
||||
first = next(group.__iter__())
|
||||
gen = ' '.join(nextfromr(group, first) for i in range(20))
|
||||
print(f" Generates:\n {gen} ...\n")
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
'''Intersecting number wheels'''
|
||||
|
||||
from itertools import cycle, islice
|
||||
from functools import reduce
|
||||
|
||||
|
||||
# clockWorkTick :: Dict -> (Dict, Char)
|
||||
def clockWorkTick(wheelMap):
|
||||
'''The new state of the wheels, tupled with a
|
||||
digit found by recursive descent from a single
|
||||
click of the first wheel.'''
|
||||
def click(wheels):
|
||||
def go(wheelName):
|
||||
wheel = wheels.get(wheelName, ['?'])
|
||||
v = wheel[0]
|
||||
return (Tuple if v.isdigit() or '?' == v else click)(
|
||||
insertDict(wheelName)(leftRotate(wheel))(wheels)
|
||||
)(v)
|
||||
return go
|
||||
return click(wheelMap)('A')
|
||||
|
||||
|
||||
# leftRotate :: [a] -> String
|
||||
def leftRotate(xs):
|
||||
''' A string shifted cyclically towards
|
||||
the left by one position.
|
||||
'''
|
||||
return ''.join(islice(cycle(xs), 1, 1 + len(xs)))
|
||||
|
||||
|
||||
# ------------------------- TEST -------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''First twenty values from each set of test wheels.'''
|
||||
|
||||
wheelMaps = [dict(kvs) for kvs in [
|
||||
[('A', "123")],
|
||||
[('A', "1B2"), ('B', "34")],
|
||||
[('A', "1DD"), ('D', "678")],
|
||||
[('A', "1BC"), ('B', "34"), ('C', "5B")]
|
||||
]]
|
||||
print('New state of wheel sets, after 20 clicks of each:\n')
|
||||
for wheels, series in [
|
||||
mapAccumL(compose(const)(clockWorkTick))(
|
||||
dct
|
||||
)(' ' * 20) for dct in wheelMaps
|
||||
]:
|
||||
print((wheels, ''.join(series)))
|
||||
|
||||
print('\nInital states:')
|
||||
for x in wheelMaps:
|
||||
print(x)
|
||||
|
||||
|
||||
# ----------------------- GENERIC ------------------------
|
||||
|
||||
# Tuple (,) :: a -> b -> (a, b)
|
||||
def Tuple(x):
|
||||
'''Constructor for a pair of values,
|
||||
possibly of two different types.
|
||||
'''
|
||||
return lambda y: (
|
||||
x + (y,)
|
||||
) if isinstance(x, tuple) else (x, y)
|
||||
|
||||
|
||||
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
||||
def compose(g):
|
||||
'''Right to left function composition.'''
|
||||
return lambda f: lambda x: g(f(x))
|
||||
|
||||
|
||||
# const :: a -> b -> a
|
||||
def const(k):
|
||||
'''The latter of two arguments,
|
||||
with the first discarded.
|
||||
'''
|
||||
return lambda _: k
|
||||
|
||||
|
||||
# insertDict :: String -> a -> Dict -> Dict
|
||||
def insertDict(k):
|
||||
'''A new dictionary updated with a (k, v) pair.'''
|
||||
def go(v, dct):
|
||||
return dict(dct, **{k: v})
|
||||
return lambda v: lambda dct: go(v, dct)
|
||||
|
||||
|
||||
# mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
|
||||
def mapAccumL(f):
|
||||
'''A tuple of an accumulation and a map
|
||||
with accumulation from left to right.
|
||||
'''
|
||||
def nxt(a, x):
|
||||
tpl = f(a[0])(x)
|
||||
return tpl[0], a[1] + [tpl[1]]
|
||||
|
||||
def go(acc):
|
||||
def g(xs):
|
||||
return reduce(nxt, xs, (acc, []))
|
||||
return g
|
||||
return go
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
[ ]this[ ]done[
|
||||
dup take behead
|
||||
dup dip
|
||||
[ nested join
|
||||
swap put ]
|
||||
do ] is wheel ( --> n )
|
||||
|
||||
[ ]'[
|
||||
]'[ nested
|
||||
' [ wheel ]
|
||||
swap join
|
||||
swap replace ] is newwheel ( --> )
|
||||
|
||||
forward is A forward is B forward is C
|
||||
forward is D ( and so on, as required )
|
||||
|
||||
[ wheel [ 1 2 3 ] ] resolves A ( --> n )
|
||||
|
||||
[ wheel [ 3 4 ] ] resolves B ( --> n )
|
||||
|
||||
[ wheel [ 5 B ] ] resolves C ( --> n )
|
||||
|
||||
[ wheel [ 6 7 8 ] ] resolves D ( --> n )
|
||||
|
||||
|
||||
20 times [ A echo sp ] cr
|
||||
|
||||
newwheel A [ 1 B 2 ]
|
||||
20 times [ A echo sp ] cr
|
||||
|
||||
newwheel A [ 1 D D ]
|
||||
20 times [ A echo sp ] cr
|
||||
|
||||
newwheel A [ 1 B C ]
|
||||
newwheel B [ 3 4 ] ( As B has been used already )
|
||||
( it's state may be [ 4 3 ]. )
|
||||
( So we reset it to [ 3 4 ]. )
|
||||
|
||||
20 times [ A echo sp ] cr
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*REXX program expresses numbers from intersecting number wheels (or wheel sets). */
|
||||
@.= /*initialize array to hold the wheels. */
|
||||
parse arg lim @.1 /*obtain optional arguments from the CL*/
|
||||
if lim='' | lim="," then lim= 20 /*Not specified? Then use the default.*/
|
||||
if @.1='' | @.1="," then do; @.1= ' A: 1 2 3 '
|
||||
@.2= ' A: 1 B 2, B: 3 4 '
|
||||
@.3= ' A: 1 D D, D: 6 7 8 '
|
||||
@.4= ' A: 1 B C, B: 3 4, C: 5 B '
|
||||
end
|
||||
do i=1 while @.i\=''; call run /*construct wheel set and "execute" it.*/
|
||||
end /*i*/
|
||||
exit 0 /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
error: procedure; say; say; say '***error***' arg(1); say; say; exit 12
|
||||
isLet: procedure; parse arg y; return datatype(y, 'M') & length(y)==1 /*is a letter? */
|
||||
isNum: procedure; parse arg y; return datatype(y, 'N') /*is a number? */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
run: @wn= 'wheel name'; first=; @noColon= "wheel name not followed by a colon:"
|
||||
@gn= 'gear name' ; gear.=; say copies("═", 79)
|
||||
say 'building wheel group for: ' @.i; wheels= space(@.i); upper wheels
|
||||
do #=1 while wheels\=''; parse var wheels w gears "," wheels; L= length(w)
|
||||
if L==2 then do; !.#= left(w, 1) /*obtain the one─character gear name. */
|
||||
if right(w, 1)\==':' then call error @noColon w
|
||||
if \isLet(!.#) then call error @wn "not a letter:" w
|
||||
end
|
||||
else call error "first token isn't a" @wn':' w
|
||||
if #==1 then first= !.1 /*Is this is the 1st wheel set? Use it*/
|
||||
if first=='' then call error "no wheel name was specified."
|
||||
n= !.# /*obtain the name of the 1st wheel set.*/
|
||||
gear.n.0= 1 /*initialize default 1st gear position.*/
|
||||
say ' setting gear.name:' n " gears=" gears
|
||||
do g=1 for words(gears); _= word(gears, g)
|
||||
if isNum(_) | isLet(_) then do; gear.n.g= _; iterate; end
|
||||
call error @gn "isn't a number or a gear name:" _
|
||||
end /*g*/
|
||||
end /*#*/
|
||||
say; say center(' running the wheel named ' first" ", 79, '─'); $=
|
||||
do dummy=0 by 0 until words($)==lim; n= first
|
||||
z= gear.n.0; x= gear.n.z; z= z + 1
|
||||
gear.n.0= z; if gear.n.z=='' then gear.n.0= 1
|
||||
if isNum(x) then do; $= $ x; iterate; end /*found a number, use it.*/
|
||||
xx= x /*different gear, keep switching 'til X*/
|
||||
do forever; nn= xx
|
||||
if gear.nn.0=='' then call error "a gear is using an unknown gear name:" x
|
||||
zz= gear.nn.0; xx= gear.nn.zz
|
||||
zz= zz + 1; gear.nn.0= zz; if gear.nn.zz=='' then gear.nn.0= 1
|
||||
if isNum(xx) then do; $= $ xx; iterate dummy; end
|
||||
end /*forever*/ /* [↑] found a number, now use FIRST.*/
|
||||
end /*dummy*/ /*"DUMMY" is needed for the ITERATE. */
|
||||
say '('lim "results): " strip($); say; say; return
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#| advance rotates a named wheel $n by consuming an item from an infinite sequence. It is called
|
||||
#| from within a gather block and so can use take in order to construct an infinite, lazy sequence
|
||||
#| of result values
|
||||
sub advance($g, $n) {
|
||||
given $g{$n}.pull-one {
|
||||
when /\d/ { take $_ }
|
||||
default { samewith $g, $_ } # samewith re-calls this function with new parameters
|
||||
}
|
||||
}
|
||||
|
||||
#| Input groups are a hash containing each wheel name as the key, and a list of values constructed
|
||||
#| using <> to split on whitespace. They are transformed using xx * to repeat the list infinitely.
|
||||
#| We then retrieve the underlying iterator in order for wheel position to be persistent. Each group
|
||||
#| is then aggregated into a lazy output sequence using an infinite loop inside a gather block.
|
||||
[
|
||||
{A => <1 2 3>},
|
||||
{A => <1 B 2>, B => <3 4>},
|
||||
{A => <1 D D>, D => <6 7 8>},
|
||||
{A => <1 B C>, B => <3 4>, C => <5 B>},
|
||||
]
|
||||
#| %() converts a list of pairs produced by map into a hash. $^k and $^v are implicit variables.
|
||||
#| They are processed in alphabetical order and make the block arity 2, called with two vars.
|
||||
#| .kv gets the list of wheel names and wheel values from the input entry
|
||||
==> map({ %(.kv.map: { $^k => (|$^v xx *).iterator }) })
|
||||
#| gather constructs a lazy sequence, in which we infinitely loop advancing wheel A
|
||||
==> map({ gather { loop { advance $_, 'A' }} })
|
||||
#| state variables are only initialised once, and are kept between invocations.
|
||||
==> map({ state $i = 1; say "Group {$i++}, First 20 values: $_[^20]" })
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
groups = [{A: [1, 2, 3]},
|
||||
{A: [1, :B, 2], B: [3, 4]},
|
||||
{A: [1, :D, :D], D: [6, 7, 8]},
|
||||
{A: [1, :B, :C], B: [3, 4], C: [5, :B]} ]
|
||||
|
||||
groups.each do |group|
|
||||
p group
|
||||
wheels = group.transform_values(&:cycle)
|
||||
res = 20.times.map do
|
||||
el = wheels[:A].next
|
||||
el = wheels[el].next until el.is_a?(Integer)
|
||||
el
|
||||
end
|
||||
puts res.join(" "),""
|
||||
end
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
Imports System.Runtime.CompilerServices
|
||||
|
||||
Module Module1
|
||||
|
||||
<Extension()>
|
||||
Iterator Function Loopy(Of T)(seq As IEnumerable(Of T)) As IEnumerable(Of T)
|
||||
While True
|
||||
For Each element In seq
|
||||
Yield element
|
||||
Next
|
||||
End While
|
||||
End Function
|
||||
|
||||
Iterator Function TurnWheels(ParamArray wheels As (name As Char, values As String)()) As IEnumerable(Of Char)
|
||||
Dim data = wheels.ToDictionary(Function(wheel) wheel.name, Function(wheel) wheel.values.Loopy.GetEnumerator)
|
||||
Dim primary = data(wheels(0).name)
|
||||
|
||||
Dim Turn As Func(Of IEnumerator(Of Char), Char) = Function(sequence As IEnumerator(Of Char))
|
||||
sequence.MoveNext()
|
||||
Dim c = sequence.Current
|
||||
Return If(Char.IsDigit(c), c, Turn(data(c)))
|
||||
End Function
|
||||
|
||||
While True
|
||||
Yield Turn(primary)
|
||||
End While
|
||||
End Function
|
||||
|
||||
<Extension()>
|
||||
Sub Print(sequence As IEnumerable(Of Char))
|
||||
Console.WriteLine(String.Join(" ", sequence))
|
||||
End Sub
|
||||
|
||||
Sub Main()
|
||||
TurnWheels(("A", "123")).Take(20).Print()
|
||||
TurnWheels(("A", "1B2"), ("B", "34")).Take(20).Print()
|
||||
TurnWheels(("A", "1DD"), ("D", "678")).Take(20).Print()
|
||||
TurnWheels(("A", "1BC"), ("B", "34"), ("C", "5B")).Take(20).Print()
|
||||
End Sub
|
||||
|
||||
End Module
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
import "/dynamic" for Struct
|
||||
import "/sort" for Sort
|
||||
import "/fmt" for Fmt
|
||||
|
||||
var Wheel = Struct.create("Wheel", ["next", "values"])
|
||||
|
||||
var generate = Fn.new { |wheels, start, maxCount|
|
||||
var count = 0
|
||||
var w = wheels[start]
|
||||
while (true) {
|
||||
var s = w.values[w.next]
|
||||
var v = Num.fromString(s)
|
||||
w.next = (w.next + 1) % w.values.count
|
||||
wheels[start] = w
|
||||
if (v) {
|
||||
System.write("%(v) ")
|
||||
count = count + 1
|
||||
if (count == maxCount) {
|
||||
System.print("...\n")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
while (true) {
|
||||
var w2 = wheels[s]
|
||||
var ss = s
|
||||
s = w2.values[w2.next]
|
||||
w2.next = (w2.next + 1) % w2.values.count
|
||||
wheels[ss] = w2
|
||||
v = Num.fromString(s)
|
||||
if (v) {
|
||||
System.write("%(v) ")
|
||||
count = count + 1
|
||||
if (count == maxCount) {
|
||||
System.print("...\n")
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var printWheels = Fn.new { |wheels|
|
||||
var names = []
|
||||
for (name in wheels.keys) names.add(name)
|
||||
Sort.quick(names)
|
||||
System.print("Intersecting Number Wheel group:")
|
||||
for (name in names) {
|
||||
Fmt.print(" $s: $n", name, wheels[name].values)
|
||||
}
|
||||
System.write(" Generates:\n ")
|
||||
}
|
||||
|
||||
var wheelMaps = [
|
||||
{
|
||||
"A": Wheel.new(0, ["1", "2", "3"])
|
||||
},
|
||||
{
|
||||
"A": Wheel.new(0, ["1", "B", "2"]),
|
||||
"B": Wheel.new(0, ["3", "4"])
|
||||
},
|
||||
{
|
||||
"A": Wheel.new(0, ["1", "D", "D"]),
|
||||
"D": Wheel.new(0, ["6", "7", "8"])
|
||||
},
|
||||
{
|
||||
"A": Wheel.new(0, ["1", "B", "C"]),
|
||||
"B": Wheel.new(0, ["3", "4"]),
|
||||
"C": Wheel.new(0, ["5", "B"])
|
||||
}
|
||||
]
|
||||
for (wheels in wheelMaps) {
|
||||
printWheels.call(wheels)
|
||||
generate.call(wheels, "A", 20)
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
fcn intersectingNumberWheelsW(wheels){ // ("A":(a,b,"C"), "C":(d,e) ...)
|
||||
ws:=wheels.pump(Dictionary(),fcn([(k,v)]){ return(k,Walker.cycle(v)) }); // new Dictionary
|
||||
Walker.zero().tweak(fcn(w,wheels){
|
||||
while(1){
|
||||
w=wheels[w].next(); // increment wheel w
|
||||
if(Int.isType(w)) return(w);
|
||||
}
|
||||
}.fp("A",ws)) // assume wheel A exists and is always first
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
wheelSets:=T( Dictionary("A",T(1,2,3)),
|
||||
Dictionary("A",T(1,"B",2), "B",T(3,4)),
|
||||
Dictionary("A",T(1,"D","D"), "D",T(6,7,8)),
|
||||
Dictionary("A",T(1,"B","C"), "C",T(5,"B"), "B",T(3,4)) );
|
||||
foreach ws in (wheelSets){
|
||||
println("Wheel set:");
|
||||
ws.pump(String,fcn([(k,v)]){ " %s: %s\n".fmt(k,v.concat(" ")) }).print();
|
||||
println("-->",intersectingNumberWheelsW(ws).walk(20).concat(" "));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue