Pascals triangle in one loop - java

Is it possible to write the pascal's triangle by using one loop ? I have written it by using more than one loop and it is working fine.

Heck, I'll make my comment an answer:
As a hint, I would create a method that takes as input the number of rows of the triangle you want to produce, then at the beginning of the method calculate total number of items this will translate out to, and then have your for loop loop through all the items. Inside the loop, you can easily calculate which row you're on and which column you're on, and then use this information to create your item value.

the code you want is Here
or
package net.yogesh.test;
import java.util.ArrayList;
import java.util.List;
public class pascal3 {
public static void main(String[] args) {
int noOfRows = 10;
int counter = 1;
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list = itMe(list, counter,noOfRows);
}
public static List<Integer> itMe(List<Integer> list, int counter,int noOfRows) {
System.out.println(list);
List<Integer> tempList = new ArrayList<Integer>();
tempList.add(1);
for (int i = 1; i < list.size(); i++) {
tempList.add(list.get(i) + list.get(i-1));
}
tempList.add(1);
if(counter != noOfRows)
itMe(tempList, ++counter,noOfRows);
return tempList;
}
}
Note
here output is as expected
but if you want in formatted view than you need to use extra loop.
Output
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]

Related

Sum of all elements of each subarray

I was solving Kadane's algorithm , a very weird approach came to my mind while solving it. What if we find a way to find out the sum of all the elements of all possible subarrays forming from an array and store it in an arraylist. I've been thinking about it for a long time now, but I'm unable to solve it. It would be great if I can get some assistance.
`
import java.util.*;
import java.lang.*;
import java.io.*;
class Sample
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for(int i=0;i<n;i++){
arr[i]=sc.nextInt();
}
ArrayList<Integer> list = new ArrayList<>();
int sum=0;
for(int i=0;i<n;i++){
sum+=arr[i];
}
list.add(sum);
for(int i=0;i<n;i++){
list.add(arr[i]);
}
for(int i=0;i<n;i++){
//sum-=arr[i];
if(!list.contains(sum-arr[i]) && (sum-arr[i])>0){
list.add(sum-arr[i]);
}
sum=sum-arr[i];
}
System.out.println(list);
}
}
`
This is what I've done till now. There's a very big flaw in the logic and I know it but I just can't seem to solve it.
This doesn't use Kadanes algorithm, but it does sum the sub arrays. It is facilitated by using the subList method of the List interface.
for (int i = 1; i < 8; i++) {
List<Integer> list =
IntStream.range(1, i+1).boxed().toList();
List<Integer> sums = new ArrayList<>();
findsubs(list, 0, list.size(), sums);
System.out.println(sums);
sums.clear();
}
prints
[1]
[3, 2, 1]
[6, 5, 3, 3, 2, 1]
[10, 9, 7, 4, 6, 5, 3, 3, 2, 1]
[15, 14, 12, 9, 5, 10, 9, 7, 4, 6, 5, 3, 3, 2, 1]
[21, 20, 18, 15, 11, 6, 15, 14, 12, 9, 5, 10, 9, 7, 4, 6, 5, 3, 3, 2, 1]
[28, 27, 25, 22, 18, 13, 7, 21, 20, 18, 15, 11, 6, 15, 14, 12, 9, 5, 10, 9, 7, 4, 6, 5, 3, 3, 2, 1]
The method
public static void findsubs(List<Integer> list, int s, int e,
List<Integer> sums) {
if (s >= e) {
return;
}
for (int i = s; i < e; i++) {
sums.add(list.subList(i, e).stream()
.mapToInt(Integer::intValue).sum());
}
findsubs(list, s, e - 1, sums);
}
long subarraySum(vector<long> &A) {
long result = 0;
int n = A.size();
for (int i=0; i <n; ++i)
{
result +=(A[i]*(i+1)*(n-i));
}
return result;
}
Sum of all sub array means,
Actually each element how many time contribute himself in each sub array
lets take : [1 2 3 4][0,0][0,1][1,1][0,2][1,2][2,2][0,3][1,3][2,3][3,3]
contribution of ith element is A[i](i+1)(n-i)

How to seperate even and odd numbers in the same array?

