Why is the integer comparision giving the wrong results? [duplicate] - java

In Java, what happens when you increment an int (or byte/short/long) beyond it's max value? Does it wrap around to the max negative value?
Does AtomicInteger.getAndIncrement() also behave in the same manner?

From the Java Language Specification section on integer operations:
The built-in integer operators do not
indicate overflow or underflow in any
way.
The results are specified by the language and independent of the JVM version: Integer.MAX_VALUE + 1 == Integer.MIN_VALUE and Integer.MIN_VALUE - 1 == Integer.MAX_VALUE. The same goes for the other integer types.
The atomic integer objects (AtomicInteger, AtomicLong, etc.) use the normal integer operators internally, so getAndDecrement(), etc. behave this way as well.

If you do something like this:
int x = 2147483647;
x++;
If you now print out x, it will have the value -2147483648.

As jterrace says, the Java run-time will "wrap' the result to the Integer.MIN_VALUE of -2147483648.
But that is Mathematically incorrect!
The correct Mathematically answer is 2147483648.
But an 'int' can't have a value of 2147483648.
The 'int' boundaries are -2147483648 to 2147483647
So why doesn't Java throw an exception?
Good question! An Array object would.
But language authors know the scope of their primitive types, so they use the 'wrapping' technique to avoid a costly exception.
You, as a developer, must test for these type boundaries.
A simple test for incrementing would be
if(x++ == Integer.MIN_VALUE)
//boundary exceeded
A simple test for decrementing would be
if(x-- == Integer.MAX_VALUE)
//boundary exceeded
A complete test for both would be
if(x++ == Integer.MIN_VALUE || x-- == Integer.MAX_VALUE)
//boundary exceeded

