Request for Counter Testcase with Google Foobar Question - Prepare the Bunnies Escape [closed] - breadth-first-search

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I recently came across GoogleFoobar's problem Prepare the Bunnies Escape, and I submitted a Shortest Path based solution.
However, only 3 / 5 cases passed, and I am really intrigued to know why.
I have attached my code below for reference.
If anyone can "Hack" my solution / provide a countercase / tell me what I am doing wrong, that would be appreciated.
PLEASE DO NOT SEND ME IMPLEMENTATIONS, verbal explanations of my mistakes / counter tests would be appreciated.
Thanks.
import java.util.PriorityQueue;
public class Solution
{
public static int ans = Integer.MAX_VALUE;
public static int dx [] = {0,0,-1,1};
public static int dy [] = {-1,1,0,0};
static class State implements Comparable<State>
{
int x,y,moves;
boolean wentThroughWall;
public State(int x, int y, int moves, boolean wentThroughWall)
{
this.x = x;
this.y = y;
this.moves = moves;
this.wentThroughWall = wentThroughWall;
}
public int compareTo(State other)
{
return moves - other.moves;
}
}
public static int solution(int[][] map)
{
PriorityQueue<State> enque = new PriorityQueue<State>();
boolean visited [][] = new boolean [map.length][map[0].length];
enque.add(new State(0, 0, 1,false));
while(!enque.isEmpty())
{
State top = enque.poll();
if(top.x == map.length - 1 && top.y == map[0].length - 1)
{
ans = Math.min(ans, top.moves);
continue;
}
if(visited[top.x][top.y])
continue;
visited[top.x][top.y] = true;
for(int i = 0; i < dx.length; i++)
{
int nx = top.x + dx[i];
int ny = top.y + dy[i];
if(nx < 0 || nx >= map.length || ny < 0 || ny >= map[0].length || (map[nx][ny] == 1 && top.wentThroughWall))
continue;
if(map[nx][ny] == 1)
enque.add(new State(nx, ny, top.moves + 1, true));
else
enque.add(new State(nx, ny, top.moves + 1, top.wentThroughWall));
}
}
return ans;
}
public static void main(String[] args) {
int [][] test = {{0, 0, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0}};
System.out.println(Solution.solution(test));
}
}
Statement:
You're awfully close to destroying the LAMBCHOP doomsday device and freeing Commander Lambda's bunny prisoners, but once they're free of the prison blocks, the bunnies are going to need to escape Lambda's space station via the escape pods as quickly as possible. Unfortunately, the halls of the space station are a maze of corridors and dead ends that will be a deathtrap for the escaping bunnies. Fortunately, Commander Lambda has put you in charge of a remodeling project that will give you the opportunity to make things a little easier for the bunnies. Unfortunately (again), you can't just remove all obstacles between the bunnies and the escape pods - at most you can remove one wall per escape pod path, both to maintain structural integrity of the station and to avoid arousing Commander Lambda's suspicions.
You have maps of parts of the space station, each starting at a prison exit and ending at the door to an escape pod. The map is represented as a matrix of 0s and 1s, where 0s are passable space and 1s are impassable walls. The door out of the prison is at the top left (0,0) and the door into an escape pod is at the bottom right (w-1,h-1).
Write a function solution(map) that generates the length of the shortest path from the prison door to the escape pod, where you are allowed to remove one wall as part of your remodeling plans. The path length is the total number of nodes you pass through, counting both the entrance and exit nodes. The starting and ending positions are always passable (0). The map will always be solvable, though you may or may not need to remove a wall. The height and width of the map can be from 2 to 20. Moves can only be made in cardinal directions; no diagonal moves are allowed.
Languages
To provide a Python solution, edit solution.py
To provide a Java solution, edit Solution.java
Test cases
Your code should pass the following test cases.
Note that it may also be run against hidden test cases not shown here.
-- Python cases --
Input:
solution.solution([[0, 1, 1, 0], [0, 0, 0, 1], [1, 1, 0, 0], [1, 1, 1, 0]])
Output:
7
Input:
solution.solution([[0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0]])
Output:
11
-- Java cases --
Input:
Solution.solution({{0, 1, 1, 0}, {0, 0, 0, 1}, {1, 1, 0, 0}, {1, 1, 1, 0}})
Output:
7
Input:
Solution.solution({{0, 0, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0}})
Output:
11

