java get all possible variants (positive and negative) - java

Lets say I got a row of number "1 2 3 4"
I need to get all possible values
1+2+3+4
1+2+3-4
1+2-3+4
1+2-3-4
...
-1-2-3-4
tried to write a recursion
but it kinda works with "1 2" and "1 2 3"
it should work with 1 2 3 ... n
checkSum(0, list.size(), list);
private void checkSum(int start, int end, List<Long> list) {
for (int i = start; i < end; i++){
list.set(i, list.get(i) * (-1L));
printLine(list);
checkSum(i+2, end, list);
}
}
private void printLine(List<Long> list) {
for (int i = 0; i < list.size(); i++) {
if (i > 0)
if (list.get(i) > 0L)
System.out.print("+");
System.out.print(String.valueOf(list.get(i)));
}
System.out.println();
}

I have an approach that can give you some really cool ideas.
I didn't it with recursion, recursion is good, but you need be careful with memory issues when you use it. If you put a big list you can be faced with Stack Overflow errors.
Ok, my solution takes advantage of the binary system.
so, in binary, counting from 0 to 8
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0
Have you got it? you can consider the ones as negative signal. You can apply a mask to get the value.
your mask starts with 1 and goes on like:
0 0 0 1
0 0 1 0
0 1 0 0
1 0 0 0
in this way you can test the values.
So, the code:
public static void listPermutation(List<Long> l) {
for (int i = 0; i <= Math.pow(2,l.size()) - 1; i++) {
List<Long> l2 = new ArrayList<Long>(l);
applyMask(l2, i);
}
}
public static void applyMask(List<Long> l, long counter) {
long mask = 1L;
for (int i = l.size() - 1; counter >= mask; i--) {
if ((mask & counter) > 0) // here testing if the bit is 1 or 0
l.set(i, l.get(i) * -1);
mask <<= 1;
}
printLine(l); // System.out.println(l);
}
Example,
List<Long> l = new ArrayList<Long>();
l.add(1l);
l.add(2l);
l.add(3l);
l.add(4l);
listPermutation(l);
results in,
1+2+3+4
1+2+3-4
1+2-3+4
1+2-3-4
1-2+3+4
1-2+3-4
1-2-3+4
1-2-3-4
-1+2+3+4
-1+2+3-4
-1+2-3+4
-1+2-3-4
-1-2+3+4
-1-2+3-4
-1-2-3+4
-1-2-3-4
At point of speed, it's not bad:
List<Long> l = new ArrayList<Long>();
l.addAll(Arrays.asList(new Long[] { 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L }));
long initTime = System.currentTimeMillis();
listPermutation(l);
long finalTime = System.currentTimeMillis();
System.out.println(finalTime - initTime + " ms");
2833 ms
Maybe (probably) this is not the best way to do that, but I'm sure that will improve your mind :)