What happens is an extra bit is added to the furthest right bit and the order decrements as a negatively signed int ... Notice what happens after 'int_32';
int _0 = 0b0000000000000000000000000000000;
int _1 = 0b0000000000000000000000000000001;
int _2 = 0b0000000000000000000000000000010;
int _3 = 0b0000000000000000000000000000100;
int _4 = 0b0000000000000000000000000001000;
int _5 = 0b0000000000000000000000000010000;
int _6 = 0b0000000000000000000000000100000;
int _7 = 0b0000000000000000000000001000000;
int _8 = 0b0000000000000000000000010000000;
int _9 = 0b0000000000000000000000100000000;
int _10 = 0b0000000000000000000001000000000;
int _11 = 0b0000000000000000000010000000000;
int _12 = 0b0000000000000000000100000000000;
int _13 = 0b0000000000000000001000000000000;
int _14 = 0b0000000000000000010000000000000;
int _15 = 0b0000000000000000100000000000000;
int _16 = 0b0000000000000001000000000000000;
int _17 = 0b0000000000000010000000000000000;
int _18 = 0b0000000000000100000000000000000;
int _19 = 0b0000000000001000000000000000000;
int _20 = 0b0000000000010000000000000000000;
int _21 = 0b0000000000100000000000000000000;
int _22 = 0b0000000001000000000000000000000;
int _23 = 0b0000000010000000000000000000000;
int _24 = 0b0000000100000000000000000000000;
int _25 = 0b0000001000000000000000000000000;
int _26 = 0b0000010000000000000000000000000;
int _27 = 0b0000100000000000000000000000000;
int _28 = 0b0001000000000000000000000000000;
int _29 = 0b0010000000000000000000000000000;
int _30 = 0b0100000000000000000000000000000;
int _31 = 0b1000000000000000000000000000000;
int _32 = 0b1111111111111111111111111111111;
int _XX = 0b10000000000000000000000000000000; // numeric overflow.
int _33 = 0b10000000000000000000000000000001;
int _34 = 0b11000000000000000000000000000000;
int _35 = 0b11100000000000000000000000000000;
int _36 = 0b11110000000000000000000000000000;
int _37 = 0b11111000000000000000000000000000;
int _38 = 0b11111100000000000000000000000000;
int _39 = 0b11111110000000000000000000000000;
int _40 = 0b11111111000000000000000000000000;
int _41 = 0b11111111100000000000000000000000;
int _42 = 0b11111111110000000000000000000000;
int _43 = 0b11111111111000000000000000000000;
int _44 = 0b11111111111100000000000000000000;
int _45 = 0b11111111111110000000000000000000;
int _46 = 0b11111111111111000000000000000000;
int _47 = 0b11111111111111100000000000000000;
int _48 = 0b11111111111111110000000000000000;
int _49 = 0b11111111111111111000000000000000;
int _50 = 0b11111111111111111100000000000000;
int _51 = 0b11111111111111111110000000000000;
int _52 = 0b11111111111111111111000000000000;
int _53 = 0b11111111111111111111100000000000;
int _54 = 0b11111111111111111111110000000000;
int _55 = 0b11111111111111111111111000000000;
int _56 = 0b11111111111111111111111100000000;
int _57 = 0b11111111111111111111111110000000;
int _58 = 0b11111111111111111111111111000000;
int _59 = 0b11111111111111111111111111100000;
int _60 = 0b11111111111111111111111111110000;
int _61 = 0b11111111111111111111111111111000;
int _62 = 0b11111111111111111111111111111100;
int _63 = 0b11111111111111111111111111111110;
int _64 = 0b11111111111111111111111111111111;
System.out.println( " _0 = " + _0 );
System.out.println( " _1 = " + _1 );
System.out.println( " _2 = " + _2 );
System.out.println( " _3 = " + _3 );
System.out.println( " _4 = " + _4 );
System.out.println( " _5 = " + _5 );
System.out.println( " _6 = " + _6 );
System.out.println( " _7 = " + _7 );
System.out.println( " _8 = " + _8 );
System.out.println( " _9 = " + _9 );
System.out.println( " _10 = " + _10 );
System.out.println( " _11 = " + _11 );
System.out.println( " _12 = " + _12 );
System.out.println( " _13 = " + _13 );
System.out.println( " _14 = " + _14 );
System.out.println( " _15 = " + _15 );
System.out.println( " _16 = " + _16 );
System.out.println( " _17 = " + _17 );
System.out.println( " _18 = " + _18 );
System.out.println( " _19 = " + _19 );
System.out.println( " _20 = " + _20 );
System.out.println( " _21 = " + _21 );
System.out.println( " _22 = " + _22 );
System.out.println( " _23 = " + _23 );
System.out.println( " _24 = " + _24 );
System.out.println( " _25 = " + _25 );
System.out.println( " _26 = " + _26 );
System.out.println( " _27 = " + _27 );
System.out.println( " _28 = " + _28 );
System.out.println( " _29 = " + _29 );
System.out.println( " _30 = " + _30 );
System.out.println( " _31 = " + _31 );
System.out.println( " _32 = " + _32 );
System.out.println( " _xx = " + _xx ); // -2147483648
System.out.println( " _33 = " + _33 );
System.out.println( " _34 = " + _34 );
System.out.println( " _35 = " + _35 );
System.out.println( " _36 = " + _36 );
System.out.println( " _37 = " + _37 );
System.out.println( " _38 = " + _38 );
System.out.println( " _39 = " + _39 );
System.out.println( " _40 = " + _40 );
System.out.println( " _41 = " + _41 );
System.out.println( " _42 = " + _42 );
System.out.println( " _43 = " + _43 );
System.out.println( " _44 = " + _44 );
System.out.println( " _45 = " + _45 );
System.out.println( " _46 = " + _46 );
System.out.println( " _47 = " + _47 );
System.out.println( " _48 = " + _48 );
System.out.println( " _49 = " + _49 );
System.out.println( " _50 = " + _50 );
System.out.println( " _51 = " + _51 );
System.out.println( " _52 = " + _52 );
System.out.println( " _53 = " + _53 );
System.out.println( " _54 = " + _54 );
System.out.println( " _55 = " + _55 );
System.out.println( " _56 = " + _56 );
System.out.println( " _57 = " + _57 );
System.out.println( " _58 = " + _58 );
System.out.println( " _59 = " + _59 );
System.out.println( " _60 = " + _60 );
System.out.println( " _61 = " + _61 );
System.out.println( " _62 = " + _62 );
System.out.println( " _63 = " + _63 );
System.out.println( " _64 = " + _64 );

