Addition of two very long integers - java

For practice, I am trying to add two very long integers by placing them in arrays and adding the corresponding elements in the arrays. However, when trying to add the carry over, I'm having problems (I.e., the carry over is the 1, that for instance, you add to the tens place when you do 199 + 199 = 398).
When doing 167 + 189 I get the right answer which is 356. However, for this very example though (199 + 199), I'm getting 288 instead of 398. My question is, why do I get an incorrect answer when I do 199 + 199, if the carry over works well when I do 167 + 189?
if (stringNumOneLength == stringNumTwoLength)
{ int answer;
int carryOver = 0;
int answerArray[] = new int[stringNumOneLength + 1];
for (int i = 1; i <= stringNumTwoLength; i = i + 1)
{
answer = Character.getNumericValue(stringNumOne.charAt(stringNumOneLength - i)) + Character.getNumericValue(stringNumTwo.charAt(stringNumTwoLength - i) + carryOver);
System.out.println(answer);
if (answer >= 10)
{
for (int j = 0; j <= 9; j = j + 1)
{
if (10 + j == answer)
{
carryOver = 1;
answer = j;
System.out.println("The carryover is " + carryOver + ".");
}
}
}
else
{
carryOver = 0;
}
answerArray[stringNumOneLength + 1 - i] = answer;
}
System.out.println(Arrays.toString(answerArray));
}
The output is the following:
[1, 9, 9]
[1, 9, 9]
18
The carryover is 1.
8
2
[0, 2, 8, 8]

You're adding the carry to the character rather than to its value:
... + Character.getNumericValue(stringNumTwo.charAt(stringNumTwoLength - i) + carryOver);
You want to move the right parent inside the +.
Note your for loop is unnecessary. This does the same thing:
if (answer >= 10)
{
answer -= 10;
carryOver = 1;
System.out.println("The carryover is 1.");
}
else ...
In case you're interested in an idiomatic solution:
public class Test {
public String add(String a, String b) {
StringBuilder r = new StringBuilder();
int carry = 0;
for (int ia = a.length() - 1, ib = b.length() - 1; ia >= 0 || ib >= 0; ia--, ib--) {
int aDigit = ia < 0 ? 0 : Character.getNumericValue(a.charAt(ia));
int bDigit = ib < 0 ? 0 : Character.getNumericValue(b.charAt(ib));
int sum = carry + aDigit + bDigit;
if (sum >= 10) {
sum -= 10;
carry = 1;
}
else {
carry = 0;
}
r.append(Character.forDigit(sum, 10));
}
if (carry > 0) {
r.append('1');
}
return r.reverse().toString();
}
public void run() {
System.out.println("789 + 89 = " + add("789", "89"));
System.out.println("12 + 128 = " + add("12", "128"));
System.out.println("999 + 999 = " + add("999", "999"));
}
public static void main(String[] args) {
new Test().run();
}
}

The parenthesis on this line:
answer = Character.getNumericValue(stringNumOne.charAt(stringNumOneLength - i)) + Character.getNumericValue(stringNumTwo.charAt(stringNumTwoLength - i) + carryOver);
are wrong. Notice how the + carryOver is within the call to Character.getNumericValue.

Related

Java: changing the order of lines with while-loop

I am new to programming and I would like to ask what should I do so that the final value of k will appear before the values of a, when I try to put it inside the loop it repeats the statement and when I put it before the loop, its value is 0.
System.out.printf("Input an integer: ");
int a = in.nextInt();
int k = 0;
System.out.print(a);
while(a > 1)
{
if(a % 2 == 0)
a = a / 2;
else
a = 3 * a + 1;
System.out.printf(", " + a);
k++;
}
System.out.println("\nk = " + k);
Output:
Input an integer: 10
10, 5, 16, 8, 4, 2, 1
k = 6
You could try:
System.out.printf("Input an integer: ");
int a = in.nextInt();
int k = 0;
String str_a = "";
System.out.print(a);
while(a > 1)
{
if(a % 2 == 0)
a = a / 2;
else
a = 3 * a + 1;
str_a += ", " + String.valueOf(a);
k++;
}
System.out.println("k = " + k);
System.out.println("a = " + str_a);

How to resolve hashing collisions in Java

