How to replace recursion in my code on Java? - java

This code calculates the number of permutations for four points by 3 (no repetitions).
Arranged with recursion, but this is awkward for me.
import java.util.*;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1,2,3,4};
System.out.println("no repetitions:");
p1(0,0, points);
}
static void p1(int nowPosition, int sizeArray, int[] points) {
if (nowPosition == POINTS_ON_LINE) {
System.out.println("Output:");
System.out.println(Arrays.toString(temp));
} else {
for(int i = sizeArray + 1; i <= TOTAL_POINTS; i++) {
temp[nowPosition] = points[i-1];
p1(nowPosition + 1, i, points);
}
}
}
}
Output:
no repetitions:
Output:
[1, 2, 3]
Output:
[1, 2, 4]
Output:
[1, 3, 4]
Output:
[2, 3, 4]
It is necessary to get rid of the recursive method call p1.
I tried to do so:
import java.util.*;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1,2,3,4};
System.out.println("no repetitions:");
p1(points);
}
static void p1(int[] points) {
int sizeArray = points.length;
for(int i = sizeArray + 1; i < TOTAL_POINTS; i++, sizeArray = i) {
int nowPosition = 0;
if(nowPosition == POINTS_ON_LINE) {
System.out.println("Output: " + Arrays.toString(temp));
} else {
temp[nowPosition] = points[i-1];
nowPosition++;
}
}
}
}
Result - Output on console - empty.
It didn't work for me.
How to replace recursion?
Method # 1 (thanks for the suggested option - #deadshot)
package com.company;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1, 2, 3, 4};
System.out.println("no repetitions:");
p1(points, POINTS_ON_LINE);
}
public static void p1(int[] arr, int base) {
int SIZE_ARRAY = arr.length;
List<Integer> indices = IntStream.range(0, base).boxed().collect(Collectors.toList());
for(Integer i : indices) {
System.out.println("- " + i);
}
if (base < SIZE_ARRAY) {
System.out.println("first");
System.out.println(indices.stream().map(idx -> arr[idx]).collect(Collectors.toList()));
boolean flag;
int i;
while (true) {
flag = false;
for (i = base - 1; i >= 0; i--)
if (indices.get(i) != i + SIZE_ARRAY - base) {
flag = true;
break;
}
if (!flag)
return;
indices.set(i, indices.get(i) + 1);
for (int j = i + 1; j < base; j++)
indices.set(j, indices.get(j - 1) + 1);
System.out.println(indices.stream().map(idx -> arr[idx]).collect(Collectors.toList()));
for(Integer x : indices) {
System.out.println("- " + x);
}
}
}
}
}

I have used python itertools.combinations code as reference to implement the method.
public class Main {
static int TOTAL_POINTS = 4, POINTS_ON_LINE = 3;
static int[] temp = new int[POINTS_ON_LINE];
public static void main(String[] args) {
int[] points = new int[]{1, 2, 3, 4};
System.out.println("no repetitions:");
p1(points, POINTS_ON_LINE);
}
public static void p1(int[] arr, int r) {
int n = arr.length, i;
int[] indices = new int[r];
for (i = 0; i < r; i++)
indices[i] = i;
if (r < n) {
for (int idx : indices)
temp[idx] = arr[idx];
System.out.println(Arrays.toString(temp));
boolean flag;
while (true) {
flag = false;
for (i = r - 1; i >= 0; i--)
if (indices[i] != i + n - r) {
flag = true;
break;
}
if (!flag)
return;
indices[i] += 1;
for (int j = i + 1; j < r; j++)
indices[j] = indices[j - 1] + 1;
for (i = 0; i < r; i++)
temp[i] = arr[indices[i]];
System.out.println(Arrays.toString(temp));
}
}
}
}

Related

The method should print the array elements between the indexes a and b including a and not including b in line 1

I don't know how to finish this code. Help someone.
package com.telukhin.hw4;
import java.util.Arrays;
public class Task10 {
public static void main(String[] args) {
int[] arr = new int[10];
list(arr, 2, 5);
}
private static void list(int[] arr, int a, int b) {
if (a >= 0 && b <= arr.length) {
for (int i = a; i < arr[b - 1]; i++) {
System.out.println(Arrays.toString(arr));
}
} else {
System.out.println("unknown");
}
}
} //
First of all, your array is empty. Take a look at the code below. In the for loop I'm checking that the index is between param a and b (including a, excluding b), and simply printing out the current index.
public static void main(String[] args) {
int[] arr = new int[10];
arr[0] = 0;
arr[1] = 1;
arr[2] = 2;
arr[3] = 3;
arr[4] = 4;
arr[5] = 5;
list(arr, 2, 5);
}
private static void list(int[] arr, int a, int b) {
if (a >= 0 && b <= arr.length) {
for (int i = a; i < b; i++) {
System.out.println(arr[i]);
}
} else {
System.out.println("unknown");
}
}
In your example you try to combine to approaches
Custom implementation
Iterate the interval and print each element
for (int i = a; i < b; i++) {
System.out.print(arr[i] + " ");
}
Existing implementation
int[] subArr = Arrays.copyOfRange(arr, a, b);
System.out.print(Arrays.toString(subArr));
You should use only one

