1// A slight modification of a JavaScript interpreter (https://esolangs.org/wiki/Talk:Arithmetic) by the esolang user PythonshellDebugwindow, which is put in the public domain. 2function arithmetic(program,input) 3{ 4 const lines = program.split("\n"); 5 let output = ""; 6 let state = 0, currentExam = 0; 7 let currentProblem, currentChoice, pointsEarned; 8 let correctAnswer, problemPoints, answerDict; 9 let m; //Holds the result of RegExp matches 10 let currentLineNumber = 0; 11 12 for(const line of lines) 13 { 14 ++currentLineNumber; 15 //Skip empty lines 16 if(line === "") 17 { 18 continue; 19 } 20 //State 0 (begin exam) 21 else if(state === 0) 22 { 23 if(line === `==Begin Exam ${currentExam + 1}==`) 24 { 25 ++currentExam; 26 state = 1; 27 currentProblem = 1; 28 pointsEarned = 0; 29 continue; 30 } 31 } 32 //State 1 (begin problem, end exam) 33 else if(state === 1) 34 {
35 //Match a problem declaration, e.g. 1. 2+3=? (100 points) 36 if((m = line.match(/^([0-9]+). ([0-9]+)\+([0-9]+)=\? \(([0-9]+) points\)$/))) 37 { 38 //Must be positive integers 39 if((+m[2]) > 0 && (+m[3]) > 0) 40 { 41 //Check if the problem number is correct 42 if((+m[1]) === currentProblem) 43 { 44 ++currentProblem; 45 answerDict = {}; 46 currentChoice = 0; 47 correctAnswer = (+m[2]) + (+m[3]); 48 problemPoints = m[4]; 49 ++state; 50 continue; 51 } 52 } 53 } 54 else if(line === `==End Exam ${currentExam}==`) 55 { 56 state = 0; 57 output += String.fromCharCode(pointsEarned % 256); 58 continue; 59 } 60 } 61 //State 2 (problem choices) 62 else if(state === 2) 63 {
64 //Match the current choice letter (A, B, etc.) followed by a period, space, then number 65 if(m = line.match(new RegExp("^(" + String.fromCharCode(currentChoice + 65) + ")\. ([0-9]+)$"))) 66 { 67 //Problems can have up to 26 choices 68 if(currentChoice < 26) 69 { 70 ++currentChoice; 71 //Must be a positive integer 72 if(+m[2] > 0) 73 { 74 //Check for duplicate correct answers 75 if(!(Object.values(answerDict).indexOf(m[2]) > -1 && (+m[2]) === correctAnswer)) 76 { 77 answerDict[m[1]] = m[2]; 78 continue; 79 } 80 } 81 } 82 } 83 else if((m = line.match(/^Answer: ([A-Z])$/))) 84 { 85 //Check whether the chosen answer is a valid choice 86 if(m[1].charCodeAt(0) - 65 < currentChoice) 87 { 88 //Check whether the chosen answer is correct 89 if((+answerDict[m[1]]) === correctAnswer) 90 { 91 pointsEarned += (problemPoints % 256); 92 } 93 --state; 94 continue; 95 } 96 } 97 } 98 throw new Error("Invalid syntax on line " + currentLineNumber); 99 } 100 if(state !== 0) 101 { 102 //The last line was not the end of an exam 103 throw new Error("Unexpected end of input"); 104 } 105 return output; 106}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.