Write the following program using Java:
Suppose Player1 has 7 dice and Player2 has 5 dice (all 12 dice are standard 1 through 6 dice and fair). Both players roll their dice and compare their individual sum totals (i.e. Player1 rolls 1,3,5,2,6,1,1 = 19 and Player2 rolls 2,1,4,6,3 = 16). If Player1 rolls a total sum higher than Player2, Player1 wins the match, otherwise, Player2 wins. If all 2,176,782,336 combinations are rolled, how many matches will Player1 win? How many matches will Player2 win? How many matches will result in a tie? (note: only totals answering the three questions need to be printed)
The part where I'm stuck is how can I guarantee that I have no duplicate rolls?
Thanks.
import java.util.Random;
public class KDice {
public static void main(String[] args) {
Random random = new Random();
long playerOneWins = 0, playerTwoWins = 0, ties = 0;
int playerOneSum, playerTwoSum;
//for long number use L as suffix
for (long i = 0; i < 2176782336L; i++) {
//roll dice for player 1
playerOneSum = rollDice(random, 7);
//roll dice for player 2
playerTwoSum = rollDice(random, 5);
//find who won
if (playerOneSum == playerTwoSum) {
ties++;
} else if (playerOneSum > playerTwoSum) {
playerOneWins++;
} else {
playerTwoWins++;
}
}
//after all the round done, display stats
System.out.println("Player 1 win: " + playerOneWins);
System.out.println("Player 2 win: " + playerTwoWins);
System.out.println("Ties: " + ties);
}
public static int rollDice(Random random, int count) {
int sum = 0;
for (int i = 0; i < count; i++) {
sum += generateRandomNumber(random);
}
return sum;
}
public static int generateRandomNumber(Random random) {
return random.nextInt(6) + 1; //return number between 1 to 6
}
}
To simulate each possible roll of 12 dice, I use 12 nested for-loops so that I can produce each possible roll.
I replaced your random rolls of the dice with this loop:
int[] dice = new int[12];
for (dice[0] = 1; dice[0] <= 6; dice[0]++) {
System.out.println("dice[0] = " + dice[0]);
for (dice[1] = 1; dice[1] <= 6; dice[1]++) {
System.out.println("dice[1] = " + dice[1]);
for (dice[2] = 1; dice[2] <= 6; dice[2]++) {
System.out.println("dice[2] = " + dice[2]);
for (dice[3] = 1; dice[3] <= 6; dice[3]++) {
for (dice[4] = 1; dice[4] <= 6; dice[4]++) {
for (dice[5] = 1; dice[5] <= 6; dice[5]++) {
for (dice[6] = 1; dice[6] <= 6; dice[6]++) {
for (dice[7] = 1; dice[7] <= 6; dice[7]++) {
for (dice[8] = 1; dice[8] <= 6; dice[8]++) {
for (dice[9] = 1; dice[9] <= 6; dice[9]++) {
for (dice[10] = 1; dice[10] <= 6; dice[10]++) {
for (dice[11] = 1; dice[11] <= 6; dice[11]++) {
playerOneSum = dice[0] + dice[1] + dice[2] + dice[3] + dice[4] + dice[5] + dice[6];
playerTwoSum = dice[7] + dice[8] + dice[9] + dice[10] + dice[11];
//find who won
if (playerOneSum == playerTwoSum) {
ties++;
} else if (playerOneSum > playerTwoSum) {
playerOneWins++;
} else {
playerTwoWins++;
}
}
}
}
}
}
}
}
}
}
}
}
}
It took about three-four minutes to run through. I put in the println's to keep me from being too impatient. The results are:
Player 1 win: 1877280394
Player 2 win: 225654001
Ties: 73847941
If you are trying to go through every combination, you should not be rolling randomly. Just systematically go through every combination (e.g., with loops), and do your counting as you go along.
It seems to me that you misunderstood the question.
The question asks you to go through all possible outcomes and classify each outcome to either "A wins", "B wins" or "a tie".
For that, you don't use random. The answer should not change if you run the program many times. To enumerate all possible combinations of rolled dice, you can use 12 nested for loops that each count from 1 to 6. This way, the body of innermost loop will be executed 6^12 times - exactly once per any possible outcome. What you need to do is to sum 7 of the loop variables and compare it to sum of 5 other loop variables. Based on that, you either increase the counter for "A wins", "B wins" or "ties".
Alternatively, you don't need to count ties, since you always know the total number of results.
Here is a more compact and slightly more efficient way of achieving this. It works by:
starting with an array of 12 dice, initialized to all 1's (except the last for the first "toss")
then those dice are essentially incremented in a quasi base 7 to get the next toss. quasi because there are no 0's.
the sums are modified by either adding 1 or subtracting 5 depending on the the transition between between adjacent dice which would alter the sum by either +1 or -5.
int[] dice = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 };
int sum5 = 4; // inital sum for sum of five dice before first toss
int sum7 = 7; // initial sum for sum of seven dice before first toss
int sum7wins = 0;
int sum5wins = 0;
int ties = 0;
outer:
for(;;) {
for (int i = dice.length - 1; i >= 0;) {
int val = dice[i];
if (val < 6) {
dice[i] = val + 1;
if (i < 7) {
sum7++;
} else {
sum5++;
}
break;
}
if (i == 0) {
// first die is a 6 so we're done.
break outer;
}
dice[i] = 1;
if(i < 7) {
sum7-=5;
} else {
sum5-=5;
}
i--;
}
if (sum5 > sum7) {
sum5wins++;
} else if (sum7 > sum5) {
sum7wins++;
} else {
ties++;
}
}
System.out.println("sum7wins: " + sum7wins);
System.out.println("sum5wins: " + sum5wins);
System.out.println("ties: " + ties);
Prints
sum7wins: 1877205968
sum5wins: 225571216
ties: 74005152
2,176,782,336 is the number of possibilities of combination that can happens (= 6^12).
As i see you are trying roll 2,176,782,336 times randomly - which i think cannot resolve your question.
Edit, using 12 nested for loop might resolve your question:
public static void main(String args[]) {
int numP1Win = 0;
int numP2Win = 0;
int numdraw = 0;
for (int i = 1; i <= 6; i++) {
for (int j = 1; j <= 6; j++) {
for (int k = 1; k <= 6; k++) {
for (int l = 1; l <= 6; l++) {
for (int m = 1; m <= 6; m++) {
for (int n = 1; n <= 6; n++) {
for (int o = 1; o <= 6; o++) {
for (int p = 1; p <= 6; p++) {
for (int q = 1; q <= 6; q++) {
for (int r = 1; r <= 6; r++) {
for (int s = 1; s <= 6; s++) {
for (int t = 1; t <= 6; t++) {
if (i + j + k + l + m + n + o > p + q + r + s + t) {
numP1Win++;
}
else if (i + j + k + l + m + n + o < p + q + r + s + t) {
numP2Win++;
}
else {
numdraw++;
}
}
}
}
}
}
}
}
}
}
}
}
}
System.out.println("Num P1 Win: " + numP1Win);
System.out.println("Num P2 Win: " + numP2Win);
System.out.println("Num Draw: " + numdraw);
}
Output:
Num P1 Win: 1877205968
Num P2 Win: 225571216
Num Draw: 74005152

