[Question]
  [
I did the IMC this year. Did anyone else here do it?
In a UKMT Intermediate Maths Challenge paper, there are twenty-five questions. The first fifteen questions give you five marks if you get them right. For the other ten questions, you get six marks for getting them right. In the last ten questions, you lose marks if you get them wrong! For questions sixteen to twenty, you lose one marks and for the last five questions, you lose two marks. If you leave a question blank, no marks are awarded or deducted. No marks are deducted for getting any of the first fifteen questions wrong. The paper is multiple choice; you can choose any answer out of A, B, C, D and E for each question. There is always just one right answer for each question.
Create a program/function that takes two strings and outputs a score. The first string will be your answers to the paper. If you skip a question, use a space, a null byte or an underscore. Otherwise, use the letter A, B, C, D or E for the answer. You can either have the inputs uppercase or lowercase. The second string will be the correct answers for each question in the paper. Your program/function will then output a score. Make your code short.
Test cases:
```
DDDDDDDDDDDDDDDDDDDDDDDDD
ABCDEABCDEABCDEABCDEABCDE
15
BDBEACCECEDDBDABBCBDAEBCD
BDBEACCECEDDBDABBCBDAEBCD
135
DBACBDCDBAEDABCDBEECACDC_
DBADBDCDBAEDABCDBEEDACDCA
117
_________________________
DABDABDABDABDABDABDABDABD
0
DBADBDCDBAEDABCD_E__A__C_
DBADBDCDBAEDABCDBEEDACDCA
99
_______________BBBBBBBBBB
AAAAAAAAAAAAAAAAAAAAAAAAA
-15
```
  
[Answer]
# C, ~~88~~ ~~87~~ ~~86~~ 81 bytes
```
c,d;i(char*a,char*b){for(c=d=0;*b;c++,a++)d+=*a^*b++?*a?-c/15-c/20:0:5+c/15;d=d;}
```
[Try it online!](https://tio.run/nexus/c-gcc#lY7bSsQwEIbv9ymGiNAcxCjszYay5PQWQUibFnthlLjeuOyz10mRysouaA7/TDI/38xNGsYpD/DZ9CJReCtTPowNuX0Pebkp5JCJwKKYFgudURXmz7GwKJbQ0eP4Wpq@Ta1UrFM95yJyThNvWXxiHed7Fvd3/f3DFuVR7uRuy@tLpTap04w94SVOualJFFChwBh0FI4bAByOuGuLiOoAINpY5y8JoeobYpzx2lpvvXPGaWMsqkfPCrnuWCHOaPy0GLyrfOO91dbZIFcK1twvi6sWXSmICPK/@wetzeVzNuBZ9yB9Regqf54SDWU4fJQMUm1O8xc "C (gcc) – TIO Nexus")
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~26~~ ~~23~~ 22 bytes
```
=s5ị"“HHHQP‘D¤_2Fæ.n⁶¥
```
[Try it online!](https://tio.run/nexus/jelly#@29bbPpwd7fSo4Y5Hh4egQGPGma4HFoSb@R2eJle3qPGbYeW/n@4e8vh5UpAsjZS4eGO7UCVCr6JBcUKJRmpCsn5KakK@WWpRWBeSWpxiUJyYnFqsd7//y64AJeTi5Oro7Ozq7Ori4uTi6OTkzOQdHVyduFycXIEsp2BlCtQHEi7ujo7Ors4K3Ap4AIgPS7IehRcFRQcFRQw9TjBwX@QOldsBH63uaC5zQXkNkcuIBc7wqPHERcAAA "Jelly – TIO Nexus")
### How it works
```
=s5ị"“HHHQP‘D¤_2Fæ.n⁶¥  Main link. Argument: t (answer to test), s (answer sheet)
=                       Test the characters of t and s for equality.
 s5                     Split into chunks of length 5.
             ¤          Combine the two preceding links into a niladic chain.
     “HHHQP‘              Yield the code points, i.e., [72, 72, 72, 81, 80].
            D             Decimal; yield [[7, 2], [7, 2], [7, 2], [8, 1], [8, 0]].
   ị"                   Index zipwith; use the Booleans in each chunk to index into
                        the corresponding pair. Indexing is 1-based and modular, so
                        1 gives the first element and 0 the last.
              _2        Subtract 2 from each result.
                F       Flatten the resulting 5x5 matrix.
                     ¥  Combine the two preceding links into a dyadic chain.
                   n⁶     Test the characters of t for inequality with space.
                 æ.     Take the dot product of the integers to the left and the
                        Booleans to the right.
```
[Answer]
## JavaScript (ES6), ~~70~~ ~~68~~ 66 bytes
*Saved 2 bytes thanks to Neil*  
*Saved 2 bytes thanks to ETHproductions*
Takes applicant answers `a` and correct answers `c` in currying syntax `(a)(c)`. Expects skipped questions to be marked with a space.
```
a=>c=>a.replace(/\S/g,(a,i)=>s+=a==c[j=i>14,i]?5+j:-j^i>19,s=0)&&s
```
### Test cases
```
let f =
a=>c=>a.replace(/\S/g,(a,i)=>s+=a==c[j=i>14,i]?5+j:-j^i>19,s=0)&&s
console.log(f
  ("DDDDDDDDDDDDDDDDDDDDDDDDD")
  ("ABCDEABCDEABCDEABCDEABCDE")
);
console.log(f
  ("BDBEACCECEDDBDABBCBDAEBCD")
  ("BDBEACCECEDDBDABBCBDAEBCD")
);
console.log(f
  ("DBACBDCDBAEDABCDBEECACDC ")
  ("DBADBDCDBAEDABCDBEEDACDCA")
);
console.log(f
  ("                         ")
  ("DABDABDABDABDABDABDABDABD")
);
console.log(f
  ("DBADBDCDBAEDABCD E  A  C ")
  ("DBADBDCDBAEDABCDBEEDACDCA")
);
console.log(f
  ("               BBBBBBBBBB")
  ("AAAAAAAAAAAAAAAAAAAAAAAAA")
);
```
[Answer]
# [Python 2](https://docs.python.org/2/), ~~86~~ ~~85~~ ~~83~~ 77 bytes
```
f=lambda t,s,i=24:~i and(i/10*-(14<i<t[i]<'_'),5+i/15)[t[i]==s[i]]+f(t,s,i-1)
```
[Try it online!](https://tio.run/nexus/python2#nZBNCoMwFIT3PUV2SarSWuym6CLv5xQiwSJCoJVSXffqNnEhVnTTIUxgJvnyyNgWj/p5b2oxxH3sikt2@zhRd41yp/R8TFSa5S4fSlfl0kodXyOfX3UZkqLovVdRq6a7SarH19t1g2iVpD3JWEgDSLxlUh9mAhCwQWRkIiADgN7ZnwqE/XJBIDA@Rr8xBTwwo0FCGwg@pVVJoTRLgt3TRDCwvVYz/Dxj2Vpj7f8zwKzpJ/ck9fgF "Python 2 – TIO Nexus")
### How it works
This defines a recursive function **f** that takes two non-optimal arguments: **t** (the answers to the test) and **s** (the answer sheet). When called only with these two arguments, **f** initializes **i** to **24**, the last index of both **t** and **s**.
Every time **f** is called, it first checks if **~i** (the bitwise NOT of **i**) is truthy/non-zero. Since **~(-1) = 0**, this happens once the **i** reaches the value **-1**. If **i = -1**, **~i = 0** is returned, but as **i** takes values from **24** to **0** (all indices of **t** and **s**), the code following `and` is executed and **f** returns the result.
While **i** is non-negative, the following happens. First,
```
(i/10*-(14<i<t[i]<'_'),5+i/15)
```
creates a tuple of length **2**:
* The quotient `i/10` is **0** if **0 ≤ i < 10**, **1** if **10 ≤ i < 20**, and **2** if **20 ≤ i < 25**. The chained comparison `14<i<t[i]<'_'` returns *True* if and only if all individual comparisons return *True*, i.e., if and only if **i ≥ 15** (the range of questions with penalty), **i** is smaller than **t[i]** (always true since all numbers are smaller than all iterables in Python 2), and **t[i]** is not an underscore.
If the comparison returns *False*, the unary `-` returns **0** and the entire expression evaluates to **0**. However, if the comparison returns *True*, the unary `-` returns **-1**, so the entire expression evaluates to **0** if **0 ≤ i < 10**, **-1** if **10 ≤ i < 20**, and **-2** if **20 ≤ i < 25**; these are the net results for wrong or missing answers for all indices **i**.
* `5+i/15` returns **5 + 0 = 5** if **0 ≤ i < 15** and **5 + 1 = 6** if **15 ≤ i < 25**. These are the net results for correct answers for all indices **i**.
Finally, `[t[i]==s[i]]` selects the first element of the constructed tuple if **t[i]** and **s[i]** differ (wrong or missing answer) and the second one if they are equal (correct answer), then adds the return value of **f** called with decremented **i** to that result. Once **i** reaches **-1**, the final score has been computed and is returned by **f**.
[Answer]
# Mathematica, 114 bytes
```
Tr@(m=MapThread)[#/.True->#2/.False->-#3&,{Tr/@Partition[m[Equal,#/."_"->u]/.u==_->0,5],{5,5,5,6,6},{0,0,0,1,2}}]&
```
Pure function taking an ordered pair of lists of characters and returning an integer. `m[Equal,#/."_"->u]` returns a list of booleans, except for unevaluated entries of the form `u=="B"` in places where the answer equaled `"_"`; then right away, `u==_->0` turns those unevaluated entries into `0`s. `Tr/@Partition[...,5]` adds these entries up 5 at a time, resulting in a list like `{4False+True, 4False+True, 4False+True, 4False+True, 4False+True}` for the first test case or `{5True, 5True, 5True, 2True, 2True}` for the last test case. Then in each coordinate, `True` and `False` are mapped to the appropriate scores, and the results are added together.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~22~~ 21 bytes
```
Zm0ṁ135µ;t€⁶E€’;E€ṫ⁹S
```
[Try it online!](https://tio.run/nexus/jelly#nZC9DQIxDIV7prBSXwFCVFf5bwI6ooxAxwCEhhmYAVqQ0nKTXBYJjkAg0KXhKfJT/PLZUspmOx9TXCxX92u/y4dLjjettj/11cd0zjGty3C0SyneO2nJdQ6JRaeKC90MvCMhRWZlFSFBIraq9sDYdvZkhdA6bKZSZ5IqIwuDsdaUn0xqhi8WWqos0vT57P2aDQqAAP/spbfqX7XkQngA "Jelly – TIO Nexus")
I *thought* @Dennis's answer was probably beatable. And after trying out a huge number of different possibilities and benefitting from an amazing coincidence, I've finally managed it!
This program takes a pair of [student's answers, correct answers] as input, and uses spaces to indicate a missing answer.
## Explanation
This program uses some bizarre internal input formats to keep track of what's going on, so we'll take this a step at a time.
1. `Z`
This transposes the input, so we'll end up with a list of 25 elements, one for each question; each element is of the form [student's answer, correct answer]. We'll indicate an element of this form with a capital letter; `A` for question 1, `B` for question 2, and so on. So the answers are currently being stored as
```
ABCDEFGHIJKLMNOPQRSTUVWXY
```
2. `m0`
This is a "greater palindrome" operation; we append the reverse of the current value to the value itself, yielding this:
```
ABCDEFGHIJKLMNOPQRSTUVWXYYXWVUTSRQPONMLKJIHGFEDCBA
```
3. `ṁ135`
The `ṁ` (mold) operator does a number of things, but in this context, it effectively takes the first 135 elements of the infinite list produced by appending the current value to itself repeatedly. That gives us the following (which I've broken into groups of 50 elements for convenience; this is just a list of 135 pairs internally):
```
ABCDEFGHIJKLMNOPQRSTUVWXYYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYYXWVUTSRQP
```
4. `µ;`
`µ` sets the current value as the new default for missing operands. We then immediately see a builtin that's missing an operand; `;` appends, but we haven't specified what to append with. As a result, the current value is appended to the value as of the last `µ` (which is also the current value), giving us the following 270-element current value:
```
ABCDEFGHIJKLMNOPQRSTUVWXYYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYYXWVUTSRQPONMLKJIHGFEDCBA
ABCDEFGHIJKLMNOPQRSTUVWXYYXWVUTSRQPABCDEFGHIJKLMNO
PQRSTUVWXYYXWVUTSRQPONMLKJIHGFEDCBAABCDEFGHIJKLMNO
PQRSTUVWXYYXWVUTSRQPONMLKJIHGFEDCBAABCDEFGHIJKLMNO
PQRSTUVWXYYXWVUTSRQP
```
5. `t€⁶`
Remember that all the capital letters above represent pairs of [student's answer, correct answer]. The `t€⁶` operation operates on each (`€`) pair, and deletes (`t`) spaces (`⁶`) from either side of the pair (i.e. any space that appears in the pair). So we still have the same convoluted list of 270 questions with many repeats, but they're of the form [correct answer] (student didn't answer) or [student's answer, correct answer] (student did answer).
6. `E€’`
The `E€’` operation also operates on each (`€`) element, and, due to the use of `E`, replaces the element with 1 if all the elements are equal (i.e. the student didn't answer or got the question right), or 0 if not all the elements are equal (i.e. the student answered but got the question wrong). The use of `’` here changes the numbering, meaning that we now use -1 or 0 respectively. I'll use lowercase letters for this new sort of element, which uses -1 for an answer which would be penalised if it were on a penalty-eligible question, or 0 for a missing or correct answer:
```
abcdefghijklmnopqrstuvwxyyxwvutsrqponmlkjihgfedcba
abcdefghijklmnopqrstuvwxyyxwvutsrqponmlkjihgfedcba
abcdefghijklmnopqrstuvwxyyxwvutsrqpabcdefghijklmno
pqrstuvwxyyxwvutsrqponmlkjihgfedcbaabcdefghijklmno
pqrstuvwxyyxwvutsrqponmlkjihgfedcbaabcdefghijklmno
pqrstuvwxyyxwvutsrqp
```
7. `;E€`
We've seen both `E€` and `;` before; we're appending something to the current value, and we're using a format of 1 if all the elements are equal, or 0 if some are different (no `’` this time!). There's a missing operand here, so we use the value as of the last `µ` (i.e. the output of step 3). Back in step 3, we hadn't deleted spaces from the elements, so we'll have 1 for a correct answer, or 0 for an incorrect or missing answer (because a space won't match the correct answer). From now on, I'll use capital letters for this 1=correct, 0=incorrect/missing format, and continue to use lowercase letters for 0=correct/missing, -1=incorrect. The resulting value has 405 elements, and looks like this:
```
abcdefghijklmnopqrstuvwxyyxwvutsrqponmlkjihgfedcba
abcdefghijklmnopqrstuvwxyyxwvutsrqponmlkjihgfedcba
abcdefghijklmnopqrstuvwxyyxwvutsrqpabcdefghijklmno
pqrstuvwxyyxwvutsrqponmlkjihgfedcbaabcdefghijklmno
pqrstuvwxyyxwvutsrqponmlkjihgfedcbaabcdefghijklmno
pqrstuvwxyyxwvutsrqpABCDEFGHIJKLMNOPQRSTUVWXYYXWVU
TSRQPONMLKJIHGFEDCBAABCDEFGHIJKLMNOPQRSTUVWXYYXWVU
TSRQPONMLKJIHGFEDCBAABCDEFGHIJKLMNOPQRSTUVWXYYXWVU
TSRQP
```
8. `ṫ⁹`
Here comes the amazing coincidence I mentioned earlier. Before talking about this bit of the code, I want to take stock of where we've got to. 
Each capital letter represents +1 for a correct answer; the first 15 questions (`A` through `O`) appear 5 times each in the string, and the last 10 questions (`P` through `Y`) appear 6 times each. That bit isn't really magical; I designed it that way when I chose the number 135 earlier on in the program (which is 5 × 15 + 6 × 10), and the only stroke of luck here is that 5 happens to be an odd number (so it's the last 10 questions that end up appearing the extra times, rather than the first 10). The 15 letters immediately preceding this contain `p` through `t` (the -1 penalty questions) once, and `u` through `y` (the -2 penalty questions) twice. That also isn't much of a coincidence; because we used `m0` earlier, the extra copies of the questions are in the order `PQRSTUVWXYYXWVUTSRQP`, and the later questions will naturally occur near the middle of that string (so taking the last 15 of the "extra" questions will give fewer repeats to the ones near the edges; and of course, it's not a surprise that the "extra" questions come last).
Because each lowercase letter subtracts 1 from the score for an incorrect, non-missing answer, and each uppercase letter adds 1 to the score for a correct answer, we therefore simply need to take the last 135 + 15 = 150 elements in order to get each sort of element the correct number of times. Jelly's command for getting a substring at the end of a list is `ṫ`; however, it doesn't specify the number of elements you want, but rather the index of the first element you want. We have 405 elements at this point, and want 150, so we need to start at index (405 - 150 + 1), or 256. In an amazing coincidence, 256 happens to be the number of distinct octets that exist, and thus has a short representation in Jelly (`⁹`). There was very little I could do in order to make this happen; step 4 added another 135 elements to the start of the list in order to hit the round number, but the fact that it was 135 elements I had to add (a value which was readily available at that point in the program) was really convenient, with basically any other number being completely unhelpful in this situation.
Here's how the internal value looks now:
```
uvwxyyxwvutsrqpABCDEFGHIJKLMNOPQRSTUVWXYYXWVUTSRQP
ONMLKJIHGFEDCBAABCDEFGHIJKLMNOPQRSTUVWXYYXWVUTSRQP
ONMLKJIHGFEDCBAABCDEFGHIJKLMNOPQRSTUVWXYYXWVUTSRQP
```
9. `S`
Finally, now we've got a list of modifications to the score from questions, all we need to do is sum them using `S`, and we're done.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~93~~ 91 bytes
```
f=lambda a,b,n=0:a>""and((a[0]==b[0])*(5+n/15)or-(n/15*n/10)*(a[0]<"^"))+f(a[1:],b[1:],n+1)
```
[Try it online!](https://tio.run/nexus/python2#@59mm5OYm5SSqJCok6STZ2tglWinpJSYl6KhkRhtEGtrmwQkNbU0TLXz9A1NNfOLdDVADC0gYQAUBqmxUYpT0tTUTgNyDK1idZLAZJ62oeb//wA "Python 2 – TIO Nexus")
-2 bytes thanks to @KritixiLithos
---
## Input:
* `a` : Answers of the student as a string, `_` for skipped question
* `b` : correct answers
* `n` : the number of the current question `0`-based, defaults to `0`
[Answer]
# k, 52 bytes
Function takes 2 strings, format per the test cases
```
{+/(~x="_")*(+,/'(15 5 5#'0 -1 -2;15 10#'5 6))@'x=y}
```
Example:
```
k){+/(~x="_")*(+,/'(15 5 5#'0 -1 -2;15 10#'5 6))@'x=y}["DBADBDCDBAEDABCD_E__A__C_";"DBADBDCDBAEDABCDBEEDACDCA"]
99
```
[Answer]
## Haskell, 84 bytes
```
i x a b|a>'Z'=0|a==b=6-0^x|1<2= -x
w x=x<$[1..5*3^0^x]
(sum.).zipWith3 i(w=<<[0..2])
```
Usage example: `((sum.).zipWith3 i(w=<<[0..2])) "DBADBDCDBAEDABCD_E__A__C_" "DBADBDCDBAEDABCDBEEDACDCA"` -> `99`. [Try it online!](https://tio.run/nexus/haskell#Zcm7CoMwFADQ3a@4BEEtePFBnXILefgNhYqGOEgzKNJaDMV/t9k7neGcDjxYGA97Sx4JFYclGqnJi8EfJa8Ich/t4MnzuCsRr5d6CNVHE6Xvz4wZft16d9uzBpfuxHlXIFZ9ds7WLUCwvtyyQQwTMC2FlloFWi2k0qY1RhijDPs/2QaVVoKdPw "Haskell – TIO Nexus").
How it works: `i x a b` calculates the score for a single answer `a` with correct result `b` and the penalty `x` for a wrong answer (a non-negative value). If you skip (`a>'Z'`), the score is `0`, if the answer is right (`a==b`), the score is `6-0^x`, else the score is `-x`.
`w=<<[0..2]` makes a list of penalties for all 25 questions by applying `w` to `0`, `1` and `2`, i.e. making `5*3^0^x` copies of each number (-> 15 times `0`, 5 times `1` and 5 times `2`).
`zipWith3` applies `i` to the list of penalties, list of answers and list of correct results. Finally all scores are added (`sum`). 
[Answer]
# Octave, ~~61~~ 54 bytes
```
@(a,b)[a==b,-(a<95&a~=b)]*[(x=1:25>15)+5,(1:25>20)+x]'
```
[Try it online!](https://tio.run/nexus/octave#nZFNasMwEIXX1Sm8iqTGhdrgRZMoRPNzCmOETGIohrTUmwThXN2VUlraEnfRxzASevPNwGjaKZ@3uvbGtPmD8punauEvptXNfa1OpliV1bao9LLK1fVePurlqZFTZ/xxWIv@cB5MFkQQkuYkhbSAxLeSFOM6wUDAFpGRiYAsAMbMsUL@6X3ABDY@YTyYUldgRouETl49@uVR8uwn7OaUYAu349vkH90dO2ed@9dk@FJa2JwinPDu5S3rM5PV6QPCamzE3f55eFWd6kMx5n0oR63F4bif3gE "Octave – TIO Nexus")
Previous answer:
```
@(a,b)(m=a==b)*(((f=kron(z=[0 0 0:2],z|1)')&1)+5)-(a<95&~m)*f
```
[Answer]
# JavaScript (ES6), ~~105~~ ~~103~~ ~~101~~ ~~94~~ ~~89~~ ~~88~~ ~~85~~ ~~84~~ ~~78~~ 77 bytes
My first solution in ES6, maybe even first in Javascript O.o
```
f=(s,a,i=24)=>i+1&&(s[i]>'Z'?0:s[i]==a[i]?5+(i>14):~(i>19)*(i>14))+f(s,a,i-1)
```
**s** is the submitted solution and **a** is the correct solution. Both will be taken as strings.
Here's a non-recursive solution at 78 bytes:
```
s=>a=>eval([...s].map((c,i)=>c>'Z'?0:c==a[i]?5+(i>14):~(i>19)*(i>14)).join`+`)
```
Takes input through the currying syntax.
Thanks to [@ETHproductions](https://codegolf.stackexchange.com/users/42545/ethproductions) for saving 9 bytes! `s[i]` to `c` and `(-1-(i>19|0))` to `~(i>19)`.
Thanks to [@Kritixi Lithos](https://codegolf.stackexchange.com/users/41805/kritixi-lithos) for saving a byte! `c=='_'` to `c>'Z'`.
[Try it online!](https://tio.run/nexus/javascript-node#hY7PCsIwDMbvPkYPW@umOJkHJ91o/ryEImWIk8Fwh9199dmyk6PFUL40@cIvmTstp7zNe30sla77rEgSOd36e51e0@ZQ@a/WrdPmlMm@LkpVfXw@q@1SqqxbCLtCzY/xPY3Dcz@ML9lJQbEQuTCAxCERSl02KxAQsEFkZCIgA4BO2U07UNwLgAiMs9ElJr8NmNEgoXUg16SVR94zIZCNhQcZCL/IRT9bLVtrrP1/0fwF)
]