Download | Plain Text | No Line Numbers


  1. /*
  2.  * Copyright (c) 2008, Manuel Mausz <manuel at mausz.at>
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions are met:
  7.  * * Redistributions of source code must retain the above copyright
  8.  * notice, this list of conditions and the following disclaimer.
  9.  * * Redistributions in binary form must reproduce the above copyright
  10.  * notice, this list of conditions and the following disclaimer in the
  11.  * documentation and/or other materials provided with the distribution.
  12.  * * Neither the name of the copyright holders nor the
  13.  * names of its contributors may be used to endorse or promote products
  14.  * derived from this software without specific prior written permission.
  15.  *
  16.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  18.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  19.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  20.  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  22.  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  23.  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  25.  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  26.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  27.  * DAMAGE.
  28.  */
  29.  
  30. import java.io.InputStream;
  31. import java.util.HashMap;
  32. import java.util.Scanner;
  33. import java.lang.Class;
  34. import java.lang.Boolean;
  35. import java.lang.reflect.*;
  36. import java.util.InputMismatchException;
  37. import java.lang.NoSuchMethodException;
  38.  
  39.  
  40. /**
  41.  * CalcOperator encapsulate an Operator
  42.  * NOTE: This class isn't public due to EPROG limitations.
  43.  * EPROG doesn't allow shipping files not specified
  44.  *
  45.  * @version 1.0
  46.  * @author Manuel Mausz (manuel at mausz.at)
  47.  * @author http://manuel.mausz.at/
  48.  */
  49. class CalcOperator
  50. {
  51. private String op;
  52.  
  53. /**
  54.   * Constructor
  55.   *
  56.   * @param value init value
  57.   */
  58. CalcOperator(String op)
  59. {
  60. this.op = op;
  61. }
  62.  
  63. /**
  64.   * @return encapsulated operator
  65.   */
  66. public String get()
  67. {
  68. return op;
  69. }
  70.  
  71. /**
  72.   * Indicates whether some other object is "equal to" this one
  73.   *
  74.   * @param obj the reference object with which to compare
  75.   * @return true if this object is the same as the obj argument; false otherwise
  76.   */
  77. public boolean equals(Object op2)
  78. {
  79. if (op2 == null)
  80. return false;
  81. else if (op2 instanceof CalcOperator)
  82. return this.op.equals(((CalcOperator) op2).get());
  83. else
  84. return false;
  85. }
  86.  
  87. /**
  88.   * Returns a hash code value for the object
  89.   *
  90.   * @return string
  91.   */
  92. public int hashCode()
  93. {
  94. return op.hashCode();
  95. }
  96.  
  97. /**
  98.   * Converts instance to string
  99.   *
  100.   * @return string
  101.   */
  102. public String toString()
  103. {
  104. return op;
  105. }
  106. }
  107.  
  108.  
  109. /**
  110.  * Abstract for CalcValue
  111.  *
  112.  * @version 1.0
  113.  * @author Manuel Mausz (manuel at mausz.at)
  114.  * @author http://manuel.mausz.at/
  115.  */
  116. abstract class CalcValue
  117. {
  118. protected static HashMap<CalcOperator, String> operators = new HashMap<CalcOperator, String>();
  119.  
  120. /**
  121.   * Assigns an operator to a method
  122.   *
  123.   * @param op operator
  124.   * @param func method name
  125.   */
  126. protected void addOp(CalcOperator op, String func)
  127. {
  128. operators.put(op, func);
  129. }
  130.  
  131. /**
  132.   * Checks if instance has an method assigned to operater
  133.   *
  134.   * @param op operator
  135.   * @return boolean
  136.   */
  137. public boolean isSupported(CalcOperator op)
  138. {
  139. return operators.containsKey(op);
  140. }
  141.  
  142. /**
  143.   * Invokes the method assigned to operator
  144.   * passes value as argument
  145.   *
  146.   * @param value argument passed to the invoked method
  147.   * @param op operator
  148.   * @return object return by invoked method
  149.   * @throws NoSuchMethodException
  150.   * @throws InvocationTargetException
  151.   */
  152. public Object calc(CalcValue value, CalcOperator op)
  153. throws NoSuchMethodException, InvocationTargetException
  154. {
  155. Object ret = null;
  156.  
  157. String methodname = operators.get(op);
  158. if (methodname == null)
  159. throw new NoSuchMethodException("Method for operator '" + op.get() + "' not found");
  160.  
  161. try
  162. {
  163. Method method = this.getClass().getMethod(methodname, new Class[] { value.getClass() });
  164. ret = method.invoke(this, new Object[] { value } );
  165. }
  166. catch(IllegalAccessException e)
  167. {
  168. throw new NoSuchMethodException(e.getMessage());
  169. }
  170.  
  171. return ret;
  172. }
  173. }
  174.  
  175.  
  176. /**
  177.  * CalcInteger encapsulate an Integer value
  178.  * NOTE: This class isn't public due to EPROG limitations.
  179.  * EPROG doesn't allow shipping files not specified
  180.  *
  181.  * @version 1.0
  182.  * @author Manuel Mausz (manuel at mausz.at)
  183.  * @author http://manuel.mausz.at/
  184.  */
  185. class CalcInteger extends CalcValue
  186. {
  187. private int value;
  188.  
  189. /**
  190.   * Constructor
  191.   *
  192.   * @param value init value
  193.   */
  194. CalcInteger(int value)
  195. {
  196. addOps();
  197. this.value = value;
  198. }
  199.  
  200. /**
  201.   * Add supported operations
  202.   */
  203. private void addOps()
  204. {
  205. addOp(new CalcOperator("+"), "add");
  206. addOp(new CalcOperator("-"), "sub");
  207. addOp(new CalcOperator("*"), "mul");
  208. addOp(new CalcOperator("/"), "div");
  209. }
  210.  
  211. /**
  212.   * @return encapsulated integer
  213.   */
  214. public int get()
  215. {
  216. return value;
  217. }
  218.  
  219. /**
  220.   * Converts instance to string
  221.   *
  222.   * @return string
  223.   */
  224. public String toString()
  225. {
  226. return Integer.toString(value);
  227. }
  228.  
  229. /**
  230.   * Addition
  231.   *
  232.   * @param val
  233.   * @return new CalcInteger instance
  234.   */
  235. public CalcInteger add(CalcInteger val)
  236. {
  237. return new CalcInteger(value + val.get());
  238. }
  239.  
  240. /**
  241.   * Subtraction
  242.   *
  243.   * @param val
  244.   * @return new CalcInteger instance
  245.   */
  246. public CalcInteger sub(CalcInteger val)
  247. {
  248. return new CalcInteger(value - val.get());
  249. }
  250.  
  251. /**
  252.   * Multiplication
  253.   *
  254.   * @param val
  255.   * @return new CalcInteger instance
  256.   */
  257. public CalcInteger mul(CalcInteger val)
  258. {
  259. return new CalcInteger(value * val.get());
  260. }
  261.  
  262. /**
  263.   * Division
  264.   *
  265.   * @param val
  266.   * @return new CalcInteger instance
  267.   */
  268. public CalcInteger div(CalcInteger val)
  269. {
  270. return new CalcInteger(value / val.get());
  271. }
  272. }
  273.  
  274.  
  275. /**
  276.  * Calculator
  277.  *
  278.  * @version 1.0
  279.  * @author Manuel Mausz (manuel at mausz.at)
  280.  * @author http://manuel.mausz.at/
  281.  */
  282. public class Calculator
  283. {
  284. private static CalcInteger val1;
  285. private static CalcInteger val2;
  286. private static CalcOperator op;
  287.  
  288. /**
  289.   * read values and operator from src
  290.   * only allow syntax: "int int op"
  291.   *
  292.   * @param src input stream
  293.   * @return boolean always true
  294.   * @throws InputMismatchException
  295.   * @throws NoSuchMethodException
  296.   * @throws InvocationTargetException
  297.   */
  298. public static boolean parse(InputStream src)
  299. throws InputMismatchException, NoSuchMethodException, InvocationTargetException
  300. {
  301. /* get first line only */
  302. Scanner scanner = new Scanner(System.in);
  303. String line1 = scanner.nextLine();
  304. scanner.close();
  305.  
  306. /* parse first line */
  307. scanner = new Scanner(line1);
  308.  
  309. if (!scanner.hasNextInt())
  310. throw new InputMismatchException("Invalid first param. No integer");
  311. val1 = new CalcInteger(scanner.nextInt());
  312.  
  313. if (!scanner.hasNextInt())
  314. throw new InputMismatchException("Invalid second param. No integer");
  315. val2 = new CalcInteger(scanner.nextInt());
  316.  
  317. if (!scanner.hasNext())
  318. throw new InputMismatchException("Invalid operator");
  319. op = new CalcOperator(scanner.next());
  320.  
  321. /* check for additional chars */
  322. if (scanner.hasNext())
  323. throw new InputMismatchException("Invalid chars at the end of line");
  324.  
  325. scanner.close();
  326.  
  327. return true;
  328. }
  329.  
  330. /**
  331.   * main method
  332.   *
  333.   * @param args not used
  334.   */
  335. public static void main(String[] args)
  336. {
  337. try
  338. {
  339. /* parse stdin */
  340. parse(System.in);
  341.  
  342. /* do calculation */
  343. Object newval = val1.calc(val2, op);
  344. if (!(newval instanceof CalcInteger))
  345. throw new InputMismatchException("Unrecognized classtype returned from operation");
  346.  
  347. /* print result to stdout */
  348. System.out.println(((CalcInteger) newval).get());
  349. }
  350. catch(Throwable e)
  351. {
  352. System.out.println("FALSCHE EINGABE");
  353. }
  354. }
  355. }
  356.