If an integer addition overflows, then
the result is the low-order bits of
the mathematical sum as represented in
some sufficiently large
two's-complement format. If overflow
occurs, then the sign of the result is
not the same as the sign of the
mathematical sum of the two operand
values.
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#13510

This is a workaround answer so you can still continue to basically infinite.
I recommend a if(int > nearmax) then pass to new int
Example:
int x = 2000000000;
x++;
int stacker = 0;
if (x > 2000000000)
{
int temp = x;
x = temp - 2000000000
stacker++;
}
then you can unstack when necessary too...
say x = 0
x--;
if (x < 0 && stacker > 0)
{
int temp = x;
x = 2000000000 + temp;//plus because it's negative
stacker--;
}
this gives 2000000000 x 2000000000 and i mean...you could keep doing this so...ya...
of course you could go even further if you want to use negative numbers...

I'm aware that this is a bit of a necropost, but I came across this and I thought I should share what I've done on my end to anyone who wants the "solved" or my attempt at a solve
package main;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Adder {
public static final int DIGITS = 25;
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("/Users/swapnil/IdeaProjects/Sum/src/Sum.txt"));
analyze(input);
}
public static void analyze(Scanner input) {
int lines = 0;
while (input.hasNextLine()) {
String line = input.nextLine();
Scanner tokens = new Scanner(line);
int[] operand = new int[DIGITS];
initAdd(tokens, operand);
while (tokens.hasNext()) {
contAdd(tokens, operand);
}
System.out.print(" = ");
printAsNumber(operand);
System.out.println();
lines++;
}
System.out.println();
System.out.println("Total lines = " + lines);
}
public static int[] getNextOperand(Scanner tokens) {
String number = tokens.next();
int lastDigitIndex = DIGITS - number.length();
int[] nextOp = new int[DIGITS];
for (int i = lastDigitIndex; i < DIGITS; i++) {
nextOp[i] = Character.getNumericValue(number.charAt(i - lastDigitIndex));
}
return nextOp;
}
public static void addColumns(Scanner tokens, int operand[], int nextOp[]) {
for (int i = DIGITS - 1; i >= 0; i--) {
operand[i] += nextOp[i];
if (operand[i] > 9) {
int currentDigit = operand[i] % 10;
operand[i] = currentDigit;
operand[i - 1]++;
}
}
}
public static void initAdd(Scanner tokens, int operand[]) {
int[] nextOp = getNextOperand(tokens);
printAsNumber(nextOp);
addColumns(tokens, operand, nextOp);
}
public static void contAdd(Scanner tokens, int operand[]) {
int[] nextOp = getNextOperand(tokens);
System.out.print(" + ");
printAsNumber(nextOp);
addColumns(tokens, operand, nextOp);
}
public static void printAsNumber(int number[]) {
int lastDigitIndex = DIGITS - 1;
for (int i = 0; i < DIGITS; i++) {
if (number[i] != 0) {
lastDigitIndex = i;
break;
}
}
for (int i = lastDigitIndex; i < DIGITS; i++) {
System.out.print(number[i]);
}
}
}

Related

Connecting a Driver File to its Corresponding File and Using Methods within that file that connect to the Driver File