Sike, I fixed it. I managed to generate a bunch of testcases using a random test case generator, and realized that my visited array isn't defined correctly.
I have listed the correct solution below for reference with the fix.
import java.util.PriorityQueue;
public class Solution
{
public static int ans = Integer.MAX_VALUE;
public static int dx [] = {0,0,-1,1};
public static int dy [] = {-1,1,0,0};
static class State implements Comparable<State>
{
int x,y,moves;
boolean wentThroughWall;
public State(int x, int y, int moves, boolean wentThroughWall)
{
this.x = x;
this.y = y;
this.moves = moves;
this.wentThroughWall = wentThroughWall;
}
public int compareTo(State other)
{
return moves - other.moves;
}
}
public static int solution(int[][] map)
{
PriorityQueue<State> enque = new PriorityQueue<State>();
boolean visited [][][] = new boolean [map.length][map[0].length][2];
enque.add(new State(0, 0, 1,false));
while(!enque.isEmpty())
{
State top = enque.poll();
if(top.x == map.length - 1 && top.y == map[0].length - 1)
{
ans = Math.min(ans, top.moves);
continue;
}
if(visited[top.x][top.y][(top.wentThroughWall ? 0 : 1)])
continue;
visited[top.x][top.y][(top.wentThroughWall ? 0 : 1)] = true;
for(int i = 0; i < dx.length; i++)
{
int nx = top.x + dx[i];
int ny = top.y + dy[i];
if(nx < 0 || nx >= map.length || ny < 0 || ny >= map[0].length || (map[nx][ny] == 1 && top.wentThroughWall))
continue;
if(map[nx][ny] == 1)
enque.add(new State(nx, ny, top.moves + 1, true));
else
enque.add(new State(nx, ny, top.moves + 1, top.wentThroughWall));
}
}
assert(ans != Integer.MAX_VALUE);
return ans;
}
public static void main(String[] args) {
int [][] test = {{0, 0, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0}};
System.out.println(Solution.solution(test));
}
}
As a competitive person myself, I would like to know if my code really works, or was it just weak testing.
If you find a testcase which breaks my code, please let me know in the comments and I will get back to you ASAP.

Related

Dart Map comprehension