How would I separate even and odd integers in an array with order preserved?
Modifications must be in place and the return is a void, and can only use built in methods.
An example would be:
{4, 5, 8, 16, 45, 12, 67, 13} -> {4, 8, 16, 12, 5, 45, 67, 13}
Explanation
You can easily solve this with one iteration, remembering the index of the current border and swapping elements.
So for your example, the process will be:
{ 4, 5, 8, 16, 45, 12, 67, 13 } // swap 4 with 4
^
{ 4, 5, 8, 16, 45, 12, 67, 13 }
^
{ 4, 8, 5, 16, 45, 12, 67, 13 } // swap 5 with 8
^
{ 4, 8, 16, 5, 45, 12, 67, 13 } // swap 5 with 16
^
{ 4, 8, 16, 12, 45, 5, 67, 13 } // swap 5 with 12
^
Where the ^ shows the current border index, which is always one ahead of the even values, pointing at the index where you want to swap the next even value to.
First draft
Here is the code for that:
int borderIndex = 0;
for (int i = 0; i < values.length; i++) {
int value = values[i];
if (value % 2 == 0) {
// swap
values[i] = values[borderIndex];
values[borderIndex] = value;
borderIndex++;
}
}
Preserving order
Now, this solution already preserves the order of the even numbers out of the box. But if you pay close attention you see that it does not preserve order of the odd values. It goes wrong as soon as you have multiple odd values after each other before an even value, like
..., 5, 45, 12, ...
because it will then swap 5 with 12 resulting in 12, 45, 5 instead of 12, 5, 45.
Even worse when there are multiple odd values:
..., 5, 7, 9, 11, 12, ...
resulting in 12, 7, 9, 11, 5.
In order to fix this, we have to not just swap 5 with the even value 12 but actually swap all the way back to 5. So:
swap 12 with 11
swap 12 with 9
swap 12 with 7
swap 12 with 5
basically shifting down 12 from right to left, until it stands right in front of 5.
We can do so easily with a simple loop that moves from 12 (at i) to 5 (at borderIndex):
int borderIndex = 0;
for (int i = 0; i < values.length; i++) {
int value = values[i];
if (value % 2 == 0) {
// swap from i to borderIndex
for (int j = i; j > borderIndex; j--) {
values[j] = values[j - 1];
values[j - 1] = value;
}
borderIndex++;
}
}
You can also do it like this. In this case your sorting them on their inherent nature as opposed to their relationship to each other.
Integer [] arr = {4, 5, 8, 16, 45, 12, 67, 13};
Arrays.sort(arr, Comparator.comparing(a->a % 2));
System.out.println(Arrays.toString(arr));
prints
[4, 8, 16, 12, 5, 45, 67, 13]

Calculating List of cumulative sums from List of integers with Java streams

