| Bytes | Lang | Time | Link |
|---|---|---|---|
| 022 | Vyxal 3 o | 250806T000524Z | pacman25 |
| 037 | Pip s | 170329T222719Z | DLosc |
| 046 | Jolf | 170330T183652Z | Conor O& |
| nan | Stacked | 170329T230310Z | Conor O& |
| 045 | CJam | 170330T145241Z | Business |
| 088 | JavaScript ES6 | 170329T214537Z | ETHprodu |
| 043 | 05AB1E | 170330T082527Z | Emigna |
| 242 | Batch | 170330T075742Z | Neil |
| 093 | Python 2 | 170329T220700Z | Rod |
Vyxal 3 -o, 22 bytes
'|s~⨥=:eṬ›„,∥∑L÷k1×◌①÷
so uh the input can just be split on | and then take the strings of length 1, 6 bytes are spent on rounding the score properly
Pip -s, 48 45 43 47 44 37 bytes
I'm definitely adding a rounding operator to my golfing language after this. :P
– DLosc, Mar 30, 2017 at 19:37
Well, it only took seven years...
/t*RNm-m/#b*#PFI{$NIb&Ua}MEbZa@`\|..`
Takes input as command-line arguments (the scan-tron page will need quoting and escaping of newlines if you run it from an actual command line). Outputs the missed questions first, then the score. Attempt This Online!
Explanation
I'm gonna do this in two parts: the incorrect questions list and the score.
PFI{$NIb&Ua}MEbZa@`\|..`
a,b are cmdline args (implicit)
a@`\|..` Find all occurrences in a of | followed by 2 chars
Regex matches don't overlap, so this finds each
selected answer and nothing else
bZ Zip with b, the correct answers
{ }ME Enumerate the resulting pairs and map this function
to them:
$NIb Fold the pair on the not-in operator
Gives 0 if correct answer matches selected answer,
1 otherwise
& Logical and
Ua Enumeration index incremented (1, 2, ...)
This gives the question number if the answer
was incorrect, or 0 if it was correct
FI Filter out the falsey (0) elements
P Print, joining on spaces (-s flag)
/t*RNm-m/#b*#...
a,b are cmdline args, t is 10, m is 1000 (implicit)
... The code from the first part
# Length of that list (i.e. number of incorrect answers)
m/#b* Times 1000/(number of questions)
m- Subtracted from 1000
We now have a number like 666.666666666667
RN Round to nearest integer
/t* Times 1/10
Print (implicit)
Jolf, 46 bytes
I can't seem to break 46 bytes. I have two solutions of this length. Try one here!
ΆRγψ~mΖ mi«\|..»d?=€H.xSEhSdHήSmX*~1/-lζlγlζ_1
(Replace □ with 0x7f in the next one)
ΆRγψΜΖψGi'|d=1lHd?□=H.xShSEdHήSmX*~1/-lζlγlζ_1
In either case, 15 bytes for rounding: mX*~1/-lζlγlζ_1. They are, for the most part, the same, except one uses a regex match to get the results, and the other splits on pipes.
Stacked, 68 + 1 = 69 bytes
'|'split[#'1-]NO neq::size:@z~>*[]YES' '#`out is0 sum z/100*1 nround
Try it online! +1 for -p flag (this script can be executed as stacked -pe "...")
Takes two inputs from the top of the stack.
Some interesting features:
[#'1-]NO
[ ]NO do not keep members where
#' its length
1- -1
is truthy (in this case, not equal to zero).
This yields all letters surrounded by pipes.
:size:@z~>*[]YES
: duplicate indices of incorrect answers
size length of incorrect answers
:@z (stored into z)
~> range from 1 to this length
* and multiply by this range
[]YES keep truthy elements
This gives us all incorrect question numbers.
CJam, 47 45 bytes
lqN/(;3%_'|f#:).=.=__:+\,d/e2XmOn:!_,,:).*0-p
Explanation
The program is in three main parts:
Right/wrong list
l e# Read the first line of input (answer key)
qN/ e# Read the rest of the input and split it on newlines
(;3% e# Delete the first line, then select every 3rd line
_ e# Duplicate the array
'|f# e# Find the index of the first | in each answer
:) e# Increment each, gives the index of the selected letter for each answer
.= e# Vectorized get-element-at with the answer strings
.= e# Vectorized equality check with the answer key
After this section, we have an array of 0s and 1s, where 0 indicates a wrong answer and 1 a right answer.
Score
__ e# Duplicate the right/wrong list twice
:+ e# Take the sum of it (number of right answers)
\, e# Swap top elements and take the length (total number of questions)
d/ e# Divide (casting to double so it's not integer division)
e2 e# Multiply by 10^2
XmO e# Round to 1 decimal place
n e# Pop and print with a newline
After this section, the stack contains only the right/wrong list, and the percentage score has been output.
Wrong answers
:! e# Logically negate each element of the right/wrong list
_,,:) e# Generate the inclusive range 1...length(list)
.* e# Vectorized multiplication of the two lists
0- e# Remove any 0s from the result
p e# Print it
JavaScript (ES6), 88 bytes
x=>y=>x.replace(/\w(?=\|)/g,c=>c==y[i++]?t++:a+=i+" ",a=i=t="")&&(t/i*1e3+.5|0)/10+`
`+a
I could save 5 bytes by using commas and returning everything one one line:
x=>y=>x.replace(/\w(?=\|)/g,c=>c==y[i++]?t++:a+=[,i],a=i=t="")&&(t/i*1e3+.5|0)/10+a
05AB1E, 43 bytes
U|3ôø`\vyy'|k>èXNèQˆ}¯OXg/3°*2z+ïT/XgL¯_Ï‚»
Explanation
U # store the answer key in X
|3ô # split the question-rows in chunks of 3
ø` # zip and flatten
\ # discard top of stack, leaving the list of
# answer rows on top
v # for each answer row
y'|k # get the index of the first "|"
y >è # get the character after that from the row
XNèQ # compare it to the corresponding entry in
# the answer key
ˆ # add it to the global list
} # end loop
¯O # calculate the number of correct answers
Xg/ # divide by the length of the answer key
3°* # multiply by 1000
2z+ # add 0.5
ï # convert to integer
T/ # divide by 10
XgL # push range [1 ... len(answer key)]
¯_Ï # keep only numbers corresponding to
# wrong answers
‚» # format output
Batch, 242 bytes
@echo off
set/as=c=0
set m=
set/pk=
:l
set/ac+=1
set/pt=
set/pl=
set/pt=
set "l=%l:*|=%
if %l:~,1%==%k:~,1% (set/as+=1)else set m=%m% %c%
set k=%k:~1%
if not "%k%"=="" goto l
set/as=(s*2000/c+1)/2
echo(%s:~,-1%.%s:~-1%
echo(%m%
Reads in the answer key on STDIN first, then n*3 question rows. Note: Score is printed without a leading zero if it is less than 1.0. Missed answers are printed with a leading space.
Python 2, 94 93 bytes
-1 byte thanks to L3viathan
s,a=input()
l=len(s)
w=[i+1for i in range(l)if"|%s|"%a[i]not in s[i]]
print(l-len(w))*1e2/l,w