This project has had me stuck for 3 days now and I am needing personal help. To give some background, I am very much the epitome of a beginner so try to explain it to me in the simplest way possible. Below is the driver file and the UML Diagram of methods I am supposed to use within the other file that connects to the driver. It is a simple calculator project, and help is much appreciated =). The param and return methods I don't need to know so don't feel the need to explain those. Really I just need to know how to set up my file to work with this driver and use the methods in the UML diagram. I hope this provides all the information needed to give a good answer.
import java.util.Scanner;
public class DriverMyCalculator{
static Scanner keyboard = null;
public static void main(String[] args) {
int num1, num2;
int max, min;
keyboard = new Scanner(System.in);
System.out.println("Plesae Enter an integer: ");
num1 = readInt();
System.out.println("Please enter another integer: ");
num2 = readInt();
min = MyCalculator.getMin(num1, num2);
max = MyCalculator.getMax(num1, num2);
System.out.println("min = " + min);
System.out.println("max = " + max);
MyCalculator.displayRange(min, max);
MyCalculator.displayAllEven(min, max);
MyCalculator.displayAllOdd(min, max);
MyCalculator.display5Multiples(min, max);
System.out.println("rangeSum = " + MyCalculator.rangeSum(min, max) );
System.out.println("rangeAvg = " + MyCalculator.rangeAvg(min, max) );
System.out.println("rangeProduct = " + MyCalculator.rangeProduct(min, max) );
System.out.println("rangePower = " + MyCalculator.power(min, max) );
System.out.println();
System.out.println(min + " isPrime = " + MyCalculator.isPrime(min) );
System.out.println(min + " smallestFactor = " + MyCalculator.smallestFactor(min) );
System.out.println(min + " factorial = " + MyCalculator.factorial(min) );
System.out.println();
System.out.println(max + " isPrime = " + MyCalculator.isPrime(max) );
System.out.println(max + " smallestFactor = " + MyCalculator.smallestFactor(max) );
System.out.println(max + " factorial = " + MyCalculator.factorial(max) );
} // end main
/**
* Do NOT change! Thank you!
*
* #return int
*/
public static int readInt(){
String temp = "";
int number = -999;
temp = keyboard.nextLine();
try {
number = Integer.parseInt(temp);
}catch(NumberFormatException e) {
System.out.println("ERROR: " + e.getMessage());
}
return number;
} // end method
} // end class
UML Diagram

logic error? diving 2 int that result in a float