I have the following list :
INPUT :: 4 5 8 -11 9 5 -7 4 6 -6 -8 -11 80 -32 -56 -15 5 -49
OUTPUT :: 4 9 17 6 15 20 13 17 23 17 9 -2 78 46 -10 -25 -20 -69
I need to calculate cumulative sum - List meaning
T(n) = T(n) + T(n-1) for n >0;
and
T(0) = T(0)
I want to calculate that with Java stream API so that I can implement it with Spark for big data calculation. I am naive in Java Streams I have tried several expressions bt none of them is working
the equivalent stuctured code should be like :
int[] numbers = {4, 5, 8, -11, 9, 5, -7, 4, 6,-6, -8, -11, 80, -32, -56, -15, 5, -49};
int temp = 0;
for (int i = 0 ; i < numbers.length ; i++) {
temp = temp + numbers[i];
numbers[i] = temp;
}
Try this.
int[] a = {4, 5, 8, -11, 9, 5, -7, 4, 6, -6, -8, -11, 80, -32, -56, -15, 5, -49};
Arrays.parallelPrefix(a, (x, y) -> x + y);
System.out.println(Arrays.toString(a));
output:
[4, 9, 17, 6, 15, 20, 13, 17, 23, 17, 9, -2, 78, 46, -10, -25, -20, -69]
Here are two ways of doing it.
The first is very inefficient as it basically uses nested loops to accumulate the values. The first IntStream specfies the range of values and the nested IntStream creates a variable range and sums up the values from 0 to the end of that range.
int[] result1 = IntStream.range(0, vals.length).map(
i -> IntStream.rangeClosed(0, i).map(k->vals[k]).reduce(0, (a, b) -> a + b))
.toArray();
This one is more in line with a more conventional method. Stream a single array of 0 and then use that to accumulate a running sum of the values.
int[] result2 = Stream.of(new int[] { 0 })
.flatMapToInt(k -> IntStream.of(vals).map(v -> {
k[0] += v;
return k[0];
})).toArray();
System.out.println(Arrays.toString(result1));
System.out.println(Arrays.toString(result2));
Both print
[4, 9, 17, 6, 15, 20, 13, 17, 23, 17, 9, -2, 78, 46, -10, -25, -20, -69]
[4, 9, 17, 6, 15, 20, 13, 17, 23, 17, 9, -2, 78, 46, -10, -25, -20, -69]
But you simply can't do any better than this.
for (int i = 1; i < vals.length; i++) {
vals[i] += vals[i-1];
}
Bottom line is to stick with what you have.
You can try using a custom collector.
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> cumulatives = integers.stream().collect(CumulativeAdd.collector());
}
private static final class CumulativeAdd {
List<Integer> retArray= new ArrayList<>();
int sum = 0;
public void accept(Integer num) {
sum +=num;
retArray.add(sum);
}
public CumulativeAdd combine(CumulativeAdd other) {
throw new UnsupportedOperationException("Parallel Stream not supported");
}
public List<Integer> finish() {
return retArray;
}
public static Collector<Integer, ?, List<Integer>> collector() {
return Collector.of(CumulativeAdd::new, CumulativeAdd::accept, CumulativeAdd::combine, CumulativeAdd::finish);
}
}

How could we split an array into two new ones which their weight differences are minimal? [duplicate]