One of a billion ways of doing it below...
public class Thingy {
public static void main(String[] args) {
printAll(0, 0, Arrays.asList(1L, 2L, 3L, 4L), "TEST1> ");
printAll(0, 0, Arrays.asList(5L, 6L, 3L, 8L, 9L), "TEST2> ");
}
private static void printAll(int i, long accumulator, List<Long> source, String output) {
if(i >= source.size()) {
System.out.println(output + " = " + accumulator);
} else {
long n = source.get(i);
printAll(i + 1, accumulator + n, source, output + " + " + n);
printAll(i + 1, accumulator - n, source, output + " - " + n);
}
}
}
Output...
TEST1> + 1 + 2 + 3 + 4 = 10
TEST1> + 1 + 2 + 3 - 4 = 2
TEST1> + 1 + 2 - 3 + 4 = 4
TEST1> + 1 + 2 - 3 - 4 = -4
TEST1> + 1 - 2 + 3 + 4 = 6
TEST1> + 1 - 2 + 3 - 4 = -2
TEST1> + 1 - 2 - 3 + 4 = 0
TEST1> + 1 - 2 - 3 - 4 = -8
TEST1> - 1 + 2 + 3 + 4 = 8
TEST1> - 1 + 2 + 3 - 4 = 0
TEST1> - 1 + 2 - 3 + 4 = 2
TEST1> - 1 + 2 - 3 - 4 = -6
TEST1> - 1 - 2 + 3 + 4 = 4
TEST1> - 1 - 2 + 3 - 4 = -4
TEST1> - 1 - 2 - 3 + 4 = -2
TEST1> - 1 - 2 - 3 - 4 = -10
TEST2> + 5 + 6 + 3 + 8 + 9 = 31
TEST2> + 5 + 6 + 3 + 8 - 9 = 13
TEST2> + 5 + 6 + 3 - 8 + 9 = 15
TEST2> + 5 + 6 + 3 - 8 - 9 = -3
TEST2> + 5 + 6 - 3 + 8 + 9 = 25
TEST2> + 5 + 6 - 3 + 8 - 9 = 7
TEST2> + 5 + 6 - 3 - 8 + 9 = 9
TEST2> + 5 + 6 - 3 - 8 - 9 = -9
TEST2> + 5 - 6 + 3 + 8 + 9 = 19
TEST2> + 5 - 6 + 3 + 8 - 9 = 1
TEST2> + 5 - 6 + 3 - 8 + 9 = 3
TEST2> + 5 - 6 + 3 - 8 - 9 = -15
TEST2> + 5 - 6 - 3 + 8 + 9 = 13
TEST2> + 5 - 6 - 3 + 8 - 9 = -5
TEST2> + 5 - 6 - 3 - 8 + 9 = -3
TEST2> + 5 - 6 - 3 - 8 - 9 = -21
TEST2> - 5 + 6 + 3 + 8 + 9 = 21
TEST2> - 5 + 6 + 3 + 8 - 9 = 3
TEST2> - 5 + 6 + 3 - 8 + 9 = 5
TEST2> - 5 + 6 + 3 - 8 - 9 = -13
TEST2> - 5 + 6 - 3 + 8 + 9 = 15
TEST2> - 5 + 6 - 3 + 8 - 9 = -3
TEST2> - 5 + 6 - 3 - 8 + 9 = -1
TEST2> - 5 + 6 - 3 - 8 - 9 = -19
TEST2> - 5 - 6 + 3 + 8 + 9 = 9
TEST2> - 5 - 6 + 3 + 8 - 9 = -9
TEST2> - 5 - 6 + 3 - 8 + 9 = -7
TEST2> - 5 - 6 + 3 - 8 - 9 = -25
TEST2> - 5 - 6 - 3 + 8 + 9 = 3
TEST2> - 5 - 6 - 3 + 8 - 9 = -15
TEST2> - 5 - 6 - 3 - 8 + 9 = -13
TEST2> - 5 - 6 - 3 - 8 - 9 = -31

For your interest, a solution using Java 8 streams and no recursion:
public class ComboCollector {
private List<String> list = Collections.singletonList("");
private ComboCollector accept(String n) {
list = Stream.concat(
list.stream().map(v -> v + "+" + n), list.stream().map(v -> v + "-" + n))
.collect(Collectors.toList());
return this;
}
private ComboCollector combine(ComboCollector other) {
other.list.stream().forEach(this::accept);
return this;
}
public Stream<String> getResult() {
return list.stream();
}
}
public static void main(String[] args) {
IntStream.range(1, 10).mapToObj(Integer::toString)
.collect(ComboCollector::new, ComboCollector::accept, ComboCollector::combine)
.getResult().forEach(System.out::println);
}
I'm not necessarily recommending this approach but just wanted to demonstrate a different mechanism than traditional recursion.

Related

Bubble sort with output