Leetcode : Remove Duplicates from Sorted Array

Why this code is not accepted by Leetcode compiler?
My program is running in netbeans. but leetcode compiler is not accepting it.
Here is my code:
import java.util.Arrays;
public class RemoveDuplicateFromArray {
public static int[] removeDuplicates(int[] nums) {
int temp, count = 0 ,l = 0;
temp = nums[0];
for(int i = 1; i < nums.length - (1 + l); i++ ) {
if(temp == nums[i]) {
count = count + 1;
for(int j = i; j < nums.length - count; j++){
nums[j] = nums[j+1];
}
i = i - 1;
} else {
temp = nums[i];
i = i ;
}
l = count;
}
nums = Arrays.copyOfRange(nums, 0, nums.length-count);
if(nums.length == 2){
if(nums[0] == nums[1]){
nums = Arrays.copyOfRange(nums, 0, nums.length-1);
}
}
return nums;
}
Here is my main mathod:
public static void main(String[] args) {
int[] nums = new int[] {1,1,1}; // showing error here.
System.err.println("nums lenght: " +nums.length);
int new_nums[] = removeDuplicates(nums);
for(int i : new_nums) {
System.err.print(i + " ");
}
}
}
The error is :
incompatible types: int[] cannot be converted to int.
I expect leetcode is having trouble with this line:
int new_nums[] = removeDuplicates(nums);
This isn't the typical way to define an integer array (this is the C style). Java does support the syntax, but it's a little arcane. See this answer for more detail.
Try this instead:
int[] new_nums = removeDuplicates(nums);
Just tried this on LeetCode, seems to work:
I would do it a bit like this myself:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
int[] nums = new int[]{1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 7, 7, 7, 8, 9, 0, 0, 0, 0};
System.out.println("nums lenght: " + nums.length);
int[] new_nums = removeDuplicates(nums);
for (int i : new_nums) {
System.out.print(i + " ");
}
}
public static int[] removeDuplicates(int[] nums) {
List<Integer> found = new ArrayList();
for (int i = 1; i < nums.length; i++) {
if (!found.contains(nums[i])) {
found.add(nums[i]);
}
}
int[] ret = new int[found.size()];
for(int i = 0; i < found.size(); i++){
ret[i] = found.get(i);
}
return ret;
}
}
public class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
int i = 0;
int j = 1;
if (n <= 1) {
return n;
}
while (j <= n - 1) {
if (nums[i] != nums[j]) {
nums[i + 1] = nums[j];
i++;
}
j++;
}
return i + 1;
}
}
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
class SolutionTest {
#Test
void removeDuplicates() {
int[] array = new int[] {1, 1, 2};
int end = new Solution().removeDuplicates(array);
assertThat(Arrays.toString(Arrays.copyOfRange(array, 0, end)), equalTo("[1, 2]"));
}
}

Code compiles and executes, but does not print anything

The time-limit-extended is the status when executing the successfully compiled class file of the following code.
import java.io.*;
public class CandidateCode {
public static int ThirstyCrowProblem(int[] input1, int input2, int input3) {
int[] arrK = new int[input3];
int minstones = 0;
for (int i = 0; i < input3; i++) //create an array of k Os.
{
int smallest = input1[0], place = 0;
for (int j = 0; j < input2; j++) {
if ((smallest >= input1[j]) && (input1[j] >= 0)) {
smallest = input1[j];
place = j;
}
}
input1[place] = -1;
arrK[i] = smallest;
}
int n = input2, i = 0;
while (i < input3)
minstones = minstones + arrK[i] * (n - i);
return minstones;
}
public static void main(String[] args) {
int[] arr = new int[] {
5, 58
};
int stones_min = CandidateCode.ThirstyCrowProblem(arr, 2, 1);
System.out.println("The result is" + stones_min);
}
}
The cursor is waiting and waiting, but I don't think there is an error in the code!??
Option A :
Change your while into an if statement :
if(i<input3) {
minstones= minstones + arrK[i]*(n-i);
}
Option B : or increment i (i++) but I don't this that's what you want
while(i<input3) {
minstones = minstones + arrK[i]*(n-i);
i++;
}
You need to increment i in your while loop.Since you are not incrementing,its going in infinite loop.
while(i<input3)
{
minstones= minstones + arrK[i]*(n-i);
i++;
}
After making this change,I got
The result is10

