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.
Related
It fails at the example [0,0,1], the output is [0,1,0] instead of [1,0,0]. I have gone through the code in debugging mode and when p1 becomes 0, it jumps out of the for loop and I don't understand why, because it should go through the loop one more time and then decrement to -1 and exit the loop.
Given an integer array nums, move all 0's to the end of it while maintaining the relative order of the non-zero elements.
Note that you must do this in-place without making a copy of the array.
Example 1:
Input: nums = [0,1,0,3,12] Output: [1,3,12,0,0]
Example 2:
Input: nums = [0] Output: [0]
package random.leetCode;
import java.util.Arrays;
public class MoveZeroes_TwoPointers_283 {
public void moveZeroes(int[] nums) {
int p2 = 0;
int tempIndex = 0;
int lastIndex = nums.length - 1;
for (int p1 = nums.length - 1; p1>=0; p1--)
{
if (nums[p1] == 0)
{
if (p1 == nums.length - 1 && nums.length == 1)
{
break;
}
tempIndex = p1;
p2 = p1 + 1;
while (p2 <= lastIndex)
{
int temp = nums[p1];
nums[p1] = nums[p2];
nums[p2] = temp;
p2 += 1;
p1 += 1;
}
p1 = tempIndex -1;
lastIndex--;
}
}
}
public static void main(String[] args) {
MoveZeroes_TwoPointers_283 example = new MoveZeroes_TwoPointers_283();
// int[] numbersToBeSorted = new int[]{0,1,0,3,12,0,11,0,0};
// int[] numbersToBeSorted = new int[]{0};
// int[] numbersToBeSorted = new int[]{0,0};
// int[] numbersToBeSorted = new int[]{1};
// int[] numbersToBeSorted = new int[]{1,1};
int[] numbersToBeSorted = new int[]{0,0,1};
example.moveZeroes(numbersToBeSorted);
System.out.println(Arrays.toString(numbersToBeSorted));
}
}```
for (int p1 = nums.length - 1; p1>=0; p1--) {
...
tempIndex = p1;
...
p1 = tempIndex -1;
}
You are decrementing p1 twice in this loop. You probably did not mean to.
Interesting. I think the problem is when you find two consecutive zeros and managing these pointers. Let me know what you think about this algorithm.
void main() {
int[] input = new int[]{0,0,1};
// whenever finds a zero, move it to the end
for (int i=0; i < input.length; i++) {
if (input[i] == 0) moveToEnd(i, input);
}
System.out.println(input);
}
// move to the end by swapping elements
void moveToEnd(pos, arr) {
for (int i = pos + 1; i < arr.length; i++) {
int aux = arr[pos];
arr[pos] = arr[i];
arr[i] = aux;
post = i;
}
}
Question : Given a sorted array nums, remove the duplicates in-place such that each element appears only once and returns the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int i = 0;
for (int j = 1; j < nums.length; j++) {
if (nums[j] != nums[i]) {
i++;
nums[i] = nums[j];
}
}
return i + 1;
}
What exactly does the return statement do here. What does return i + 1 mean here ?
The return i + 1 is returning how many unique integers are there. I believe this is a Leetcode problem, and since its in place, the int[] is passed in by reference, Leetcode wants to know how many numbers to check (you're supposed to put the unique numbers in the first i + 1 spots).
If you look at the question, it says:
Which means that you return the length of the array.
So, if you have the array [1,1,2,3,4,4], you would turn that into [1,2,3,4,...], where the ... is the rest of the array. However, you return 4 because the length of the new array should be 4.
Hope this clears things up for you!
Your question has been already answered here; in addition to that, we can also start from zero and remove the first if statement:
Test with a b.java file:
import java.util.*;
class Solution {
public static final int removeDuplicates(
final int[] nums
) {
int i = 0;
for (int num : nums)
if (i == 0 || num > nums[i - 1]) {
nums[i++] = num;
}
return i;
}
}
class b {
public static void main(String[] args) {
System.out.println(new Solution().removeDuplicates(new int[] { 1, 1, 2}));
System.out.println(new Solution().removeDuplicates(new int[] { 0, 0, 1, 1, 1, 2, 2, 3, 3, 4}));
}
}
prints
2
5
I tried in this easy way. Here Time complexity is O(n) and space
complexity: O(1).
static int removeDuplicates(int[] nums){
if(nums.length == 0) {
return 0;
}
int value = nums[0];
int lastIndex = 0;
int count = 1;
for (int i = 1; i < nums.length; i++) {
if(nums[i] > value) {
value = nums[i];
lastIndex = lastIndex+1;
nums[lastIndex] = value;
count++;
}
}
return count;
}
class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
if (n == 0 || n == 1)
return n;
int j = 0;
for (int i=0; i<n-1; i++)
if (nums[i]!= nums[i+1])
nums[j++] = nums[i];
nums[j++]=nums[n-1];
return j;
}
}
public class RemoveDuplicateSortedArray {
//Remove Duplicates from Sorted Array
public static void main(String[] args) {
int[] intArray = new int[]{0, 0, 1, 1, 1, 2, 2, 3, 3, 4};
int count = extracted(intArray);
for (int i = 0; i < count; i++) {
System.out.println(intArray[i]);
}
}
private static int extracted(int[] intArray) {
int size = intArray.length;
int count = 1;
if (size == 1) {
return 1;
} else if (size == 2) {
if (intArray[0] == intArray[1]) {
return 1;
} else {
return 2;
}
} else {
for (int i = 0, j = i + 1; j < size; j++) {
if (intArray[i] < intArray[j]) {
i++;
intArray[i] = intArray[j];
count++;
}
}
return count;
}
}
}
I am having issues with my code it is returning 1 when it should be returning 2. The pairs I have are: new CityPairs(6, 2), new CityPairs( 4, 3 ), new CityPairs( 2, 6) , new CityPairs( 1, 5 ). Which it should return 2 bridges but is returning 1. Below is my code.
class CityPairs {
int north, south;
public CityPairs(int north, int south){
this.north = north;
this.south = south;
}
}
class CityPairsDriver {
// function to find the maximum number
// of bridges that can be built
static int maxBridges(CityPairs values[], int n) {
int lis[] = new int[n];
for (int i = 0; i < n; i++)
lis[i] = 1;
Arrays.sort(values, new Comparator<CityPairs>() {
#Override
public int compare(CityPairs a, CityPairs b) {
if (a.south == b.south)
if (a.north < b.north)
return -1;
else
return 1;
else {
if (a.south < b.south)
return 1;
else
return 1;
}
}
});
// logic of longest increasing subsequence
// applied on the northern coordinates
for (int i = 1; i < n; i++)
for (int j = 0; j < i; j++)
if (values[i].north >= values[j].north && lis[i] < 1 + lis[j])
lis[i] = 1 + lis[j];
int max = lis[0];
for (int i = 1; i < n; i++)
if (max < lis[i])
max = lis[i];
// required number of bridges
// that can be built
return max;
}
// Driver program to test above
public static void main(String args[]) {
CityPairs values[] = { new CityPairs(6, 2), new CityPairs( 4, 3 ), new CityPairs( 2, 6) , new CityPairs( 1, 5 ) };
int n = 4;
System.out.println("Maximum number of bridges = " + maxBridges(values, n));
}
}
I based my answer off of this:
https://www.geeksforgeeks.org/dynamic-programming-building-bridges/
you have 3 return that return the same value i think you need to change the last one
so your problem is in the compare function
I have made this program using array concept in java. I am getting Exception as ArrayIndexOutOfBound while trying to generate product.
I made the function generateFNos(int max) to generate factors of the given number. For example a number 6 will have factors 1,2,3,6. Now,i tried to combine the first and the last digit so that the product becomes equal to 6.
I have not used the logic of finding the smallest number in that array right now. I will do it later.
Question is Why i am getting Exception as ArrayIndexOutOfBound? [i couldn't figure out]
Below is my code
public class SmallestNoProduct {
public static void generateFNos(int max) {
int ar[] = new int[max];
int k = 0;
for (int i = 1; i <= max; i++) {
if (max % i == 0) {
ar[k] = i;
k++;
}
}
smallestNoProduct(ar);
}
public static void smallestNoProduct(int x[]) {
int j[] = new int[x.length];
int p = x.length;
for (int d = 0; d < p / 2;) {
String t = x[d++] + "" + x[p--];
int i = Integer.parseInt(t);
j[d] = i;
}
for (int u = 0; u < j.length; u++) {
System.out.println(j[u]);
}
}
public static void main(String s[]) {
generateFNos(6);
}
}
****OutputShown****
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
at SmallestNoProduct.smallestNoProduct(SmallestNoProduct.java:36)
at SmallestNoProduct.generateFNos(SmallestNoProduct.java:27)
at SmallestNoProduct.main(SmallestNoProduct.java:52)
#Edit
The improved Code using array only.
public class SmallestNoProduct {
public static void generateFNos(int max) {
int s = 0;
int ar[] = new int[max];
int k = 0;
for (int i = 1; i <= max; i++) {
if (max % i == 0) {
ar[k] = i;
k++;
s++;
}
}
for (int g = 0; g < s; g++) {
System.out.println(ar[g]);
}
smallestNoProduct(ar, s);
}
public static void smallestNoProduct(int x[], int s) {
int j[] = new int[x.length];
int p = s - 1;
for (int d = 0; d < p;) {
String t = x[d++] + "" + x[p--];
System.out.println(t);
int i = Integer.parseInt(t);
j[d] = i;
}
/*for (int u = 0; u < j.length; u++) {
System.out.println(j[u]);
}*/
}
public static void main(String s[]) {
generateFNos(6);
}
}
Maybe it better:
public class SmallestNoProduct {
public static int smallest(int n) {
int small = n*n;
for(int i = 1; i < Math.sqrt(n); i++) {
if(n%i == 0) {
int temp = Integer.parseInt(""+i+""+n/i);
int temp2 = Integer.parseInt(""+n/i+""+i);
temp = temp2 < temp? temp2: temp;
if(temp < small) {
small = temp;
}
}
}
return small;
}
public static void main(String[] args) {
System.out.println(smallest(6)); //6
System.out.println(smallest(10)); //25
System.out.println(smallest(100)); //205
}
}
Problem lies in this line
String t=x[d++]+""+x[p--];
x[p--] will try to fetch 7th position value, as p is length of array x i.e. 6 which results in ArrayIndexOutOfBound exception. Array index starts from 0, so max position is 5 and not 6.
You can refer this question regarding postfix expression.
Note: I haven't checked your logic, this answer is only to point out the cause of exception.
We are unnecessarily using array here...
below method should work....
public int getSmallerMultiplier(int n)
{
if(n >0 && n <10) // if n is 6
return (1*10+n); // it will be always (1*10+6) - we cannot find smallest number than this
else
{
int number =10;
while(true)
{
//loop throuogh the digits of n and check for their multiplication
number++;
}
}
}
int num = n;
for(i=9;i>1;i--)
{
while(n%d==0)
{
n=n/d;
arr[i++] = d;
}
}
if(num<=9)
arr[i++] = 1;
//printing array in reverse order;
for(j=i-1;j>=0;j--)
system.out.println(arr[j]);
I am trying to write a program which can solve the 8-Puzzle problem.I am using the A* algorithm to find the solution.
I have reviewed my code many times and also tried making some changes.
Even my friends tried to help me find the bug,but they couldn't. I still don't understand where i went wrong.I used javadocs to see if I did something wrong,even that din't solve my problem. I have created three classes to solve this problem.
import java.util.*;
public class Solver implements Iterable<State>
{
ArrayList<State> queue,solQueue;
public int sol[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 0 } };
int temp[][],i;
int moves;
int leastPriority,removeIndex;
State removeTemp;
public Solver(State initial)
{
queue = new ArrayList<State>();
solQueue = new ArrayList<State>();
queue.ensureCapacity(16);
solQueue.ensureCapacity(16);
temp = new int[3][3];
i=1;
leastPriority = 100;
removeTemp=initial;
queue.add(removeTemp);
Iterator<State> qu = queue.iterator();
while(removeTemp.m!=sol)
{
leastPriority = 100;
i=0;
queue.iterator();
for (State s : queue)
{
if((s.mh + s.count) <leastPriority)
{
leastPriority = (s.mh + s.count);
removeIndex = i;
}
if(qu.hasNext())
i++;
}
for(State s : removeTemp.neighbours() )
{
queue.add(s);
}
removeTemp=queue.remove(removeIndex);
solQueue.add(removeTemp);
}
this.moves();
this.solution();
}
public int moves()
{
System.out.print("Solution found out in "+ moves+" moves");
moves = removeTemp.count;
return moves;
}
public Iterable<State> solution()
{
for(State s : solQueue)
{
System.out.println(s.m);
System.out.println("");
}
return solQueue;
}
#SuppressWarnings({ "unchecked", "rawtypes" })
#Override
public Iterator iterator() {
return null;
}
}
And the JVM is throwing an exception.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0,Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at Solver.<init>(Solver.java:41)
at Main.main(Main.java:13)
What i don't understand is that how can the size of the ArrayList be 1 when i have explicitly state it as 16.
The State Class has the heuristic function which is suppose to make the algorithm efficient.The following is the State Class.
import java.util.ArrayList;
import java.util.Iterator;
public class State implements Iterable<State>
{
public int sol[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 0 } };
int m[][], bi, bj, count, priority, si, sj;
int i,j,tempm[][];
int mh = 0;
boolean isInitialState, isRepeatedState;
State previousState, tempState;
ArrayList<State> neighbourStates;
public State(State s, int c, int[][] array)
{
neighbourStates = new ArrayList<State>();
neighbourStates.ensureCapacity(16);
tempState =this;
m = new int[3][3];
m=array;
if (s == null)
{
isInitialState = true;
count = 0;
previousState =null;
}
else
{
previousState = s;
count = c+1;
}
this.findZero();
this.manhattanHeuristic();
}
private void findZero()
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
{
if(m[i][j]==0)
{
bi=i;
bj=j;
}
}
}
private void manhattanHeuristic() {
int n = 1;
mh = 0;
for (int i = 0; i < 3; i++)
Z: for (int j = 0; j < 3; j++) {
if ((i == bi) && (j == bj)) {
continue Z;
}
else if (m[i][j] == n) {
n++;
}
else {
this.getSolutionIndex();
mh = mh + Math.abs(i - si) + Math.abs(j - sj);
}
}
}
void getSolutionIndex() {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
if (m[i][j] == 0) {
si = i;
sj = j;
}
}
}
public Iterable<State> neighbours()
{
tempm = m;
this.up();
if(!(equals(tempm)))
{
tempState = new State(this,count,tempm);
neighbourStates.add(tempState);
}
this.down();
if(!(equals(tempm)))
{
tempState = new State(this,count,tempm);
neighbourStates.add(tempState);
}
this.left();
if(!(equals(tempm)))
{
tempState = new State(this,count,tempm);
neighbourStates.add(tempState);
}
this.right();
if(!(equals(tempm)))
{
tempState = new State(this,count,tempm);
neighbourStates.add(tempState);
}
return neighbourStates;
}
public boolean equals(int s[][])
{
if((isInitialState==false)&&(previousState.m == s))
return true;
else
return false;
}
#Override
public Iterator<State> iterator() {
// TODO Auto-generated method stub
return null;
}
public void up()
{
if ((bi > 1) && (bi < 2) && (bj < 3)&& (bj > 1))
{
i = bi;
i = i + 1;
this.move(i,bj);
}
}
public void down()
{
if ((bi > 2) && (bi < 3) && (bj < 3) && (bj > 1))
{
i = bi;
i = i - 1;
this.move(i,bj);
}
}
public void left()
{
if ((bi > 1) && (bi < 3) && (bj < 2)&& (bj > 1)) {
j = bj;
j = j + 1;
this.move(bi, j);
}
}
public void right()
{
if ((bi > 1) && (bi < 3) && (bj < 3) && (bj > 2)) {
j = bj;
j = j - 1;
this.move(bi, j);
}
}
public void move(int x, int y) {
{
tempm = m;
}
if ((tempm[x + 1][y] == 0) || (tempm[x - 1][y] == 0) || (tempm[x][y + 1] == 0)|| (tempm[x][y - 1] == 0)) {
tempm[bi][bj] = tempm[x][y];
tempm[x][y] = 0;
bi = x;
bj = y;
}
}
}
And the finally the class with the main function.
import java.util.Scanner;
public class Main {
public static void main(String[] args)
{
#SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
int[][] tiles = new int[3][3];
System.out.println("Enter the elements");
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
tiles[i][j] = sc.nextInt();
State initial = new State(null,0,tiles);
Solver solver = new Solver(initial);
solver.solution();
System.out.println("Minimum number of moves = " + solver.moves());
}
}
What i don't understand is that how can the size of the ArrayList be 1 when i have explicitly state it as 16.
You did not set the size of the ArrayList to 16. You've set the capacity:
queue.ensureCapacity(16);
solQueue.ensureCapacity(16);
This does not make the ArrayList have a size of 16.
An ArrayList has an array to hold its data. When you add more elements to the ArrayList and its internal array is full, it will have to allocate a larger array and copy the content of what it currently holds plus the new element.
The capacity of the ArrayList is the minimum size that the internal array has. You can use ensureCapacity to make sure that the ArrayList doesn't have to resize too often (resizing and copying the content is an expensive operation). So, ensureCapacity is a call you make to make it work effiently.
It does not make the ArrayList have 16 elements; it only makes sure that the ArrayList has room for at least 16 elements.
If you want the ArrayList to have 16 elements, you'll have to add those elements one by one.
Size of the collection and the capacity are 2 different concepts.
capacity represents the maximum size of items a collection can hold without a reallocation.
size represents the current number of items in the collection.
IndexOutOfBoundsException is saying that you are trying to access an item with index that does not exist in the collection.
please try the below code in Solver.java
if(!queue.isEmpty())
removeTemp=queue.remove(removeIndex);
else
break;