I am writing a combat simulator. My attacker class initiates an attack and my defender class is supposed to block it. manager is my main class that computes and prints the results. My problem is with my highRatio, mediumRatio and lowRatio variables. If they are not equal to 1 all of them are set to zero. Any ideas as to what may be going?
//defender class
public int defenseSelector(int highAtkCounter, int mediumAtkCounter, int lowAtkCounter, int rounds, int roundCounter)
{
Random defenseTypeGenerator;
int defense = 0;
float highRatio;
float mediumRatio;
float lowRatio;
defenseTypeGenerator = new Random();
int defenseType = defenseTypeGenerator.nextInt(MAX_ROUNDS) + 1;
highRatio = highAtkCounter/roundCounter;
mediumRatio = mediumAtkCounter/roundCounter;
lowRatio = lowAtkCounter/roundCounter;
if(roundCounter > 3 && roundCounter <= rounds) //AI portion
{
if (highRatio > mediumRatio && highRatio > lowRatio)
{
defense = HIGH;
}
else if (mediumRatio > highRatio && mediumRatio > lowRatio)
{
defense = MEDIUM;
}
else if (lowRatio > highRatio && lowRatio > mediumRatio)
{
defense = LOW;
}
else
{
System.out.println("AI ERROR ratios " + highRatio + " " + mediumRatio + " " + lowRatio);
System.out.println("AI ERROR atkCounters " + highAtkCounter + " " + mediumAtkCounter + " " + lowAtkCounter);
System.out.println("AI ERROR rCounters " + roundCounter);
//manager class
while(roundCounter <= rounds)
{
int attack = theAttacker.attackSelector(high, medium, low);
int highAtkTracker = theAttacker.countHighAtks(attack);
System.out.println("DEBUG " + attack);
System.out.println("DEBUG " + highAtkTracker);
int mediumAtkTracker = theAttacker.countMediumAtks(attack);
System.out.println("DEBUG " + attack);
System.out.println("DEBUG " + mediumAtkTracker);
int lowAtkTracker = theAttacker.countLowAtks(attack);
System.out.println("DEBUG " + attack);
System.out.println("DEBUG " + lowAtkTracker);
highAtkCounter = highAtkCounter + highAtkTracker;
mediumAtkCounter = mediumAtkCounter + mediumAtkTracker;
lowAtkCounter = lowAtkCounter + lowAtkTracker;
int defense = theDefender.defenseSelector(highAtkCounter, mediumAtkCounter, lowAtkCounter, rounds, roundCounter);
In java any arithmetic operation with an integer results in an integer.
Therefore you must cast the integer into the floating point type explicitly:
highAtkCounter = highAtkCounter + (float)highAtkTracker;
mediumAtkCounter = mediumAtkCounter + (float)mediumAtkTracker;
lowAtkCounter = lowAtkCounter + (float)lowAtkTracker;

I can't get the right answer to Project Euler Q8 with Java

There are 2 answers. The first answer is for 4 consecutive numbers and the answer is provided: 5832. The 2nd answer is for 13 consecutive numbers and it's the answer they want me to input. This answer is: 23514624000.
My answer for the 1st questions is: 29760696 which is impossible and way off
public class test {
public static void main(String[] args)
{
String big = "73167176531330624919225119674426574742355349194934"
+ "96983520312774506326239578318016984801869478851843"
+ "85861560789112949495459501737958331952853208805511"
+ "12540698747158523863050715693290963295227443043557"
+ "66896648950445244523161731856403098711121722383113"
+ "62229893423380308135336276614282806444486645238749"
+ "30358907296290491560440772390713810515859307960866"
+ "70172427121883998797908792274921901699720888093776"
+ "65727333001053367881220235421809751254540594752243"
+ "52584907711670556013604839586446706324415722155397"
+ "53697817977846174064955149290862569321978468622482"
+ "83972241375657056057490261407972968652414535100474"
+ "82166370484403199890008895243450658541227588666881"
+ "16427171479924442928230863465674813919123162824586"
+ "17866458359124566529476545682848912883142607690042"
+ "24219022671055626321111109370544217506941658960408"
+ "07198403850962455444362981230987879927244284909188"
+ "84580156166097919133875499200524063689912560717606"
+ "05886116467109405077541002256983155200055935729725"
+ "71636269561882670428252483600823257530420752963450"
;
//System.out.println(big.length());
int product=1;
int newProduct=0;
for(int i=0;i<big.length()-1-4;i++)
{
product=1;
for(int j=i+1;j<i+5;j++)
{
product=(big.charAt(i)-48)*(big.charAt(j)-48)*product;
}
if(product>newProduct)
{
newProduct=product;
}
}
System.out.println(newProduct);
}
My answer for the 2nd question is: 2135048192 and is a lot closer. Why is this the case? My code is as follows. thanks
public class test {
public static void main(String[] args)
{
String big = "73167176531330624919225119674426574742355349194934"
+ "96983520312774506326239578318016984801869478851843"
+ "85861560789112949495459501737958331952853208805511"
+ "12540698747158523863050715693290963295227443043557"
+ "66896648950445244523161731856403098711121722383113"
+ "62229893423380308135336276614282806444486645238749"
+ "30358907296290491560440772390713810515859307960866"
+ "70172427121883998797908792274921901699720888093776"
+ "65727333001053367881220235421809751254540594752243"
+ "52584907711670556013604839586446706324415722155397"
+ "53697817977846174064955149290862569321978468622482"
+ "83972241375657056057490261407972968652414535100474"
+ "82166370484403199890008895243450658541227588666881"
+ "16427171479924442928230863465674813919123162824586"
+ "17866458359124566529476545682848912883142607690042"
+ "24219022671055626321111109370544217506941658960408"
+ "07198403850962455444362981230987879927244284909188"
+ "84580156166097919133875499200524063689912560717606"
+ "05886116467109405077541002256983155200055935729725"
+ "71636269561882670428252483600823257530420752963450"
;
//System.out.println(big.length());
int product=1;
int newProduct=0;
for(int i=0;i<big.length()-1-13;i++)
{
product=1;
for(int j=i+1;j<i+14;j++)
{
product=(big.charAt(i)-48)*(big.charAt(j)-48)*product;
}
if(product>newProduct)
{
newProduct=product;
}
}
System.out.println(newProduct);
}
You are experiencing integer overflow (use a long). Character.digit(char,int) (where the second argument is the radix) can get you the int value of a char). Also, you can use Math.max(long, long) to get the maximum of two long(s). Putting that together, it might look something like
long max = 0;
for (int i = 0; i < big.length() - 13; i++) {
String str = big.substring(i, i + 13);
long product = 1;
for (char ch : str.toCharArray()) {
product *= Character.digit(ch, 10);
}
max = Math.max(max, product);
}
System.out.println(max);
And I get (the expected)
23514624000

Java: How can I make this calculus method on limits more efficient?

how can I initialize all of my variables more easier?
is there a calculus package?
is there a more efficient solution overall?
import java.util.Scanner;
public class limits {
public static void main(String[] args)
{
String introMessage = " ***Calculus: Limits***" + "\n"
+ "This application uses the method of exhaustion" + "\n"
+ "to test limits. You enter the number that x" + "\n"
+ "approches and this program will give you three" + "\n"
+ "numbers on either side of the limit showing" + "\n"
+ "closer approximations of the limit.";
System.out.println(introMessage);
System.out.println();
String polynomialMessage = "Our function: " + "\n"
+ " lim f(x) = x^2 + x + 1 = L" + "\n"
+ "x -> a";
System.out.println(polynomialMessage);
System.out.println();
System.out.println("As x approaches a, what will our limit L be?");
System.out.println();
can I initialize all of these at once?
// initialize variables
double belowAOne = 0.0;
double belowATwo = 0.0;
double belowAThree = 0.0;
double belowAFour = 0.0;
double aboveAOne = 0.0;
double aboveATwo = 0.0;
double aboveAThree = 0.0;
double aboveAFour = 0.0;
double totalBAOne = 0.0;
double totalBATwo = 0.0;
double totalBAThree = 0.0;
double totalBAFour = 0.0;
double totalAAOne = 0.0;
double totalAATwo = 0.0;
double totalAAThree = 0.0;
double totalAAFour = 0.0;
double L = 0;
// create a Scanner object named sc
Scanner sc = new Scanner(System.in);
// perform invoice calculations until choice isn't equal to "y" or "Y"
String choice = "y";
while (!choice.equalsIgnoreCase("n"))
{
System.out.println("Please enter a whole number between 1 and 10 for a: ");
double a = sc.nextDouble();
if (a > 0 && a <=10 )
{
// calculate L
L = (a*a) + a + 1;
// create values that approaches a
belowAOne = a - .5;
belowATwo = a - .1;
belowAThree = a - .01;
belowAFour = a - .001;
aboveAOne = a + .5;
aboveATwo = a + .1;
aboveAThree = a + .01;
aboveAFour = a + .001;
totalBAOne = (belowAOne * belowAOne) + belowAOne + 1;
totalBATwo = (belowATwo * belowATwo) + belowATwo + 1;
totalBAThree = (belowAThree * belowAThree) + belowAThree + 1;
totalBAFour = (belowAFour * belowAFour) + belowAFour + 1;
totalAAOne = (aboveAOne * aboveAOne) + aboveAOne + 1;
totalAATwo = (aboveATwo * aboveATwo) + aboveATwo + 1;
totalAAThree = (aboveAThree * aboveAThree) + aboveAThree + 1;
totalAAFour = (aboveAFour * aboveAFour) + aboveAFour + 1;
String chart = " x " + "x^2 + x + 1" + "\n"
+ "---------+--------------" + "\n"
+ " " + belowAOne + " : " + totalBAOne + "\n"
+ " " + belowATwo + " : " + totalBATwo + "\n"
+ " " + belowAThree + " : " + totalBAThree + "\n"
+ " " + belowAFour + " : " + totalBAFour + "\n"
+ " " + " a " + " : " + "L" + "\n"
+ " " + aboveAFour + " : " + totalAAFour + "\n"
+ " " + aboveAThree + " : " + totalAAThree + "\n"
+ " " + aboveATwo + " : " + totalAATwo + "\n"
+ " " + aboveAOne + " : " + totalAAOne + "\n";
System.out.println();
System.out.println();
System.out.println();
System.out.println(chart);
System.out.println();
System.out.println("As X approaches " + a + ", our guess "
+ "for L is: " + L);
System.out.println();
// end the program
choice = "n";
}
else
{
System.out.println();
System.out.println("***Invalid Entry***");
System.out.println();
}
}
}
}
Is there a better way to write this program?
or you could use a loop instead like this:
double[] belowA = {a - .5, a - .1, a - .01, a - .001};
double[] totalBA = new double[4];
for(int i = 0; i < 4; ++i) {
totalBA[i] = (belowA[i] * belowA[i]) + belowA[i] + 1;
}
also with a StringBuilder / StringBuffer
and finally you could create a method to handle below/above in the same way without duplicated code

Longest monotonic subsequence algorithm NOT longest increasing algorithm

I have some numbers at the input:
1 1 7 3 2 0 0 4 5 5 6 2 1
And I look for a longest monotonic subsequence and what is the sum of this subsequence. The result is:
6 20
I cannot find the algorithm at the internet. Do you own/found one? This is about longest monotonic not longest increasing subsequence.
Definition of monotonic: http://en.wikipedia.org/wiki/Monotonic_function
I know that someone will ask: What have you tried? So i tried writing it(please don't check it I only post it so no one asks that question above I look for different algorithm->optimal one)
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Rozwiazanie {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//2^63 > 10^16 = 10^7 * 10^9 longi starcza
//10^9 inty starcza
//int 32 bity, long 64 bity
long podsuma = 0;
int dlugosc = 0;
int maxDlugosc = 0;
long maxPodsuma = 0;
int poczatekRownych = 0;
int poprzedniWyraz = 0, aktualnyWyraz;//uwaga jakby cos nie gralo w sprawdzarce zmien typ na long
boolean czyRosnacy = false, rowny = false;
String[] splittedLinia = br.readLine().split((char) 32 + "");//moglaby byc " " ale tak na wszelki wypadek nie ma chuja zeby sie popierdolilo teraz nawet na linuxie
for (int i = 0; i < splittedLinia.length; i++) {
if (i == 0) {
aktualnyWyraz = Integer.parseInt(splittedLinia[0]);
maxDlugosc = dlugosc = 1;
maxPodsuma = podsuma = aktualnyWyraz;
if (splittedLinia.length > 1) {
int nastepnyWyraz = Integer.parseInt(splittedLinia[1]);
czyRosnacy = nastepnyWyraz > aktualnyWyraz;
rowny = nastepnyWyraz == aktualnyWyraz;
}
System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 1);
} else {
aktualnyWyraz = Integer.parseInt(splittedLinia[i]);
System.out.println(rowny);
if (aktualnyWyraz == poprzedniWyraz && rowny) {
podsuma += aktualnyWyraz;
dlugosc++;
System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 2);
} else if (rowny) {
rowny = false;
czyRosnacy = aktualnyWyraz > poprzedniWyraz;
System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 3);
}
if (!rowny) {
if (aktualnyWyraz >= poprzedniWyraz && czyRosnacy) {
podsuma += aktualnyWyraz;
dlugosc++;
System.out.println("akt:" + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 4);
} else if (aktualnyWyraz <= poprzedniWyraz && !czyRosnacy) {
podsuma += aktualnyWyraz;
dlugosc++;
System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 5);
} else {
// if (aktualnyWyraz == poprzedniWyraz) {
rowny = true;
// } else {
if (maxDlugosc < dlugosc) {
maxDlugosc = dlugosc;
maxPodsuma = podsuma;
}
podsuma = poprzedniWyraz + aktualnyWyraz;
dlugosc = 2;
czyRosnacy = aktualnyWyraz > poprzedniWyraz;
rowny = aktualnyWyraz == poprzedniWyraz;
System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 6);
//}
}
}
}
poprzedniWyraz = aktualnyWyraz;
}
System.out.println(maxDlugosc + " " + maxPodsuma);
} catch (Exception e) {
e.printStackTrace();
}
}
}
//65 87 47 5 12 74 25 32 78 44 40 77 85 4 29 57:
try this one:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Rozwiazanie {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] splittedLinia = br.readLine().split((char) 32 + "");//moglaby byc " " ale tak na wszelki wypadek nie ma chuja zeby sie popierdolilo teraz nawet na linuxie
int aktualnyWyraz = Integer.parseInt(splittedLinia[0]);//uwaga jakby cos nie gralo w sprawdzarce zmien typ na long
int poprzedniWyraz = 0;
long podsumaRosnaca = aktualnyWyraz;
long podsumaSpadajaca = aktualnyWyraz;
int dlugoscRosnaca = 1;
int dlugoscSpadajaca = 1;
int maxDlugosc = 1;
long maxPodsuma = aktualnyWyraz;
int czyRosnacy = 0; // 0 -- nie znane (jezeli w poczatku wszystkie liczby sa rowne), 1 -- rosnacy, -1 -- spadajacy
boolean rowny = false;
System.out.println("akt: " + aktualnyWyraz + " dlR: " + dlugoscRosnaca + " podsumaR: " + podsumaRosnaca + " dlP: " + dlugoscSpadajaca + " podsumaP: " + podsumaSpadajaca);
for (int i = 1; i < splittedLinia.length; i++) {
poprzedniWyraz = aktualnyWyraz;
aktualnyWyraz = Integer.parseInt(splittedLinia[i]);
if (aktualnyWyraz == poprzedniWyraz) {
podsumaRosnaca += aktualnyWyraz;
podsumaSpadajaca += aktualnyWyraz;
dlugoscRosnaca++;
dlugoscSpadajaca++;
rowny = true;
} else { // rozne liczby
if (aktualnyWyraz > poprzedniWyraz) { // rosnie
podsumaRosnaca += aktualnyWyraz;
dlugoscRosnaca++;
if (rowny) {
dlugoscSpadajaca = 1;
podsumaSpadajaca = 0;
rowny = false;
}
if (czyRosnacy < 0) {
if (dlugoscSpadajaca > maxDlugosc) {
maxDlugosc = dlugoscSpadajaca;
maxPodsuma = podsumaSpadajaca;
}
podsumaSpadajaca = 0;
dlugoscSpadajaca = 1;
}
czyRosnacy = 1;
} else { // spada
podsumaSpadajaca += aktualnyWyraz;
dlugoscSpadajaca++;
if (rowny) {
dlugoscRosnaca = 1;
podsumaRosnaca = 0;
rowny = false;
}
if (czyRosnacy == 1) {
if (dlugoscRosnaca > maxDlugosc) {
maxDlugosc = dlugoscRosnaca;
maxPodsuma = podsumaRosnaca;
}
podsumaRosnaca = 0;
dlugoscRosnaca = 1;
}
czyRosnacy = -1;
}
}
System.out.println("akt: " + aktualnyWyraz + " dlR: " + dlugoscRosnaca + " podsumaR: " + podsumaRosnaca + " dlP: " + dlugoscSpadajaca + " podsumaP: " + podsumaSpadajaca);
}
System.out.println("maxDlugosc " + maxDlugosc + " maxPodsuma " + maxPodsuma);
} catch (Exception e) {
e.printStackTrace();
}
}
}
what I had to change:
you need a counter [dlugosc] (+ sum [podsuma]) for ascending
[rosnacy] and descending [spadajacy] values, as you need to count
both when the values are the same [rowny].
I changed boolean "rowny"
[equal] to int, as I thought that there are 3 values possible:
ascending, descending or unknown. If there are several equal values
at the beginning, there's all the time "unknown".
this program needs at least one number, but therefore you don't need to check in every
iteration of the loop whether i == 0 or not.
Going through the
numbers, I have to check several things, most important is, whether
the actual value [aktualnyWyraz] and the last used value
[poprzedniWyraz] are the same (then all counters and sums have to be
changed) or different. Different can mean ascending or descending, so
we have to increment the related counters and sum up the related sum.
What happens the "opposite" variables? Well, we need to check whether
the counter is bigger then the maximum one (so maybe these values are
useful for the result) and then set them back to their start.

Categories

Resources