Waffle Stacking Algorithm needs improvement

I am working on a problem called Waffle Stacking. I am aware that a question already exists but the post needed to know where to start but I already have most of it done. The problem can be seen here: http://www.hpcodewars.org/past/cw16/problems/Prob20--WaffleStacking.pdf
My algorithm calculates the 120 permutations (5!) of the String "12345". I then place then row by row and make sure that they match the side clues. Then I check if it so far matches the top side. (Meaning that I go through the tiles that I currently have and I find the tallest stack and I look for the unused stacks and check if they are higher than the current highest stack and then I can see if I use the unused stacks they will match the clue). Using the example, my algorithm is very flawed. It produces only 4 rows and only one is correct. I believe it is due to checking the column. Any help is apprectated with checking the top and bottom sides.
package HP2013;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class WaffleStacking
{
public static String t[];
public static String l[];
public static String r[];
public static String b[];
public static void getInput()
{
try{
Scanner keyb = new Scanner(new File("src/HP2013/WaffleStacking.dat"));
t = keyb.nextLine().split(" ");
l = new String[5];
r = new String[5];
for (int i = 0; i < 5; i++)
{
String a[] = keyb.nextLine().split(" ");
l[i] = a[0];
r[i] = a[1];
}
b = keyb.nextLine().split(" ");
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static ArrayList<String> perms = new ArrayList<String>();
public static void getPerms(String s)
{
getPerms("", s);
}
public static void getPerms(String pfx, String s)
{
int n = s.length();
if (n == 0)
perms.add(pfx);
else
{
for (int i = 0; i < s.length(); i++)
getPerms(pfx + s.charAt(i) + "", s.substring(0, i) + s.substring(i + 1));
}
}
public static void solve()
{
int mat[][] = new int[5][5];
for (int r = 0; r < 5; r++)
{
String row = "";
for (int p = 0; p < perms.size(); p++)
{
if (goodRow(perms.get(p), r))
{
row = perms.get(p);
for (int c = 0; c < row.length(); c++)
mat[r][c] = Integer.valueOf(row.charAt(c) + "");
if (uniqueCol(mat, r + 1) && goodCol(mat, r + 1))
break;
else
{
mat[r] = new int[] {0, 0, 0, 0, 0}.clone();
}
}
}
}
for (int m[] : mat)
System.out.println(Arrays.toString(m));
}
public static boolean uniqueCol(int mat[][], int rStop)
{
for (int c = 0; c < mat.length; c++)
{
ArrayList<Integer> col = new ArrayList<Integer>();
for (int r = 0; r < rStop; r++)
col.add(mat[r][c]);
Collections.sort(col);
for (int i = 0; i < col.size() - 1; i++)
if (col.get(i) == col.get(i + 1))
return false;
}
return true;
}
public static boolean goodRow(String row, int index)
{
int left = 0;
int max = -1;
for (int i = 0; i < row.length(); i++)
{
int stack = Integer.valueOf(row.charAt(i) + "");
if (stack > max)
{
left++;
max = stack;
}
}
int right = 0;
max = -1;
for (int i = row.length() - 1; i >= 0; i--)
{
int stack = Integer.valueOf(row.charAt(i) + "");
if (stack > max)
{
right++;
max = stack;
}
}
if (left == Integer.valueOf(l[index]) && right == Integer.valueOf(r[index]))
return true;
return false;
}
public static boolean goodCol(int mat[][], int rStop)
{
return checkTop(mat, rStop);
}
public static boolean checkTop(int mat[][], int rStop)
{
for (int c = 0; c < 5; c++)
{
int left = Integer.valueOf(t[c] + "");
int max = -1;
String used = "";
for (int r = 0; r < rStop; r++)
{
int stack = mat[r][c];
used += stack;
if (stack > max)
{
max = stack;
left--;
}
}
ArrayList<Integer> leftovers = new ArrayList<Integer>();
for (int n = 1; n <= 5; n++)
{
if (!used.contains(n + ""))
leftovers.add(n);
}
for (int j = 0; j < leftovers.size(); j++)
{
if (leftovers.get(j) > max)
{
max = leftovers.get(j);
left--;
}
}
if (left > 0)
return false;
}
return true;
}
public static void main(String args[])
{
getInput();
getPerms("12345");
solve();
}
}
Input:
2 2 3 2 1
4 1
1 4
3 2
2 2
3 2
3 2 1 3 4
Output:
[1, 3, 2, 4, 5]
[5, 1, 4, 3, 2]
[2, 4, 1, 5, 3]
[3, 2, 5, 1, 4]
[0, 0, 0, 0, 0]
So the first problem I see is no way to jump out when you've found a good answer. You're loops are probably continuing on after they've found the correct answer and unrolling to a point where you're losing the last row because of your else clause for a bad match.
Bottom side checking was not the problem, I overthought it; It should be very similar to top side checking. The solve method was very faulty and I switched to a recursive solution which ended up solving the problem. That way I can try several possibilities of valid rows while maintaining unique columns and then check if the columns were valid as well. If they weren't I can continue trying different possibilities.

Filtering out ints on an array

method takes in an array of ints and returns the new array of ints without even ints. Ive written something up but cannot get the print right in the main method....heres what I have
//filterAway method taking out evens from string
public static int[] filterArray(int[] x){
int [] arrayOne;
int size = 0;
for(int i=0; i<x.length; i++){
if(x[i] % 2 != 0){
size++;
}
}
arrayOne = new int [size];
int index =0;
for(int i=0; i<x.length; i++){
if(x[i] % 2 != 0){
arrayOne[index] = x[1];
index++;
}
}
return arrayOne;
}
//main
public static void main(String args[]){
int[] f = {1,2,3,4,5,6,7,8,9,10,11,12};
for (int i =0; i <f.length; i++){
System.out.print(f[i] + " ");
}
System.out.println(" ");
//here is where im struggling.
int [] fA= (filterAway); // say the string is 1-12....cannot get
// filtered array to print
for (int i =0; i <fA.length; i++){
System.out.print(arrayOne[i] + " ");
}``
System.out.println(" ");
}
Fixing the Display Problem
Try this revised main method, just replace YourClassName with your class name:
public static void main(String args[]) {
int[] f = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
for (int i = 0; i < f.length; i++) {
System.out.print(f[i] + " ");
}
System.out.println(" ");
// here is where im struggling.
int[] fA = YourClassName.filterArray(f);
// filtered array to print
for (int i = 0; i < fA.length; i++) {
System.out.print(fA[i] + " ");
}
System.out.println(" ");
}
However, you'll see you might end up getting something like 2, 2, 2, 2 there. You need to revisit your filterArray function.
Fixing the filterArray function
Since the title of your question is Filtering Out Ints in Java, here's the culprit, change 1 to i, that's why it gives out 2, 2, 2, 2. Also, you want even numbers, so you should look for 0 modulo, change your comparator to ==, instead of !=.
Here's what you should do with your requirements:
package com.sandbox;
public class Sandbox {
public static void main(String[] args) {
int[] all = new int[]{1, 2, 3, 4, 5, 6};
int[] filtered = odds(all);
for (int i : filtered) {
System.out.println(i);
}
}
private static int[] odds(int[] all) {
int sizeOfResult = 0;
for (int i : all) {
if (isOdd(i)) {
sizeOfResult++;
}
}
int[] result = new int[sizeOfResult];
int resultIndex = 0;
for (int i : all) {
if (isOdd(i)) {
result[resultIndex] = i;
resultIndex++;
}
}
return result;
}
private static boolean isOdd(int i) {
return i % 2 != 0;
}
}
Here's what I'd do if I were writing this on my own though: I'd use a List instead of an array, and I'd use CollectionUtils.filter. Here's a snippet of code that will do what you want:
package com.sandbox;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.primitives.Ints.asList;
public class Sandbox {
public static void main(String[] args) {
List<Integer> result = new ArrayList<Integer>(asList(1, 2, 3, 4, 5, 6));
CollectionUtils.filter(result, new Predicate() {
#Override
public boolean evaluate(Object o) {
return isOdd((Integer) o);
}
});
for (Integer integer : result) {
System.out.println(integer);
}
}
private static boolean isOdd(int i) {
return i % 2 != 0;
}
}
You will need to pass your f[] as an argument to your filterAway() method.
public static void main(String args[]){
int[] f = {1,2,3,4,5,6,7,8,9,10,11,12};
for (int i =0; i <f.length; i++){
System.out.print(f[i] + " ");
}
System.out.println(" ");
int [] fA= filterArray(f);
for (int i =0; i <fA.length; i++){
System.out.print(fA[i] + " ");
}
System.out.println();
}

Categories

Resources