So I have edited it some and am getting almost exactly what I want. The only problem I am having now is that I am getting a line of output that I don't want. I feel like the fix here is simple but my brain is fried right now.
static void bubbleSort(int[] myArray) {
int n = myArray.length;
int temp = 0;
int counter = 0;
for (int i = 0; i < n; i++) {
int k;
for (k = 0; k < n; k++) {
System.out.print(myArray[k] + "|");
}
System.out.println(" Num swaps: " + counter);
for (int j = 1; j < (n - i); j++) {
if (myArray[j - 1] > myArray[j]) {
//swap elements
temp = myArray[j - 1];
myArray[j - 1] = myArray[j];
myArray[j] = temp;
counter++;
}
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] myArray = new int[10];
for (int i = 0; i < 10; i++) {
System.out.print("Enter slot " + i + ": ");
myArray[i] = sc.nextInt();
}
bubbleSort(myArray);
}
Here is an example of what I get:
Enter slot 0: 10
Enter slot 1: 9
Enter slot 2: 8
Enter slot 3: 7
Enter slot 4: 6
Enter slot 5: 5
Enter slot 6: 4
Enter slot 7: 3
Enter slot 8: 2
Enter slot 9: 1
10|9|8|7|6|5|4|3|2|1| Num swaps: 0
9|8|7|6|5|4|3|2|1|10| Num swaps: 9
8|7|6|5|4|3|2|1|9|10| Num swaps: 17
7|6|5|4|3|2|1|8|9|10| Num swaps: 24
6|5|4|3|2|1|7|8|9|10| Num swaps: 30
5|4|3|2|1|6|7|8|9|10| Num swaps: 35
4|3|2|1|5|6|7|8|9|10| Num swaps: 39
3|2|1|4|5|6|7|8|9|10| Num swaps: 42
2|1|3|4|5|6|7|8|9|10| Num swaps: 44
1|2|3|4|5|6|7|8|9|10| Num swaps: 45
That first line of output where it just repeats what the user input and says 0 swaps. I don't want that.
Just changed the position of the for loops. Hope this is the output you actually want :).
static void bubbleSort(int[] myArray) {
int n = myArray.length;
int temp = 0;
int counter = 0;
for (int i = 0; i < n; i++) {
for (int j = 1; j < (n - i); j++) {
if (myArray[j - 1] > myArray[j]) {
// swap elements
temp = myArray[j - 1];
myArray[j - 1] = myArray[j];
myArray[j] = temp;
counter++;
}
}
int k;
for (k = 0; k < n; k++) {
System.out.print(myArray[k] + "|");
}
System.out.println(" Num swaps: " + counter);
}
}
Algorithm with two nested streams: Bubble sort with step-by-step output Java 8
Bubble sort with step-by-step output
The outer do-while-loop repeats until the array is sorted, and the inner for-loop passes through the array, swapping the unordered adjacent elements. The output is the swapped elements in the inner loop, grouped by passes in the outer loop.
public static void main(String[] args) {
int[] arr = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
bubbleSort(arr);
}
public static void bubbleSort(int[] arr) {
// counters
int passes = 0, swaps = 0;
// marker
boolean swapped;
// repeat the passes through the array until
// all the elements are in the correct order
do {
// output the beginning of the pass and increase the counter of passes
System.out.print((passes == 0 ? "<pre>" : "<br>") + "Pass: " + passes++);
swapped = false;
// pass through the array and
// compare adjacent elements
for (int i = 0; i < arr.length - 1; i++) {
// if this element is greater than
// the next one, then swap them
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
swapped = true;
// output the array and increase the counter of swaps
System.out.print(outputSwapped(arr, i, i + 1, swaps++));
}
}
// if there are no swapped elements at the
// current pass, then this is the last pass
} while (swapped);
// output total
System.out.print("<br>Total: Passes=" + passes);
System.out.println(", swaps=" + swaps + "</pre>");
}
static String outputSwapped(int[] arr, int e1, int e2, int counter) {
StringBuilder sb = new StringBuilder("<br>");
for (int i = 0; i < arr.length; i++) {
if (i == e1 || i == e2) {
// swapped elements are in bold
sb.append("<b>").append(arr[i]).append("</b>");
} else {
// other elements
sb.append(arr[i]);
}
sb.append(" ");
}
return sb.append("| ").append(counter).toString();
}
Output:
Pass: 09 10 8 7 6 5 4 3 2 1 | 09 8 10 7 6 5 4 3 2 1 | 19 8 7 10 6 5 4 3 2 1 | 29 8 7 6 10 5 4 3 2 1 | 39 8 7 6 5 10 4 3 2 1 | 49 8 7 6 5 4 10 3 2 1 | 59 8 7 6 5 4 3 10 2 1 | 69 8 7 6 5 4 3 2 10 1 | 79 8 7 6 5 4 3 2 1 10 | 8Pass: 18 9 7 6 5 4 3 2 1 10 | 98 7 9 6 5 4 3 2 1 10 | 108 7 6 9 5 4 3 2 1 10 | 118 7 6 5 9 4 3 2 1 10 | 128 7 6 5 4 9 3 2 1 10 | 138 7 6 5 4 3 9 2 1 10 | 148 7 6 5 4 3 2 9 1 10 | 158 7 6 5 4 3 2 1 9 10 | 16Pass: 27 8 6 5 4 3 2 1 9 10 | 177 6 8 5 4 3 2 1 9 10 | 187 6 5 8 4 3 2 1 9 10 | 197 6 5 4 8 3 2 1 9 10 | 207 6 5 4 3 8 2 1 9 10 | 217 6 5 4 3 2 8 1 9 10 | 227 6 5 4 3 2 1 8 9 10 | 23Pass: 36 7 5 4 3 2 1 8 9 10 | 246 5 7 4 3 2 1 8 9 10 | 256 5 4 7 3 2 1 8 9 10 | 266 5 4 3 7 2 1 8 9 10 | 276 5 4 3 2 7 1 8 9 10 | 286 5 4 3 2 1 7 8 9 10 | 29Pass: 45 6 4 3 2 1 7 8 9 10 | 305 4 6 3 2 1 7 8 9 10 | 315 4 3 6 2 1 7 8 9 10 | 325 4 3 2 6 1 7 8 9 10 | 335 4 3 2 1 6 7 8 9 10 | 34Pass: 54 5 3 2 1 6 7 8 9 10 | 354 3 5 2 1 6 7 8 9 10 | 364 3 2 5 1 6 7 8 9 10 | 374 3 2 1 5 6 7 8 9 10 | 38Pass: 63 4 2 1 5 6 7 8 9 10 | 393 2 4 1 5 6 7 8 9 10 | 403 2 1 4 5 6 7 8 9 10 | 41Pass: 72 3 1 4 5 6 7 8 9 10 | 422 1 3 4 5 6 7 8 9 10 | 43Pass: 81 2 3 4 5 6 7 8 9 10 | 44Pass: 9Total: Passes=10, swaps=45
See also: Bubble sort output is incorrect

