예제 #1
0
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner in = new Scanner(System.in);
    int t = in.nextInt();
    TreeMap<Long, Long> tmap = new TreeMap<>();
    long res = 0;
    while (t-- > 0) {
      res = 0;
      int n = in.nextInt();
      long m = in.nextLong();
      tmap.clear();
      long[] arr = new long[n];
      res = in.nextLong();
      arr[0] = res % m;
      res = Long.MIN_VALUE;
      tmap.put(arr[0], arr[0]);
      for (int i = 1; i < arr.length; i++) {
        arr[i] = in.nextLong();
        arr[i] %= m;
        arr[i] += arr[i - 1];
        arr[i] %= m;

        if (tmap.higherEntry(arr[i]) == null) {
          res = Math.max(res, arr[i]);
          tmap.put(arr[i], arr[i]);
          continue;
        }
        long val = tmap.higherEntry(arr[i]).getValue();
        res = Math.max(res, (arr[i] - val + m) % m);
        tmap.put(arr[i], arr[i]);
      }

      System.out.println(res);
    }
  }
예제 #2
0
 private void setHoverLocation(
     org.eclipse.swt.widgets.Shell shell, org.eclipse.swt.graphics.Point position) {
   org.eclipse.swt.graphics.Rectangle displayBounds = shell.getDisplay().getBounds();
   org.eclipse.swt.graphics.Rectangle shellBounds = shell.getBounds();
   shellBounds.x = Math.max(Math.min(position.x, displayBounds.width - shellBounds.width), 0);
   shellBounds.y =
       Math.max(Math.min(position.y + 16, displayBounds.height - shellBounds.height), 0);
   shell.setBounds(shellBounds);
 }
예제 #3
0
파일: Token.java 프로젝트: nikhi/basex
  /**
   * Returns a partial token.
   *
   * @param token input text
   * @param start start position
   * @param end end position
   * @return resulting text
   */
  public static byte[] subtoken(final byte[] token, final int start, final int end) {
    int s = Math.max(0, start);
    final int e = Math.min(end, token.length);
    if (s == 0 && e == token.length) return token;
    if (s >= e) return EMPTY;

    int t = Math.max(0, s - 4);
    for (; t != s && t < e; t += cl(token, t)) {
      if (t >= s) s = t;
    }
    for (; t < e; t += cl(token, t)) ;
    return Arrays.copyOfRange(token, s, t);
  }
 public static void main(String[] args) {
   Scanner inp = new Scanner(System.in);
   int n = inp.nextInt();
   String[] store = new String[n];
   for (int i = 0; i < n; i++) store[i] = inp.next();
   int[] cnt = new int[n];
   Arrays.fill(cnt, 0);
   String str = inp.next();
   for (int j = 0; j < n; j++) {
     int l1 = store[j].length();
     for (int k = 0; k <= (str.length() - l1); k++) {
       if (str.substring(k, k + l1).equals(store[j])) {
         cnt[j] = cnt[j] + 1;
       }
     }
   }
   int y = 0;
   for (int m = 0; m < n; m++) {
     y = Math.max(y, cnt[m]);
   }
   System.out.println(y);
   for (int h = 0; h < n; h++) {
     if (cnt[h] == y) System.out.println(store[h]);
   }
 }
예제 #5
0
  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    int arr[][] = new int[6][6];
    int max = -10000; // lowest possible value is -9*6=-54
    int sum;
    for (int arr_i = 0; arr_i < 6; arr_i++) {
      for (int arr_j = 0; arr_j < 6; arr_j++) {
        arr[arr_i][arr_j] = in.nextInt();
      }
    }

    for (int i = 0; i < 4; i++) {
      for (int j = 0; j < 4; j++) {
        sum =
            arr[i][j]
                + arr[i][j + 1]
                + arr[i][j + 2]
                + arr[i + 1][j + 1]
                + arr[i + 2][j]
                + arr[i + 2][j + 1]
                + arr[i + 2][j + 2];
        max = Math.max(sum, max);
      }
    }
    System.out.println(max);
  }
예제 #6
0
  public static void main(String[] args) throws IOException {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int n = Integer.parseInt(br.readLine());
    int a[] = new int[n];
    int c[] = new int[n];
    for (int i = 0; i < n; i++) {
      a[i] = Integer.parseInt(br.readLine());
    }

    for (int i = 0; i < n; i++) {
      c[i] = 1;
    }

    for (int j = 1; j < n; j++) {
      if (a[j] > a[j - 1]) c[j] = c[j - 1] + 1;
    }

    for (int k = n - 2; k >= 0; k--) {
      if (a[k] > a[k + 1]) c[k] = Math.max(c[k + 1] + 1, c[k]);
    }
    int count = 0;
    for (int i = 0; i < n; i++) {
      count += c[i];
    }

    System.out.println(count);
  }
예제 #7
0
 private static int height(TreeNode t) {
   if (t == null) {
     return 0;
   } else {
     return 1 + Math.max(height(t.left), height(t.right));
   }
 }
예제 #8
0
  private static void doStep(long n) {
    long mutations = actuallyMut;

    doYoungGenAlloc(n, WORDS_DEAD);
    doMutWork(n);
    oldGenAlloc(n / promoteRate);
    oldGenMut(Math.max(0L, (mutations + ptrMutRate) - actuallyMut));
  }
예제 #9
0
 /**
  * Formats the specified value and enters it in the text field.
  *
  * @param value the value to be entered
  */
 public void setValue(double value) {
   if (!isVisible()) return;
   if (minValue != null) value = Math.max(value, minValue.doubleValue());
   if (maxValue != null) value = Math.min(value, maxValue.doubleValue());
   setFormatFor(value);
   setText(format.format(value));
   prevValue = value;
 }