In python I'd write:
{a:0 for a in range(5)}
to get
{0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
How can I achieve the same in Dart?
So far I have this:
List<Map<String, double>>.generate(5, (i) => { i: 0 });
but this generates list of maps [{0: 0}, {1: 0}, {2: 0}, {3: 0}, {4: 0}],
while I want a simple map
Dart has a collection for syntax that is similar to Python's comprehensions. The Dart Language Tour provides examples for Lists, but it can be used for Sets and Maps too:
final map = {for (var a = 0; a < 5; a += 1) a: 0};
You can consult the feature specification for more details.
You can do it this way if you want a solution using one line:
void main() {
final map = Map.fromEntries(Iterable.generate(5, (i) => MapEntry(i, 0)));
print(map); // {0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
}
Map<int, int> map = {};
for (int i = 0; i < 5; i++) {
map[i] = 0;
}
Prints
{0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
Edit:
You can also try this approach:
List<int> list1 = List.generate(5, (i) => i);
List<int> list2 = List.generate(5, (i) => 0);
var map = Map.fromIterables(list1, list2);

Unreadable Int16 from UInt8List, wrong data when cast asByteArray

I tried to get int, short from data, the data get from websocket, but some thing is wrong, and when i cast from UInt8List -> Byte Data -> UInt8List, it add 2 new uint8 in my array. Any one suggest me how is correct way to get int from byte array. (It's big Endian, my code in Swift and the base write data in Dart still correct). Thank anyone for reading this.
I am using 'dart:typed_data'; and get data from WebSocket (dart:io)
print(responseData); // UInt8List: [0, 1, 0, 1, 0, 1, 49]
var byteData = responseData.buffer.asByteData();
var array = byteData.buffer.asUint8List();
print(array); // UInt8List: [130, 7, 0, 1, 0, 1, 0, 1, 49]
var shortValue = responseData.buffer.asByteData().getInt16(0);
print(shortValue); // -32249 ( 2 first byte: [0 ,1] so it must be 1 )
There's something else going on, because your code does not add any extra bytes - and actually, it doesn't use array.
This code:
import 'dart:typed_data';
void main() {
Uint8List responseData = Uint8List.fromList([0, 1, 0, 1, 0, 1, 49]);
print(responseData); // UInt8List: [0, 1, 0, 1, 0, 1, 49]
var byteData = responseData.buffer.asByteData();
//var array = byteData.buffer.asUint8List();
//print(array); // UInt8List: [130, 7, 0, 1, 0, 1, 0, 1, 49]
var shortValue = responseData.buffer.asByteData().getInt16(0);
print(shortValue); // -32249 ( 2 first byte: [0 ,1] so it must be 1 )
}
prints (as expected)
[0, 1, 0, 1, 0, 1, 49]
1
EDIT - as suggested in the comment, the Uint8List you have is in fact a view on a ByteBuffer with a non-zero offset. So, responseData.buffer is that underlying buffer, which includes additional bytes. The simplest solution is to make a copy of the view.
import 'dart:typed_data';
void main() {
Uint8List original = Uint8List.fromList([130, 7, 0, 1, 0, 1, 0, 1, 49]);
print(original);
Uint8List view = Uint8List.view(original.buffer, 2);
print(view);
print(view.buffer.lengthInBytes); // prints 9
print(view.buffer.asByteData().getUint16(0)); // unexpected result
Uint8List copy = Uint8List.fromList(view);
print(copy.buffer.lengthInBytes); // prints 7
print(copy.buffer.asByteData().getUint16(0)); // expected result
}

OpenCV arithmetic operations on matrices

Can someone explain the following, totally unintuitive, results:
Mat_<Vec3f> mat(Size(3,3),0);
Mat_<Vec3f> mat_add = (mat + 9);
Mat_<Vec3f> mat_add_div = (mat + 9) / 3;
magically, I don't have any other explanation for it:
mat_add = [9,0,0,9,0,0,9,0,0];
mat_add_div = [3,3,3,3,3,3,3,3,3];
EDIT:
My take: this is a legacy bug that can't be fixed anymore because it is retroactive and will impact lot of projects. Also it would be pretty nasty to debug (except project has already pretty thorough unit testing)
Mat_<Vec3f> mat_add = (mat + 9);
is equivalent to
Mat_<Vec3f> temp(Size(3,3),Vec3f(9,0,0));
Mat_<Vec3f> mat_add = mat+temp;
So, you will get
mat_add =
[9, 0, 0, 9, 0, 0, 9, 0, 0;
9, 0, 0, 9, 0, 0, 9, 0, 0;
9, 0, 0, 9, 0, 0, 9, 0, 0]
However, I have no clue for why you will get values like that for mat_add_div. In fact, if you replace it by:
Mat_<Vec3f> mat_add_div = mat_add / 3;
You will end up with
mat_add_div =
[3, 0, 0, 3, 0, 0, 3, 0, 0;
3, 0, 0, 3, 0, 0, 3, 0, 0;
3, 0, 0, 3, 0, 0, 3, 0, 0]
This result is however reasonable based on the same theory as said in above.

Changing Values of a C-Struct in a Class for OpenGL - Objective C

I have the following hard coded vertex information in my object class for use for OpenGLES 2.0 :
typedef struct {
float Position[3];
float Color[4];
} Vertex;
static Vertex Vertices [] = {
{{0.0, -0.0, 0}, {1, 0, 0, 1}},
{{0.0 , 50 , 0}, {1, 0, 0, 1}},
{{-50.0, 50.0, 0}, {1, 0, 0, 1}},
{{-50.0, -0.0, 0}, {1, 0, 0, 1}}
};
static GLubyte Indices []= {
0, 1, 2,
2, 3, 0
};
What I want to do is amend this class so that I can set the vertices information when I instantiate the class. So far I have tried declaring and exposing the object in the implementation :
#interface StandObject : NSObject {
Vertex * Vertices;
}
#property (nonatomic, assign) Vertex * Vertices;
And the in the .m file
#synthesize Vertices;
I then try to set the Vertices as follows, however I think the formatting here is wrong :
Vertices[0].Position = {0.0, -0.0, 0};
Can anyone offer any advice on the best way to achieve this and if I am on the right lines ?
Try doing it in this way:
Vertices[0].Position[0] = 0.0;
Vertices[0].Position[1] = -0.0;
Vertices[0].Position[2] = 0;
Maybe it's not the cleaner solution, but it will work

Programmatically Generate OpenGL Vertex Data in iOS

Basically what I want to do is generate my vertex coordinates programmatically instead of storing it in a statically predefined array. Unfortunately I am not able to convert a very simple example to a dynamic array.
Everything works fine if I stick to static arrays:
typedef struct {
GLfloat Position[3];
GLfloat Color[4];
GLfloat TexCoord[2];
float Normal[3];
} Vertex;
Vertex sphereVertices[] = {
{{1, -1, 1}, {1, 0, 0, 1}, {1, 0}, {0, 0, 1}},
{{1, 1, 1}, {0, 1, 0, 1}, {1, 1}, {0, 0, 1}},
{{-1, 1, 1}, {0, 0, 1, 1}, {0, 1}, {0, 0, 1}},
{{-1, -1, 1}, {0, 0, 0, 1}, {0, 0}, {0, 0, 1}}
};
GLubyte sphereIndices [] = {
0, 1, 2,
2, 3, 0
};
...
glGenBuffers(1, &sphereIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sphereIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(sphereIndices), sphereIndices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));
...
glDrawElements(GL_TRIANGLES, 6 * sizeof(GLubyte), GL_UNSIGNED_BYTE, 0);
As soon as I switch my indices to a dynamic array only the first triangle shows up.
GLubyte *sphereIndices;
+(void)initialize {
sphereIndices = malloc(6 * sizeof(GLubyte));
sphereIndices[0] = 0;
sphereIndices[1] = 1;
sphereIndices[2] = 2;
sphereIndices[3] = 2;
sphereIndices[4] = 3;
sphereIndices[5] = 0;
}
Probably this has something to do with pointers. Does anybody know what I am doing wrong?
Thanks!
I was able to solve the problem myself. As I already expected the problem had to do with my missing understanding of pointers.
As far as I found out, there is no way to get the size of a dynamic array. Because of that sizeof(sphereIndices) always returns 4 which is the size of the pointer not the size of the data. That's why glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(sphereIndices), sphereIndices, GL_STATIC_DRAW) only sends 4 indices to openGL instead of 6.
I fixed the problem by introducing an additional variable to keep track of the number of indices.

Resources