Strange attractors III

*** Reload repeatedly if blank ***

As seen on mathworld.wolfram.com/strangeattractor.html

I included a few strings that I found interesting.
Create your own! Use the empty string in [trajectories] and put wildcards in some places to drive a reduced search. Example limited search: TURTLETOY***. The final trajectory string is printed to the console.
The random search attempts to find trajectories that stay close to the center but are not too focussed on very small areas.
I threw all coding standards out the window for this one...

Log in to post a comment.

// LL 2021

// From Wolfram Alpha
// const trajectory = 0 // min=0 max=16 step=1 (Random search,"AMTMNQQXUYGA", "CVQKGHQTPHTE", "FIRCDERRPVLD", "GIIETPIQRRUL", "GLXOESFTTPSV", "GXQSNSKEECTX", "HGUHDPHNSGOH", "ILIBVPKJWGRR", "LUFBBFISGJYS", "MCRBIPOPHTBN", "MDVAIDOYHYEA", "ODGQCNXODNYA", "QFFVSLMJJGCR", "UWACXDQIGKHF", "VBWNBDELYHUL", "WNCSLFLGIHGL")
// const trajectories = [ "", "AMTMNQQXUYGA", "CVQKGHQTPHTE", "FIRCDERRPVLD", "GIIETPIQRRUL", "GLXOESFTTPSV", "GXQSNSKEECTX", "HGUHDPHNSGOH", "ILIBVPKJWGRR", "LUFBBFISGJYS", "MCRBIPOPHTBN", "MDVAIDOYHYEA", "ODGQCNXODNYA", "QFFVSLMJJGCR", "UWACXDQIGKHF", "VBWNBDELYHUL", "WNCSLFLGIHGL" ]

// Random ones
// const trajectory = 0 // min=0 max=10 step=1 (Random search, TURTLETOYvoa, Ewtlmwugutaq, Bitglqlmqyjb, Oaegihulgckd, Ujgiufqoledg, Hiooquqfthee, Thpoiknyvwtd, Gtwlfwqxmbpv, Aklogsxymbkg, Bqrphltsatji)
// const trajectories = [ "", "TURTLETOYvoa", "Ewtlmwugutaq", "Bitglqlmqyjb", "Oaegihulgckd", "Ujgiufqoledg", "Hiooquqfthee", "Thpoiknyvwtd", "Gtwlfwqxmbpv", "Aklogsxymbkg", "Bqrphltsatji" ]

// English words
const trajectory = 0 // min=0 max=32 step=1 (Random search,Mockingbirds,Imprevisible,Unsquirelike,Precipitancy,Nonrectified,Prodigiously,Overhumanity,Tobogganists,Reminiscence,Innoculation,Frustrations,Pseudogaster,Significator,Equidistance,Barometrical,Nonobsession,Unconfidence,Begottenness,Unfavourable,Orthoclastic,Irreprovably,Hexiological,Pinguiferous,Plasmodesmus,Unobtainably,Maleficences,Representant,Kendallville,Unassessable,Reinoculated,Reimbushment,Verificatory)
const trajectories = [ "", "Mockingbirds", "Imprevisible", "Unsquirelike", "Precipitancy", "Nonrectified", "Prodigiously", "Overhumanity", "Tobogganists", "Reminiscence", "Innoculation", "Frustrations", "Pseudogaster", "Significator", "Equidistance", "Barometrical", "Nonobsession", "Unconfidence", "Begottenness", "Unfavourable", "Orthoclastic", "Irreprovably", "Hexiological", "Pinguiferous", "Plasmodesmus", "Unobtainably", "Maleficences", "Representant", "Kendallville", "Unassessable", "Reinoculated", "Reimbushment", "Verificatory" ]

