xxxxxxxxxx
343
// Revisiting the Card Algorithm
// Where we deal one card on the "table"
// then deal the next card to the bottom of the deck in hand
// Then repeat this until we are out of cards.
// Pickup the deck and repeat until the deck is back in order.
// The optimization I plan to implement will only
// deal through the deck once and then track
// where each card went/ collect all of the "cycle"
// data and calculate the LCM from there. This should be
// MUCH faster than dealing through the deck multiple times.
var auto=false; // Flag to check next number or not
var dl=1; // This is the deck length
var deck=[]; // Original Deck Order
var ndeck=[]; // Deck order after 1 cycle
var cycles=[]; // Track how many steps in each cycle
var factors=[]; // Compiles all of the factors together.
var totals=[]; // total # of cycles for each #
var primeTotals=[]; // Keeps track of HOW MANY of those primes we are using.
var pfactors=[]; // Prime factors of factors[]
var LCM=1; // Least Common Multiple
var primes=[];
var maxdl = 100; // Number we are going to
var output=[]; // Output we will try to copy for excel
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
}
function keyPressed()
{
//console.log(keyCode);
switch(keyCode)
{
case 32: dl*=2;
break;
case 38: dl++;
break;
case 40: dl--;
break;
}
initialize();
}
// This function takes the deck and
// deals one down, then one to the back
// of the deck until the entire deck has been
// distributed to the new deck
function execute()
{
var ct=0; // Number of cards we have cycled;
var temp; // Temporary card
ndeck.length=0;
do{
temp==undefined;
ndeck.push(deck.pop());
ct++;
if(deck.length)
{
temp=deck[deck.length-1];
}
for(var d=deck.length-1; d>0; d--)
{
deck[d]=deck[d-1];
}
if(deck.length)
{
deck[0]=temp;
ct++;
}
}while(deck.length);
for(var e=0; e<ndeck.length; e++)
{
deck[e]=ndeck[e];
}
}
function track()
{
var currentcycle=[]; // Steps in current cycle
var next=0; // Next number looking for
var nextndx=0; // Index of next spot
for(i=0; i<cycles.length; i++)
{
currentcycle=[];
if(cycles[i]==0)
{
next=i+1;
do{
nextndx=findIt(next);
currentcycle.push(dl-(nextndx+1)+1);
next=(dl)-(nextndx+1)+1;
}while (currentcycle[currentcycle.length-1]!=i+1)
// console.log(currentcycle);
for(var j=0; j<currentcycle.length-1; j++)
{
cycles[currentcycle[j]-1]=-1;
}
cycles[i]=currentcycle.length;
}
}
for(var i=0; i<cycles.length; i++)
{
if(cycles[i]>0)
{
found=false;
for(j=0; j<totals.length && !found; j++)
{
if(cycles[i]==totals[j])
{
found=true;
}
}
if(!found)
{
totals.push(cycles[i]);
}
}
}
totals.sort();
//console.log(totals);
//reverseOrder();
//console.log(totals);
}
//This function takes a number
// and returnes the index of the location
// of that number in the new deck
function findIt(num)
{
var found=false;
var indx=-1;
for(var i=0; i<ndeck.length && !found; i++)
{
if(ndeck[i]==num)
{
found=true;
indx=i;
}
}
return indx;
}
// This function goes through the totals array
// and eliminates smaller factors of bigger cycles
// ie eliminates a 3 if there is a cycle with 9
// Then stores it in a new array called factors
function removeFactors()
{
factoronce=false;
var keep;
for(var i=0; i<totals.length; i++)
{
keep=true;
for(var j=0; j<totals.length && keep; j++)
{
if((totals[j]%totals[i]==0) && (totals[i]!=totals[j]) && totals[j]>1)
{
keep=false;
}
}
if(keep)
{
factors.push(totals[i]);
}
}
//factors.sort();
}
function initialize()
{
deck=[]; // Original Deck Order
ndeck=[]; // Deck order after 1 cycle
cycles=[]; // Track how many steps in each cycle
factors=[]; // Compiles all of the factors together.
totals=[]; // total # of cycles for each #
primeTotals=[]; // Keeps track of HOW MANY of those primes we are using.
pfactors=[]; // Prime factors of factors[]
LCM=1; // Least Common Multiple
primes=[];
for(var i=dl; i>0; i--)
{
deck.push(i);
cycles.push(0);
}
execute(); // Run one Cycle
//console.log(ndeck);
track(); // Track the moves
//console.log("Chains for " + dl + ":" +totals);
removeFactors(); // Remove Factors of other factors
//console.log(factors);
doMagic();
}
// This SHOULD be where all the magic happens??
// We take all of the cycles and remove smaller
// factors of big cycles (ie 3 if we have 9)
// Then we gen a list of primes up to the highest
// # of cycles and also create an array of 0's for that
// After that for each cycle we have to do the prime
// factorization then add the number of each prime
// in that factorization to the 0's array IF the new
// number is bigger.
// Finally, we will raise each prime to the power of its 0
// array value and multiply everything together.
function doMagic()
{
LCM=1;
//removeFactors();
//genPrimes(factors[0]*2);
//genPrimes(floor(dl/2)*2);
genPrimes(dl+1);
// console.log(factors);
for(var i=0; i<factors.length; i++)
{
pFactor(factors[i]);
for(j=0; j<primeTotals.length; j++)
{
pcount=0;
for(k=0; k<pfactors.length; k++)
{
if(primes[j]==pfactors[k])
pcount++;
}
if(pcount>primeTotals[j])
{
primeTotals[j]=pcount
}
}
}
//console.log(primeTotals);
for(var i=0; i<primeTotals.length; i++)
{
LCM=LCM * (pow(primes[i], primeTotals[i]));
}
//output.push(dl);
output.push(LCM);
console.log(dl + " , " + LCM);
// if(dl<maxdl)
// {
// dl++;
// initialize();
// }
// else
// {
// var mt= (minute());
// var fname= "out" + mt+ ".txt"// + mt + ".txt");
// save(output, fname);
// //console.table(output);
// }
}
function genPrimes(n)
{
var prm;
primes.length=0;
primeTotals.length=0;
for(var i=2; i<n; i++)
{
prm=true;
for(var j=0; j<primes.length && prm; j++)
{
if(i%primes[j]==0)
{
prm=false;
}
}
if(prm)
{
primes.push(i);
primeTotals.push(0);
}
}
//console.log(primes);
}
function pFactor(num)
{
pfactors.length=0;
divisor=2;
var n=num;
//for (var i=0; i<n/2; i++)
while(n>=2)
{
if(n%divisor==0)
{
pfactors.push(divisor);
n=n/divisor;
}
else
{
divisor++;
}
}
//console.log(factors);
}