- mark[1,0]=1; top=1; stack[top].row=1; stack[top].col=0;
stack[top].dir=1; while (top>0) {
loc = pop();
cr=loc.row; cc=loc.col; cd=loc.dir;
while (cd <= 4) {
nr=cr+move[cd].r; nc=cc+move[cd].c;
if (nr==grow && nc==gcol) {
for(i=0; i<=top; i++) printLoc(stack[i]);
print(cr, cc); print(grow, gcol);
return;
}
if (maze[nr][nc]==0 && mark[nr][nc]==0) {
mark[nr][nc] = 1;
loc.row=cr; loc.col=cc; loc.dir=cd+1;
push(loc);
cr=nr; cc=nc; cd=1;
}
else cd=cd+1;
} } print(“no path in maze”);
I've been looking at this algorithm for about an hour but still can't understand it.
I understand that col/row/direction = column, row, direction, and mark means a 2-dimensional array. But I can't get how to implement this algorithm and turn it into code since I can't understand how it works.
Could someone explain this algorithm, please?
More info: 1 = 0,1(move right), 2 = 1,0(move down), 3 = 0, -1(move left), 4 = -1,0(move up). To store the path use stack. If you use stack choose depth-first search, if you use queue choose breadth-first search. 1 is the blocked path while 0 is the path you can walk on.
Related
I'm trying to find a simple path of length N in a RxC matrix, given a starting cell. The path should follow a restriction, given by a boolean function. The goal is to later use this to find the longest path in the matrix.
I got a solution set up, however I don't know how to modify it to know when a solution does not exist.
My solution consists of a DFS approach using backtracking. The solution is correct when there is one, but the program returns the longest path found instead of saying such path doesn't exist.
I know there are similar problems with solutions available but I'd like to understand where my logic is failing.
Here's the code (from a cell we can move in all 8 directions):
Bool DFS(Map *map,Point* srcPt,short steps,Bool (*restrictionCompare)(Point *p1, Point *p2))
{
Point *target;
short row = getPointRow(srcPt);
short col = getPointCol(srcPt);
// Found N-steps path!
if (steps == 0)
{
puts("Path found!\n");
return 1;
}
//Mark the M[row][col] as visited
markAsVisited(map,row,col);
// Iterate over all 8 directions of a cell
for (short i = 0; i < DIRECTIONS; ++i)
{
short coords[2];
// Get a valid adjacent cell
if (getNeighbour(map,srcPt,i,coords,restrictionCompare) == FALSE) continue;
target = getMapPoint(map,coords[0],coords[1]); // This is the valid neighbour
//if cell wasn't visited before...
if (isVisited(target) == FALSE)
{
// ..recursively call DFS from cell
if(DFS(map,target,--steps,restrictionCompare) == TRUE)
{
// Show point
showPoint(target);
return TRUE;
}
}
}
// Backtrack
markAsUnvisited(map,row,col);
return FALSE;
}
An example of path of length found by the program:
Any suggestions on how to improve the code's efficiency is also welcome.
I'm making my very first text adventure game but keep getting an error thrown at me. I honestly have no clue what's going on or how to even start fixing the issue. I'll post my code and the error message I'm receiving exactly.
PFont computer; //creates a variable for the font to be used
int level = 0; //starting level
int branch = 0; //starting level
String[][] textOptions = new String[][]{
{"Welcome to our text adventure. You are in a room.\n" //new line
+ "It looks like no one has been in here for years.\n"
+ "Would you like to look around? Y/N",""},
{"You decide to look around the room.\n"
+ "You stand by your initial observation.\n"
+ "The room is covered in a thick layer of dust with cobwebs reaching out in every corner.\n"
+ "There are a few shelves, lined with decaying boxes and files. The terminal you are looking for is nowhere to be seen. \n"
+ "You are now in a hallway. There are two rooms to explore. L/R?",
"You decide to leave this room. You are now in a hallway.\n"
+ "There are two rooms to explore. L/R?"},
{"You decide to check the room to the right.",
"You decide to check the room to the left."},
};
void setup()
{
size(1350,700);
computer = createFont("computer.ttf",25);
}
void draw()
{
background(0);
textSize(20);
textFont(computer);
text(textOptions[level][branch],10,25);
fill(0,239,31);
}
void keyPressed()
{
if(key == 'y')
{
println("Player is looking around.");
if(level < 2)
{
level = level+ 1;
branch = 0;
}
}
else if(key == 'n')
{
println("Player decided to leave this room.");
if(level < 2)
{
level = level+ 1;
branch = 1;
}
}
{
if(key == 'r')
{
println("Player has chosen the room to the right.");
if(level < 3)
{
level = level+ 1;
branch = 2;
}
}
else if(key == 'l')
{
println("Player has chosen the room to the left.");
if(level < 3)
{
level = level+ 1;
branch = 3;
}
}
}
}
I keep getting the error code:
java.lang.ArrayIndexOutOfBoundsException: 3
at sketch_171010c.draw(sketch_171010c.java:50)
at processing.core.PApplet.handleDraw(PApplet.java:2437)
at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1557)
at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:316)
and it appears to be highlighting the portion of draw that says textOptions[level][branch] but I still don't understand what this means or how to fix this issue whatsoever. Any help or input on how to literally do anything would greatly be appreciated. Thank you!
You should get into the habit of debugging your code so you understand exactly what it's doing.
The exception is caused by trying to access an index that an array doesn't have. Here's a simpler example:
String[] array = {"test"};
String x = array[100];
This code would throw an ArrayIndexOutOfBoundsException because the array only has a single element, but we're trying to access index 100. That's what's happening in your code.
Now, why that's happening is going to require debugging your code. Step through it with a piece of paper and a pencil to track the value of the variables, or use the debugger that comes with the Processing IDE.
I'm working on "Move Zeroes" of leetcode with scala. https://leetcode.com/problems/move-zeroes/description/
Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. You must do this in-place without making a copy of the array.
I have a solution which works well in IntelliJ but get the same Array with input while executing in Leetcode, also I'm not sure whether it is done in-place... Something wrong with my code ?
Thanks
def moveZeroes(nums: Array[Int]): Array[Int] = {
val lengthOrig = nums.length
val lengthFilfter = nums.filter(_ != 0).length
var numsWithoutZero = nums.filter(_ != 0)
var numZero = lengthOrig - lengthFilfter
while (numZero > 0){
numsWithoutZero = numsWithoutZero :+ 0
numZero = numZero - 1
}
numsWithoutZero
}
And one more thing: the template code given by leetcode returns Unit type but mine returns Array.
def moveZeroes(nums: Array[Int]): Unit = {
}
While I agree with #ayush, Leetcode is explicitly asking you to use mutable states. You need to update the input array so that it contains the changes. Also, they ask you to do that in a minimal number of operations.
So, while it is not idiomatic Scala code, I suggest you a solution allong these lines:
def moveZeroes(nums: Array[Int]): Unit = {
var i = 0
var lastNonZeroFoundAt = 0
while (i < nums.size) {
if(nums(i) != 0) {
nums(lastNonZeroFoundAt) = nums(i)
lastNonZeroFoundAt += 1
}
i += 1
i = lastNonZeroFoundAt
while(i < nums.size) {
nums(i) = 0
i += 1
}
}
As this is non-idomatic Scala, writing such code is not encouraged and thus, a little bit difficult to read. The C++ version that is shown in the solutions may actually be easier to read and help you to understand my code above:
void moveZeroes(vector<int>& nums) {
int lastNonZeroFoundAt = 0;
// If the current element is not 0, then we need to
// append it just in front of last non 0 element we found.
for (int i = 0; i < nums.size(); i++) {
if (nums[i] != 0) {
nums[lastNonZeroFoundAt++] = nums[i];
}
}
// After we have finished processing new elements,
// all the non-zero elements are already at beginning of array.
// We just need to fill remaining array with 0's.
for (int i = lastNonZeroFoundAt; i < nums.size(); i++) {
nums[i] = 0;
}
}
Your answer gives TLE (Time Limit Exceeded) error in LeetCode..I do not know what the criteria is for that to occur..However i see a lot of things in your code that are not perfect .
Pure functional programming discourages use of any mutable state and rather focuses on using val for everything.
I would try it this way --
def moveZeroes(nums: Array[Int]): Array[Int] = {
val nonZero = nums.filter(_ != 0)
val numZero = nums.length - nonZero.length
val zeros = Array.fill(numZero){0}
nonZero ++ zeros
}
P.S - This also gives TLE in Leetcode but still i guess in terms of being functional its better..Open for reviews though.
I have problems calculating the minimal distance in arrays. Since I'm a newbie in using C, there could be a major obvious mistake I'm making but can't spot.
I will give an example. Delta_dis should be the calculated distance.
array[0][0]=9.317;
array[0][1]=3;
array[1][0]=3;
array[1][1]=3;
array[2][0]=10;
array[2][1]=10;
array[3][0]=3;
array[3][1]=10;
for (i=0; i<4; i++)
{
for (k=0; k<4; k++)
{
delta_dis[k] = sqrt(pow((array[i][0]-array[k][0]),2) + pow((array[i][1]-array[k][1]),2));
printf("\ndelta_dis_before[%i]: %f",i,delta_dis[k])
if (delta_dis[k-1]!=0)
{
if (delta_dis[k]>delta_dis[k-1])
{
delta_dis[k] = delta_dis[k-1];
}else if (delta_dis[k]<delta_dis[k-1] & i==k)
{
delta_dis[k] = delta_dis[k-1];
}else
{
delta_dis[k] = delta_dis[k];
}
}else
{
delta_dis[k]=delta_dis[k];
}
printf("\ndelta_dis_after[%i]: %f",i,delta_dis[k])
}
}
So in the first step I calculate the distance between these points. And the result (called delta_dis_before[k]) is correct. Then I want to check, if the previous calculated distance is smaller, if so, then delta_dis[k] should be exchanged with the smaller distance. However the minimal distance should not be changed if the selected arrays are the same i=k.
But as soon as I run this through, delta_dis_after is always 0.
For example what I get for i=0 is (I did round the numbers in the following)
delta_dis_before[0]: 0
delta_dis_after[0]: 0
delta_dis_before[1]: 6.317
delta_dis_after[1]: 0
delta_dis_before[2]: 7.033
delta_dis_after[2]: 0
delta_dis_before[3]: 9.429
delta_dis_after[3]: 0
but what I want is:
delta_dis_before[0]: 0
delta_dis_after[0]: 0
delta_dis_before[1]: 6.317
delta_dis_after[1]: 6.317
delta_dis_before[2]: 7.033
delta_dis_after[2]: 6.317
delta_dis_before[3]: 9.429
delta_dis_after[3]: 6.317
I hope I could explain properly what the problem is and what I want it to calculate.
Can someone please help me resolve this issue? Thank you!
This is a tough one, at least for my minimal c skills.
Basically, the user enters a list of prices into an array, and then the desired number of items he wants to purchase, and finally a maximum cost not to exceed.
I need to check how many combinations of the desired number of items are less than or equal to the cost given.
If the problem was a fixed number of items in the combination, say 3, it would be much easier with just three loops selecting each price and adding them to test.
Where I get stumped is the requirement that the user enter any number of items, up to the number of items in the array.
This is what I decided on at first, before realizing that the user could specify combinations of any number, not just three. It was created with help from a similar topic on here, but again it only works if the user specifies he wants 3 items per combination. Otherwise it doesn't work.
// test if any combinations of items can be made
for (one = 0; one < (count-2); one++) // count -2 to account for the two other variables
{
for (two = one + 1; two < (count-1); two++) // count -1 to account for the last variable
{
for (three = two + 1; three < count; three++)
{
total = itemCosts[one] + itemCosts[two] + itemCosts[three];
if (total <= funds)
{
// DEBUG printf("\nMatch found! %d + %d + %d, total: %d.", itemCosts[one], itemCosts[two], itemCosts[three], total);
combos++;
}
}
}
}
As far as I can tell there's no easy way to adapt this to be flexible based on the user's desired number of items per combination.
I would really appreciate any help given.
One trick to flattening nested iterations is to use recursion.
Make a function that takes an array of items that you have selected so far, and the number of items you've picked up to this point. The algorithm should go like this:
If you have picked the number of items equal to your target of N, compute the sum and check it against the limit
If you have not picked enough items, add one more item to your list, and make a recursive call.
To ensure that you do not pick the same item twice, pass the smallest index from which the function may pick. The declaration of the function may look like this:
int count_combinations(
int itemCosts[]
, size_t costCount
, int pickedItems[]
, size_t pickedCount
, size_t pickedTargetCount
, size_t minIndex
, int funds
) {
if (pickedCount == pickedTargetCount) {
// This is the base case. It has the code similar to
// the "if" statement from your code, but the number of items
// is not fixed.
int sum = 0;
for (size_t i = 0 ; i != pickedCount ; i++) {
sum += pickedItems[i];
}
// The following line will return 0 or 1,
// depending on the result of the comparison.
return sum <= funds;
} else {
// This is the recursive case. It is similar to one of your "for"
// loops, but instead of setting "one", "two", or "three"
// it sets pickedItems[0], pickedItems[1], etc.
int res = 0;
for (size_t i = minIndex ; i != costCount ; i++) {
pickedItems[pickedCount] = itemCosts[i];
res += count_combinations(
itemCosts
, costCount
, pickedItems
, pickedCount+1
, pickedTargetCount
, i+1
, funds
);
}
return res;
}
}
You call this function like this:
int itemCosts[C] = {...}; // The costs
int pickedItems[N]; // No need to initialize this array
int res = count_combinations(itemCosts, C, pickedItems, 0, N, 0, funds);
Demo.
This can be done by using a backtracking algorithm. This is equivalent to implementing a list of nested for loops. This can be better understood by trying to see the execution pattern of a sequence of nested for loops.
For example lets say you have, as you presented, a sequence of 3 fors and the code execution has reached the third level (the innermost). After this goes through all its iterations you return to the second level for where you go to the next iteration in which you jump again in third level for. Similarly, when the second level finishes all its iteration you jump back to the first level for which continues with the next iteration in which you jump in the second level and from there in the third.
So, in a given level you try go to the deeper one (if there is one) and if there are no more iterations you go back a level (back track).
Using the backtracking you represent the nested for by an array where each element is an index variable: array[0] is the index for for level 0, and so on.
Here is a sample implementation for your problem:
#define NUMBER_OF_OBJECTS 10
#define FORLOOP_DEPTH 4 // This is equivalent with the number of
// of nested fors and in the problem is
// the number of requested objects
#define FORLOOP_ARRAY_INIT -1 // This is a init value for each "forloop" variable
#define true 1
#define false 0
typedef int bool;
int main(void)
{
int object_prices[NUMBER_OF_OBJECTS];
int forLoopsArray[FORLOOP_DEPTH];
bool isLoopVariableValueUsed[NUMBER_OF_OBJECTS];
int forLoopLevel = 0;
for (int i = 0; i < FORLOOP_DEPTH; i++)
{
forLoopsArray[i] = FORLOOP_ARRAY_INIT;
}
for (int i = 0; i < NUMBER_OF_OBJECTS; i++)
{
isLoopVariableValueUsed[i] = false;
}
forLoopLevel = 0; // Start from level zero
while (forLoopLevel >= 0)
{
bool isOkVal = false;
if (forLoopsArray[forLoopLevel] != FORLOOP_ARRAY_INIT)
{
// We'll mark the loopvariable value from the last iterration unused
// since we'll use a new one (in this iterration)
isLoopVariableValueUsed[forLoopsArray[forLoopLevel]] = false;
}
/* All iterations (in all levels) start basically from zero
* Because of that here I check that the loop variable for this level
* is different than the previous ones or try the next value otherwise
*/
while ( isOkVal == false
&& forLoopsArray[forLoopLevel] < (NUMBER_OF_OBJECTS - 1))
{
forLoopsArray[forLoopLevel]++; // Try a new value
if (loopVariableValueUsed[forLoopsArray[forLoopLevel]] == false)
{
objectUsed[forLoopsArray[forLoopLevel]] = true;
isOkVal = true;
}
}
if (isOkVal == true) // Have we found in this level an different item?
{
if (forLoopLevel == FORLOOP_DEPTH - 1) // Is it the innermost?
{
/* Here is the innermost level where you can test
* if the sum of all selected items is smaller than
* the target
*/
}
else // Nope, go a level deeper
{
forLoopLevel++;
}
}
else // We've run out of values in this level, go back
{
forLoopsArray[forLoopLevel] = FORLOOP_ARRAY_INIT;
forLoopLevel--;
}
}
}