const plottable = 0; // min=0 max=1 step=1 (No,Yes)
Canvas.setpenopacity(plottable?1:-0.25)
// MOCKINGBIRDS, IMPREVISIBLE, NONRECTIFIED, PRECIPITANCY, UNSQUIRELIKE, PRODIGIOUSLY, OVERHUMANITY, TOBOGGANISTS, REMINISCENCE, INNOCULATION, FRUSTRATIONS, PSEUDOGASTER, SIGNIFICATOR, EQUIDISTANCE, BAROMETRICAL, NONOBSESSION, UNCONFIDENCE, BEGOTTENNESS, UNFAVOURABLE, ORTHOCLASTIC, IRREPROVABLY, HEXIOLOGICAL, PINGUIFEROUS, PLASMODESMUS, UNOBTAINABLY, MALEFICENCES, REPRESENTANT, KENDALLVILLE, UNASSESSABLE, REINOCULATED, REIMBUSHMENT, VERIFICATORY
turtle = plottable ? new Slowpoke() : new Turtle(), a = []
redo = rewind = 0, newTrajectory(), init_iterations = 100000
function walk(ii) {
    const nx = a[0] + a[1] * x + a[2] * x**2 + a[3] * x * y + a[4]  * y + a[5]  * y**2
    const ny = a[6] + a[7] * x + a[8] * x**2 + a[9] * x * y + a[10] * y + a[11] * y**2
    x = nx, y = ny, i = ii - rewind
    if (i < init_iterations * 0.99 && (isNaN(x) || Math.abs(x) > 10 || isNaN(y) || Math.abs(y) > 10)) newTrajectory(ii)
    if (isNaN(x) || Math.abs(x) > 10 || isNaN(y) || Math.abs(y) > 10) newTrajectory(ii);
    if (i < init_iterations && x == nx && y == ny) {
        addToBins(ii)
        min_x = Math.min(min_x, x), max_x = Math.max(max_x, x)
        min_y = Math.min(min_y, y), max_y = Math.max(max_y, y)
    } else if (i == init_iterations) {
        x = y = 0
        if ((max_x - min_x) > (max_y - min_y)) { const cc = (min_y + max_y) / 2, dd = (max_x - min_x) / 2; min_y = cc - dd, max_y = cc + dd }
        else { const cc = (min_x + max_x) / 2, dd = (max_y - min_y) / 2; min_x = cc - dd, max_x = cc + dd }
        console.log(`setup: ${setup} - attempts: ${redo} - x: [${min_x.toFixed(2)},${max_x.toFixed(2)}] - y: [${min_y.toFixed(2)},${max_y.toFixed(2)}]`)
    } else if (x == nx && y == ny) {
        const bx = ((x - min_x) / (max_x - min_x) - 0.5) * 190, by = ((max_y - y) / (max_y - min_y) - 0.5) * 190
        turtle.jump(bx, by), turtle.forward(plottable?0.5:0.1)
    }
    if (i < 1<<(plottable?18:21)) return true
	if (plottable) console.log(`Slowpoke: draw: ${slowpoke_draw}, skip: ${slowpoke_skip}`)
	return false
}
function newTrajectory(rw=0) { 
    if (typeof word_list !== 'undefined' && word_list.length > 0) setup = word_list[Math.random() * word_list.length | 0].toUpperCase();
    else setup = "" + trajectories[trajectory].toUpperCase()
    min_x = min_y = Number.MAX_VALUE, max_x = max_y = -Number.MAX_VALUE, x = y = 0, redo++, bins = {}
    if (rewind < 1 << 15) rewind=rw
    while (setup.length < 12) r = Math.random() * 25 | 0, setup += String.fromCharCode(r + 65)
    for (var j=0; j<12; j++) {
        a[j] = (setup.charCodeAt(j) - 65) * 0.1 - 1.2
        if (Math.abs(a[j]) > 1.21) r = Math.random() * 25 | 0, a[j] = r * 0.1 - 1.2, setup = setup.substring(0, j) + String.fromCharCode(r + 65) + setup.substring(j + 1)
    }
}
function addToBins(ii) {
    mx = (x - min_x) / (max_x - min_x), my = (y - min_y) / (max_y - min_y)
    key = '' + mx.toFixed(2)+';'+my.toFixed(2);
    if (key in bins) bins[key]++; else bins[key] = 1
    if (bins[key] > 10000) newTrajectory(ii)
}

////////////////////////////////////////////////////////////////
// Slowpoke utility code. Created by Reinder Nijhoff 2019
// https://turtletoy.net/turtle/cfe9091ad8
////////////////////////////////////////////////////////////////
function Slowpoke(o,e){const t={};return new class extends Turtle{goto(o,e){const s=Array.isArray(o)?[...o]:[o,e];if(this.isdown()){const o=[this.x(),this.y()],e=0,i=1,r=o[0].toFixed(e)+"_"+s[0].toFixed(e)+o[1].toFixed(i)+"_"+s[1].toFixed(i),d=s[0].toFixed(e)+"_"+o[0].toFixed(e)+s[1].toFixed(i)+"_"+o[1].toFixed(i);if(t[r]||t[d])return super.up(),super.goto(s),super.down(),void slowpoke_skip++;t[r]=t[d]=!0,slowpoke_draw++}super.goto(s)}}(o,e)}var slowpoke_skip=0,slowpoke_draw=0;

// Optional word list to guide the search
//word_list = []