How to Print Random number in a Math Table?

I am implementing a math table using two integers (a and tableSize). I have built a random operation named R. I am going to calculate a random number between the row and column range and print the random number. For those instances where the row value is larger than the column value, the output is a dash ("-").
Here is my code,
int a = 4;
int tableSize = 10;
System.out.print(" R ");
for(int i = a; i <= tableSize;i++ )
{
System.out.format("%4d",i);
}
System.out.println();
for(int i = a ;i <= tableSize;i++)
{
System.out.format("%4d ",i);
for(int j=a;j <= tableSize;j++)
{
int randomNum = rand.nextInt (j) + i;
if(!(i > j))
{
System.out.format("%4d", randomNum);
} else
{
System.out.format("%4s", "-");
}
}
System.out.println();
}
The output I need is like this,
R 4 5 6 7 8 9 10
4 4 4 5 5 4 9 8
5 - 5 5 6 5 9 8
6 - - 6 6 7 9 6
7 - - - 7 7 7 7
8 - - - - 8 9 9
9 - - - - - 9 10
10 - - - - - - 10
But the problem is I didn't get output like that. output I receive is,
R 4 5 6 7 8 9 10
4 5 7 6 8 8 10 13
5 - 5 9 8 8 10 12
6 - - 9 8 11 10 11
7 - - - 8 14 9 16
8 - - - - 14 12 11
9 - - - - - 13 18
10 - - - - - - 19
And the row value is larger than the column value, Please anyone can help me? Thanks in advance.
The problem is that you are computing the cell value as the sum of a random number between 1 and the column number plus the row number. The logic I think you want is that a given cell in the matrix can be no larger than the max of the row or column number. If so, then you need to change this line:
int randomNum = rand.nextInt(j) + i;
To this:
int randomNum = rand.nextInt((Math.max(i, j) - a) + 1) + a;
Demo
Change your random number like this.
int randomNum = rand.nextInt((tableSize - a) +1)+a;
Output:
R 4 5 6 7 8 9 10
4 4 6 7 6 6 7 7
5 - 6 5 4 6 8 8
6 - - 7 8 7 7 8
7 - - - 10 7 5 5
8 - - - - 9 5 8
9 - - - - - 8 8
10 - - - - - - 4
You want a number that can be up to the higher limit (inclusive), but Random.nextInt(int) excludes the higher limit, so you need to add 1 to the argument. To get a random number from zero to 10 (inclusive), you can use rand.nextInt(10+1).
But you also have a lower bound. It's correct that you need to add the lower bound to the result as you did, but you need to subtract it from the range first.
You need to change this line:
int randomNum = rand.nextInt (j) + i;
To this:
int randomNum = rand.nextInt(j + 1 - i) + i;
But you need to move this line within your check that i <= j, or else your range becomes negative:
if (i <= j) {
int randomNum = rand.nextInt(j + 1 - i) + i;
System.out.format("%4d", randomNum);
} else {
System.out.format("%4s", "-");
}
Output:
R 4 5 6 7 8 9 10
4 4 5 5 7 4 5 8
5 - 5 6 6 5 5 5
6 - - 6 6 8 8 9
7 - - - 7 7 9 9
8 - - - - 8 9 9
9 - - - - - 9 9
10 - - - - - - 10
First, you should know how to get random between two integers, and then code the rest (check code comments)
Here is an implementation using ternary operator ?:, which is good to know of
PrintR.java:
import java.util.Random;
public class PrintR {
public static void main(String[] args) {
int a = 4;
int end = 10;
printRTable(a, end);
}
public static void printRTable(int init, int end) {
Random rand = new Random();
// first print the top header row
System.out.format(" R ");
for(int i = init; i<=end;i++ ) {
System.out.format("%4d",i);
}
System.out.println();
System.out.println("------------------------------------------");
for(int i = init ;i<=end;i++) {
// print left most column first
System.out.format("%4d |",i);
for(int j=init;j<=end;j++) {
//Ternary operator
//r.nextInt(High-Low + 1) + Low; gives you a random number in between Low (inclusive) and High (inclusive)
System.out.format("%4s", i > j ? "-" : (rand.nextInt(j-i+1)) + i);
}
System.out.println();
}
}
}
Example output:
R 4 5 6 7 8 9 10
------------------------------------------
4 | 4 4 5 7 5 5 4
5 | - 5 6 6 5 8 10
6 | - - 6 7 7 6 8
7 | - - - 7 7 7 10
8 | - - - - 8 8 10
9 | - - - - - 9 10
10 | - - - - - - 10

