AnnouncementsMatrixEventsFunnyVideosMusicAncapsTechnologyEconomicsPrivacyGIFSCringeAnarchyFilmPicsThemesIdeas4MatrixAskMatrixHelpTop Subs
3
Add topics
Comment preview
[-]x0x72(+2|0)

I'll write it as psuedo code for now because I want to use a language I don't really know that well because I'm trying to learn it. I'll set it as a task for later today to do the actual code.

So we need a partial permutation of a collection of numbers and we need each partial permutation to be different. I don't know what a special number is because I don't play the lottery. I already get extra points for this, equal to or greater than someone who can add the special numbers but also plays the lottery.

This is easy. We are going to use a single random selected number per row to drive a shuffle algorithm. Given your parameters a random selection and checking against a set should be fine. If not it can be adjusted later to a shuffle itself if the number of samples selected is huge.

Ok. I'll write some code. We're going to need factorial to get the choose function.

fac(1)->1;
fac(N)->N*fac(N-1).

I could use a guard there.

choose(N,K)->fac(N)/(fac(K)*fac(N-K)).

I could speed that up. Honestly a non-functional language would make dynamic programming like tabulation easy.

function choose(N,K) {
 var NK = N-K;
 var facN,facK,facNK;
 var cur=1;
 for(var i=1;i<=N;++i) {
  cur*=i;
  if(i==K) facK=cur;
  if(i==NK) facNK=cur;
 }
 facN=cur;
 return facN/(facK*facNK);
}

Though who knows if that's actually faster because we've added some branching to a loop.

Now the shuffle alg is where Erlang doesn't make things straightforward because the one I know uses sequence mutation.

function getSubPerm(N,k,seed) {
 var list = range(1,N+1);
 for(var i=0;i<k;++i) {
  var optionCount = N-i;
  var swapOffset = seed%optionCount;
  var temp = list[i];
  list[i]=list[swapOffset+i];
  seed-=swapOffset*optionCount;
 }
 return list.slice(0,k);
}

So I'll have to research later how to do that in an immutable way. Lol, I actually was up past 2am last night learning C interop with Erlang so I could just do that bit in C. Easier.

Then picking random numbers is easy. What would be interesting is estimating the point at which a random trial method is better or worse than using a random subpermutation for the outer list.

function randomSeeds_impl_trial(N,k,R) {
 var choices = choose(N,k);
 var set = new Set();
 while(set.size<R) {
  set.add(Math.floor(Math.random()*choices));
 }
 return [...set];
}
function randomSeeds_impl_subperm(N,k,R) {
 var choices = choose(N,k);
 var super_choices = choose(choices,R);
 var super_seed = Math.floor(Math.random()*super_choices);
 return getSubPerm(choices,R,super_seed);
}

Anyways that's just some initial thought documenting. I'll be translating some of this to Erlang and or a mix of C later.


I'm back. I decided I want to take a soft stab at turning the shuffle to an immutable and functional solution in Erlang without gpt. Like I said, I'm new to Erlang.

My first instinct is to just start using more functional patterns within the current solution and see where it take us.

To do things more functional like we should precompute all states our driver variables will hit over time, and then see if we can map from them. So we want to translate seed into a list of swap offsets. We'll make this more and more functional in stages.

function getSubPerm(N,k,seed) {
 var list = range(1,N+1);
 var offsets = [];
 for(var i=0;i<k;++i) {
  var offset = seed%(N-i);
  offsets.push(offset);
  seed -= offset*(N-i);
 }
 for(var i=0;i<k;++i) {
  var temp = list[i];
  list[i]=list[offsets[i]+i];
  list[offsets[i]+i]=temp;
 }
 return list.slice(0,k);
}

Now we want to make how we do that approach more function/erlangish

var seedToOffset=(
 [N,seed],
 offset=seed%N
) => N==1?[0]:[offset].concat(seedToOffset([N-1,seed-offset*N]));

function getSubPerm(N,k,seed) {
 var list = range(1,N+1);
 var offsets = seedToOffset([N,seed]);
 for(var i=0;i<k;++i) {
  var temp = list[i];
  list[i]=list[offsets[i]+i];
  list[offsets[i]+i]=temp;
 }
 return list.slice(0,k);
}

I wrote that Erlang as fuck.

Let's double down on some Erlangisms

var seedToOffset=(
 [N,seed],
 offset=seed%N
) => N==1?[0]:[offset,seedToOffset([N-1,seed-offset*N])];

function getSubPerm(N,k,seed) {
 var list = range(1,N+1);
 var offsets = seedToOffset([N,seed]);
 for(var i=0;i<k;++i) {
  var temp = list[i];
  list[i]=list[offsets[0]+i];
  list[offsets[0]+i]=temp;
  offsets=offsets[1];
 }
 return list.slice(0,k);
}

I'm letting you go along for the ride through all of it, rather than fixing bugs backwards. Me realizing the choose function is for distinct sets as output, rather than distinct lists.

function choose(N,k) {
 return fac(N)/fac(N-k);
}
choose(N,K)->fac(N)/fac(N-k).

Or

choose(N,K)->choose(N,K,N-K).
choose(N,_,N)->1;
choose(N,K,NminusK)->N*choose(N-1,K,NminusK).
[-]mortuss0(+0|0)

good try

[-]x0x71(+1|0)

If was doing it in JS it would take 5 seconds. Not worth bothering with. I may still do the Erlang implementation but it's not a big priority when I have a lot of other code I need to write.

[-]mortuss0(+0|0)

create a room on CTD(https://chat-to.dev/createchat) to talk about coding, projects and even business if it interests you