This question already has answers here:
Minimum sum partition of an array
(3 answers)
Closed 2 years ago.
I am doing the following programming exercise: Stone pile. The statement is:
You are given pile of stones with different weights.
Your task is to divide this stone pile into two parts, so the weight
difference between the piles will be minimal. You can't break one
stone into smaller ones.
For example if we have stones:
[1, 2, 3, 4]
We could divide them into:
[2, 3], [1, 4]
So the difference will be 0
If you are given empty stone pile, you can still divide it into two
piles with no stones.
The pile will contain maximum 22 stones. 🗿
Following the examples I have thought:
Sort stones in ascending order
for each stone
if length is even
if movement is even
add min and max to right list
remove them
if movement is odd
add min and max to left list
remove them
if length is odd
if movement is even
add max to left
remove it
if movement is odd
add min to right
remove it
if there are more items
add next min
remove it
So in code would be:
import java.util.*;
import java.util.stream.*;
public class Pile {
public static int minDiff(int[] stones) {
System.out.println("stones: "+Arrays.toString(stones));
Arrays.sort(stones);
System.out.println("stones: "+Arrays.toString(stones));
List<Integer> allStones = Arrays.stream(stones).boxed().collect(Collectors.toList());
System.out.println("allStones: "+Arrays.toString(allStones.toArray()));
ArrayList<Integer> left = new ArrayList<>();
ArrayList<Integer> right = new ArrayList<>();
for(int i = 0; allStones.size()>0; i++){
if(stones.length%2==0){
if(i%2==0){
right.add(allStones.get(0));
right.add(allStones.get(allStones.size()-1));
allStones.remove(0);
allStones.remove(allStones.size()-1);
}else{
left.add(allStones.get(0));
left.add(allStones.get(allStones.size()-1));
allStones.remove(0);
allStones.remove(allStones.size()-1);
}
}else{
if(i%2==0){
left.add(allStones.get(allStones.size()-1));
allStones.remove(allStones.size()-1);
}else{
right.add(allStones.get(0));
allStones.remove(0);
if(allStones.size()>0){
right.add(allStones.get(0));
allStones.remove(0);
}
}
}
}
System.out.println("left: "+Arrays.toString(left.toArray()));
System.out.println("right: "+Arrays.toString(right.toArray()));
return left.stream().mapToInt(Integer::intValue).sum()-right.stream().mapToInt(Integer::intValue).sum();
}
}
Currently it is just working when we test it with inputs where the difference is zero. However if we test it with other inputs, it will fail.
Given the following tests, the first suite will pass, the others fail:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;
public class PersonTest {
#Test
public void testDifferenceShouldBeZero(){
assertEquals(0, Pile.minDiff(new int[]{1, 2, 3}));
assertEquals(0, Pile.minDiff(new int[]{1, 2, 3, 4}));
assertEquals(0, Pile.minDiff(new int[]{5,5,4,3,3}));
}
#Test
public void testDifferenceShouldBeOne(){
assertEquals(1, Pile.minDiff(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}));
}
#Test
public void testDifferenceShouldBeTwo(){
assertEquals(2, Pile.minDiff(new int[]{89409, 34351, 3065, 10128, 27694, 27585, 87350, 33875, 2658, 41606, 57512, 73368, 83345, 37048, 31827, 94644, 15972, 74813, 31441, 70395}));
}
}
For example, when stones are: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
Trace is:
stones: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
stones: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
allStones: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
left: [2, 21, 4, 19, 6, 17, 8, 15, 10, 13]
right: [1, 22, 3, 20, 5, 18, 7, 16, 9, 14, 11, 12]
Being the result:
expected:<1> but was:<-23>
How could we split the stone pile in two chunks where the difference is the minimum, for the general case?
We have read:
Make copy of an array
How to convert int[] into List<Integer> in Java?
How to get the last value of an ArrayList
Is there possibility of sum of ArrayList without looping
I would use bit combination to divide the stones into two groups and sum up every possible combination, comparing them to choose the one with lowest difference:
import java.util.Arrays;
import java.util.LinkedList;
public class Pile {
/**
* return solution as int, if bit is set use the "bitNumber" as index for stone
* for one side, otherwise for the other
**/
private static int divide(int[] stones) {
int solution = -1;
long minDifference = Long.MAX_VALUE;
for (int n = 0; n < (1 << (stones.length + 1)); n++) {
long sumLeft = 0;
long sumRight = 0;
for (int bit = 0; bit < stones.length; bit++) {
boolean isSet = (n & (1 << bit)) > 0;
if (isSet) {
sumLeft += stones[bit];
} else {
sumRight += stones[bit];
}
}
long diff = Math.abs(sumLeft - sumRight);
if (diff < minDifference) {
solution = n;
minDifference = diff;
}
}
return solution;
}
public static long minDiff(int[] stones) {
int solution = divide(stones);
long sumLeft = 0;
long sumRight = 0;
LinkedList<Integer> left = new LinkedList<>();
LinkedList<Integer> right = new LinkedList<>();
for (int bit = 0; bit < stones.length; bit++) {
boolean isSet = (solution & (1 << bit)) > 0;
if (isSet) {
sumLeft += stones[bit];
left.add(stones[bit]);
} else {
sumRight += stones[bit];
right.add(stones[bit]);
}
}
System.out.println("left: " + Arrays.toString(left.toArray()));
System.out.println("right: " + Arrays.toString(right.toArray()));
return Math.abs(sumRight - sumLeft);
}
}

How to get range to first index when the loop reach end?

