WeBWorK Problems

keys and randomization

by Alex Jordan -
Number of replies: 1
I just made an observation that I though other problem authors may find interesting.

In perl,
keys %hash

returns an array of the keys from %hash. I was using this in a problem that needs to randomly create three intervals of different type (open, closed, open-closed, closed-open). I will eventually need to know what delimiter opens each interval, so I made:

%left=(op=>'(',cl=>'[',oc=>'(',co=>'[');
and then I thought I could use the following to choose three random types of interval from among 'op', 'cl', 'oc', and 'co'.
@type=(keys %left)[NchooseK(4,3)];

I'm just being overly "perly" here because I could easily do this instead:

@type=('op','cl','oc','co')[NchooseK(4,3)];
The NchooseK(4,3) chooses three distinct numbers from (0,1,2,3) and then applies those as indices to the array (keys %left) to give the three-element array @type.

But here is the observation. keys %hash does not return the keys in the same order on every compilation. It randomizes the order and pays no attention to the seed, the alphabetical order of the keys, or the order they were originally defined. So my @type array was giving randomly different results every time I looked at the problem.

The solution is to be less perly.

Re: keys and randomization

by Alex Jordan -
This would also work:
@type=(lex_sort(keys %left))[NchooseK(4,3)];
which would put the keys in a fixed order before indices are randomly chosen