How can I print these numbers in correspoding location with array?

import java.util.*;
import java.io.*;
public class PracticeFinal {
public static void main (String[] args) throws FileNotFoundException{
Scanner input = new Scanner (new File("altitude.txt"));
int[] x = new int [400];
int[] y = new int [400];
float[] altitude = new float [400];
x[0] = 0;
y[0] = 0;
altitude[0] = 0;
int i = 0;
System.out.println("x\ty\taltitude");
while (input.hasNextFloat()) {
int line = input.nextInt();
x[i]=line;
int line2=input.nextInt();
y[i]=line2;
float line3 = input.nextFloat();
altitude[i]=line3;
System.out.println(x[i]+"\t" + y[i]+"\t"+ altitude[i]+"\t");
i+=1; }
printMax(altitude,x,y);
printMin(altitude,x,y);
printAverage(altitude);
printContour(altitude,x,y);
}
public static void printMax(float []altitude, int []x, int []y) {
float max=altitude[0];
int ind=0;
for(int i=0;i<100;i++)
{
if (altitude[i]>max)
{
max = altitude[i];
ind=i;
}
}
System.out.println("The maximum altitude is "+"("+x[ind]+","+y[ind]+","+max+")");
}
public static void printMin(float []altitude, int []x, int []y){
float min=altitude[0];
int ind=0;
for(int i=0;i<100;i++)
{
if (altitude[i] < min)
{
min = altitude[i];
ind=i;
}
}
System.out.println("The minimum altitude is "+"("+x[ind]+","+y[ind]+","+min+")");
}
public static void printAverage(float []altitude){
float total = 0;
for(int i=0;i<100;i++)
{
total += altitude[i];
}
float avg = total / 100;
System.out.printf("The aveage altitude of the region is " + "%.2f", avg);
System.out.println();
}
public static void printContour(float []altitude, int[]x, int[]y){
for (int i=0;i<100;i++) {
System.out.print (altitude[i] + " ");
}
}
}
I need help with the last part of this program there is an x and y chart with altitudes ex, 0,0 = 109.1 1,0= 200
So for the last method i need to print out the altitude in its corresponding location starting from 1,1 to 2,1 to 3,1 and so on
Dont know what to do next after the for loop
This is the file im reading first number is x second is y and third is the altitude.
1 1 101.0
2 2 97.2
3 3 112.3
4 4 114.2
5 5 100.2
6 6 97.5
7 7 97.8
8 8 81.3
9 9 105.4
10 10 108.7
3 1 107.8
3 2 115.4
3 4 118.3
3 5 120.3
3 6 122.3
3 7 90.3
3 8 81.7
3 9 87.4
3 10 113.2
1 2 102.3
1 3 104.5
1 4 109.8
1 5 99.8
1 6 88.9
1 7 89.3
1 8 100.1
1 9 110.8
1 10 98.3
2 1 98.8
2 3 80.5
2 4 85.1
2 5 83.2
2 6 92.3
2 7 94.3
2 8 199.3
2 9 104.3
2 10 105.2
4 1 120.5
4 2 87.3
4 3 82.3
5 1 83.2
5 2 84.5
5 3 96.9
5 4 86.7
4 5 115.3
4 6 101.3
4 7 102.6
4 8 106.9
4 9 109.8
4 10 93.4
6 7 93.2
6 8 92.4
6 9 80.9
6 10 81.2
5 6 102.3
5 7 101.1
5 8 106.7
5 9 105.3
5 10 88.9
6 1 80.8
6 2 81.3
6 3 84.5
6 4 90.8
6 5 99.8
8 1 98.6
8 2 101.1
8 3 103.5
8 4 104.6
8 5 105.8
8 6 80.9
8 7 80.1
7 1 98.3
7 2 96.4
7 3 95.1
7 4 83.4
7 5 95.1
7 6 96.3
7 8 99.9
7 9 100.0
7 10 102.3
10 3 99.9
10 4 98.3
10 5 91.3
10 6 94.3
10 7 95.3
10 8 103.2
8 9 90.2
8 10 91.3
9 1 93.2
9 2 81.5
9 3 91.0
9 4 95.3
9 5 122.3
9 6 119.8
9 7 118.7
9 8 117.3
9 10 107.8
10 1 108.8
10 2 109.9
10 9 104.2
public static void printContour(float []altitude, int[]x, int[]y){
for (int i = 0; i < 100; i++) {
for (int a = 0; a < 100; a++) {
if (x[i] < x[a]) {
int temp_for_x = x[i];
x[i] = x[a];
x[a] = temp_for_x;
int temp_for_y = y[i];
y[i] = y[a];
y[a] = temp_for_y;
float temp_for_alt = altitude[i];
altitude[i] = altitude[a];
altitude[a] = temp_for_alt;
}
if(y[i] < y[a]){
int temp_for_x = x[i];
x[i] = x[a];
x[a] = temp_for_x;
int temp_for_y = y[i];
y[i] = y[a];
y[a] = temp_for_y;
float temp_for_alt = altitude[i];
altitude[i] = altitude[a];
altitude[a] = temp_for_alt;
}
}
}
for (int incr=0;incr<100;incr++) {
System.out.print(x[incr]+ " " + y[incr] + " " + altitude[incr]+ " ");
if(incr%10 == 9)
System.out.println();
}
}
}
There are better sorting algorithms you can use Here

