From 1c672d502f473d13b2f3f9776a87b4dc1dee2067 Mon Sep 17 00:00:00 2001 From: lllllllllwith10ls Date: Sun, 19 Jan 2025 20:59:00 -0600 Subject: [PATCH 1/2] Added ingrown hydra --- index.html | 1 + ingrown.js | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+) create mode 100644 ingrown.js diff --git a/index.html b/index.html index 2d2d6cf..9e2cee0 100644 --- a/index.html +++ b/index.html @@ -48,6 +48,7 @@ + diff --git a/ingrown.js b/ingrown.js new file mode 100644 index 0000000..b1d4db5 --- /dev/null +++ b/ingrown.js @@ -0,0 +1,220 @@ +let ingrown_compare = (seq1,seq2)=>{ + if(seq1.length===0){ + if(seq2.length===0) return 0 + else return -1 + }else{ + if(seq2.length===0) return 1 + else{ + if(seq1[0][0] < seq2[0][0]) { + let seq3 = []; + let diff = seq2[0][0] - seq1[0][0]; + for(let i = 0; i < seq2.length; i++) { + seq3.push([]); + for(let j = 0; j < seq2[i].length; j++) { + if(seq2[i][j] > diff) { + seq3[i].push(seq2[i][j] - diff); + } else { + seq3[i].push(0); + } + } + } + seq2 = seq3; + } + for(let i = 0; i < Math.max(seq1[0].length,seq2[0].length); i++) + { + if(!seq1[0][i] && !seq2[0][i]) break; + else if(!seq1[0][i] && seq2[0][i]) return -1; + else if(seq1[0][i] && !seq2[0][i]) return 1; + else if(seq1[0][i]seq2[0][i]) return 1; + } + return ingrown_compare(seq1.slice(1),seq2.slice(1)) + } + } +}; + +let ingrownSvg = (seq) => { + + var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + var path1 = document.createElementNS("http://www.w3.org/2000/svg", 'path'); + var path2 = document.createElementNS("http://www.w3.org/2000/svg", 'path'); + + svg.setAttribute("aria-hidden","true"); + + + var svgElements = subSvg(seq,0,0,0,[]).svgElements; + + for(let i in svgElements) { + svg.appendChild(svgElements[i]); + } + document.body.appendChild(svg); + + let bbox = svg.getBBox({stroke:true}); + + svg.remove(); + + // Set the viewport with these bounds + svg.setAttribute("viewBox", `${bbox.x-10} ${bbox.y-10} ${bbox.width+20} ${bbox.height+20}`); + svg.setAttribute('width', `${bbox.width+10}`); + svg.setAttribute('height', `${bbox.height+10}`); + + return svg.outerHTML; +} + +let subSvg = (seq,num,x,y,prev,toggleWidth) => { + if(seq.length == 0) { + return {width: 20, svgElements: []}; + } + let totalWidth = 0; + let result = []; + for(let i = seq.length-1; i >= 0; i--) { + if(seq[i][0] == num) { + let svgElement = document.createElementNS("http://www.w3.org/2000/svg","circle"); + if(seq[i][1] && seq[i][1] > 0 && totalWidth == 0) { + if(!toggleWidth) { + totalWidth = 20; + } + toggleWidth = !toggleWidth; + } else { + toggleWidth = false; + } + svgElement.className.baseVal = "node"; + svgElement.cx.baseVal.value = x+totalWidth; + svgElement.cy.baseVal.value = y; + svgElement.r.baseVal.value = 5; + svgElement.style.fill = 'rgb(0,0,0)'; + result.push(svgElement); + for(let j = 0; j < seq[i].length; j++) { + if(seq[i][j] > 0) { + let svgElement2 = document.createElementNS("http://www.w3.org/2000/svg","line"); + svgElement2.className.baseVal = "segment"; + svgElement2.x1.baseVal.value = prev[seq[i][j]-1][0]; + svgElement2.y1.baseVal.value = prev[seq[i][j]-1][1]; + svgElement2.x2.baseVal.value = x+totalWidth; + svgElement2.y2.baseVal.value = y; + svgElement2.style.stroke = 'rgb(0,0,0)'; + svgElement2.style["stroke-width"] = '1.2px'; + svgElement2.style["stroke-linecap"] = 'round'; + svgElement2.style["stroke-linejoin"] = 'round'; + result.push(svgElement2); + } else { + break; + } + } + let sub = subSvg(getSubtree(seq,i),num+1,x+totalWidth,y-40/(num+1),prev.concat([[x+totalWidth,y]]),toggleWidth); + result = result.concat(sub.svgElements); + totalWidth += sub.width; + } + } + return {width: totalWidth, svgElements: result}; +} + +let getSubtree = (seq, i) => { + let j = i+1; + for(j; j < seq.length; j++) { + if(seq[j][0] <= seq[i][0]) { + break; + } + } + return seq.slice(i+1,j); +} + +let getSubtree2 = (seq, i) => { + let j = i+1; + for(j; j < seq.length; j++) { + if(seq[j][0] <= seq[i][0]) { + break; + } + } + return seq.slice(i,j); +} + +let ingrown_display = expr=>''+expr==='Infinity'?'Limit': ingrownSvg(expr)+expr.map(col => col.toString().split(',0')[0]).join(' '); +let ingrown_display2 = expr=>''+expr==='Infinity'?'Limit': expr.map(col => col.toString().split(',0')[0]).join(' '); +let ingrown_limit = seq=>seq.length>0&&seq[seq.length-1][0]>0; + +{ + let lim = (FSterm)=>{ + if(FSterm == 0) + { + return [[0]]; + } + else + { + let arr = []; + for(let i = FSterm; i >= 0; i--) + { + arr.push(i); + } + return lim(FSterm-1).concat([arr]); + } + }; + let ingrown = (seq,FSterm)=>{ + let seq2 = seq.slice(0,seq.length-1); + if(FSterm === 0) + { + return seq2; + } + if(seq[seq.length-1][1]===0) + { + let index = seq.findLastIndex((x) => x[0] === seq[seq.length-1][0]-1); + return ingrown(seq,FSterm-1).concat(seq2.slice(index)); + } + else + { + let subindex = seq[seq.length-1].findLastIndex((x) => x !== 0); + let diffTotal = seq[seq.length-1][subindex] + subindex - 1; + let index = seq.findLastIndex((x) => x[0] === diffTotal - 1); + let index2 = seq.findLastIndex((x) => x[0] === diffTotal); + if(ingrown_compare(getSubtree2(seq,index),getSubtree2(seq,index2)) === -1) { + index = index2-1; + } + let repeat = seq2.slice(index); + repeat.shift(); + return ingrown(seq,FSterm-1).concat(increment(repeat,FSterm,seq[seq.length-1][0] - diffTotal,seq[seq.length-1])); + } + }; + let increment = (seq,FSterm,add,last)=>{ + return seq.map(x => x.map(y => increment2(y,FSterm,add,last))); + } + let increment2 = (num,FSterm,add,last)=>{ + for(let i = 0; i < FSterm; i++) + { + if (num < last.findLast((x) => x !== 0)) { + break; + } + if(last.indexOf(num) > 0 && num > 0 && num < last[0] - add) { + num = last[last.indexOf(num)-1]; + } else if (num < last[0] - add) { + let diff = num - last.find((z) => z < num); + num = last.findLast((z) => z > num) + diff; + } else { + num = num + add; + } + } + return num; + } +register.push({ + id:'ingrown', + name:'Ingrown hydra', + display:ingrown_display, + able:ingrown_limit, + compare:ingrown_compare, + FS:(()=>{ + var data={}; + return (seq,FSterm)=>{ + if(!seq.length) return [] + var datakey=''+seq; + if(datakey==='Infinity') return lim(FSterm); + if(seq[seq.length-1][0]===0) return seq.slice(0,seq.length-1); + if(!data[datakey]) data[datakey] = []; + else if(data[datakey][FSterm]!==undefined) return data[datakey][FSterm]; + return data[datakey][FSterm] = ingrown(seq,FSterm); + }; + })(), + init:()=>([ + {expr:[[[Infinity]]],low:[[]],subitems:[]} + ,{expr:[],low:[[]],subitems:[]} + ]) +}) +} \ No newline at end of file From 9b140e37f32da576fa1e604e18f9ebce831cd358 Mon Sep 17 00:00:00 2001 From: lllllllllwith10ls Date: Tue, 22 Jul 2025 18:46:07 -0500 Subject: [PATCH 2/2] hydra_test --- hydra-test.js | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 3 +- 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 hydra-test.js diff --git a/hydra-test.js b/hydra-test.js new file mode 100644 index 0000000..9587d1c --- /dev/null +++ b/hydra-test.js @@ -0,0 +1,142 @@ +let hydra_test_map = { + ":": 2, + "[": 1, + "]": 0, +} + +let hydra_test_compare = (seq1, seq2) => { + if(seq1.length===0){ + if(seq2.length===0) return 0 + else return -1 + }else{ + if(seq2.length===0) return 1 + else{ + if (hydra_test_map[seq1[0]] === hydra_test_map[seq2[0]]) { + return hydra_test_compare(seq1.slice(1),seq2.slice(1)) + } + return Math.sign(hydra_test_map[seq1[0]] - hydra_test_map[seq2[0]]); + } + } +}; + +let matching_parenthesis_close = (str, index, open, close) => { + let openIndex = index; + let counter = 1; + while (counter > 0 && openIndex >= 0) { + openIndex--; + let c = str[openIndex]; + if (c === close) { + counter++; + } + if (c === open) { + counter--; + } + } + return openIndex; +} + +{ + let lim = (FSterm)=>{ + if(FSterm == 0) + { + return "[[]]"; + } + else + { + let result = "[[!]]"; + for(let i = 0; i < FSterm; i++) + { + result = result.replace("!", "[:!]"); + } + return result.replace("!",""); + } + }; + let hydra_test = (str, FSterm) => { + let indexopen = str.lastIndexOf("["); + let indexclose = indexopen + 1; + if(str[indexclose] === "]") { + let outerclose = indexopen + 2; + let outeropen = matching_parenthesis_close(str, outerclose, "[", "]"); + let repeat = str.slice(outeropen, indexopen) + str.slice(indexclose + 1, outerclose + 1) + "!"; + let result = str.slice(0, outeropen) + "!" + str.slice(outerclose + 1); + for (let i = 0; i < FSterm; i++) { + result = result.replace("!", repeat); + } + return result.replace("!", ""); + } else if (str[indexclose] === ":") { + let indexclose = indexopen + 2; + let outerclose = indexopen + 3; + let outeropen = matching_parenthesis_close(str, outerclose, "[", "]"); + let innerclose = indexclose; + let inneropen = indexopen; + let innerclose2 = innerclose; + let inneropen2 = inneropen; + let breakout = false; + for (let i = 0; i < 3; i++) { + while (hydra_test_compare(str.slice(inneropen, innerclose + 1), str.slice(outeropen, outerclose + 1)) <= 0) { + outerclose = outerclose + 1; + outeropen = matching_parenthesis_close(str, outerclose, "[", "]"); + + if (outerclose >= str.length || (i > 3 && hydra_test_compare(str.slice(inneropen2, innerclose2 + 1), str.slice(outeropen, outerclose + 1)) > 0) || (hydra_test_compare("[[:]]", str.slice(outeropen, outerclose + 1)) > 0)) { + outerclose = outerclose - 1; + outeropen = outeropen + 1; + breakout = true; + break; + } + } + if (breakout) { + break; + } + innerclose = outerclose; + inneropen = outeropen; + if (i === 0) { + innerclose2 = innerclose; + inneropen2 = inneropen; + } + } + if (!breakout) { + indexclose = innerclose2; + indexopen = inneropen2; + outerclose = outerclose-1; + outeropen = matching_parenthesis_close(str, outerclose, "[", "]"); + } + let repeat = str.slice(outeropen, indexopen) + "!" + str.slice(indexclose + 1, outerclose + 1); + let result = str.slice(0, outeropen) + "!" + str.slice(outerclose + 1); + for (let i = 0; i < FSterm; i++) { + result = result.replace("!", repeat); + } + return result.replace("!", ""); + } + }; + let display = (str) => { + for (let i = str.length - 1; i >= 0; i--) { + if (str[i] == "]" && str[matching_parenthesis_close(str, i, "[", "]") + 1] == ":") { + str = str.slice(0, i) + ">" + str.slice(i+1); + } + } + return str.replaceAll("[:", "<"); + } +register.push({ + id:'hydra_test', + name:'hydra_test', + display:display, + able:(x) => (x.length >= 2 && x[x.length-2]!=="["), + compare:hydra_test_compare, + FS:(()=>{ + var data={}; + return (seq,FSterm)=>{ + if(!seq.length) return "" + var datakey=seq; + if(datakey==='Limit') return lim(FSterm); + if(seq[seq.length-2]==="[") return seq.substring(0,seq.length-2); + if(!data[datakey]) data[datakey] = []; + else if(data[datakey][FSterm]!==undefined) return data[datakey][FSterm]; + return data[datakey][FSterm] = hydra_test(seq,FSterm); + }; + })(), + init:()=>([ + {expr:"Limit",low:[""],subitems:[]} + ,{expr:"",low:[""],subitems:[]} + ]) +}) +} \ No newline at end of file diff --git a/index.html b/index.html index d87b6c1..3131722 100644 --- a/index.html +++ b/index.html @@ -55,7 +55,8 @@ - + + \ No newline at end of file