Adding two integers together using only 1's - java

http://puu.sh/8ekfm.png
Zonko's government (The Kingdom of Zumbania) decided to ban directly adding numbers greater than 1 to other numbers. Zonko decided to create his own addition method (for positive integers) to circumvent the ban. Can you help finish his code?
To get the sum of a and b, Zonko starts by setting a variable sum equal to a. He then repeatedly adds 1 to sum until it reaches a+b. 1 is added every iteration of the loop until its been added the right number of times. What is the correct condition in the loop so it stops at the right time?
public int add(int a, int b){
int sum = a;
for(int i=1; LOOP-CONDITION; i=i+1){
sum = sum + 1; //this will add 1 to sum every iteration
}
return sum;
}
Can someone explain this and tell me how they got the answer?

The Java idiomatic for loops to perform an action a certain number of times are:
for(int i=1; i <= [numTimes]; i=i+1){
and
for(int i=0; i < [numTimes]; i=i+1){
The former has the correct starting condition, so your loop condition would be: i <= b.

The trick is in the words :
Zonko's government (The Kingdom of Zumbania) decided to ban directly
adding numbers greater than 1 to other numbers.
This means a cannot be added to b directly when b is greater than 1.
Assume you want to add a = 5 and b = 3. You can get the answer by adding 1 to 5 three times.
a = 5;
loop(b times){
a = a + 1;
}
Here is how the loop will go:
a = 5;
loop starts
a = 5 + 1;
a = 6 + 1; // we made it 6 in previous step
a = 7 + 1;
loop ends

Related

Maximum number of times this loop executes

I have this for loop and I am preparing for an exam. I want to see how many times this loop executes.
without knowing the value of K and somevalue, how can we determine the number of times SMALL is printed. The book answer says it is K-1.
for(int i=2; i<= k; i++)
if(arr[i]< someValue)
System.out.println("SMALL");
If it were simply
for (int i = 0; i < k; i++) {
The loop would run k times since you are starting at 0 but not reaching k
So add 2 to the starting point you get k-2 times
add back in 1 because it is <= and you get k-1 times.
It tends to get a little less obvious when the increment isn't 1
Note: That is how many times the loop will execute. The number of times SMALL will print can't be determined without more information.
in this case somevalue doesn't matter, you can calculate the count of executed loop your self by using another variable, use this:
int count = 0;
for (int i = 2; i <= k; i++) {
if (arr[i] < someValue) {
System.out.println("SMALL");
}
count++;
}
System.out.println("this for loop executed: " + count + " times.");
The question needs more inputs because without the values of arr[] and somevalue, we cannot find the answer.
However, since the loop starts at 2 and runs till its equal to k, we can say that it will run till k times -1 (since loop starts 2 for a <= condition instead of the usual 1), which translates to k-1 executions of the loop.
Still it doesn't guarantee the number of times "SMALL" will be printed. That is only possible if all values in the array arr are less than somevalue

Finding the longest run of duplicate numbers in an ArrayList? (Beginner java)

This is my first time using stack overflow, so I'm so sorry if this is formatted incorrectly in any way. For a comp sci project, I have to do some different things to a 40-item Array List of random numbers.
The task I'm struggling with is this:
Count the longest run of the same number. A run continues only when consecutive numbers
have the same value. The repeated number and the length of the run is then printed. (Ex: Longest run is of number: 3, length is: 5.)
If there is more than one run of maximum length, mark the last one. Print the array with the longest run marked in the following fashion:
1 1 1 6 5 4 6 3 2 3 2 (3 3 3 3 3) 1 5 6 3 4 4 4
I genuinely have no idea how to approach this problem. Even just some pseudocode could be helpful; I know that these should probably be 2 different 'for' loops, one that detects the run and the other that prints it. I have some code from a friend who completed this using Arrays instead of ArrayLists:
public String longestRun()
{
int maxRun=1;
int currentLen = 1;
int repeated = x[0];
for (int i =1; i< 40-1; i++)
{
if (x[i] == x[i+1])
currentLen++;
else
{
if (currentLen >= maxRun)
{
maxRun = currentLen;
repeated = x[i-1];
startRun = i-maxRun;
endRun = i-1;
}
currentLen = 1;
}
}
return "The longest run is " + maxRun + " and the repeated number is " + repeated ;
}
public String printParenth()
{
for(int i = 0; i<40; i++)
{
if(i != startRun+1 && i != endRun+1)
System.out.print(x[i]);
else if(i == startRun+1)
System.out.print("(" + x[i]);
else
System.out.print(x[i] + ")");
}
return "";
}
I know how to create the ArrayList, convert to string & print, etc, it's just this one task that I don't understand. I assume this should be easier with an ArrayList, considering the increased number and utility of ArrayList methods. Thanks so much in advance, I really appreciate it!
Put your numbers in a list or an array.
Set max to 1 (you will always have at least 1 number).
initialize count to 1.
initialize the variable most to the first number in the array
also set the variable last to the first number in the array.
Now iterate thru the list starting with the second number.
If the current number is the same as last, increment count.
then see if count > max.
if it is
set max = count.
set most = last
if it isn't
set count = 1
set last = current number
continue in this fashion until all numbers have been checked.
At the end most will contain the number that was repeated and max will contain the length of the repetition.

product of the numbers in list in java

My task here is to find the minimal positive integer number say 'A' so that the product of digits of 'A' is exactly equal to N.
example: lets say my N = 32
so my A would be 48 coz the divisors of 32 would be 1,2,4,8,16,32 and the minimum numbers that would make 32 is 4 and 8. so output is 48.
what i did is first read N, then found the divisors and stored them in a list. and used
if(l.get(i)*l.get(i+1)==N) {
sysout.print(l.get(i));
sysout.print(l.get(i+1));
but im not able to make the numbers as minimum. and also i need to print as -1 if no match is found.
for that i did:
if (l.get(i)*l.get(i+1)!=N) {
System.out.print(-1);
break;
}
but it is printing -1 initially only and breaking off. now im stuck here. please find my code below:
my code:
int N=1;
Scanner in = new Scanner(System.in);
List<Integer> l = new ArrayList<Integer>();
System.out.println("Enter N: ");
if (N>=0 && N<=Math.pow(10, 9)) {
N = in.nextInt();
}
for (int i=1; i<=N;i++) {
if (N%i==0) {
l.add(i);
}
}
System.out.println(l);
for (int i=0; i<l.size()-1;i++) {
if (l.get(i)*l.get(i+1)==N) {
System.out.print(l.get(i));
System.out.print(l.get(i+1));
}
}
in.close();
kindly help. thanks.
You're on the right track with finding the divisors on N. I'm not going to code it for you(you'll learn more by doing) but here's what you do: The divisors will be sorted already so loop the arraylist adding first to last and finding the min.
So for 1,2,4,8,16,32: Find 1+32, 2+16, 4+8; And then fin the max among these.
This is to get you started:
int first = 0;
int last = l.size()-1;
while(first<last){
//Find min using Math.min;
++first;
--last;
}
Happy Coding!
Could not resist. Below is a quick way to do what you want. Tested it here
(https://ideone.com/E0f4X9):
public class Test {
static ArrayList<Integer> nums = new ArrayList<>();
public static void main(String[] args){
int N =32;
findDivisors(N);
int first = 0, a = 0, b = 0;
int last = nums.size()-1;
int results = Integer.MAX_VALUE;
while(first < last){
int sum = nums.get(first) + nums.get(last);
results = Math.min(sum,results);
a = nums.get(first);
b = nums.get(last);
first++;
last--;
}
System.out.println(a+" "+b);
}
private static void findDivisors(int n){
for(int i=1; i<=n; i++){
if(n%i == 0){
nums.add(i);
}
}
}
}
Obviously if N<10 then A=N.
Otherwise A has to consist of more than one digit. Every digit of A is a divisor of N. The more significant digits of A always have to be less or equal than the lesser significant digits. Otherwise the order of digits could be changed to produce a smaller number.
For example A could not be 523 because the digits could be rearranged into 235 which is a smaller number. In this example we have 2 < 3 < 5.
Observation #1: when looking at A the smallest digits are at the front, the digits get higher towards the end.
Observation #2, A can never contain two digits a and b if the product of a and b is also a digit. For example, there can never be a 2 and a 3, there would have to be a 6 instead. There could never be three 2s, it would have to be an 8 instead.
This suggests that when building A we should start with the highest possible divisors of N (because a 9 is always better than two 3s, and so on). Then we should put that digit at the end of A.
So, while N > 10, find the highest divisor x of N that is a single digit (2<=x<=9). Add this value x to the end of A. Divide N by x and proceed with the loop.
Example:
N=126, A=?
Highest possible divisor x that is less or equal to 9 is 9. So 9 is going to be the last digit of A.
Divide N by 9 and repeat the process. N=126/9=14.
Now N=14, A=?9
Highest possible divisor x that is less or equal to 9 is 7. We have found the second to last digit of A.
Divide N by 7 and repeat the process. N=14/7=2.
Now N=2, A=?79
N<10. So 2 is the first digit of A.
The solution is A=279

Explain what this code is doing

I'm a newbie in java. I was going through some tutorials and came across this code I was not able to understand the code. Please explain what it means.
class Randoms
{
public static void main(String[] args)
{
Random rand = new Random();
int freq[] = new int[7];
for(int roll = 1; roll < 10; roll++)
{
(++freq[1 + rand.nextInt(6)]);
}
...
Line by line:
Random rand = new Random(); create new instance of the Random object, this is responsible for the creation of random numbers.
int[] freq = new int[7]; create a new int array that can store 7 elements, with indices from 0...6. It is worth noting that in Java, the ints stored in the array are initialized to 0. (This is not true for all languages, an example being C, as in C the int arrays initially store memory junk data, and must be explicitly initialized to zero).
for(int roll = 1; roll < 10; roll++) this rolls 9 times (because 1...9, but it's better practice to go from 0)
(++freq[1 + rand.nextInt(6)]); this line is something that you shouldn't ever do in this sort of fashion, because it's a monstrosity as you can see.
Do something like this:
for(int roll = 0; roll < 9; roll++)
{
int randomNumber = rand.nextInt(6); //number between 0...5
int index = 1 + randomNumber; //number between 1...6
freq[index]++; //increment the number specified by the index by 1
//nearly equivalent to freq[index] += 1;
}
So basically it randomizes the number of 9 dice throws, and stores the dice throw count (or so it calls it, frequency) in the array.
Thus, it's simulating 9 dice throws (numbers from 1...6), and each time it "rolls" a particular number, it increases the number stored in the array at that specific location.
So in the end, if you say:
for(int i = 1; i <= 6; i++)
{
System.out.println("Thrown " + freq[i] + " times of number " + i);
}
Then it will be clearly visible what's happened.
(++freq[1 + rand.nextInt(6)]); // this line of code.
The above line of code is pre-incrementing the value of freq[] array at the specified position,i.e., 1+rand.nextInt(6) --- referred value is ++freq[some-position to be evaluated] which we will evaluate below.
This rand.nextInt(6) will generate an integer number lesser than 6 and greater than 0,as it is a pre-defined method of Random Class ,randomly.We can't predict it.
And,then say number generated is 4. SO, 1+rand.nextInt(6)=5.
Hence,your code would simplify to (++freq[1 + rand.nextInt(6)]) OR `(++freq[5]).
So,simplification of this code will be equivalent to a number which equals 1 more than 6th element of array freq[].
// as freq[5] is the 6th element of the array freq[].
Also,there are some other points which SIR David Wallace suggested me to include which I would like to explain a bit more.It goes below :-
++a here ++ is called pre-increment operator and it increases the value of a by 1. There also exists an altered reverse version of it.
a++ here this ++ is called post-increment operator and it also increases the value of a by 1.But,WAIT,you might have thought that there aren't differences,but there are.
For the differences potion,I'd like to suggest to have a reading of What is the difference between pre-increment and post-increment in the cycle (for/while)?, though it is questioned in sense of C++,the same is in Java too!
// Create a new Random Object, this helps you generate random numbers
Random rand = new Random();
// create a integer array with 7 integers
int freq[] = new int[7];
// loop 9 times
for(int roll = 1; roll < 10; roll++)
{
// rand.nextInt(6) generates a number between 0 and 5 (<6). add one to it
// ++ adds one to the integer in the array that is at the index of 1-6.
(++freq[1 + rand.nextInt(6)]);
}
Some strange things about this code:
Roll loop starts at 1 then goes to 10 so at first glance it would seem to loop 10 times but actually runs 9 times.
The ++ inside the loop would generally be located on the right and could lead to some confusion among newer programmers.
freq[1 + rand.nextInt(6)] causes freq[0] to never be used.
At first a new object of the Random-Class and an array with 7 elements are created. Each element of the Array has the value 0. Inside the for-loop you randomly pick element 2 to 7 of the Array and increase its current value by 1. This is done 9 times.
Your code will never pick the first element of the Array which has the index 0.
I would rewrite the code to make it more clear:
Random rand = new Random();
int freq[] = new int[6];
int randomIndex = 0;
for(int roll = 0; roll < 9; ++roll)
{
randomIndex = rand.nextInt(6);
freq[randomIndex] = freq[randomIndex] + 1;
}
This code has not been tested, but it should basicly do the same.

Why does this merge sort give incorrect results?

My assignment is to merge two arrays using int arrays that the user fills and we have to assume that there will be a maximum of 10000 inputs from the user, and the user inputs a negative number to stop. Then sort the array from least to greatest and print it out. Initially i thought that this would be quite easy but when i finished, i began getting outputs such as:
Enter the values for the first array, up to 10000 values, enter a negative number to quit: 1
3
5
-1
Enter the values for the second array, up to 10000 values, enter a negative number to quit
2
4
6
-1
First Array:
1
3
5
Second Array:
2
4
6
Merged Array:
6 1 2 3 4 5
as you can see, the six is out of place and i have no idea how to fix it. Here is the source code, i have included copious comments because I really want you guys to help me out to the best of your abilities. IF it's possible to use the same exact technique without implement new techniques and methods into the code please do so. I know there are methods in java that can do all of this in one line but it's for an assignment at a more basic level.
import java.util.Scanner;
public class Merge
{
public static void main(String [] args)
{
Scanner scan = new Scanner(System.in);
int [] first = new int[10000]; //first array, assume 10k inputs max
int [] second = new int[10000]; //first array, assume 10k inputs max
boolean legal = true; //WILL IMPLIMENT LATER
int end = 0; // set how many elements to put in my "both" array
int end2 = 0;// set how many elements to put in my "both" array
System.out.print("Enter the values for the first array, up to 10000 values, enter a negative number to quit");
//get values
for(int i = 0; i<first.length; i++)
{
first[i] = scan.nextInt(); //fill first with user input
if(first[i] <0) //if negative number, stop loop
{
end = i; //get position of end of user input
break;
}
}
System.out.println("Enter the values for the second array, up to 10000 values, enter a negative number to quit");
for(int i = 0; i<second.length; i++) //exact same as the first get values loop
{
second[i] = scan.nextInt();
if(second[i] <0)
{
end2 = i;
break;
}
}
System.out.print("First Array:\n");
for(int i = 0; i<first.length; i++) //print first array
{
if(i == end) //this prevents from printing thousands of zeros, only prints values that user inputed
break;
System.out.println(first[i] + " ");
}
System.out.print("Second Array:\n");
for(int i = 0; i<second.length; i++) //same as printing first array
{
if(i == end2)
break;
System.out.println(second[i] + " ");
}
int [] both = new int[(end)+(end2)]; //instanciate an int array to hold only inputted values from first[] and second[]
int [] bothF = new int[(end)+(end2)]; //this is for my simple sorter algotithm loop
for(int i = 0; i<both.length; i++) //fill both with the first array that was filled
{
both[i] = first[i];
}
int temp = end; // see below
for(int i = 0;i<both.length; i++) //fill array with the second array that was filled(starting from the end of the first array so that the first set is not overwritten
{
if(temp<both.length){ //this prevents an out of bounds
both[temp] = second[i];
temp++;}
}
//simple sorting algorithm
for(int d = both.length -1;d>=0;d--)
{
for(int i = 0; i<both.length; i++)
{
if(both[d]<both[i])
{
bothF[d] = both[d];
both[d] = both[i];
both[i] = bothF[d];
}
}
}
System.out.println("Merged Array:"); //print the results
for(int i = 0; i<both.length; i++)
{
System.out.print(both[i] + " ");
}
//System.out.println("ERROR: Array not in correct order");
}
Your sorting algorithm is faulty.
It's similar to selection sort, in that you take two elements and swap them if they're out of place. However, you don't stop the comparisons when you should: when the index d is less than the index i, the comparison-and-swap based on arr[d] > arr[i] is no longer valid.
The inner loop should terminate with i=d.
The logic of your sort goes something like this:
On the d-th loop, the elements at d+1 and to the right are correctly sorted (the larger numbers). This is true at the beginning, because there are 0 elements correctly sorted to the right of the right-most element.
On each of the outer loops (with the d counter), compare the d-th largest element slot with every unsorted element, and swap if the other element is larger.
This is sufficient to sort the array, but if you begin to compare the d-th largest element slot with already-sorted elements to its right, you'll end up with a larger number in the slot than should be. Therefore, the inner loop should terminate when it reaches d.
Sure, you can do it like this
for (int i = 0; i < end; i++) {
both[i] = first[i];
}
for (int i = 0; i < end2; i++) {
both[i + end] = second[i];
}
// simple sorting algorithm
for (int d = both.length - 1; d >= 0; d--) {
for (int i = 0; i < d; i++) {
if (both[i] > both[d]) {
int t = both[d];
both[d] = both[i];
both[i] = t;
}
}
}
Output(s) -
Enter the values for the first array, up to 10000 values, enter a negative number to quit3
5
-1
Enter the values for the second array, up to 10000 values, enter a negative number to quit
2
4
6
-1
First Array:
3
5
Second Array:
2
4
6
-1
Merged Array:
2 3 4 5 6
First I will start with some recommendations:
1.Give end1 and end2 the initial value as the array lengths.
The printing part - instead of breaking the loop - loop till i == end(if its not changed by the first part it will stay the array length).
One suggestion is to use a "while" statement on the user input to do the reading part (it seems cleaner then breaking the loop- but its OK to do it like you have done too).
Try to use more functions.
now to the main thing- why not to insert the numbers from both arrays to the join array keeping them sorted?
Guiding:
Keep a marker for each array.
Iterate over the new join array If arr1[marker1]> arr2[marker2]
insert arr2[marker2] to the joint array in the current position.
and add 1 to marker2. and the opposite.
(don't forget to choose what happens if the are equal).
This can be achieved because the arrays were sorted in the first place.
Have fun practicing!
I guess you have sort of a reverse "selection sort"-algorithm going on there. I made an class that run your code and printed out the output after every swap. Here is the code which is the same as you got in your application with the addition of print.
for(int d = both.length -1;d>=0;d--)
{
for(int i = 0; i<both.length; i++)
{
if(both[d]<both[i])
{
int temp = both[d];
both[d] = both[i];
both[i] = temp;
printArray(both);
}
}
}
and when we run this on an example array we get this output
[9, 8, 7, 6]=
-> 6879
-> 6789
-> 6798
-> 6978
-> 9678
The algorithm actually had the correct answer after two swaps but then it started shuffling them into wrong order. The issue is the inner for loops end parameter. When you have run the outer loop once, you can be certain that the biggest number is in the end. 'd' is here 3 and it will swap out a bigger number every time it encounters it. the if clause comparisions in the first loop is 6-9 (swap), 9-8, 9-7, 9-9. All good so far.
Potential problems comes in the second iteration with 'd' as 2. Array is now [6,8,7,9] and comparisons are 7-6, 7-8 (swap with result [6,7,8,9]), 8-8, 8-9 (swap!!) resulting in [6,7,9,8]. the last swap was the problematic one. We knew that the biggest number was already in the last spot, but we still compare against it. with every gotrough of the whole inner loop it will always find the biggest number (and all other bigger than both[d] that is already in place) and swap it to some wrong position.
As we know that the biggest number will be last after one iteration of the outer loop, we shouldn't compare against it in the second iteration. You sort of lock the 9 in the array and only try to sort the rest, being in this case [6,8,7] where d = 3, value 7. hence, your inner loop for(int i = 0; i<both.length; i++) becomes for(int i = 0; i<=d; i++). As an added bonus, you know that in the last iteration i==d, and thus the code inside it, if(both[d]<both[i]) will never be true, and you can further enhance the loop into for(int i = 0; i<d; i++).
In your algorithm you always do four comparisons in the inner loop over four iterations of the outer loop, which means there is a total of 16 comparisons. if we use the i<d we'll just do three comparisons in the inner loop on the first iteration of the outer loop, then two, then one. This brings it to a total of six comparisons.
Sorry if too rambling, just wanted to be thorough.

Categories

Resources