예제 #10
0
  public int solve(int start, int maxV, int be, int[] ivl) {
    if (start < 0 || start > maxV) return -1;
    if (be == ivl.length) return start;

    if (DP[be][start] != -2) return DP[be][start];
    return DP[be][start] =
        Math.max(
            solve(start + ivl[be], maxV, be + 1, ivl), solve(start - ivl[be], maxV, be + 1, ivl));
  }
예제 #11
0
  /**
   * Computes CPU usage (fraction of 1.0) between <code>start[1]</code> and <code>end[1]</code> time
   * points [1.0 corresponds to 100% utilization of all processors].
   *
   * @throws IllegalArgumentException if start and end time points are less than #MIN_ELAPSED_TIME
   *     ms apart.
   * @throws IllegalArgumentException if either argument is null
   * @param start,end long[2]: [0] system time stamp, [1] process CPU time (as returned by
   *     makeCPUUsageSnapshot()).
   */
  public static double getProcessCPUUsage(long[] start, long[] end) {
    if (start == null) throw new IllegalArgumentException("null input: start");
    if (end == null) throw new IllegalArgumentException("null input: end");
    // if (end[0] < start[0] + MIN_ELAPSED_TIME) throw new IllegalArgumentException("end time must
    // be at least " + MIN_ELAPSED_TIME + " ms later than start time");
    end[0] = Math.max(end[0], start[0] + MIN_ELAPSED_TIME);

    return ((double) (end[1] - start[1])) / (double) (end[0] - start[0]);
  }
 // BEGIN KAWIGIEDIT TESTING
 // Generated by KawigiEdit-pf 2.3.0
 private static boolean KawigiEdit_RunTest(
     int testNum, int[] p0, int[] p1, boolean hasAnswer, double p2) {
   System.out.print("Test " + testNum + ": [" + "{");
   for (int i = 0; p0.length > i; ++i) {
     if (i > 0) {
       System.out.print(",");
     }
     System.out.print(p0[i]);
   }
   System.out.print("}" + "," + "{");
   for (int i = 0; p1.length > i; ++i) {
     if (i > 0) {
       System.out.print(",");
     }
     System.out.print(p1[i]);
   }
   System.out.print("}");
   System.out.println("]");
   GreaterGame obj;
   double answer;
   obj = new GreaterGame();
   long startTime = System.currentTimeMillis();
   answer = obj.calc(p0, p1);
   long endTime = System.currentTimeMillis();
   boolean res;
   res = true;
   System.out.println("Time: " + (endTime - startTime) / 1000.0 + " seconds");
   if (hasAnswer) {
     System.out.println("Desired answer:");
     System.out.println("\t" + p2);
   }
   System.out.println("Your answer:");
   System.out.println("\t" + answer);
   if (hasAnswer) {
     res = answer == answer && Math.abs(p2 - answer) <= 1e-9 * Math.max(1.0, Math.abs(p2));
   }
   if (!res) {
     System.out.println("DOESN'T MATCH!!!!");
   } else if ((endTime - startTime) / 1000.0 >= 2) {
     System.out.println("FAIL the timeout");
     res = false;
   } else if (hasAnswer) {
     System.out.println("Match :-)");
   } else {
     System.out.println("OK, but is it right?");
   }
   System.out.println("");
   return res;
 }
예제 #13
0
 public CachedProbe(AffyProbe ap, Vector<AffyExperiment> expts) {
   probe = ap;
   min = max = 0.0;
   color = Color.lightGray;
   stroke = new BasicStroke((float) 2.0);
   values = new Vector<Double>();
   for (AffyExperiment e : expts) {
     AffyMeasurement am = e.getMeasurement(probe);
     if (am != null) {
       values.add(am.getValue());
       min = Math.min(am.getValue(), min);
       max = Math.max(am.getValue(), max);
     } else {
       values.add(null);
     }
   }
 }
예제 #14
0
  /**
   * Read block from file.
   *
   * @param file - File to read.
   * @param off - Marker position in file to start read from if {@code -1} read last blockSz bytes.
   * @param blockSz - Maximum number of chars to read.
   * @param lastModified - File last modification time.
   * @return Read file block.
   * @throws IOException In case of error.
   */
  public static VisorFileBlock readBlock(File file, long off, int blockSz, long lastModified)
      throws IOException {
    RandomAccessFile raf = null;

    try {
      long fSz = file.length();
      long fLastModified = file.lastModified();

      long pos = off >= 0 ? off : Math.max(fSz - blockSz, 0);

      // Try read more that file length.
      if (fLastModified == lastModified && fSz != 0 && pos >= fSz)
        throw new IOException(
            "Trying to read file block with wrong offset: " + pos + " while file size: " + fSz);

      if (fSz == 0)
        return new VisorFileBlock(file.getPath(), pos, fLastModified, 0, false, EMPTY_FILE_BUF);
      else {
        int toRead = Math.min(blockSz, (int) (fSz - pos));

        byte[] buf = new byte[toRead];

        raf = new RandomAccessFile(file, "r");

        raf.seek(pos);

        int cntRead = raf.read(buf, 0, toRead);

        if (cntRead != toRead)
          throw new IOException(
              "Count of requested and actually read bytes does not match [cntRead="
                  + cntRead
                  + ", toRead="
                  + toRead
                  + ']');

        boolean zipped = buf.length > 512;

        return new VisorFileBlock(
            file.getPath(), pos, fSz, fLastModified, zipped, zipped ? zipBytes(buf) : buf);
      }
    } finally {
      U.close(raf, null);
    }
  }
 /**
  * Calculates statistical values for a data array.
  *
  * @param data the data array
  * @return the max, min, mean, SD, SE and non-NaN data count
  */
 private double[] getStatistics(double[] data) {
   double max = -Double.MAX_VALUE;
   double min = Double.MAX_VALUE;
   double sum = 0.0;
   double squareSum = 0.0;
   int count = 0;
   for (int i = 0; i < data.length; i++) {
     if (Double.isNaN(data[i])) {
       continue;
     }
     count++;
     max = Math.max(max, data[i]);
     min = Math.min(min, data[i]);
     sum += data[i];
     squareSum += data[i] * data[i];
   }
   double mean = sum / count;
   double sd = count < 2 ? Double.NaN : Math.sqrt((squareSum - count * mean * mean) / (count - 1));
   if (max == -Double.MAX_VALUE) max = Double.NaN;
   if (min == Double.MAX_VALUE) min = Double.NaN;
   return new double[] {max, min, mean, sd, sd / Math.sqrt(count), count};
 }