How to check each variable in the array, if the next element in the array is increasing?

I'm supposed to write a program that reads an array of ints and outputs the number of "triples" in the array.
A "triple" is three consecutive ints in increasing order differing by 1 (i.e. 3,4,5 is a triple, but 5,4,3 and 2,4,6 are not).
How do I check for the "triples"?
Current Code:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
// put your code here
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] array = new int[size];
int iterator = 0;
for(int i = 0; i < size; i++){
array[i] = scanner.nextInt();
} for(int j =0; j < size; j++){
iterator++;
}
}
}
The following code loops through the entire array of integers. Inside of the loop it is checked if the third integer exists inside of the array ((i + 2) < array.Length) and the other 2 conditions are all about whether value1 is the same as the value2 decreased by 1 (array[i] == array[i + 1] - 1 and array[i + 1] == array[i + 2] - 1):
for (int i = 0; i < array.Length; i++)
{
if((i + 2) < array.Length && array[i] == array[i + 1] - 1 && array[i + 1] == array[i + 2] - 1)
System.out.println("Three values at indexes" + i + " " + (i + 1) + " and " + (i + 2) + " are a triple");
}
The code below is C# and sadly not compatible to Java that easily, I'll just leave that here for anyone who wants to know how its handled in C# (the vt variable is a so called ValueTriple):
(int, int, int) vt;
for (var i = 0; i < array.Length; i++)
{
if (i + 2 >= array.Length) continue;
vt = (array[i], array[i + 1], array[i + 2]);
if (vt.Item1 == vt.Item2 - 1 && vt.Item2 == vt.Item3 - 1)
Console.WriteLine($"Three values at indexes {i}, {i + 1} and {i + 2} (Values: {array[i]}, {array[i + 1]}, {array[i + 2]}) are a triple");
}
You may try following code
import java.util.Scanner;
public class Triplet {
public static void main(String[] args) {
// put your code here
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] array = new int[size];
for(int i = 0; i < size; i++){
array[i] = scanner.nextInt();
}
Integer counter = 0;
for(int i = 0; i < size-2; i++) {
if(array[i] == array[i+1] - 1 && array[i] == array[i+2] - 2) { //checking if three consecutive ints in increasing order differing by 1
counter++;
}
}
System.out.println(counter);
}
}
Hope this will help.
A method to find out the number of triplets could look like this. You then just have to call the method depending how your input is obtained and you wish to present the result.
public static int getNumberOfTriplets(int[] toBeChecked) {
int numberOfTriplets = 0;
int nextIndex = 0;
while (nextIndex < toBeChecked.length - 2) {
int first = toBeChecked[nextIndex];
int second = toBeChecked[nextIndex + 1];
int third = toBeChecked[nextIndex + 2];
if ((first + 1 == second) && (second + 1 == third)) {
numberOfTriplets++;
}
nextIndex++;
}
return numberOfTriplets;
}
Regardless of allowing the numbers to be in more than one triplet, the answer is fairly similar in how I would personally approach it:
//determines if the input sequence is consecutive
public boolean isConsecutive(int... values) {
return IntStream.range(1, values.length)
.allMatch(i -> values[i] == values[i - 1] + 1);
}
public int countTriples(int[] input, boolean uniques) {
if (input.length < 3) {
return 0;
}
int back = 0;
for(int i = 2; i < input.length; i++) {
if (isConsecutive(input[i - 2], input[i - 1], input [i]) {
back++;
if (uniques) { //whether to disallow overlapping numbers
i += 2; //triple found, ignore the used numbers if needed
}
}
}
return back;
}
Then in calling it:
Int[] input = new int[] {1, 2, 3, 5, 6, 7, 8};
countTriples(input, true); //3
countTriples(input, false); //2

Generating Pythagorean Triples using Fibonacci Sequence

I'm using the Fibonacci sequence to generate some pythagorean triples (3, 4, 5, etc) based off this page: http://en.wikipedia.org/wiki/Formulas_for_generating_Pythagorean_triples starting at "Generalized Fibonacci Sequence".
public static int fib(int n) {
if(n == 0) return 0;
if(n <= 2) return 1;
int i = 1;
int temp = 0;
while(n != 1) {
i += temp;
temp = i - temp;
n--;
}
return i;
}
public static void main(String[] args) {
int a = 4; //a(3)
int b = 3; //b(3)
int c = 5; //c(3)
for(int n = 4; n < 10; n++) {
System.out.println(a + "^2 + " + b + "^2 = " + c + "^2");
a = a + b + c;
b = fib((2 * n) - 1) - b;
c = fib(2 * n);
}
}
However, the output my program is giving me is not accurate:
4^2 + 3^2 = 5^2
12^2 + 10^2 = 21^2
43^2 + 24^2 = 55^2
122^2 + 65^2 = 144^2
331^2 + 168^2 = 377^2
876^2 + 442^2 = 987^2
What could be causing this problem? Have I been duped by Wikipedia?
#MarkDickinson pointed out that the formula required F(1) = 0 and F(2) = 1, which is different from what is widely used, where F(1) = 1 and F(2) = 1. That fixed my problem!

Am I adding items to my Java array wrong?

public class ProjectEulerProb2 {
int firstInt = 1, secondInt = 2, thirdInt = 0, answer = 0;
int[] array = new int[4000000];
int[] evenArray = new int[90];
public static void main(String args[]) {
ProjectEulerProb2 prob = new ProjectEulerProb2();
prob.doIt();
prob = null;
}
public void doIt() {
for (int i = 0; i <= 4000000; i++) {
if (i == 0) {
thirdInt = firstInt + secondInt;
}
else {
firstInt = secondInt;
secondInt = thirdInt;
thirdInt = firstInt + secondInt;
}
array[i] = firstInt;
array[i + 1] = secondInt;
array[i + 2] = thirdInt;
if (thirdInt >= 4000000) {
break;
}
}
for (int j = 0; j <= 90; j = j + 3) {
if (j == 0) {
if (array[j + 1] % 2 == 0) {
System.out.println(" " + array[j + 1] % 2 + " " + array[j + 1]);
evenArray[j / 3] = array[j + 1];
}
if (array[j + 2] % 2 == 0) {
System.out.println(" " + array[j + 2] % 2 + " " + array[j + 2]);
evenArray[j / 3] = array[j + 2];
}
}
if (array[j] % 2 == 0) {
System.out.println(" " + array[j] % 2 + " " + array[j]);
evenArray[j / 3] = array[j];
}
}
for (int u = 0; u < evenArray.length; u++) {
if (u == 0) {
answer = evenArray[u];
}
else {
answer = answer + evenArray[u];
}
}
System.out.println(answer);
}
}
Could someone please help me find the problem? Every time I print the values of the array it comes out as 0 instead of the assigned value.
EDIT: Okay I took all the 'System.out.println's'
out that I didn't need.
EDIT 2: Okay so I rewrote the code to not use arrays anymore. Still interested in figuring out where I went wrong with the last version though.
public class ProjectEulerProb2Other {
static int firstInt=1, secondInt=2, thirdInt=0, answer=0;
public static void main(String[] args){
for(int i = 0; i<=4000000;i++){
if(i==0){
if(firstInt%2==0){
answer = answer+firstInt;
}
if(secondInt%2==0){
answer = answer+secondInt;
}
thirdInt = firstInt+secondInt;
}else{
firstInt = secondInt;
secondInt = thirdInt;
thirdInt = firstInt+secondInt;
if(thirdInt%2==0){
answer = answer+thirdInt;
}
}
if(thirdInt>=4000000){
System.out.println(answer);
break;
}
}
}
}
There is no problem with how you add elements to your array.
array[i] = firstInt;
Is correct. However, there are problems in your logic. Since this is probably an homework, I'll let you find them :)
EDIT
Okay so the problem was in this loop in your first version:
for (int j = 0; j <= 90; j = j + 3) {
if (j == 0) { //Bad idea!!
if (array[j + 1] % 2 == 0) { //Always false. array[0 + 1] == 1
System.out.println(" " + array[j + 1] % 2 + " " + array[j + 1]);
evenArray[j / 3] = array[j + 1];
}
if (array[j + 2] % 2 == 0) { //Always true. array[0 + 2] == 2
System.out.println(" " + array[j + 2] % 2 + " " + array[j + 2]);
evenArray[j / 3] = array[j + 2];
}
}
if (array[j] % 2 == 0) {
System.out.println(" " + array[j] % 2 + " " + array[j]);
evenArray[j / 3] = array[j];
}
}
My fix:
int jCpt = 0; //To add in evenArray in an orderly manner
for (int j = 0; jCpt < 90 && j < 4000000; ++j) { //Changed this
if (array[j] % 2 == 0) {
System.out.println(" " + array[j] % 2 + " " + array[j]);
evenArray[jCpt++] = array[j]; //We add alement #j from array to evenArray
/* Equivalent of
* evenArray[jCpt] = array[j];
* jCpt = jCpt + 1;
*/
}
}
But that version is probably better:
int evenCpt = 0; //To insert the even numbers one after the other
int fibonacciCpt = 0; //To iterate through the fibonacci numbers in array
for (; evenCpt < 90 && fibonacciCpt < 4000000; ++fibonacciCpt) {
if (array[fibonacciCpt] % 2 == 0)
evenArray[evenCpt++] = array[fibonacciCpt];
}
Congratulations, you solved Problem #2 :)

Categories

Resources