How to associate file number with coordinate information in a matrix?

I have a image raster of dimensions width = 155 and height = 175. Each pixel coordinate is associated with a number, meaning (1,1) is 1, (1,155) is 155 and (175,155) is 27125. Given a number, how can I find the coordinate (x,y)? I am working in Java.
Smaller matrix width = 3 height = 4
1 2 3
1,1 1,2 1,3
4 5 6
2,1 2,2 2,3
7 8 9
3,1 3,2 3,3
10 11 12
4,1 4,2 4,3
Something like that should work:
private int X_SIZE = 155;
public int getX(int position) {
return position % X_SIZE; // Starts from 0
}
public int getY(int position) {
return position / X_SIZE; // starts from 0
}
Where 155 is the dimension of the x size.
Imagine to have a matrix 3 x 5. X_SIZE is 3.
Here is the matrix population
X
Y 0 1 2
----------------
0 | 0 1 2
1 | 3 4 5
2 | 6 7 8
3 | 9 10 11
4 |12 13 14
And here are some values:
getX(0) = 0 % 3 = 0
getY(0) = 0 / 3 = 0
getX(1) = 1 % 3 = 1
getY(1) = 1 / 3 = 0
getX(8) = 8 % 3 = 2
getY(8) = 8 / 3 = 2
getX(12) = 12 % 3 = 0
getY(12) = 12 / 3 = 4
This work is you use a 0 based x and y calculation and starts from 0 to populate the array.
To have a 1 based for x and y and starting from 1 to populate the array you need to change the functions as follow:
private int X_SIZE = 155;
public int getX(int position) {
return (position - 1) % X_SIZE + 1; // Starts from 1
}
public int getY(int position) {
return (position - 1) / X_SIZE + 1; // starts from 1
}
Here are the same example as before:
X
Y 1 2 3
----------------
1 | 1 2 3
2 | 4 5 6
3 | 7 8 9
4 |10 11 12
5 |13 14 15
And here are some values:
getX(1) = (1 - 1) % 3 + 1 = 1
getY(1) = (1 - 1) / 3 + 1 = 1
getX(2) = (2 - 1) % 3 + 1 = 2
getY(2) = (2 - 1) / 3 + 1 = 1
getX(9) = (9 - 1) % 3 + 1 = 3
getY(9) = (9 - 1) / 3 + 1 = 3
getX(13) = (13 - 1) % 3 + 1 = 1
getY(13) = (13 - 1) / 3 + 1 = 5

