Last active
June 25, 2021 10:10
-
-
Save likev/1a1457a1a83317a96bb0844b2d2dbbf9 to your computer and use it in GitHub Desktop.
Starting with 2, integers are added, in order, as vertices to a graph. Any two vertices are joined if one of them is a factor of the other. What is the maximum integer if none of the edges are allowed to cross? https://twitter.com/mathstechnology/status/1407585626015338499
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//numbers 2-23 | |
var run = async _ => { | |
let canvas = $("<canvas width=1000 height=800></canvas>")[0] | |
$('body').empty().append(canvas) | |
const ctx = canvas.getContext('2d'); | |
const get_random = (a, b) => { | |
return (b - a) * Math.random() + a; | |
} | |
const draw_circle = (x, y, r) => { | |
// Draw the ellipse | |
ctx.beginPath(); | |
ctx.ellipse(x, y, r, r, Math.PI / 4, 0, 2 * Math.PI); // | |
ctx.stroke(); | |
} | |
const draw_text = (x, y, n) => { | |
ctx.font = 'bold 24px monospace'; | |
ctx.fillStyle = 'red'; | |
ctx.fillText(`${n}`, x - 5, y + 5); | |
} | |
const draw_line = (p1, p2) => { | |
// Draw the ellipse | |
ctx.beginPath(); | |
ctx.moveTo(p1[0], p1[1]) | |
ctx.lineTo(p2[0], p2[1]) | |
ctx.stroke(); | |
} | |
const check_cross = (line1, line2) => { | |
let [x11, y11] = line1[0], [x12, y12] = line1[1], | |
[x21, y21] = line2[0], [x22, y22] = line2[1]; | |
let xa = [x12 - x11, y12 - y11], | |
xb = [x22 - x21, y22 - y21]; | |
if (Math.abs(xa[0] * xb[1] - xa[1] * xb[0]) < 1e-6) return false; | |
let x1min = Math.min(x11, x12), | |
x1max = Math.max(x11, x12), | |
x2min = Math.min(x21, x22), | |
x2max = Math.max(x21, x22), | |
k1 = xa[1] / xa[0], | |
b1 = y11 - x11 * k1, | |
k2 = xb[1] / xb[0], | |
b2 = y21 - x21 * k2; | |
let cross_x = (b2 - b1) / (k1 - k2); | |
//console.log(cross_x) | |
if (cross_x > x1min + 0.1 && cross_x < x1max - 0.1 && | |
cross_x > x2min + 0.1 && cross_x < x2max - 0.1) return true; | |
return false; | |
} | |
console.log(check_cross([ | |
[0, 0], | |
[100, 100] | |
], [ | |
[0, 2], | |
[100, 102] | |
])); //false | |
console.log(check_cross([ | |
[0, 0], | |
[100, 100] | |
], [ | |
[2, 2], | |
[102, 102] | |
])); //false | |
console.log(check_cross([ | |
[0, 0], | |
[100, 100] | |
], [ | |
[0, 100], | |
[100, 0] | |
])); //true | |
console.log(check_cross([ | |
[0, 0], | |
[100, 100] | |
], [ | |
[0, 100], | |
[50, 55] | |
])); //false | |
const test_once = (N, show_circle = false) => { | |
let lines = [], | |
points = new Map(); | |
if (show_circle) ctx.clearRect(0, 0, 1000, 800); | |
let findall = true; | |
for (let n = 2; n <= N; n++) { | |
let find = false; | |
//let lines_back = JSON.parse(JSON.stringify(lines)) | |
const lines_length = lines.length; | |
for (let i = 0; i < n * n; i++) { //every point try n*n times | |
//lines = JSON.parse(JSON.stringify(lines_back)); | |
lines.length = lines_length; | |
let x = get_random(100, 900), | |
y = get_random(100, 700); | |
if (show_circle) { | |
draw_circle(x, y, 30) | |
draw_text(x, y, n) | |
} | |
points.set(n, [x, y]) | |
let cross = false; | |
for (let k = 2; k < n; k++) { //check cross of divide | |
if (n % k === 0) { | |
let line1 = [points.get(k), points.get(n)]; | |
for (let line2 of lines) { | |
if (check_cross(line1, line2)) { | |
cross = true; | |
break; | |
}; | |
} | |
if (cross) break; | |
if (show_circle) draw_line(line1[0], line1[1]) | |
lines.push(line1) | |
} | |
} | |
if (cross) continue; | |
find = true; | |
break; | |
} | |
if (!find) { | |
findall = false; | |
break; | |
} | |
} | |
if (!findall) return false; | |
ctx.clearRect(0, 0, 1000, 800); | |
for (let n = 2; n <= N; n++) { | |
let [x, y] = points.get(n); | |
draw_circle(x, y, 30) | |
draw_text(x, y, n) | |
} | |
for (let line of lines) { | |
draw_line(line[0], line[1]) | |
} | |
return true; | |
} | |
function sleep(ms) { | |
return new Promise(resolve => setTimeout(resolve, ms)); | |
} | |
let show_circle = false; | |
for (let i = 0; i < 1e6; i++) { | |
if (i % 1E2 === 0) console.log(`find ${i} times`); | |
if (i % 1E2 === 0) { | |
//show_circle = true; | |
//await sleep(100) | |
} else show_circle = false; | |
if (test_once(23, show_circle)) { | |
break; | |
} | |
} | |
} | |
run() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//any numbers | |
var run = async _ => { | |
let canvas = $("<canvas width=1000 height=800></canvas>")[0] | |
$('body').empty().append(canvas) | |
const ctx = canvas.getContext('2d'); | |
const get_random = (a, b) => { | |
return (b - a) * Math.random() + a; | |
} | |
const draw_circle = (x, y, r) => { | |
// Draw the ellipse | |
ctx.beginPath(); | |
ctx.ellipse(x, y, r, r, Math.PI / 4, 0, 2 * Math.PI); // | |
ctx.stroke(); | |
} | |
const draw_text = (x, y, n) => { | |
ctx.font = 'bold 24px monospace'; | |
ctx.fillStyle = 'red'; | |
ctx.fillText(`${n}`, x - 5, y + 5); | |
} | |
const draw_line = (p1, p2) => { | |
// Draw the ellipse | |
ctx.beginPath(); | |
ctx.moveTo(p1[0], p1[1]) | |
ctx.lineTo(p2[0], p2[1]) | |
ctx.stroke(); | |
} | |
const check_cross = (line1, line2) => { | |
let [x11, y11] = line1[0], [x12, y12] = line1[1], | |
[x21, y21] = line2[0], [x22, y22] = line2[1]; | |
let xa = [x12 - x11, y12 - y11], | |
xb = [x22 - x21, y22 - y21]; | |
//if (Math.abs(xa[0]) < 1e-6 || Math.abs(xb[0]) < 1e-6) return true; | |
if (Math.abs(xa[0] * xb[1] - xa[1] * xb[0]) < 1e-6) return false; | |
let x1min = Math.min(x11, x12), | |
x1max = Math.max(x11, x12), | |
x2min = Math.min(x21, x22), | |
x2max = Math.max(x21, x22), | |
k1 = xa[1] / xa[0], | |
b1 = y11 - x11 * k1, | |
k2 = xb[1] / xb[0], | |
b2 = y21 - x21 * k2; | |
let cross_x = (b2 - b1) / (k1 - k2); | |
//console.log(cross_x) | |
if (cross_x > x1min && cross_x < x1max && | |
cross_x > x2min && cross_x < x2max) return true; | |
return false; | |
} | |
console.log(check_cross([ | |
[0, 0], | |
[100, 100] | |
], [ | |
[0, 2], | |
[100, 102] | |
])); //false | |
console.log(check_cross([ | |
[0, 0], | |
[100, 100] | |
], [ | |
[2, 2], | |
[102, 102] | |
])); //false | |
console.log(check_cross([ | |
[0, 0], | |
[100, 100] | |
], [ | |
[0, 100], | |
[100, 0] | |
])); //true | |
console.log(check_cross([ | |
[0, 0], | |
[100, 100] | |
], [ | |
[0, 100], | |
[50, 55] | |
])); //false | |
const test_once = (numbers, show_circle = false) => { | |
let lines = [], | |
points = new Map(); | |
if (show_circle) ctx.clearRect(0, 0, 1000, 800); | |
let findall = true; | |
for (let n of numbers) { | |
let find = false; | |
//let lines_back = JSON.parse(JSON.stringify(lines)) | |
const lines_length = lines.length; | |
for (let i = 0; i < n * n; i++) { //every point try n*n times | |
//lines = JSON.parse(JSON.stringify(lines_back)); | |
lines.length = lines_length; | |
let x = get_random(100, 900), | |
y = get_random(100, 700); | |
if (show_circle) { | |
draw_circle(x, y, 30) | |
draw_text(x, y, n) | |
} | |
points.set(n, [x, y]) | |
let cross = false; | |
for (let k of numbers) { //check cross of divide | |
if (k >= n) break; | |
if (n % k === 0) { | |
let line1 = [points.get(k), points.get(n)]; | |
for (let line2 of lines) { | |
if (check_cross(line1, line2)) { | |
cross = true; | |
break; | |
}; | |
} | |
if (cross) break; | |
if (show_circle) draw_line(line1[0], line1[1]) | |
lines.push(line1) | |
} | |
} | |
if (cross) continue; | |
find = true; | |
break; | |
} | |
if (!find) { | |
findall = false; | |
break; | |
} | |
} | |
if (!findall) return false; | |
ctx.clearRect(0, 0, 1000, 800); | |
for (let n of numbers) { | |
let [x, y] = points.get(n); | |
draw_circle(x, y, 20) | |
draw_text(x, y, n) | |
} | |
for (let line of lines) { | |
draw_line(line[0], line[1]) | |
} | |
return true; | |
} | |
function sleep(ms) { | |
return new Promise(resolve => setTimeout(resolve, ms)); | |
} | |
let show_circle = false; | |
const numbers = []; | |
for (let i = 20; i <= 100; i++) { | |
numbers.push(i); | |
} | |
for (let i = 0; i < 1e6; i++) { | |
if (i % 1E2 === 0) console.log(`find ${i} times`); | |
if (i % 1E2 === 0) { | |
//show_circle = true; | |
//await sleep(100) | |
} else show_circle = false; | |
if (test_once(numbers, show_circle)) { | |
break; | |
} | |
} | |
} | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment