Lowest fully divisible integer fun!
ok, so here's my current challenge: build a system that calculates an integer which is divisible (in a whole number) from six adjustable integers (for evil rhythmic purposes!)
I've rigged up a cute implementation this morning, but it's slow (being based around a trial and error counter object) and is probably one bang short of a stack overflow; so I'm looking for any suggestions as to a more efficient way of doing this, possibly from an algebraic perspective.
Very interesting...I love geeking out on this math stuff. Seems to work well. I like trying various combinations and seeing how long the numbers count up, especially when you throw in a number like 11, pesky primes...
Not sure if this method would be faster, but I found a prime-factorization javascript on the Forums awhile back, and wrapped it into a simple factorization patch. So you could have 6 of these, combine the lists of factors with [zl group], eliminate all repeated factors with [zl thin], multiply the remaining numbers together with [accum] and that should give you the least common multiple of all of them. At least I think that's how them numbers work... :)
If anyone has a clean way to implement the js logic using standard Max objects, I'd like to see it, it's been kind of tricky to get the iterations to work right (the "while" loops). Curious to see people's techniques for this.
the patch:
save as primes.js:
////////////////////////////////
function msg_int(v)
{
while (v%2==0)
{
outlet(0,2);
v/=2;
}
var i=3;
while (i*i
{
if (v%i==0)
{
v/=i;
outlet(0,i);
}
else i+=2;
}
if (v>1) outlet(0,v);
}
////////////////////////////////
Here's a javascript that will compute the lowest common multiple from a list of positive integers. It might complain if the size of the lists or numbers are too high. It uses the fact that the LCM of two numbers can be found by multiplying them together and dividing by their greatest common divisor. The GCD is much easier to find than cycling through primes so it should be more efficient, however it still does a fair bit of iteration, especially with longer lists, so there might be more intelligent ways to solve this. I hope it helps.
lh
// lh.lcm.js
function list() {
a = arrayfromargs(arguments).map(check);
while (a.length>1) {
a.push(lcm(a.shift(),a.shift()));
}
outlet(0,a[0]);
function lcm(x,y) {
var w = x*y;
while (y!=0) {
var z = x%y;
x = y;
y = z;
}
return w/x;
}
function check(i) {
if (i
Awesome, awesome, thanks for the help guys.
This is now an excellent excuse to get my head around the JS side of max.
good luck with everything!
Thanks to both Luke Hall and Seejay James for these! I know this post is ancient, but I'm digging it up because these bits of js are throwing up errors all over the place in Max 6.1.9. Some of the errors include: "error calling function msg_int," "no function list," and "no function msg_int." I could copy the contents of the js I'm using, but it's copy and pasted from the two posts above. Does anyone else have an issue running that code? Maybe it's just me?
Nevermind, solved my own problem. Here's the code that I slightly altered to work in Max 6.1.9:
// lcm.js
inlets = 1;
outlets = 1;
function list() {
a = arrayfromargs(arguments).map(check);
while (a.length>1) {
a.push(lcm(a.shift(),a.shift()));
}
outlet(0,a[0]);
function lcm(x,y) {
var w = x*y;
while (y!=0) {
var z = x%y;
x = y;
y = z;
}
return w/x;
}
function check(i) {
if (i
return 1;
} else {
return i;
}
}
}
function anything() {
post();
post();
}
autowatch = 1;
// EOF
made this little JS to spit out 4 numbers between 4–30 that are all pairwise coprime — handy for early reflection delays.
First time using JS in Max… mainly because it's trouble to think up coprime numbers every time by hand.
function bang() {
var nums = [];
while (nums.length < 4) {
var n = Math.floor(Math.random() * 26) + 5; // 5–30
if (nums.indexOf(n) === -1 && coprimeWithAll(n, nums)) {
nums.push(n);
}
}
nums.sort(function(a, b) { return a - b; }); // ascending order
outlet(0, nums);
}
function coprimeWithAll(n, arr) {
for (var i = 0; i < arr.length; i++) {
if (gcd(n, arr[i]) !== 1) return false;
}
return true;
}
function gcd(a, b) {
while (b != 0) {
var t = b;
b = a % b;
a = t;
}
return a;
}