Standardized testing usually comes with a scan-tron or some type of answer document that records your answer. A computer or human(s) would then check your answers and determine your grade. So here, given a scan-tron and the answer key, determine the score and questions missed if any. A scan-tron is just a document with multiple lines with answers in which the user fills in (in this case, circled). Example:

   ---
1. |a| b c d
---


As you can see, this is question 1 with answer choice a selected since it has a box around it. For the challenge, you will be given a scan-tron with n questions ( 1 <= n <= 10) with only four answers denoted as a, b, c, or d. The answer key will be given as a string with no spaces and with all lowercase. Example scan-tron with answer key:

Scan-tron
---
1. |a| b c d
---
---
2. a |b| c d
---
---
3. a b |c| d
---

abb


You can take in the answer key and scan-tron as separate inputs or in a chosen order as long they can be identified (i.e the answer key is separated from the scan-tron). Scores will be rounded to the nearest tenth of a point. Example output for the above:

Score: 66.7
Missed #: 3


66.7
3


or if multiple questions are missed

66.7
3 4 5


as long the question numbers for those missed are separated from the by spaces and not on the same line as the score.

Rules and Specs

• The scan-tron can be inputted as a multi-line string or one question at a time (as a string with newlines is acceptable)
• Given a scan-tron and answer key, you must output the score on one line and the question(s) missed on another, with the numbers separated by spaces. If no questions are missed, no question numbers should be outputted
• Scores are rounded to the nearest tenth
• Selected answers are surrounded by this box:

---
| |
---

• On the scan-tron, every question takes three spaces (the top and bottom of the box takes two extra lines)
• Must work for the above example
• Assume that there will always be only one answer boxed

Winning Criteria

Shortest code wins!

• the scan-tron can be a list of questions ? And each question be a single string with newlines? – Rod Mar 29 '17 at 21:30
• @Rod Yes and I will clarify that – Anthony Pham Mar 29 '17 at 21:34
• The language of "missed" is confusing to me, since a "missed" question could mean a question that the student failed to answer (as opposed to your apparent meaning, answered incorrectly). – DLosc Mar 29 '17 at 22:04
• @DLosc There will always be only one circled answer – Anthony Pham Mar 29 '17 at 22:13
• Is a score like 50 acceptable, or does it have to be 50.0? – DLosc Mar 29 '17 at 22:22

# 05AB1E, 43 bytes

U|3ôø\vyy'|k>èXNèQˆ}¯OXg/3°*2z+ïT/XgL¯_Ï‚»


Try it online!

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
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
ˆ                         # 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
ï            # convert to integer
T/          # divide by 10
XgL       # push range [1 ... len(answer key)]
¯_Ï    # keep only numbers corresponding to
‚» # format output


# 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
:@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.

# 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


Try it online!

• Nice, much better than mine. You can replace 100. with 1e2 – L3viathan Mar 29 '17 at 22:09
• I don't believe this meets the requirement to round the score to "the nearest tenth of a point," does it? – DLosc Mar 30 '17 at 2:11

# Pip, 49464448 45 bytes

Ugh, that rounding takes so many bytes... 44 bytes of code, +1 for -s flag.

(/2+m-m/#b*#P_FI{++nbNa?un}MZa@\|..b)//1/t


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. Try it online!

### Explanation

I'm gonna do this in two parts: the incorrect questions list and the score.

P_FI{++nbNa?un}MZa@\|..b
a,b are cmdline args, u is nil, n is newline (implicit)
Note that a string like n, in math contexts, is equivalent to 0
a@\|..   Find all occurrences in a of | followed by 2 chars
Because regex matches don't overlap, this does what we need
{         }MZ        b  Zip with b and map this function to each pair of items:
++n                     Increment n (so the first time through, it's 1)
bNa                  Is 2nd arg a substring of 1st?
?un               If so, return nil; if not, return n
Now we have a list containing nil for correct questions
and the question number for incorrect questions
_FI                        Filter on identity function (keep only truthy values)
P                           Print, joining on spaces (-s flag)

(/2+m-m/#b*#...)//1/t
a,b are cmdline args, m is 1000 (implicit)
...        The code from the first part
#           Length of that list (i.e. number of incorrect questions)
m/#b*            Times 1000/(number of questions)
m-                 Subtracted from 1000
/2+                   Plus 1/2 (= 0.5)
We now have a number like 667.1666666666667
(              )//1    Int-divide by 1 to truncate
/t  and divide that by 10
Print (implicit)


## 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


## 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.

# CJam, 47 45 bytes

lqN/(;3%_'|f#:).=.=__:+\,d/e2XmOn:!_,,:).*0-p


Try it online!

Explanation

The program is in three main parts:

Right/wrong list

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


# 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.