|
| 1 | +# [2019. The Score of Students Solving Math Expression](https://leetcode.com/problems/the-score-of-students-solving-math-expression) |
| 2 | + |
| 3 | +## Description |
| 4 | + |
| 5 | +<div class="elfjS" data-track-load="description_content"><p>You are given a string <code>s</code> that contains digits <code>0-9</code>, addition symbols <code>'+'</code>, and multiplication symbols <code>'*'</code> <strong>only</strong>, representing a <strong>valid</strong> math expression of <strong>single digit numbers</strong> (e.g., <code>3+5*2</code>). This expression was given to <code>n</code> elementary school students. The students were instructed to get the answer of the expression by following this <strong>order of operations</strong>:</p> |
| 6 | + |
| 7 | +<ol> |
| 8 | + <li>Compute <strong>multiplication</strong>, reading from <strong>left to right</strong>; Then,</li> |
| 9 | + <li>Compute <strong>addition</strong>, reading from <strong>left to right</strong>.</li> |
| 10 | +</ol> |
| 11 | + |
| 12 | +<p>You are given an integer array <code>answers</code> of length <code>n</code>, which are the submitted answers of the students in no particular order. You are asked to grade the <code>answers</code>, by following these <strong>rules</strong>:</p> |
| 13 | + |
| 14 | +<ul> |
| 15 | + <li>If an answer <strong>equals</strong> the correct answer of the expression, this student will be rewarded <code>5</code> points;</li> |
| 16 | + <li>Otherwise, if the answer <strong>could be interpreted</strong> as if the student applied the operators <strong>in the wrong order</strong> but had <strong>correct arithmetic</strong>, this student will be rewarded <code>2</code> points;</li> |
| 17 | + <li>Otherwise, this student will be rewarded <code>0</code> points.</li> |
| 18 | +</ul> |
| 19 | + |
| 20 | +<p>Return <em>the sum of the points of the students</em>.</p> |
| 21 | + |
| 22 | +<p> </p> |
| 23 | +<p><strong class="example">Example 1:</strong></p> |
| 24 | +<img alt="" src="https://assets.leetcode.com/uploads/2021/09/17/student_solving_math.png" style="width: 678px; height: 109px;"> |
| 25 | +<pre><strong>Input:</strong> s = "7+3*1*2", answers = [20,13,42] |
| 26 | +<strong>Output:</strong> 7 |
| 27 | +<strong>Explanation:</strong> As illustrated above, the correct answer of the expression is 13, therefore one student is rewarded 5 points: [20,<u><strong>13</strong></u>,42] |
| 28 | +A student might have applied the operators in this wrong order: ((7+3)*1)*2 = 20. Therefore one student is rewarded 2 points: [<u><strong>20</strong></u>,13,42] |
| 29 | +The points for the students are: [2,5,0]. The sum of the points is 2+5+0=7. |
| 30 | +</pre> |
| 31 | + |
| 32 | +<p><strong class="example">Example 2:</strong></p> |
| 33 | + |
| 34 | +<pre><strong>Input:</strong> s = "3+5*2", answers = [13,0,10,13,13,16,16] |
| 35 | +<strong>Output:</strong> 19 |
| 36 | +<strong>Explanation:</strong> The correct answer of the expression is 13, therefore three students are rewarded 5 points each: [<strong><u>13</u></strong>,0,10,<strong><u>13</u></strong>,<strong><u>13</u></strong>,16,16] |
| 37 | +A student might have applied the operators in this wrong order: ((3+5)*2 = 16. Therefore two students are rewarded 2 points: [13,0,10,13,13,<strong><u>16</u></strong>,<strong><u>16</u></strong>] |
| 38 | +The points for the students are: [5,0,0,5,5,2,2]. The sum of the points is 5+0+0+5+5+2+2=19. |
| 39 | +</pre> |
| 40 | + |
| 41 | +<p><strong class="example">Example 3:</strong></p> |
| 42 | + |
| 43 | +<pre><strong>Input:</strong> s = "6+0*1", answers = [12,9,6,4,8,6] |
| 44 | +<strong>Output:</strong> 10 |
| 45 | +<strong>Explanation:</strong> The correct answer of the expression is 6. |
| 46 | +If a student had incorrectly done (6+0)*1, the answer would also be 6. |
| 47 | +By the rules of grading, the students will still be rewarded 5 points (as they got the correct answer), not 2 points. |
| 48 | +The points for the students are: [0,0,5,0,0,5]. The sum of the points is 10. |
| 49 | +</pre> |
| 50 | + |
| 51 | +<p> </p> |
| 52 | +<p><strong>Constraints:</strong></p> |
| 53 | + |
| 54 | +<ul> |
| 55 | + <li><code>3 <= s.length <= 31</code></li> |
| 56 | + <li><code>s</code> represents a valid expression that contains only digits <code>0-9</code>, <code>'+'</code>, and <code>'*'</code> only.</li> |
| 57 | + <li>All the integer operands in the expression are in the <strong>inclusive</strong> range <code>[0, 9]</code>.</li> |
| 58 | + <li><code>1 <=</code> The count of all operators (<code>'+'</code> and <code>'*'</code>) in the math expression <code><= 15</code></li> |
| 59 | + <li>Test data are generated such that the correct answer of the expression is in the range of <code>[0, 1000]</code>.</li> |
| 60 | + <li>Test data are generated such that value never exceeds 10<sup>9</sup> in intermediate steps of multiplication.</li> |
| 61 | + <li><code>n == answers.length</code></li> |
| 62 | + <li><code>1 <= n <= 10<sup>4</sup></code></li> |
| 63 | + <li><code>0 <= answers[i] <= 1000</code></li> |
| 64 | +</ul> |
| 65 | +</div> |
| 66 | + |
| 67 | +<p> </p> |
| 68 | + |
| 69 | +## Solutions |
| 70 | + |
| 71 | +**Solution: `Dynamic Programming`** |
| 72 | + |
| 73 | +- Time complexity: <em>O(n<sup>3</sup>limit<sup>2</sup>)</em> |
| 74 | +- Space complexity: <em>O(n<sup>2</sup>limit<sup>2</sup>)</em> |
| 75 | + |
| 76 | +<p> </p> |
| 77 | + |
| 78 | +### **JavaScript** |
| 79 | + |
| 80 | +```js |
| 81 | +/** |
| 82 | + * @param {string} s |
| 83 | + * @param {number[]} answers |
| 84 | + * @return {number} |
| 85 | + */ |
| 86 | +const scoreOfStudents = function (s, answers) { |
| 87 | + const n = s.length; |
| 88 | + const ANSWER_LIMIT = 1000; |
| 89 | + |
| 90 | + const compute = () => { |
| 91 | + const solves = s.split('+'); |
| 92 | + |
| 93 | + return solves.reduce((result, solve) => { |
| 94 | + let current = Number(solve[0]); |
| 95 | + |
| 96 | + for (let index = 2; index < solve.length; index += 2) { |
| 97 | + current *= solve[index]; |
| 98 | + } |
| 99 | + |
| 100 | + return result + current; |
| 101 | + }, 0); |
| 102 | + }; |
| 103 | + |
| 104 | + const correctAnswer = compute(); |
| 105 | + const dp = Array.from({ length: n }, () => new Array(n).fill(-1)); |
| 106 | + |
| 107 | + const getScores = (left, right) => { |
| 108 | + if (left === right) { |
| 109 | + const num = Number(s[left]); |
| 110 | + |
| 111 | + dp[left][right] = new Set([num]); |
| 112 | + |
| 113 | + return dp[left][right]; |
| 114 | + } |
| 115 | + |
| 116 | + if (dp[left][right] !== -1) return dp[left][right]; |
| 117 | + |
| 118 | + const result = new Set(); |
| 119 | + |
| 120 | + for (let index = left + 1; index < right; index += 2) { |
| 121 | + const leftScores = getScores(left, index - 1); |
| 122 | + const rightScores = getScores(index + 1, right); |
| 123 | + |
| 124 | + for (const scoreA of leftScores) { |
| 125 | + for (const scoreB of rightScores) { |
| 126 | + const operation = s[index]; |
| 127 | + const score = operation === '+' ? scoreA + scoreB : scoreA * scoreB; |
| 128 | + |
| 129 | + if (score > ANSWER_LIMIT) continue; |
| 130 | + |
| 131 | + result.add(score); |
| 132 | + } |
| 133 | + } |
| 134 | + } |
| 135 | + |
| 136 | + dp[left][right] = result; |
| 137 | + |
| 138 | + return result; |
| 139 | + }; |
| 140 | + |
| 141 | + const scores = getScores(0, n - 1); |
| 142 | + |
| 143 | + return answers.reduce((result, answer) => { |
| 144 | + if (answer === correctAnswer) return result + 5; |
| 145 | + if (scores.has(answer)) return result + 2; |
| 146 | + |
| 147 | + return result; |
| 148 | + }, 0); |
| 149 | +}; |
| 150 | +``` |
0 commit comments