I am trying to add two parts of an array together to go into an int value. I am using Luhn algorithm to figure out of a credit card is a valid credit card. We are only using 6 digit credit card's just to make sure no one enter's a real credit card number. The part I am confused on is when I go to split a number that is above 10 and add it together. Example if the algorithm was to give me 12 I would need to separate it into 1 and 2 and then add them together to equal 3. I believe I am splitting it currently in the code but when I go to add them together I get some number that makes no since. here is a section of the code with some notes about it.
I have printed out numbers in certain places to show myself what is going on in certain places. I have also added in some comments that say that either the number that is printed out is what is expected, and some comments for when there isn't something I expected
int[] cardNumber = new int[]{ 1,2,3,4,5,5};
int doubleVariablesum = 0;
int singleVariablesum = 0;
int totalSum = 0;
int cutOffVar = 0;
String temp2;
for (int i = cardNumber.length - 1; i >= 0;) {
int tempSum = 0;
int temp = cardNumber[i];
temp = temp * 2;
System.out.println("This is the temp at temp * 2: " + temp);
temp2 = Integer.toString(temp);
if (temp2.length() == 1) {
System.out.println("Temp2 char 0: "+ temp2.charAt(0));
// this prints out the correct number
// Example: if there number should be 4 it will print 4
tempSum = temp2.charAt(0);
System.out.println("This is tempSum == 1: " + tempSum);
// when this goes to add temp2.charAt(0) which should be 4 it prints out //something like 56
} else {
System.out.println("TEMP2 char 0 and char 1: " + temp2.charAt(0) + " " + temp2.charAt(1));
// this prints out the correct number successfully spited
tempSum = temp2.charAt(0) + temp2.charAt(1);
System.out.println("This is tempSum != 1: " + tempSum);
// but here it when I try to add them together it is giving me something
// like 97 which doesn't make since for the numbers I am giving it
}
doubleVariablesum = tempSum + doubleVariablesum;
System.out.println("This is the Double variable: " + doubleVariablesum);
System.out.println();
i = i - 2;
}
Since you are converting the number to a string to split the integer, and then trying to add them back together. You're essentially adding the two characters numerical values together which is giving you that odd number. You would need to convert it back to an integer, which you can do by using
Integer.parseInt(String.valueOf(temp2.charAt(0)))
When adding char symbols '0' and '1' their ASCII values are added - not numbers 0 and 1.
It is possible to use method Character::getNumericValue or just subtract '0' when converting digit symbol to int.
However, it is also possible to calculate sum of digits in a 2-digit number without any conversion to String and char manipulation like this:
int sum2digits = sum / 10 + sum % 10; // sum / 10 always returns 1 if sum is a total of 2 digits
Seems like charAt() type casts into integer value, but the ascii one. Hence for the characters '0' and '1', the numbers 48 and 49 are returned resulting in a sum of 97. To fix this, you could just assign temp2 to (temp / 10) + (temp % 10). Which actually splits a two digit integer and adds their sum.
You need to be aware of the following when dealing with char and String
Assigning the result of charAt(index) to an int will assign the ASCII value and not the actual integer value. To get the actual value you need to String.valueOf(temp2.charAt(0)).
The result of concatenating chars is the sum of the ASCII values.
eg if char c = '1'; System.out.println(c + c); will print "98" not "11".
However System.out.println("" + c + c); will print "11". Note the "" will force String concatenation.
I was asked below question in an interview:
Every number can be described via the addition and subtraction of powers of 2. For example, 29 = 2^0 + 2^2 + 2^3 + 2^4.
Given an int n, return minimum number of additions
and subtractions of 2^i to get n.
Example 1:
Input: 15
Output: 2
Explanation: 2^4 - 2^0 = 16 - 1 = 15
Example 2:
Input: 8
Output: 1
Example 3:
Input: 0
Output: 0
Below is what I got but is there any way to improve this or is there any better way to solve above problem?
public static int minPowerTwo(int n) {
if (n == 0) {
return 0;
}
if (Integer.bitCount(n) == 1) {
return 1;
}
String binary = Integer.toBinaryString(n);
StringBuilder sb = new StringBuilder();
sb.append(binary.charAt(0));
for (int i = 0; i < binary.length() - 1; i++) {
sb.append('0');
}
int min = Integer.parseInt(sb.toString(), 2);
sb.append('0');
int max = Integer.parseInt(sb.toString(), 2);
return 1 + Math.min(minPowerTwo(n - min), minPowerTwo(max - n));
}
Well... we can deduce that each power of two should be used only once, because otherwise you can get the same result a shorter way, since 2x + 2x = 2x+1, -2x - 2x = -2x+1, and 2x - 2x = 0.
Considering the powers used in order, each one has to change the corresponding bit from an incorrect value to the correct value, because there will be no further opportunities to fix that bit, since each power is used only once.
When you need to add or subtract, the difference is what happens to the higher bits:
000000 000000 111100 111100
+ 100 - 100 + 100 - 100
------ ------ ------ ------
000100 111100 000000 111000
One way, all the higher bits are flipped. The other way they are not.
Since each decision can independently determine the state of all the higher bits, the consequences of choosing between + or - are only relevant in determining the next power of 2.
When you have to choose + or -, one choice will correct 1 bit, but the other choice will correct 2 bits or more, meaning that the next bit that requires correction will be higher.
So, this problem has a very straightforward solution with no dynamic programming or searching or anything like that:
Find the smallest power of 2 that needs correction.
Either add it or subtract it. Pick the option that corrects 2 bits.
Repeat until all the bits are correct
in java, that would look like this. Instead of finding the operations required to make the value, I'll find the operations required to change the value to zero, which is the same thing with opposite signs:
int minPowersToFix(int val) {
int result = 0;
while(val!=0) {
++result;
int firstbit = val&-val; //smallest bit that needs fixed
int pluscase = val+firstbit;
if ((pluscase & (firstbit<<1)) == 0) {
val+=firstbit;
} else {
val-=firstbit;
}
}
return result;
}
And, here is a test case to check whether a solution is correct, written in Java.
(It was written for my solution, which is proven not correct in some case, so I removed that answer, but the test case is still relevant.)
Matt Timmermans's answer passes all the test cases, including negative numbers.
And, Integer.bitCount(val ^ (3 * val)) passes most of them, except when input is Integer.MAX_VALUE.
Code
MinCountOf2PowerTest.java
import org.testng.Assert;
import org.testng.annotations.Test;
public class MinCountOf2PowerTest {
#Test
public void testPositive() {
// no flip,
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("01010001", 2)), 3);
// flip,
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("011", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("0111", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("01111", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.MAX_VALUE), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("01101", 2)), 3);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("011011", 2)), 3);
// flip, there are multiple flippable location,
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("0100000111", 2)), 3);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("010010000000111", 2)), 4);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("0100100000001111111", 2)), 4);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("010011000000001111111", 2)), 5);
}
#Test
public void testZero() {
Assert.assertEquals(MinCountOf2Power.minCount(0), 0);
}
#Test
public void testNegative() {
Assert.assertEquals(MinCountOf2Power.minCount(-1), 1);
Assert.assertEquals(MinCountOf2Power.minCount(-9), 2);
Assert.assertEquals(MinCountOf2Power.minCount(-100), 3);
}
// a positive number has the same result as its negative number,
#Test
public void testPositiveVsNegative() {
for (int i = 1; i <= 1000; i++) {
Assert.assertEquals(MinCountOf2Power.minCount(i), MinCountOf2Power.minCount(-i));
}
Assert.assertEquals(MinCountOf2Power.minCount(Integer.MAX_VALUE), MinCountOf2Power.minCount(-Integer.MAX_VALUE));
}
// corner case - ending 0,
#Test
public void testCornerEnding0() {
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("01110", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("011110", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("011100", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("0111000", 2)), 2);
Assert.assertEquals(MinCountOf2Power.minCount(Integer.parseInt("01110000", 2)), 2);
}
// input from OP's question, refer: https://stackoverflow.com/questions/57797157
#Test
public void testOpInput() {
Assert.assertEquals(MinCountOf2Power.minCount(15), 2);
Assert.assertEquals(MinCountOf2Power.minCount(8), 1);
Assert.assertEquals(MinCountOf2Power.minCount(0), 0);
}
}
Tips:
It's written in Java, and use TestNG.
But you can use JUnit instead simply by replacing the import statement, I guess.
Or translate to other languages by coping the input / output value pairs with specific syntax.
I also found that a positive integer always has the same result as its negative number.
And there is a test case included to proved that.
I wrote this algorithm to solve the problem.
Given N a positive integer:
Find the highest power of 2 A and the lowest power of 2 B, such that A ≤ N ≤ B and A≠B. In other words find in what interval of
consecutive powers of 2 N belongs;
Find if N is closer to A or B, for example by comparing N with the mid value between A and B (It is their average, and since B=2×A the average is 3×A/2 or 1.5×A)
If N is closer to the lower bound (A) than N = A + δ: Append "subtract B" to the explanation message;
If N is closer to the higher bound (B) than N = B - δ: Append "add A" to the explanation message;
Replace N with δ and repeat
The number of iterations minus 1 is the solution you are looking for.
To solve step 1 I wrote this support method that returns the closest power of 2 that is smaller than input, that is A (and we can get B because it is just the double of A)
public int getClosestLowerboundPowerof2 (int n)
{
int i = 1;
while (i<=n/2){
i*=2;
}
return i;
}
The rest is done here:
int operations;
String explanation = "";
if (input>0){
operations = -1;
int n = input, a;
while (n >= 1) {
operations++;
a = getClosestLowerboundPowerof2(n);
if (n > a*1.5) {
explanation += " - "+ a * 2;
n = a * 2 - n;
} else {
explanation += " + " + a;
n -= a;
}
}
System.out.println(input + " = " + explanation.substring(3,explanation.length()) + ", that " + ((operations==1)?"is":"are") + " "+ operations + " operation" + ((operations==1)?"":"s"));
}
else{
System.out.println("Input must be positive");
}
As an example with input = 403 it would print:
403 = 512 - 128 + 16 + 2 + 1, that are 4 operations
Hope I helped!
NOTE: I first misinterpreted the question so I put effort in writing a detailed answer to the wrong problem...
I'm keeping here the original answer because it may be interesting for somebody.
The problem is actually a mathematical argument: how to convert a
number from base 10 to base 2, and they just asked you to implement
an algorithm for that.
Here some theory about this concept and here a method for
reference.
Programmatically I'm interpreting the problem as "Given an integer
print a string of its representation in base 2". For instance given
100 print 2^6 + 2^5 + 2^2. As the linked wiki on radixes explains,
that there is no need for subtractions, so there will only be
additions.
The shortest way to do is to start from n, halve it at each iteration
(i), and write 2^i only if this number (m) is odd. This is tested
with modulo operator (% in java). So the method will be just
this:
public String from10to2(int n){
String str = "";
for (int m = n, i=0; m>=1; m/=2, i++){
str = ((m%2==1)?"+ 2^"+i+" ":"")+str; //"adds '+ 2^i' on top of the string when m is odd, keep str the same otherwise
}
return str.substring(2,str.length()); //debug to remove " + " at the start of the string
}
The content of the for may look inintuitive because I put effort to
make the code as short as possible.
With little effort my method can be generalized to convert a number in
base 10 to any base:
public String baseConverter(int targetBase, int decimalNumber){
String str = "";
for (int m = decimalNumber, i=0; m>=1; m/=targetBase, i++){
str = ((m%targetBase==1)?"+ "+targetBase+"^"+i+" ":"")+str; //"adds '+ x^i' on top of the string when m is odd, keep str the same
otherwise
}
return str.substring(2,str.length()); //debug to remove " + " at the start of the string
}
PS: I didn't use StringBuilder because it's not conceived to append a string on the start. The use of the String concatenation as I
did is argument of debate (someone approve it, other don't).
I guess
For example, 29 = 2^0 + 2^2 + 2^3 + 2^4
is not a correct example in the context of this question. As far as I understand, I should be able to do like
29 = 2^5 - 2^2 + 2^0
Alright, basically this is a math problem. So if math isn't your best suit like me then i would advise you to consider logarithm in the first place whenever you see exponentials in a question. Sometimes it is very useful like in this case since it reduces this problem to a sort of coin change problem with dynamical denominators and also subtraction is allowed.
First I need to find the biggest n that's close to the target.
Lets find the exact n value in 2^n = 29 which is basically log
(2^n) = log 29, which is n log 2 = log 29 so n = log 29 / log
2. Which happens to be 4.857980995127573 and now i know that i
will start with by rounding it to 5.
2^5 is an overshoot. Now i need to reach 32-29 = 3 and also since 32 > 29 the result, 2^2 will be subtracted.
Now we have 2^5 - 2^2 which is 28 and less than 29. Now we need to add the next result and our target is 1.
Ok here is a simple recursive code in JS. I haven't fully tested but seemingly applies the logic just fine.
function pot(t, pr = 0){ // target and previous result
var d = Math.abs(t - pr), // difference
n = Math.round(Math.log(d)/Math.log(2)), // the n figure
cr = t > pr ? pr + 2**n // current result
: pr - 2**n;
return t > cr ? `2^${n} + ` + pot(t, cr) // compose the string result
: t < cr ? `2^${n} - ` + pot(t, cr)
: `2^${n}`;
}
console.log(pot(29));
console.log(pot(1453));
console.log(pot(8565368));
This seems pretty trivial to solve for the cases presented in the examples, like:
0111...1
You can replace any of this pattern with just two powers; i.e.: 7 = 8 - 1 or 15 = 16 - 1 and so on.
You can also deduce that if there are less then 3 consecutive ones, you don't gain much, for example:
0110 (4 + 2)
0110 (8 - 2)
But at the same time, you don't lose anything by doing that operation; in contrast for some cases this is even beneficial:
0110110 - // 54, this has 4 powers
we can take the "last" 0110 and replace it with 1000 - 0010 (8-2) or:
0111000 - 000010 (56 - 2)
but now we can replace 0111 with just two powers : 1000 - 0001.
As such a simple "replace" algorithm can be made:
static int count(int x) {
String s = new StringBuffer(Integer.toBinaryString(x)).reverse().toString() + "0";
Pattern p = Pattern.compile("1+10");
Matcher m = p.matcher(s);
int count = 0;
while (m.find()) {
++count;
s = m.replaceFirst("1");
m = p.matcher(s);
}
return Integer.bitCount(Integer.parseInt(s, 2)) + count;
}
I have a Java program that generates 2 random numbers and asks a user for a mathematical operator and uses those 3 elements to ask the user an equation. I am trying to check if the answer the user inputs is correct and display either correct or incorrect.
RandomGenerator rand = new RandomGenerator();
x=rand.nextInt(-10,10);
y=rand.nextInt(-10,10);
op=readLine("Choose an operator (+, -, /, or *): ");
equ = x + op + y + "= ";
val = readInt(equ);
z = x + op + y
if(z == val) {
println("CORRECT!!");
}
if(z != val) {
println("Incorrect.");
}
The number of operators are limited so you may want to have Switch cases for each operator and calculate the values. for example
case '+':
value = a + b;
case '-':
String value = a + b;
This question already has answers here:
How to evaluate a math expression given in string form?
(26 answers)
Closed 7 years ago.
I am trying to write a program in Java which takes input a String value
like s = "1+27-63*5/3+2" and returns the calculation in integer value
Here below is my code
package numberofcharacters;
import java.util.ArrayList;
public class App {
public static void main(String[] args) {
String toCalculate = "123+98-79÷2*5";
int operator_count = 0;
ArrayList<Character> operators = new ArrayList<>();
for (int i=0; i < toCalculate.length(); i++){
if (toCalculate.charAt(i) == '+' || toCalculate.charAt(i) == '-' ||
toCalculate.charAt(i) == '*' || toCalculate.charAt(i) == '÷' ) {
operator_count++; /*Calculating
number of operators in a String toCalculate
*/
operators.add(toCalculate.charAt(i)); /* Adding that operator to
ArrayList*/
}
}
System.out.println("");
System.out.println("Return Value :" );
String[] retval = toCalculate.split("\\+|\\-|\\*|\\÷", operator_count + 1);
int num1 = Integer.parseInt(retval[0]);
int num2 = 0;
int j = 0;
for (int i = 1; i < retval.length; i++) {
num2 = Integer.parseInt(retval[i]);
char operator = operators.get(j);
if (operator == '+') {
num1 = num1 + num2;
}else if(operator == '-'){
num1 = num1 - num2;
}else if(operator == '÷'){
num1 = num1 / num2;
}else{
num1 = num1 * num2;
}
j++;
}
System.out.println(num1); // Prints the result value
}
}
****The problem is I need to perform calculation according to Order of operations in Math like Multiplication and division first , than addition and subtraction.
How can I resolve this? ****
I have used String split() method to seperate the String wherever the operators "+-/*" occurs. I have used character ArrayList to add operators in it.
Than at the last portion of code I am looping in that splitted array of Strings and I've initialize int num1 with the first value of splitted array of strings by parsing it to Integer. and int num2 with the second value and the using operators arraylist to perform calculation between them (whatever the operator at that index of arraylist). and storing the result in int num1 and doing vice versa until the end of the string array.
[P.S] I tried to use Collection.sort but it sorts the above arraylist of operators in that order [*, +, -, /]. It puts division at the end while it should put division after or before multiplication symbol
If you want to do it with roughly the same structure of code, and not turn it into something like reverse Polish notation first, you could try an approach that deals with the operations in reverse priority order.
So assuming that you have * and / as highest precedence, and you're treating them as equal precedence and therefore to be dealt with left-to-right; and the same for + and -; then you would
Split first on + and -.
Evaluate the parts that are separated by + and -, but now processing * and / in left-to-right order.
Apply your + and - to these evaluated parts.
So if your expression is 3*4+5-6/2 then your code would split first into
3*4 + 5 - 6/2
Now evaluate these sub-expressions
12 + 5 - 3
Now process left-to-right to evaluate the final answer
14
In more general terms, the number of passes you'll need through your expression is determined by the number of precedence levels you have; and you need to process the precedence levels from lowest to highest. Split expression up; recursively evaluate sub-expressions just considering next precedence level and upwards; combine to get final answer.
This would be a nice little Java 8 streams exercise!
Can anyone explain me how different spacing affects the unary operator?
int i = 1;
int j = i+ + +i; // this will print j=2
int k = i++ +i; // this will print k=3
int l = i+++i; // this will print l=3
int m = i++++i; // compile time error
.
First, let's separate this into three separate cases which can't interact:
int i = 1;
System.out.println(i+ + +i); // 2
int j = 1;
System.out.println(j++ +j); // 3
int k = 1;
System.out.println(k+++k); // 3
Now let's rewrite them using brackets:
int i = 1;
System.out.println(i + (+(+i)));
int j = 1;
System.out.println((j++) + j);
int k = 1;
System.out.println((k++) + k);
First operation
Here we can't be using the prefix or postfix ++ operators, as we don't have a token of ++ anywhere. Instead, we have a binary + operator and two unary + operators.
Second operation
This one's simple: it's pretty much as it reads, a postfix ++ operator followed by a binary + operator (not the unary + operator that +j might otherwise imply).
Third operation
The final line is parsed as (k++) + k rather than k + (++k). Both will actually give the same answer in this situation, but we can prove which is which by using two different variables instead:
int k1 = 1;
int k2 = 1;
System.out.println(k1+++k2); // Prints 2
System.out.println(k1); // Prints 2
System.out.println(k2); // Prints 1
As you can see, it's k1 that's been incremented rather than k2.
The reason that k+++k is parsed as tokens of k, ++, +, k is due to section 3.2 of the JLS, which includes:
The longest possible translation is used at each step, even if the result does not ultimately make a correct program while another lexical translation would.
Fourth operation (compile failure)
The same "longest possible translation" rule parses i++++i as i, ++ ,++, i which isn't a valid expression (because the result of the ++ operation is a value, not a variable).
+ is an operator, and ++ is an operator, but + + is not - + + is interpreted as two +s, not one ++. So the space forces your code to be interpreted differently.
+ is both a binary operator which adds two numbers and a unary operator which does not change a number (it exists only for consistency with the unary - operator).
If we use add instead of binary +, no-change instead of unary +, and increment instead of ++ then it might be more clear.
int j=i+ + +i becomes int j = i add no-change no-change i;.
int k=i++ +i; becomes int k=i increment add i;.
I suspect int k = i+++i; also becomes int k = i increment add i; but I have not checked this with the language specification.