Help! My calculator malfunctions!
JavaScript (ES7), 159 158 bytes
Edit: new version to comply with the updated rules regarding --
Saved 1 byte thanks to @Shaggy
Takes input in currying syntax (e)(r)
where e is the array of equations and r is the array of expected results. Returns an array of characters.
e=>r=>(l=[...2**29+'4+-*/']).filter(x=>l.some(y=>eval("try{eval((S=(s=`[${e}]`).replace(/./g,c=>c==x?y:c==y?x:c)).split`--`.join`+`)+''==r&S!=s}catch(e){}")))
Test cases
let f =
e=>r=>(l=[...2**29+'4+-*/']).filter(x=>l.some(y=>eval("try{eval((S=(s=`[${e}]`).replace(/./g,c=>c==x?y:c==y?x:c)).split`--`.join`+`)+''==r&S!=s}catch(e){}")))
console.log(JSON.stringify(f
([ '123', '8423', '4+4', '4*7-10', '9/3', '42-9' ])
([ 3, 252, 8, 417, 3, -36 ])
));
console.log(JSON.stringify(f
([ '4/2', '3/0', '0/8+2', '95-5', '4+2' ])
([ 6, 3, 4, 90, 2 ])
));
console.log(JSON.stringify(f
([ '7+4', '5-15', '212-23' ])
([ 11, 46, -2121 ])
));
console.log(JSON.stringify(f
([ '4+8/2-9*1', '99/3-13', '1+2+3+4', '4-3-2-1' ])
([ -5, 20, 10, -6 ])
));
console.log(JSON.stringify(f
([ '18/18', '98-8', '55*88', '-5--15' ])
([ 1, 90, 4840, 10 ])
));
console.log(JSON.stringify(f
([ '9119', '5-3', '8*-9', '13116/3' ])
([ 18, 513, 152, -1 ])
));
Formatted and commented
e => r => // given e and r
(l = [...2 ** 29 + '4+-*/']) // generate l = [...'5368709124+-*/']
.filter(x => // for each character x of l
l.some(y => // for each character y of l
eval("try { // we need to 'try', because we don't know
eval( // whether the following expression is valid
(S = (s = `[${e}]`). // s = list of equations coerced to a string
replace(/./g, c => // S =
c == x ? y : c == y ? x : c // s with x and y exchanged
) // end of replace()
).split`--`.join`+` // replace '--' with '+'
) + '' == r // does the resulting list match r?
& S != s // and was at least one character modified?
} catch(e){}") // if we try, we oughta catch
) // end of some()
) // end of filter()
Perl 6, 132 113 bytes
Thanks to Jo King for -19 bytes.
->\e,$r {first {($!=e.trans($_=>.flip))ne e&&try "all {$!.&{S:g/\-/- /}} Z==$r".EVAL},[X~] (|^10,|<+ - * />)xx 2}
Try it online!
Input is a comma-separated string of equations and a comma-separated string of results (hope this is OK). Output is a string containing the two swapped buttons.
Correctly handles --
. Might product false positives for ---
, ++
, **
, or //
, but I couldn't come up with a test case.
Oracle SQL & PL/SQL, 458 Bytes
Input can be in any reasonable format. [...] a list with equations and another list with the correct results.
Compile the PL/SQL function (210 bytes):
CREATE FUNCTION f(x CHAR,y CHAR)RETURN NUMBER IS o NUMBER;BEGIN EXECUTE IMMEDIATE 'BEGIN :1:='||REPLACE(x,'--','- -')||';END;'USING OUT o;RETURN CASE o WHEN y THEN 1 END;EXCEPTION WHEN OTHERS THEN RETURN 0;END;
Run the SQL (248 bytes):
WITH r(v)AS(SELECT SUBSTR('1234567890-+*/',LEVEL,1)FROM DUAL CONNECT BY LEVEL<15)SELECT r.v,s.v FROM T,r,r s WHERE r.v<>s.v GROUP BY r.v,s.v HAVING SUM(f(TRANSLATE(x,r.v||s.v,s.v||r.v),y))=(SELECT COUNT(1)FROM T)AND SUM(INSTR(x,r.v)+INSTR(x,s.v))>0
After having create a table T
with the test data:
CREATE TABLE T(X,Y) AS
SELECT '123', 3 FROM DUAL UNION ALL
SELECT '8423', 252 FROM DUAL UNION ALL
SELECT '4+4', 8 FROM DUAL UNION ALL
SELECT '4*7-10', 417 FROM DUAL UNION ALL
SELECT '9/3', 3 FROM DUAL UNION ALL
SELECT '42-9', -36 FROM DUAL
Output:
V V_1
- ---
2 *
* 2
Previous Version:
Assumed a string input like '123 = 3'
:
Same PL/SQL function and the SQL (322 bytes):
WITH r(v)AS(SELECT SUBSTR('1234567890-+*/',LEVEL,1)FROM DUAL CONNECT BY LEVEL<15),y(x,y)AS(SELECT REGEXP_SUBSTR(t,'[^=]+'),REGEXP_SUBSTR(t,'-?\d+$')FROM T)SELECT r.v,s.v FROM y,r,r s WHERE r.v<>s.v GROUP BY r.v,s.v HAVING SUM(f(TRANSLATE(x,r.v||s.v,s.v||r.v),y))=(SELECT COUNT(1)FROM T)AND SUM(INSTR(x,r.v)+INSTR(x,s.v))>0
After having create a table T
with the test data:
CREATE TABLE T(T) AS
SELECT '123 = 3' FROM DUAL UNION ALL
SELECT '8423 = 252' FROM DUAL UNION ALL
SELECT '4+4 = 8' FROM DUAL UNION ALL
SELECT '4*7-10 = 417' FROM DUAL UNION ALL
SELECT '9/3 = 3' FROM DUAL UNION ALL
SELECT '42-9 = -36' FROM DUAL;
Output:
V V_1
- ---
2 *
* 2
Update - Testing:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE FUNCTION F(x CHAR,y CHAR)RETURN NUMBER IS o NUMBER;BEGIN EXECUTE IMMEDIATE 'BEGIN :1:='||REPLACE(x,'--','- -')||';END;'USING OUT o;RETURN CASE o WHEN y THEN 1 END;EXCEPTION WHEN OTHERS THEN RETURN 0;END;
/
CREATE TABLE A(X,Y) AS
SELECT '123', 3 FROM DUAL UNION ALL
SELECT '8423', 252 FROM DUAL UNION ALL
SELECT '4+4', 8 FROM DUAL UNION ALL
SELECT '4*7-10', 417 FROM DUAL UNION ALL
SELECT '9/3', 3 FROM DUAL UNION ALL
SELECT '42-9', -36 FROM DUAL
/
CREATE TABLE B(X,Y) AS
SELECT '4/2', 6 FROM DUAL UNION ALL
SELECT '3/0', 3 FROM DUAL UNION ALL
SELECT '0/8+2', 4 FROM DUAL UNION ALL
SELECT '95-5', 90 FROM DUAL UNION ALL
SELECT '4+2', 2 FROM DUAL
/
CREATE TABLE C(X,Y) AS
SELECT '7+4', 11 FROM DUAL UNION ALL
SELECT '5-15', 46 FROM DUAL UNION ALL
SELECT '212-23', -2121 FROM DUAL
/
CREATE TABLE D(X,Y) AS
SELECT '4+8/2-9*1', -5 FROM DUAL UNION ALL
SELECT '99/3-13', 20 FROM DUAL UNION ALL
SELECT '1+2+3+4', 10 FROM DUAL UNION ALL
SELECT '4-3-2-1', -6 FROM DUAL
/
CREATE TABLE E(X,Y) AS
SELECT '18/18', 1 FROM DUAL UNION ALL
SELECT '98-8', 90 FROM DUAL UNION ALL
SELECT '55*88', 4840 FROM DUAL UNION ALL
SELECT '-5--15', 10 FROM DUAL
/
CREATE TABLE G(X,Y) AS
SELECT '9119', 18 FROM DUAL UNION ALL
SELECT '5-3', 513 FROM DUAL UNION ALL
SELECT '8*-9', 152 FROM DUAL UNION ALL
SELECT '13116/3', -1 FROM DUAL
/
Query 1:
WITH r(v)AS(SELECT SUBSTR('1234567890-+*/',LEVEL,1)FROM DUAL CONNECT BY LEVEL<15)SELECT r.v,s.v FROM A,r,r s WHERE r.v<>s.v GROUP BY r.v,s.v HAVING SUM(f(TRANSLATE(x,r.v||s.v,s.v||r.v),y))=(SELECT COUNT(1)FROM A)AND SUM(INSTR(x,r.v)+INSTR(x,s.v))>0
Results:
| V | V |
|---|---|
| 2 | * |
| * | 2 |
Query 2:
WITH r(v)AS(SELECT SUBSTR('1234567890-+*/',LEVEL,1)FROM DUAL CONNECT BY LEVEL<15)SELECT r.v,s.v FROM B,r,r s WHERE r.v<>s.v GROUP BY r.v,s.v HAVING SUM(f(TRANSLATE(x,r.v||s.v,s.v||r.v),y))=(SELECT COUNT(1)FROM B)AND SUM(INSTR(x,r.v)+INSTR(x,s.v))>0
Results:
| V | V |
|---|---|
| + | / |
| / | + |
Query 3:
WITH r(v)AS(SELECT SUBSTR('1234567890-+*/',LEVEL,1)FROM DUAL CONNECT BY LEVEL<15)SELECT r.v,s.v FROM C,r,r s WHERE r.v<>s.v GROUP BY r.v,s.v HAVING SUM(f(TRANSLATE(x,r.v||s.v,s.v||r.v),y))=(SELECT COUNT(1)FROM C)AND SUM(INSTR(x,r.v)+INSTR(x,s.v))>0
Results:
| V | V |
|---|---|
| 1 | - |
| - | 1 |
Query 4:
WITH r(v)AS(SELECT SUBSTR('1234567890-+*/',LEVEL,1)FROM DUAL CONNECT BY LEVEL<15)SELECT r.v,s.v FROM D,r,r s WHERE r.v<>s.v GROUP BY r.v,s.v HAVING SUM(f(TRANSLATE(x,r.v||s.v,s.v||r.v),y))=(SELECT COUNT(1)FROM D)AND SUM(INSTR(x,r.v)+INSTR(x,s.v))>0
Results:
| V | V |
|---|---|
| 2 | 4 |
| 4 | 2 |
Query 5:
WITH r(v)AS(SELECT SUBSTR('1234567890-+*/',LEVEL,1)FROM DUAL CONNECT BY LEVEL<15)SELECT r.v,s.v FROM E,r,r s WHERE r.v<>s.v GROUP BY r.v,s.v HAVING SUM(f(TRANSLATE(x,r.v||s.v,s.v||r.v),y))=(SELECT COUNT(1)FROM E)AND SUM(INSTR(x,r.v)+INSTR(x,s.v))>0
Results:
| V | V |
|---|---|
| 5 | 8 |
| 8 | 5 |
Query 6:
WITH r(v)AS(SELECT SUBSTR('1234567890-+*/',LEVEL,1)FROM DUAL CONNECT BY LEVEL<15)SELECT r.v,s.v FROM G,r,r s WHERE r.v<>s.v GROUP BY r.v,s.v HAVING SUM(f(TRANSLATE(x,r.v||s.v,s.v||r.v),y))=(SELECT COUNT(1)FROM G)AND SUM(INSTR(x,r.v)+INSTR(x,s.v))>0
Results:
| V | V |
|---|---|
| 1 | - |
| - | 1 |