예제 #16
0
 double trim(double x, double min_value, double max_value) {
   return Math.min(Math.max(x, min_value), max_value);
 }
예제 #17
0
  public int selectAction() {

    if (currentPath != -1) {
      if (nodePaths[currentPath].contains(currentNode)) {
        currentIndex = nodePaths[currentPath].indexOf(currentNode);
      }
    }
    if (firstStep) {

      pathLength = 0;
      // currentPath=generator.nextInt(paths.length);

      currentPath = selectCycle();
      previousPath = currentPath;
      System.out.println("New path is generated");
      System.out.println(currentPath);
      System.out.println(currentNode);
      firstStep = false;
      if (nodePaths[currentPath].contains(currentNode)) {
        pathLength++;
        currentIndex = nodePaths[currentPath].indexOf(currentNode);
        startTime = System.currentTimeMillis();
        cycleReward =
            cycleReward + payout - travelCost; // currentUtilitiesforVisitingNodes[currentNode];
        return paths[currentPath].get(currentIndex);

      } else {
        cycleReward = 0;

        return 0;
      }
    } else {
      if (currentIndex == 0 && nodePaths[currentPath].contains(currentNode)) {
        currentPath = selectCycle();
        previousPath = currentPath;
        pathLength = 0;

        System.out.println("New path is generated");
        System.out.println(currentPath);
        System.out.println(currentNode);
        firstStep = false;
        if (nodePaths[currentPath].contains(currentNode)) {
          pathLength++;
          currentIndex = nodePaths[currentPath].indexOf(currentNode);
          startTime = System.currentTimeMillis();
          cycleReward =
              cycleReward + payout - travelCost; // currentUtilitiesforVisitingNodes[currentNode];
          return paths[currentPath].get(currentIndex);
        } else {
          cycleReward = 0;
          return 0;
        }
      }
      // if(currentIndex==paths[currentPath].size()-1){

      //	firstStep=true;
      // }
      if (pathLength == paths[currentPath].size() - 1) {
        firstStep = true;
        endTime = System.currentTimeMillis();
        Rtmp = cycleReward * 1000 / (endTime - startTime);
        if (t < N) {
          Rmax = Math.max(Rmax, Rtmp);
        }
        if (t == N) {
          alpha = Rmax;
        }

        if (t > N) {
          alpha = lambda * alpha + (1 - lambda) * Rtmp;
        }
        t = t + 1;
      }
      return paths[currentPath].get(currentIndex);
    }
  }
  /**
   * Overriden in an attempt to honor the literals.
   *
   * <p>If we do not allow invalid values and are in overwrite mode, this does the following for
   * each character in the replacement range:
   *
   * <ol>
   *   <li>If the character is a literal, add it to the string to replace with. If there is text to
   *       insert and it doesn't match the literal, then insert the literal in the the middle of the
   *       insert text. This allows you to either paste in literals or not and get the same
   *       behavior.
   *   <li>If there is no text to insert, replace it with ' '.
   * </ol>
   *
   * If not in overwrite mode, and there is text to insert it is inserted at the next non literal
   * index going forward. If there is only text to remove, it is removed from the next non literal
   * index going backward.
   */
  boolean canReplace(ReplaceHolder rh) {
    if (!getAllowsInvalid()) {
      String text = rh.text;
      int tl = (text != null) ? text.length() : 0;

      if (tl == 0 && rh.length == 1 && getFormattedTextField().getSelectionStart() != rh.offset) {
        // Backspace, adjust to actually delete next non-literal.
        rh.offset = getNextNonliteralIndex(rh.offset, -1);
      }
      if (getOverwriteMode()) {
        StringBuffer replace = null;

        for (int counter = 0, textIndex = 0, max = Math.max(tl, rh.length);
            counter < max;
            counter++) {
          if (isLiteral(rh.offset + counter)) {
            if (replace != null) {
              replace.append(getLiteral(rh.offset + counter));
            }
            if (textIndex < tl && text.charAt(textIndex) == getLiteral(rh.offset + counter)) {
              textIndex++;
            } else if (textIndex == 0) {
              rh.offset++;
              rh.length--;
              counter--;
              max--;
            } else if (replace == null) {
              replace = new StringBuffer(max);
              replace.append(text.substring(0, textIndex));
              replace.append(getLiteral(rh.offset + counter));
            }
          } else if (textIndex < tl) {
            if (replace != null) {
              replace.append(text.charAt(textIndex));
            }
            textIndex++;
          } else {
            // Nothing to replace it with, assume ' '
            if (replace == null) {
              replace = new StringBuffer(max);
              if (textIndex > 0) {
                replace.append(text.substring(0, textIndex));
              }
            }
            if (replace != null) {
              replace.append(' ');
            }
          }
        }
        if (replace != null) {
          rh.text = replace.toString();
        }
      } else if (tl > 0) {
        // insert (or insert and remove)
        rh.offset = getNextNonliteralIndex(rh.offset, 1);
      } else {
        // remove only
        rh.offset = getNextNonliteralIndex(rh.offset, -1);
      }
      ((ExtendedReplaceHolder) rh).endOffset = rh.offset;
      ((ExtendedReplaceHolder) rh).endTextLength = (rh.text != null) ? rh.text.length() : 0;
    } else {
      ((ExtendedReplaceHolder) rh).endOffset = rh.offset;
      ((ExtendedReplaceHolder) rh).endTextLength = (rh.text != null) ? rh.text.length() : 0;
    }
    boolean can = super.canReplace(rh);
    if (can && !getAllowsInvalid()) {
      ((ExtendedReplaceHolder) rh).resetFromValue(this);
    }
    return can;
  }