I've got List<List<Integer>> with several objects. Each of inner element contains randomly shuffled indexes, for example (it's only a part of indexes).
[1, 4, 5, 2, 0, 3, 6]
[4, 2, 5, 3, 1, 6, 0]
[0, 3, 6, 1, 2, 4, 5]
I've got also an array with some values (int[][] array)
And I need to do a loop for each element to get value from indexes and move forward by 1 index and when I reach last index I need to get value from this index and the first one. After that loop end and sum values. It might look difficult but pictrue will show what I mean. But I dont know how to do this (loop is required for each element, I'm gonna have a massive List of List<Integer> inside and every object gonna have multiple indexes.
I'm reading data from file and write it to array
List<String> result = new ArrayList<>();
int[][] array = new int[][]{};
try (Scanner sc = new Scanner(theFile)) {
while (sc.hasNext()) {
result.add(sc.nextLine());
}
int max = Integer.parseInt(result.get(0).trim());
array = new int[max][max];
for (int i = 1; i < result.size(); i++) {
String[] tmp = result.get(i).trim().split(" ");
for (int j = 0; j < tmp.length; j++) {
array[i - 1][j] = Integer.parseInt(tmp[j]);
array[j][i - 1] = array[i - 1][j];
}
}
List<List<Integer>> collectionWithSubjects = new ArrayList<>();
for (int i = 0; i < 40; i++) {
List<Integer> sub = new ArrayList<>();
sub = sequence(0,51);
Collections.shuffle(sub);
collectionWithSubjects.add(sub);
}
You've done a decent job of explaining the problem. It sounds like you're getting caught up on trying to do everything in a single for loop, rather than breaking down the problem into two pieces.
This is your statement:
I need to do a loop for each element to get value from indexes and move forward by 1 index and when I reach last index I need to get value from this index and the first one.
This can be divided into two pieces:
I need to do a loop for each element to get value from indexes and move forward by 1 index
This is a for loop that iterates from 0 -> size() - 1. If we go from 0 -> size() we get an overflow.
for(int i = 0; i < list.size() - 1; i++) {
int firstCoord = list.get(i);
int secondCoord = list.get(i+1);
//do stuff
}
when I reach last index I need to get value from this index and the first one.
This is getting the last element and the first element.
int firstCoord = list.get(list.size() - 1);
int secondCoord = list.get(0);
Combine both together and you've got the framework for getting the coordinates.
for(int i = 0; i < list.size() - 1; i++) {
int firstCoord = list.get(i);
int secondCoord = list.get(i+1);
//do stuff
}
int firstCoord = list.get(list.size() - 1);
int secondCoord = list.get(0);
//do stuff
I'll leave the actual implementation up to you.
// given array
int[][] array = [[31, 21, 34, 22, 67, 14, 41],
[17, 42, 31, 57, 26, 23, 52],
[5, 92, 52, 52, 31, 22, 62],
[17, 42, 31, 57, 26, 23, 52],
[5, 92, 52, 52, 31, 22, 62],
[31, 21, 34, 22, 67, 14, 41],
[5, 92, 52, 52, 31, 22, 62]];
// given list of lists of randomly-ordered indices
List<List<Integer>> indexList = Arrays.toList([
Arrays.toList([1, 4, 5, 2, 0, 3, 6]),
Arrays.toList([4, 2, 5, 3, 1, 6, 0]),
Arrays.toList([0, 3, 6, 1, 2, 4, 5])
]);
// first, create a place to store the sums corresponding to each random list
List<Integer> sums = new ArrayList<Integer>();
// iterate over each of the lists of random elements
for(List<Integer> randomIndices: indexList){
// create a running sum for this list
int randomSum = 0;
// iterate over each element of the randomized index list
for(int j = 0; j < randomIndices.size(); j++){
// read the current and next index (using modulo to wrap around)
current = randomIndices.get(j);
next = randomIndices.get((j + 1) % randomIndices.size());
// add the relevant index in array to the running sum
randomSum += array[current][next];
}
// add the recorded randomSum to the sums list.
// Its index is the same as the random list we just iterated over
sums.add(randomSum);
}
System.out.println(sums);
You may iterate over the alues of each List<Integer> then look them by pair (use % to go back at the beginning) and use them to index the 2d array
for (List<Integer> l : list) {
int sum = 0;
for (int i = 0; i < l.size(); i++) {
int p1 = l.get(i % l.size());
int p2 = l.get((i + 1) % l.size());
sum += values[p1][p2];
}
System.out.println(sum);
}
With this as initial data
List<List<Integer>> list = List.of(List.of(1, 4, 5, 2, 0, 3, 6), List.of(4, 2, 5, 3, 1, 6, 0));
int[][] values = new int[][]{new int[]{31, 21, 34, 22, 67, 14, 41}, new int[]{17, 42, 31, 57, 26, 23, 52}, new int[]{5, 92, 52, 52, 31, 22, 62},
new int[]{17, 42, 31, 57, 26, 23, 52}, new int[]{5, 92, 52, 52, 31, 22, 62}, new int[]{31, 21, 34, 22, 67, 14, 41}, new int[]{5, 92, 52, 52, 31, 22, 62},};
it'll print
253
262

Categories