Randomize the test

21

6

I'm a teacher, and in a few days I have to give my students a test. Now, I'm always worried about my loveliest students being hurt by the least loveliest ones when they cheat, so I want to randomize the tests so no one can cheat off of anyone.

Right now, I have my tests saved in this format:

When was Java invented?
  Why does this matter?
  1941
  War was beginning
  None of the above

What is the increment operator in Java?
  Stack Overflow>how 2 incrememnt
  Google>how 2 incrememnt
  increment
  ++

That is, the questions are separated by a single blank line, and the answers are all preceded by two spaces. This is the output I need:

What is the increment operator in Java?
  ++
  increment
  Google>how 2 incrememnt
  Stack Overflow>how 2 incrememnt

When was Java invented?
  War was beginning
  1941
  Why does this matter?
  None of the above

That is, each answer on a question in a random order, and the question order randomized as well. Keep in mind that if the answer choice is "None of the above", it should stay at the bottom. Every question always has exactly four answers, and "None of the above" only ever appears as the last answer choice -- and never appears as a substring of an answer choice that is not "None of the above". Unfortunately, I can't rewrite all of my tests, so you'll have to take them in that format. Also, my students have to be able to read it, so I can't really take output any other way (except as described below).

I don't need it to be perfectly random. As long as it's close.

Standard loopholes are banned.


Bonus

Now, my students are used to that plain format, but if you can make it look like this...

1. What is the increment operator in Java?
  A. ++
  B. increment
  C. Google>how 2 incrememnt
  D. Stack Overflow>how 2 incrememnt

2. When was Java invented?
  A. War was beginning
  B. 1941
  C. Why does this matter?
  D. None of the above

I'll take 25% off of your final score. You'll get input the same way, though.

That is, if you number the questions and label the answers. Please keep in mind that questions should start at 1, and the answers are from A to D.


NB: The examples are different from the ones in the answers because I changed them after the fact. The specific examples aren't the point anyway; answers had to work with any arbitrary question(s).

Fund Monica's Lawsuit

Posted 2016-03-11T00:08:54.343

Reputation: 564

Bonuses in code golf are generally discouraged. None of the current submissions take the bonus (except this one, but with the bonus is a worse score than without), so that's a pretty good indicator that the challenge would be better without the bonus. – Mego – 2016-04-24T09:09:54.690

@Mego It fits the theme of the question and is easy to understand. There's no harm in it. – Fund Monica's Lawsuit – 2016-04-24T14:16:19.377

Answers

7

Pyth - 48 42 41 39 bytes

Will packed string.

js.Sm++hd/D"None of the above".Stdkc.zk

Try it online here.

Maltysen

Posted 2016-03-11T00:08:54.343

Reputation: 25 023

Accepting this answer because this question was [code-golf] and this answer is the shortest. Well done! – Fund Monica's Lawsuit – 2016-04-24T00:34:32.293

4

JavaScript ES6, 170 bytes

Is an anonymous function, name it. Note: this uses the random sort method, which isn't entirely random, but is sufficient, provided you aren't a probability teacher.

t=>t.split`

`.map(x=>(x=x.split`
`,R=[],(k=x.pop())=="  None of the above"?(R=[k]):x.push(k),[x.shift(),...x.sort(r=_=>.5-Math.random()),...R].join`
`)).sort(r).join`

`

With the bonus, 180.75 bytes

t=>t.split`

`.map(x=>(x=x.split`
`,R=[],(k=x.pop())=="  None of the above"?(R=[k]):x.push(k),[x.shift(),...x.sort(r=_=>.5-Math.random()),...R].map((k,i)=>(i?`  ${" ABCD"[i]}. `:"")+k.trim()).join`
`),a=0).sort(r).map(e=>++a+". "+e).join`

`

Test it out!

F=t=>t.split`

`.map(x=>(x=x.split`
`,R=[],(k=x.pop())=="  None of the above"?(R=[k]):x.push(k),[x.shift(),...x.sort(r=_=>.5-Math.random()),...R].join`
`)).sort(r).join`

`;

g.onclick=function(){o.innerHTML = ""; o.appendChild(document.createTextNode(F(i.value)));}
g.click();
textarea{width:100%;height:14em;}textarea,div,button{font-family:Consolas,monospace;white-space:pre;}
<textarea id=i>When was the War of 1812?
  1812.5
  1776
  1812
  1821

What is the capital of France?
  46
  F
  Nice
  None of the above

What is the square root of -1 (simplified)?
  i
  i don't know
  square root of -1
  wait this is a math test?</textarea><button id=g>go &rarr;</button><div id=o></div>

Conor O'Brien

Posted 2016-03-11T00:08:54.343

Reputation: 36 228

Did you try going for the bonus? – CalculatorFeline – 2016-03-11T01:03:08.057

@CatsAreFluffy No, net yet ;) – Conor O'Brien – 2016-03-11T01:03:24.740

What's a net? Is it like a not? – CalculatorFeline – 2016-03-11T01:04:40.320

1@CatsAreFluffy Well, it's a highly technical... thing. – Conor O'Brien – 2016-03-11T01:06:02.840

"Mostly random" is perfectly acceptable. – Fund Monica's Lawsuit – 2016-03-11T01:09:48.247

3What's a highly? What's a thing? What's a technical? What's a ? What's a ...? What's a 493 characters left? – CalculatorFeline – 2016-03-11T01:09:52.370

Pretty sure you can save two bytes by removing an "=_" from your random sort. Thanks for the intro to ES6! – andrewgu – 2016-03-11T02:32:39.683

1

@fond42518 My pleasure! However, in that random sort, I am saving the function _=>.5-Math.random() to the variable r, which I reference later on the fifth line. I am actually performing two random sorts: one on the items, and the other on the questions. If you want to learn more ES6, I suggest reading here.

– Conor O'Brien – 2016-03-11T02:34:43.450

2

CJam, 54 53 55 52 bytes

Saved 1 byte from using a later release (avaliable on TIO). Gained 2 bytes because I forgot to randomize order of questions. Saved 2 bytes from yet another bug fixed on TIO.

qNN+/mr{N/(\mr_"  None of the above"#3e\N*N\++}%NN+*

Try it online!

GamrCorps

Posted 2016-03-11T00:08:54.343

Reputation: 7 058

Only two bytes gained? o_O – Conor O'Brien – 2016-03-11T01:10:42.753

@CᴏɴᴏʀO'Bʀɪᴇɴ lol yeah, I split based on questions at the beginning, then so I just added the mr operator (randomize) to randomize order of questions before the answer logic takes place. – GamrCorps – 2016-03-11T01:11:42.183