xxxxxxxxxx
300
function setup() {
noCanvas(); noLoop();
Term.init();
}
Term.dialogue((function() {
let gentype = 'poly';
let pnum = [1, 0, 0], pstart = 0;
let rnum = [1, 1], rseed = [1, 1];
let rnd_low = -10, rnd_high = 10;
let seqsize = 10;
let level = 4, bounds = [1, 1];
let seq = [0,1,2,3,4,5,6,7,8,9];
let wall = [];
let cell_mod = 2n;
let A = 2, B = 1, C = 69;
let negative_hue = 230, positive_hue = 30;
let pack = false;
const sketch = function(p) {
let w = 4, h = 2;
p.setup = function() {
if(pack) [w, h] = [2, 1];
p.createCanvas(w*seqsize+14, h*seqsize+12);
p.noLoop();
};
p.draw = function() {
p.background('#001000');
p.strokeWeight(pack ? 2 : 3.5);
let cell_max = Number(cell_mod);
for(let row = 1; row < wall.length; row++) {
for(let col = 0; col < wall[0].length; col++) {
let cell = wall[row][col];
if(cell !== undefined) {
let intensity = Number(cell % cell_mod);
let light = round(map(abs(intensity), 0, cell_max, 0, 100));
let hue = intensity < 0 ? negative_hue : positive_hue;
p.stroke(`hsl(${hue},100%,${light}%)`);
p.point(7+w*col, 4+w*row);
}
}
}
};
};
return function(ticket, value) {
switch(ticket) {
case 'init':
Term.print(`
Numberwalls and colorful patterns. A program to generate a number wall
from a sequence entered by the user. Inspired by a Mathologer video tutorial
"https://www.youtube.com/watch?v=NO1_-qptr6c" teaching us how to use the cross
and horseshoe rule to complete a wall. `);
case 'menu':
Term.print(`
Options:
'menu' : Show this menu.
'poly' : Create the sequence using a polynomial function.
Functions are entered as a polynumber such as 1,0,0
to represent f(x) = x*x.
'recur' : Create the sequence using a linear recurrence function.
Functions are entered as numbers like 1,1 to represent
Eₙ = (1)Eₙ-₁ + (1)Eₙ-₂, then a seed sequence is entered like 1,1.
'far' : A002487 Starting with 2 positive integers
'fly <size>' : A133058 'Fly Straight Dammit'
'eck <size>' : A181391 'Van Eck's Sequence'
'pag <size>' : A301849 'Pagoda Sequence'
'fact <size>' : Euler's twisted machine 'https://www.youtube.com/watch?v=iJ8pnCO0nTY&t=979s'
'lcg <A> <B> <C>' : f(x) = (Ax + B) mod C
Display symmetric patters such as the cartioid 'lcg 2 1 100', 'lcg 2 1 212' mod 3
'alien' : Generate a random alien textile, (mod 7)
user mod <n> to see it in a different base
'rand' : Create a random sequence.
'user' : Enter or paste in a comma separated sequence
'tab' : Show the calculated wall in a table
'mod <n>' : Show the calculated wall as a pattern, each cell modulo n
: + (orange), - (blue) pivot around 0 (black)
'pack' : Pack image dots
'hue <n> <p>' : Set the colors for negative and positive values for numberwall cells.
values are a hue (0 to 360)
'test' : Verify the wall with the short cross
'clear' : Clear the terminal.`);
Term.scan('type');
break;
case 'type':
Term.goto(value);
break;
case 'mod':
if(value[0]) {
cell_mod = BigInt(value[0]);
wall = Wall.get();
let div = document.createElement('div');
div.setAttribute('id', 'pattern')
Term.insert_block(div);
new p5(sketch, div);
}
Term.scan('type');
break;
case 'lcg':
if(value[0]) A = parseInt(value[0]);
if(value[1]) B = parseInt(value[1]);
if(value[2]) C = parseInt(value[2]);
seq = Sequence.lcg(A, B, C);
seqsize = seq.length;
Wall.create(seq);
if(seqsize < 51) Term.table(Wall.get()); else Term.print('Wall created.');
Term.scan('type');
break;
case 'pack':
pack = !pack;
Term.print(pack ? 'pack on' : 'pack off');
Term.scan('type');
break;
case 'far':
Term.scan('level', 'Tree level (4)?');
Term.scan('bounds', 'Start and end ints eg: 1, 1');
break;
case 'level':
if(value.length) level = parseInt(value);
break;
case 'bounds':
if(value.length) bounds = value.split(',').map(n=>parseInt(n));
Wall.create(Sequence.faray(level, bounds));
seqsize = 2 ** level + 1;
if(seqsize < 51) Term.table(Wall.get()); else Term.print('Wall created.');
Term.scan('type');
break;
case 'fly':
seqsize = parseInt(value[0]);
if(seqsize) Wall.create(Sequence.fly_straight(seqsize));
if(seqsize < 51) Term.table(Wall.get()); else Term.print('Wall created.');
Term.scan('type');
break;
case 'eck':
seqsize = parseInt(value[0]);
if(seqsize) Wall.create(Sequence.van_eck(seqsize));
if(seqsize < 51) Term.table(Wall.get()); else Term.print('Wall created.');
Term.scan('type');
break;
case 'pag':
seqsize = parseInt(value[0]);
if(seqsize) Wall.create(Sequence.pagoda(seqsize));
if(seqsize < 51) Term.table(Wall.get()); else Term.print('Wall created.');
Term.scan('type');
break;
case 'clear':
Term.clear();
Term.scan('type');
break;
case 'poly':
Term.scan('pnum', 'Enter the coefficients: ');
Term.scan('size', 'Sequence size?');
Term.scan('pstart', 'Start x at (0)?');
break;
case 'pnum':
if(value.length) pnum = value.split(',').map(n=>parseInt(n));
break;
case 'size':
if(value.length) seqsize = parseInt(value);
break;
case 'pstart':
if(value.length) pstart = parseInt(value);
Wall.create(Sequence.polynomial(pnum, seqsize, pstart));
if(seqsize < 51) Term.table(Wall.get()); else Term.print('Wall created.');
Term.scan('type');
break;
case 'recur':
Term.scan('rnum', 'Enter the coefficients: ');
Term.scan('size', 'Sequence size?');
Term.scan('rseed', 'Enter the seed numbers: ');
break;
case 'rnum':
if(value.length) rnum = value.split(',').map(n=>parseInt(n));
break;
case 'rseed':
if(value.length) rseed = value.split(',').map(n=>parseInt(n));
Wall.create(Sequence.recurrence(rnum, rseed, seqsize));
if(seqsize < 51) Term.table(Wall.get()); else Term.print('Wall created.');
Term.scan('type');
break;
case 'rand':
Term.scan('size', 'Random integer Sequence size?');
Term.scan('rndrange', 'Range for integers eg -10, 10');
break;
case 'rndrange':
if(value.length) [rnd_low, rnd_high] = value.split(',').map(n=>parseInt(n));
Wall.create(Sequence.random(rnd_low, rnd_high, seqsize));
if(seqsize < 51) Term.table(Wall.get()); else Term.print('Wall created.');
Term.scan('type');
break;
case 'user':
Term.print('Enter a comma separated integer sequence');
Term.scan('byhand');
break;
case 'fact':
seqsize = parseInt(value[0]);
if(seqsize) Wall.create(Sequence.partitions(seqsize));
if(seqsize < 51) Term.table(Wall.get()); else Term.print('Wall created.');
Term.scan('type');
break;
case 'lion':
seq = [1,1,1,0,0,1,0,1,1,0,1,1,0,1,1,0,1,0,0,0,0,1,1,1,0,0,1,
1,1,0,0,0,0,1,0,1,1,0,1,1,0,1,1,0,1,0,0,1,0,1,0,0,0,0,
0,0,1,0,1,0,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,0,1,1,1,0,0,
0,0,1,1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,0,1,0,1,0,0,
0,0,0,0,1,0,1,0,0,1,0,1,1,0,1,1,0,1,1,0,1,0,0,0,0,1,1,
1,0,0,1,1,1,0,0,0,0,1,0,1,1,0,1,1,0,1,1,0,1,0,0,1,1,1];
seqsize = seq.length;
cell_mod = 7n;
pack = true;
wall = Wall.create(seq);
let div = document.createElement('div');
div.setAttribute('id', 'pattern')
Term.insert_block(div);
let [n, p] = [negative_hue, positive_hue];
[negative_hue, positive_hue] = [230, 30];
new p5(sketch, div);
[negative_hue, positive_hue] = [n, p];
Term.scan('type');
break;
case 'alien':
seq = Sequence.rand128();
seqsize = seq.length;
cell_mod = 7n;
pack = true;
wall = Wall.create(seq);
let div2 = document.createElement('div');
div2.setAttribute('id', 'pattern')
Term.insert_block(div2);
new p5(sketch, div2);
Term.scan('type');
break;
case 'byhand':
if(value.length) seq = value.split(',').map(n=>parseInt(n));
seqsize = seq.length;
Wall.create(seq);
if(seqsize < 51) Term.table(Wall.get()); else Term.print('Wall created.');
Term.scan('type');
break;
case 'tab':
Term.table(Wall.get());
Term.scan('type');
break;
case 'hue':
if(value[0]) negative_hue = parseInt(value[0]);
if(value[1]) positive_hue = parseInt(value[1]);
Term.scan('type');
break;
case 'test':
let success = Wall.valid();
Term.print(success ? 'Wall OK' : 'Errors Found!');
Term.scan('type');
break;
default:
Term.scan('type');
}
}
}()));