예제 #19
0
파일: Token.java 프로젝트: nikhi/basex
 /**
  * Returns a substring of the specified token. Note that this method does not correctly split UTF8
  * character; use {@link #subtoken} instead.
  *
  * @param token input token
  * @param start start position
  * @param end end position
  * @return substring
  */
 public static byte[] substring(final byte[] token, final int start, final int end) {
   final int s = Math.max(0, start);
   final int e = Math.min(end, token.length);
   if (s == 0 && e == token.length) return token;
   return s >= e ? EMPTY : Arrays.copyOfRange(token, s, e);
 }
예제 #20
0
 // -------------------------------------------
 public static int max3(int v1, int v2, int v3) {
   return Math.max(Math.max(v1, v2), v3);
 }
예제 #21
0
 /**
  * Sets the default point index. This defines the index of the points array used to get the point
  * initially selected when the step is created.
  *
  * @param index the index
  */
 public void setDefaultPointIndex(int index) {
   index = Math.min(index, points.length - 1);
   defaultIndex = Math.max(0, index);
 }
예제 #22
0
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.WHITE);
    // Draws a white arrow and the principal axis
    g.drawLine(0, 200, 700, 200);
    g.drawLine(arrow_x, 200, arrow_x, arrow_y2);

    // Show coordinates of arrow tip
    arrowCoordinate_x = arrow_x - startingPosition;
    arrowCoordinate_x /= 10;
    arrowCoordinate_y = 200 - arrow_y2;
    arrowCoordinate_y /= 10;

    // Coordinates
    Optics.lbl_arrowCoordinates.setText(
        "<html>(d<sub>o</sub>, h<sub>o</sub>) = ("
            + arrowCoordinate_x
            + ", "
            + arrowCoordinate_y
            + ")</html>");

    if (arrow_y2 < 200) // if arrow is above principal axis
    {
      g.drawLine(arrow_x, arrow_y2, arrow_x - 7, arrow_y2 + 7);
      g.drawLine(arrow_x, arrow_y2, arrow_x + 7, arrow_y2 + 7);
    } else if (arrow_y2 > 200) // if arrow is below principal axis
    {
      g.drawLine(arrow_x, arrow_y2, arrow_x - 7, arrow_y2 - 7);
      g.drawLine(arrow_x, arrow_y2, arrow_x + 7, arrow_y2 - 7);
    }
    // Draws lines for the grid
    if (lenses) startingPosition = 350;
    else {
      radiusOfCurvature = 20 * focalLength;
      if (type == 0) startingPosition = 500;
      else startingPosition = 350;
    }
    {
      for (int i = startingPosition; i <= 700; i += 10) {
        if ((i - startingPosition) % (10 * focalLength) == 0) {
          g.setColor(Color.ORANGE);
          g.drawLine(i, 195, i, 205);
        } else {
          g.setColor(Color.WHITE);
          g.drawLine(i, 197, i, 203);
        }
      }
      for (int i = startingPosition; i >= 0; i -= 10) {
        if ((i - startingPosition) % (10 * focalLength) == 0 && i != 0) {
          g.setColor(Color.ORANGE);
          g.drawLine(i, 195, i, 205);
        } else {
          g.setColor(Color.WHITE);
          g.drawLine(i, 197, i, 203);
        }
      }
    }
    g.setColor(Color.WHITE);

    if (lenses) {
      if (type == 0) // If Converging
      {
        // Draws a converging lens
        g.drawArc(340, 50, 40, 300, 120, 120);
        g.drawArc(320, 50, 40, 300, 60, -120);
        // draws horizontal line from the tip of the arrow to the lens (line 1/3)
        g.setColor(Color.RED);
        g.drawLine(arrow_x, arrow_y2, 350, arrow_y2);
        // calculates necessary information to form equation of line from lens to focal point (line
        // 2/3)

        dy_1 = 200 - arrow_y2;

        if (arrow_x > 350) dx_1 = -10 * focalLength;
        else dx_1 = 10 * focalLength;
        slope_1 = dy_1 / dx_1;

        if (arrow_x > 350) y_intercept_1 = 200 - slope_1 * (350 - 10 * focalLength);
        else y_intercept_1 = 200 - slope_1 * (10 * focalLength + 350);
        // Calculates coordinates of points on the edge of screen (endpoints)
        if (arrow_x <= 350)
          y_screenIntersection_1 = (int) (Math.round(slope_1 * 700 + y_intercept_1));
        else y_screenIntersection_1 = (int) (Math.round(y_intercept_1));
        if (slope_1 != 0)
          if (arrow_y2 <= 200)
            x_screenIntersection_1 = (int) (Math.round((400 - y_intercept_1) / slope_1));
          else x_screenIntersection_1 = (int) (Math.round(-y_intercept_1 / slope_1));
        if (x_screenIntersection_1 >= 0
            && x_screenIntersection_1 <= 700) // If endpoint is on the x-edge
        if (arrow_y2 <= 200) g.drawLine(350, arrow_y2, x_screenIntersection_1, 400);
          else g.drawLine(350, arrow_y2, x_screenIntersection_1, 0);
        else if (arrow_x > 350) g.drawLine(350, arrow_y2, 0, y_screenIntersection_1);
        else
          g.drawLine(350, arrow_y2, 700, y_screenIntersection_1); // Else: endpoint is on the y-edge
      } else // Else: Diverging
      {
        // Draws a diverging lens
        g.drawArc(360, 50, 40, 300, 120, 120);
        g.drawArc(300, 50, 40, 300, 60, -120);
        g.drawLine(330, 68, 370, 68);
        g.drawLine(330, 330, 370, 330);

        // draws horizontal line from the tip of the arrow to the lens (line 1/3)
        g.setColor(Color.RED);
        g.drawLine(arrow_x, arrow_y2, 350, arrow_y2);

        // calculates necessary information to form equation of line from lens to focal point (line
        // 2/3)

        dy_1 = arrow_y2 - 200;

        if (arrow_x > 350) dx_1 = -10 * focalLength;
        else dx_1 = 10 * focalLength;
        slope_1 = dy_1 / dx_1;

        if (arrow_x > 350) y_intercept_1 = 200 - slope_1 * (10 * focalLength + 350);
        else y_intercept_1 = 200 - slope_1 * (350 - 10 * focalLength);
        // Calculates coordinates of points on the edge of screen (endpoints)
        if (arrow_x <= 350)
          y_screenIntersection_1 = (int) (Math.round(slope_1 * 700 + y_intercept_1));
        else y_screenIntersection_1 = (int) (Math.round(y_intercept_1));
        if (slope_1 != 0)
          if (arrow_y2 <= 200)
            x_screenIntersection_1 = (int) (Math.round(-y_intercept_1 / slope_1));
          else x_screenIntersection_1 = (int) (Math.round((400 - y_intercept_1) / slope_1));
        if (x_screenIntersection_1 >= 0
            && x_screenIntersection_1 <= 700) // If endpoint is on the x-edge
        if (arrow_y2 <= 200) g.drawLine(350, arrow_y2, x_screenIntersection_1, 0);
          else g.drawLine(350, arrow_y2, x_screenIntersection_1, 400);
        else // Else: endpoint is on the y-edge
        if (arrow_x > 350) g.drawLine(350, arrow_y2, 0, y_screenIntersection_1);
        else g.drawLine(350, arrow_y2, 700, y_screenIntersection_1);
      }
      // Line 3/3
      dy_2 = 200 - arrow_y2;
      dx_2 = 350 - arrow_x;
      slope_2 = dy_2 / dx_2;
      y_intercept_2 = 200 - slope_2 * 350;
      if (arrow_x <= 350)
        y_screenIntersection_2 = (int) (Math.round(slope_2 * 700 + y_intercept_2));
      else y_screenIntersection_2 = (int) (Math.round(y_intercept_2));
      if (slope_2 != 0)
        if (arrow_y2 <= 200)
          x_screenIntersection_2 = (int) (Math.round((400 - y_intercept_2) / slope_2));
        else x_screenIntersection_2 = (int) (Math.round(-y_intercept_2 / slope_2));

      if (x_screenIntersection_2 >= 0
          && x_screenIntersection_2 <= 700) // If endpoint is on the x-edge
      if (arrow_y2 <= 200) g.drawLine(arrow_x, arrow_y2, x_screenIntersection_2, 400);
        else g.drawLine(arrow_x, arrow_y2, x_screenIntersection_2, 0);
      else if (arrow_x <= 350)
        g.drawLine(
            arrow_x, arrow_y2, 700, y_screenIntersection_2); // Else: endpoint is on the y-edge
      else g.drawLine(arrow_x, arrow_y2, 0, y_screenIntersection_2);

      // POI between Line 2 & Line 3
      x_pointOfIntersection = (int) ((y_intercept_2 - y_intercept_1) / (slope_1 - slope_2));
      y_pointOfIntersection = (int) (slope_1 * x_pointOfIntersection + y_intercept_1);
      // Draw image
      g.setColor(Color.ORANGE);
      g.drawLine(x_pointOfIntersection, 200, x_pointOfIntersection, y_pointOfIntersection);
      if (y_pointOfIntersection < 200) {
        g.drawLine(
            x_pointOfIntersection,
            y_pointOfIntersection,
            x_pointOfIntersection - 7,
            y_pointOfIntersection + 7);
        g.drawLine(
            x_pointOfIntersection,
            y_pointOfIntersection,
            x_pointOfIntersection + 7,
            y_pointOfIntersection + 7);
      } else {
        g.drawLine(
            x_pointOfIntersection,
            y_pointOfIntersection,
            x_pointOfIntersection - 7,
            y_pointOfIntersection - 7);
        g.drawLine(
            x_pointOfIntersection,
            y_pointOfIntersection,
            x_pointOfIntersection + 7,
            y_pointOfIntersection - 7);
      }
      // Same side image line continuation
      if (((x_pointOfIntersection > 350 && arrow_x > 350)
              || (x_pointOfIntersection < 350 && arrow_x < 350))
          && (arrow_x != 350 - 10 * focalLength && arrow_x != 350 + 10 * focalLength
              || type == 1)) {
        g.setColor(Color.YELLOW);
        g.drawLine(x_pointOfIntersection, y_pointOfIntersection, 350, arrow_y2);
        if (type == 0) g.drawLine(x_pointOfIntersection, y_pointOfIntersection, arrow_x, arrow_y2);
      }

      // Mag calculations
      height_image = 200 - y_pointOfIntersection;
      height_object = 200 - arrow_y2;
      if (height_object != 0) magnification = height_image / height_object;

      if (magnification <= 9999 && magnification >= -9999)
        Optics.txt_magnification.setText("" + roundTwoDecimals(magnification));
      else if (magnification > 9999) {
        magnification = Double.POSITIVE_INFINITY;
        Optics.txt_magnification.setText("N/A");
      } else {
        magnification = Double.NEGATIVE_INFINITY;
        Optics.txt_magnification.setText("N/A");
      }
      // Characteristics
      g.setColor(Color.ORANGE);
      g.drawString("Image Characteristics:", 20, 300);
      if (type == 0) {
        if ((Math.abs(magnification) > 1 && Math.abs(magnification) < 9999))
          g.drawString("Magnification:  Enlarged", 20, 320);
        else if (arrow_x == 350 - 20 * focalLength
            || arrow_x == 350 + 20 * focalLength
            || (int) (Math.abs(magnification)) == 1) g.drawString("Magnification:  None", 20, 320);
        else if (Math.abs(magnification) < 1 && Math.abs(magnification) > 0)
          g.drawString("Magnification:  Diminished", 20, 320);
        else g.drawString("Magnification:  N/A", 20, 320);
        if (arrow_x == 350 - 10 * focalLength || arrow_x == 350 + 10 * focalLength)
          g.drawString("Orientation:      N/A", 20, 335);
        else if ((arrow_y2 < 200 && y_pointOfIntersection < 200)
            || (arrow_y2 > 200 && y_pointOfIntersection > 200))
          g.drawString("Orientation:      Upright", 20, 335);
        else g.drawString("Orientation:      Inverted", 20, 335);
        if (arrow_x == 350 - 10 * focalLength || arrow_x == 350 + 10 * focalLength)
          g.drawString("Type:                 N/A", 20, 350);
        else if ((x_pointOfIntersection < 350 && arrow_x < 350)
            || (x_pointOfIntersection > 350 && arrow_x > 350))
          g.drawString("Type:                 Virtual", 20, 350);
        else g.drawString("Type:                 Real", 20, 350);
      } else {
        g.drawString("Magnification:  Diminished", 20, 320);
        g.drawString("Orientation:      Upright", 20, 335);
        g.drawString("Type:                 Virtual", 20, 350);
      }

      height_image /= 10;

      if (height_image > 9999 || height_image < -9999)
        Optics.lbl_heightImage.setText("<html>h<sub>i</sub>= N/A</html>");
      else Optics.lbl_heightImage.setText("<html>h<sub>i</sub>= " + height_image + "</html>");

      distance_image = x_pointOfIntersection - 350;
      distance_image /= 10;
      if (distance_image > 9999 || distance_image < -9999)
        Optics.lbl_distanceImage.setText("<html>d<sub>i</sub>= N/A</html>");
      else Optics.lbl_distanceImage.setText("<html>d<sub>i</sub>= " + distance_image + "</html>");
    } else // Else: mirrors
    {

      if (type == 0) // If converging
      {
        // draws converging mirror
        g.drawArc(
            500 - 2 * radiusOfCurvature,
            200 - radiusOfCurvature,
            2 * radiusOfCurvature,
            2 * radiusOfCurvature,
            60,
            -120);
        // draws horizontal line from the tip of the arrow to the lens (line 1/4)
        g.setColor(Color.RED);
        x_arcIntersection_1 =
            (int)
                ((Math.sqrt(Math.abs(Math.pow(radiusOfCurvature, 2) - Math.pow(arrow_y2 - 200, 2))))
                    + (500 - radiusOfCurvature));
        g.drawLine(arrow_x, arrow_y2, x_arcIntersection_1, arrow_y2);

        // line 2/4
        dy_1 = arrow_y2 - 200;
        dx_1 = x_arcIntersection_1 - (500 - focalLength * 10);
        slope_1 = dy_1 / dx_1;
        y_intercept_1 = 200 - slope_1 * (500 - focalLength * 10);

        // Calculates coordinates of points on the edge of screen (endpoints)
        y_screenIntersection_1 = (int) (Math.round(y_intercept_1));
        if (slope_1 != 0)
          if (arrow_y2 <= 200)
            x_screenIntersection_1 = (int) (Math.round((400 - y_intercept_1) / slope_1));
          else x_screenIntersection_1 = (int) (Math.round(-y_intercept_1 / slope_1));
        if (x_screenIntersection_1 >= 0
            && x_screenIntersection_1 <= 700) // If endpoint is on the x-edge
        if (arrow_y2 <= 200) g.drawLine(x_arcIntersection_1, arrow_y2, x_screenIntersection_1, 400);
          else g.drawLine(x_arcIntersection_1, arrow_y2, x_screenIntersection_1, 0);
        else
          g.drawLine(
              x_arcIntersection_1,
              arrow_y2,
              0,
              y_screenIntersection_1); // Else: endpoint is on the y-edge
        // line 3/4
        if (!(arrow_x > 495 - focalLength * 10 && arrow_x < 505 - focalLength * 10)) {
          dy_2 = 200 - arrow_y2;
          dx_2 = (500 - 10 * focalLength) - arrow_x;
          slope_2 = dy_2 / dx_2;
          y_intercept_2 = arrow_y2 - slope_2 * arrow_x;
          quadratic_a = (float) (Math.pow(slope_2, 2) + 1);
          quadratic_b =
              (float)
                  (((2 * slope_2 * y_intercept_2)
                      - (400 * slope_2)
                      + ((radiusOfCurvature - 500) * 2)));
          quadratic_c =
              (float)
                  ((Math.pow(y_intercept_2, 2)
                      - Math.pow(radiusOfCurvature, 2)
                      - (400 * y_intercept_2)
                      + 40000
                      + Math.pow((radiusOfCurvature - 500), 2)));
          discriminant = (float) (Math.pow(quadratic_b, 2) - (4 * quadratic_a * quadratic_c));
          if (discriminant >= 0)
            x_arcIntersection_2 =
                (int)
                    (Math.max(
                        ((-quadratic_b + Math.sqrt(discriminant)) / (2 * quadratic_a)),
                        ((-quadratic_b - Math.sqrt(discriminant)) / (2 * quadratic_a))));
          else System.out.println("Error, imaginary root!");
          y_arcIntersection_2 = (int) (slope_2 * x_arcIntersection_2 + y_intercept_2);
          g.drawLine(arrow_x, arrow_y2, x_arcIntersection_2, y_arcIntersection_2);
          // System.out.println ("slope: " + slope_2 + "\n yintercept: " + y_intercept_2 + "\n
          // quadratic-a: " + quadratic_a + "\n quadratic-b: " + quadratic_b + "\n quadratic_c: " +
          // quadratic_c + "\n discriminant: " + discriminant + "\n xarcintersection2: " +
          // x_arcIntersection_2 + "\n yarcintersection2: " + y_arcIntersection_2);
          // line 4/4
          g.drawLine(x_arcIntersection_2, y_arcIntersection_2, 0, y_arcIntersection_2);

          // POI between line 2 and line 4
          x_pointOfIntersection = (int) ((y_arcIntersection_2 - y_intercept_1) / slope_1);
          y_pointOfIntersection = y_arcIntersection_2;
          g.setColor(Color.ORANGE);
          g.drawLine(x_pointOfIntersection, y_pointOfIntersection, x_pointOfIntersection, 200);

          if (y_pointOfIntersection < 200) {
            g.drawLine(
                x_pointOfIntersection,
                y_pointOfIntersection,
                x_pointOfIntersection - 7,
                y_pointOfIntersection + 7);
            g.drawLine(
                x_pointOfIntersection,
                y_pointOfIntersection,
                x_pointOfIntersection + 7,
                y_pointOfIntersection + 7);
          } else {
            g.drawLine(
                x_pointOfIntersection,
                y_pointOfIntersection,
                x_pointOfIntersection - 7,
                y_pointOfIntersection - 7);
            g.drawLine(
                x_pointOfIntersection,
                y_pointOfIntersection,
                x_pointOfIntersection + 7,
                y_pointOfIntersection - 7);
          }
          // Same side image line continuation
          if (arrow_x > 500 - 10 * focalLength) {
            g.setColor(Color.YELLOW);
            g.drawLine(x_pointOfIntersection, y_pointOfIntersection, x_arcIntersection_1, arrow_y2);
            g.drawLine(
                x_pointOfIntersection,
                y_pointOfIntersection,
                x_arcIntersection_2,
                y_arcIntersection_2);
          }
        }
      } else // Diverging
      {
        // draws converging mirror
        g.drawArc(
            350, 200 - radiusOfCurvature, 2 * radiusOfCurvature, 2 * radiusOfCurvature, 120, 120);
        // draws horizontal line from the tip of the arrow to the lens (line 1/4)
        g.setColor(Color.RED);
        x_arcIntersection_1 =
            (int)
                (-(Math.sqrt(Math.pow(radiusOfCurvature, 2) - Math.pow(arrow_y2 - 200, 2)))
                    + (350 + radiusOfCurvature));
        g.drawLine(arrow_x, arrow_y2, x_arcIntersection_1, arrow_y2);

        // line 2/4
        dy_1 = arrow_y2 - 200;
        dx_1 = x_arcIntersection_1 - (350 + focalLength * 10);
        slope_1 = dy_1 / dx_1;
        y_intercept_1 = 200 - slope_1 * (350 + focalLength * 10);

        // Calculates coordinates of points on the edge of screen (endpoints)
        y_screenIntersection_1 = (int) (Math.round(y_intercept_1));
        if (slope_1 != 0)
          if (arrow_y2 <= 200)
            x_screenIntersection_1 = (int) (Math.round(-y_intercept_1 / slope_1));
          else if (arrow_y2 > 200)
            x_screenIntersection_1 = (int) (Math.round(400 - y_intercept_1 / slope_1));
        if (x_screenIntersection_1 >= 0
            && x_screenIntersection_1 <= 700) // If endpoint is on the x-edge
        if (arrow_y2 <= 200) g.drawLine(x_arcIntersection_1, arrow_y2, x_screenIntersection_1, 0);
          else g.drawLine(x_arcIntersection_1, arrow_y2, x_screenIntersection_1, 400);
        else
          g.drawLine(
              x_arcIntersection_1,
              arrow_y2,
              0,
              y_screenIntersection_1); // Else: endpoint is on the y-edge
        // line 3/4

        dy_2 = 200 - arrow_y2;
        dx_2 = (350 + 10 * focalLength) - arrow_x;
        slope_2 = dy_2 / dx_2;
        y_intercept_2 = arrow_y2 - slope_2 * arrow_x;
        quadratic_a = (float) (Math.pow(slope_2, 2) + 1);
        quadratic_b =
            (float)
                ((2 * slope_2 * y_intercept_2) - (400 * slope_2) - (2 * radiusOfCurvature + 700));
        quadratic_c =
            (float)
                ((Math.pow(y_intercept_2, 2)
                    - Math.pow(radiusOfCurvature, 2)
                    - (400 * y_intercept_2)
                    + 40000
                    + Math.pow((radiusOfCurvature + 350), 2)));
        discriminant = (float) (Math.pow(quadratic_b, 2) - (4 * quadratic_a * quadratic_c));
        if (discriminant >= 0)
          x_arcIntersection_2 =
              (int)
                  (Math.min(
                      ((-quadratic_b + Math.sqrt(discriminant)) / (2 * quadratic_a)),
                      ((-quadratic_b - Math.sqrt(discriminant)) / (2 * quadratic_a))));
        else System.out.println("Error, imaginary root!");
        y_arcIntersection_2 = (int) (slope_2 * x_arcIntersection_2 + y_intercept_2);
        g.drawLine(arrow_x, arrow_y2, x_arcIntersection_2, y_arcIntersection_2);
        // System.out.println ("slope: " + slope_2 + "\n yintercept: " + y_intercept_2 + "\n
        // quadratic-a: " + quadratic_a + "\n quadratic-b: " + quadratic_b + "\n quadratic_c: " +
        // quadratic_c + "\n discriminant: " + discriminant + "\n xarcintersection2: " +
        // x_arcIntersection_2 + "\n yarcintersection2: " + y_arcIntersection_2);
        // line 4/4
        g.drawLine(x_arcIntersection_2, y_arcIntersection_2, 0, y_arcIntersection_2);

        // POI between line 2 and line 4
        x_pointOfIntersection = (int) ((y_arcIntersection_2 - y_intercept_1) / slope_1);
        y_pointOfIntersection = y_arcIntersection_2;
        g.setColor(Color.ORANGE);
        g.drawLine(x_pointOfIntersection, y_pointOfIntersection, x_pointOfIntersection, 200);

        if (y_pointOfIntersection < 200) {
          g.drawLine(
              x_pointOfIntersection,
              y_pointOfIntersection,
              x_pointOfIntersection - 7,
              y_pointOfIntersection + 7);
          g.drawLine(
              x_pointOfIntersection,
              y_pointOfIntersection,
              x_pointOfIntersection + 7,
              y_pointOfIntersection + 7);
        } else {
          g.drawLine(
              x_pointOfIntersection,
              y_pointOfIntersection,
              x_pointOfIntersection - 7,
              y_pointOfIntersection - 7);
          g.drawLine(
              x_pointOfIntersection,
              y_pointOfIntersection,
              x_pointOfIntersection + 7,
              y_pointOfIntersection - 7);
        }
        // Same side image line continuation
        g.setColor(Color.YELLOW);
        g.drawLine(x_pointOfIntersection, y_pointOfIntersection, x_arcIntersection_1, arrow_y2);
        g.drawLine(
            x_pointOfIntersection, y_pointOfIntersection, x_arcIntersection_2, y_arcIntersection_2);
      }

      // Mag calculations
      height_image = 200 - y_pointOfIntersection;
      height_object = 200 - arrow_y2;
      if (height_object != 0) magnification = height_image / height_object;

      if (magnification <= 9999 && magnification >= -9999)
        Optics.txt_magnification.setText("" + roundTwoDecimals(magnification));
      else if (magnification > 9999) {
        magnification = Double.POSITIVE_INFINITY;
        Optics.txt_magnification.setText("N/A");
      } else {
        magnification = Double.NEGATIVE_INFINITY;
        Optics.txt_magnification.setText("N/A");
      }
      // Characteristics
      g.setColor(Color.ORANGE);
      g.drawString("Image Characteristics:", 20, 300);
      if (type == 0) {

        if ((Math.abs(magnification) > 1 && Math.abs(magnification) < 9999)
            && arrow_x != 500 - 10 * focalLength) g.drawString("Magnification:  Enlarged", 20, 320);
        else if ((int) (Math.abs(magnification)) == 1)
          g.drawString("Magnification:  None", 20, 320);
        else if (Math.abs(magnification) < 1 && Math.abs(magnification) > 0)
          g.drawString("Magnification:  Diminished", 20, 320);
        else {
          g.drawString("Magnification:  N/A", 20, 320);
          Optics.txt_magnification.setText("N/A");
          Optics.lbl_distanceImage.setText("<html>d<sub>i</sub>= N/A</html>");
          Optics.lbl_heightImage.setText("<html>h<sub>i</sub>= N/A</html>");
        }
        if (arrow_x == 500 - 10 * focalLength) g.drawString("Orientation:      N/A", 20, 335);
        else if ((arrow_y2 < 200 && y_pointOfIntersection < 200)
            || (arrow_y2 > 200 && y_pointOfIntersection > 200))
          g.drawString("Orientation:      Upright", 20, 335);
        else g.drawString("Orientation:      Inverted", 20, 335);
        if (arrow_x == 500 - 10 * focalLength) g.drawString("Type:                 N/A", 20, 350);
        else if (x_pointOfIntersection < 500 && arrow_x < 500)
          g.drawString("Type:                 Real", 20, 350);
        else if (x_pointOfIntersection > 500 && arrow_x < 500)
          g.drawString("Type:                 Virtual", 20, 350);
      } else {
        g.drawString("Magnification:  Diminished", 20, 320);
        g.drawString("Orientation:      Upright", 20, 335);
        g.drawString("Type:                 Virtual", 20, 350);
      }

      height_image /= 10;

      if (height_image > 9999 || height_image < -9999 || arrow_x == 500 - 10 * focalLength)
        Optics.lbl_heightImage.setText("<html>h<sub>i</sub>= N/A</html>");
      else Optics.lbl_heightImage.setText("<html>h<sub>i</sub>= " + height_image + "</html>");
      if (type == 0) distance_image = x_pointOfIntersection - 500;
      else distance_image = x_pointOfIntersection - 350;
      distance_image /= 10;
      if (distance_image > 9999 || distance_image < -9999 || arrow_x == 500 - 10 * focalLength)
        Optics.lbl_distanceImage.setText("<html>d<sub>i</sub>= N/A</html>");
      else Optics.lbl_distanceImage.setText("<html>d<sub>i</sub>= " + distance_image + "</html>");
    }
  }