2 recursive calls in function in Java

I am having some problems with Recursion in Java.
Here is my code
public class recursionTrial {
public static void main(String[] args)
{
System.out.println(doSomething(6));
}
public static int doSomething(int n)
{
if (n==0 || n==1)
return 0;
else
return n + doSomething(n-1) + doSomething(n-2);
}
}
Which gives me an output of 38. However I am unable to trace the recursive function in my head or on paper. How will the working out look? 6+5.... and so on.
I get if it were just
return n + doSomething(n-1)
then it would be 6+5+4+3+2 = 20 ; it is the second part of the code that is confusing me. If someone could explain to me how to trace the recursive function properly and write the working out I would appreciate it! Also is there a way to write a piece of code that prints the value of n before it changes each time?
In the absence of side effects one can think of this recursive function as of a regular function. You can draw a small table showing the results of invocation of your function, starting with zero:
n res computation
- --- -----------
0 0 0
1 0 0
2 2 2+0+0
3 5 3+2+0
4 11 4+5+2
5 21 5+11+5
6 38 6+21+11
No special mental treatment is required for the second recursive invocation: it is the same as the first one.
Note: your function will be taking progressively longer time as the value of n goes up, because it would be re-doing a lot of computations it has already done. Fortunately, this can be addressed with a simple and very common trick, called memoization.
Your recursive function is
f(n) = n + f(n-2) + f(n-1)
The execution flow is as follows.
f(n-2) is evaluated first... To compute f(n-2) the program again makes a recursive call to f(n-4) and f(n-3) and so on...
Next, f(n-1) is evaluated... this again depends on computed values of f(n-3) and f(n-2) and so on...
These two values are added with n to get the final result...
For example, the recursion tree for n=4 is as follows (I'm not showing the addition with n for simplicity):
f(4) {
f(2) {
f(0) {0}
f(1) {0}
}
f(3) {
f(1) {0}
f(2) {
f(0) {0}
f(1) {0}
}
}
}
doSomething(1)= return 0,
doSomething(2)== 2+dosomething(1)= 2+0=2,
doSomething(3)=3+doSomething(2)=3+2=5,
doSomething(4)=4+doSomething(3)+doSomething(2)=4+5+2=11
doSomething(5)=5+doSomething(4)+doSomething(3)=5+11+5=21,
doSomething(6)=6+doSomething(5)+doSomething(4)=6+21+11=38
Start at doSomething(6), it calls: doSomething(5) go to that line, to figure out doSomething(5) we need to know doSomething(4) and doSomething(3).... and work your way up the tree, till you get to an actual "Return value" which in this case would be when we reach doSomething(1), then put those values in as you back down the tree.
public static int doSomething(int n) {
if (n==0 || n==1)
return 0;
else
return n + doSomething(n-1) + doSomething(n-2);
}
You could try to expand recursively, this is conceptually what the program does.
doSomething(6) expands to 6 + doSomething(5) + doSomething(4)
doSomething(5) expands to 5 + doSomething(4) + doSomething(3)
doSomething(4) expands to 4 + doSomething(3) + doSomething(2)
...
Simply go down the recursion. For example (I use dS for doSomething):
dS(6) = 6 + dS(5) + dS(4) =
6 + 5 + dS(4) + dS(3) + 4 + dS(3) + dS(2) =
6 + 5 + 4 + dS(3) + dS(2) + 3 + dS(2) + dS(1) + 4 + 3 + dS(2) + dS(1) + 2 + dS(1) + dS(0) =
6 + 5 + 4 + 3 + dS(2) + dS(1) + 2 + dS(1) + dS(0) + 3 + 2 + dS(1) + dS(0) + 0 + 4 + 3 + 2 + dS(1) + dS(0) + 0 + 2 + 0 + 0 =
6 + 5 + 4 + 3 + 2 + dS(1) + dS(0) + 0 + 2 + 0 + 0 + 3 + 2 + dS(1) + 0 + 0 + 4 + 3 + 2 + 0 + 0 + 0 + 2 + 0 + 0 =
6 + 5 + 4 + 3 + 2 + 0 + 0 + 0 + 2 + 0 + 0 + 3 + 2 + 0 + 0 + 0 + 4 + 3 + 2 + 0 + 0 + 0 + 2 + 0 + 0 =
38 <-- Final result
Beware that this has exponential complexity.
doSomething(6) calls doSomething(5) and doSomething(4)
doSomething(5) calls doSomething(4) and doSomething(3)
doSomething(4) calls doSomething(3) and doSomething(2)
doSomething(3) calls doSomething(2) and doSomething(1)
doSomething(2) calls doSomething(1) and doSomething(0)
doSomething(1) is 0
doSomething(0) is 0
This illustrates callings of doSomething(), they are not results, since you are adding n for each call.
6
_______|_______
/ \
5 4
____|____ _|_
/ \ / \
4 3 3 2
_|_ | | |
/ \ / \ / \ / \
3 2 2 1 2 1 1 0
/ \ / \ / \ / \
2 1 1 0 1 0 1 0
/ \
1 0

Categories