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.
I am still new with dart, so I'm trying to figure things out. Right now, I tried to create matrix and calculate using this formula.
import 'dart:math';
void main() {
List<List<double>> normalisasi = new List<List<double>>();
List<List<double>> data = [
[10000000, 35, 110, 7],
[12000000, 45, 125, 6],
[15000000, 40, 150, 8],
[14000000, 37.5, 125, 7.5],
];
var bobot = [0.35, 0.25, 0.15, 0.25];
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data.length; j++) {
normalisasi[i][j] = data[i][j] / (pow(data[j][i], 2));
print(normalisasi[i][j]);
}
}
}
But I get this instead:
RangeError (index): Index out of range: no indices are valid: 0
Please help me, thank you.
Your normalisasi List is growable, therefore you need to use the 'add()' function to grow it. Alternatively, you can specify the fixed dimensions of the arrays on creation.
See fixed-size vs growable lists
I am trying to produce a negative buffer (offset) of a polygon using GEOS (with the c api).
So far I have accomplished a positive offset (see image), however when I try to make the width '-'ve, it produces nothing. I suspect that 'offset' requires clipping somehow prior to retrieving the exterior ring.
Had a good look through documentation but can't solve it, any help would be greatly appreciated!!
My code is below if that helps at all:
#include <geos_c.h>
// Define coordinate sequence
int noPoints = 6 + 1; // +1 because it is a loop
GEOSCoordSequence* points = GEOSCoordSeq_create(noPoints, 2 /*# ordinates*/);
GEOSCoordSeq_setX(points, 0, 0);
GEOSCoordSeq_setY(points, 0, 0);
GEOSCoordSeq_setX(points, 1, 0);
GEOSCoordSeq_setY(points, 1, 50);
GEOSCoordSeq_setX(points, 2, 50);
GEOSCoordSeq_setY(points, 2, 50);
GEOSCoordSeq_setX(points, 3, 50);
GEOSCoordSeq_setY(points, 3, 0);
GEOSCoordSeq_setX(points, 4, 30);
GEOSCoordSeq_setY(points, 4, 15);
GEOSCoordSeq_setX(points, 5, 20);
GEOSCoordSeq_setY(points, 5, 15);
GEOSCoordSeq_setX(points, noPoints-1, 0);
GEOSCoordSeq_setY(points, noPoints-1, 0);
// Define linear ring
GEOSGeometry* ploop = GEOSGeom_createLinearRing(points);
// Define offset
double width = 15;
int quadsegs = 100;
int endCapStyle = 1;
int joinStyle = 1;
double mitreLimit = 1.0;
const GEOSGeometry* offset = GEOSBufferWithStyle(ploop, width, quadsegs, endCapStyle, joinStyle, mitreLimit);
// Get exterior ring
const GEOSGeometry* exteriorRing = GEOSGetExteriorRing(offset);
// Convert to coord sequence and draw points
const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq(exteriorRing);
uint numPoints = GEOSGeomGetNumPoints(exteriorRing);
double xCoord, yCoord;
for (uint p = 0; p < numPoints; p++) {
GEOSCoordSeq_getX(coordSeq, p, &xCoord);
GEOSCoordSeq_getY(coordSeq, p, &yCoord);
printf("x: %g\ty:%g\n", xCoord, yCoord);
drawPoint(xCoord, yCoord);
}
Thanks in advance!
Finally solved it! the geometry I was feeding in was a linear ring, rather than a polygon. For anyone with a similar issue in the future:
Replace:
GEOSGeometry* ploop = GEOSGeom_createLinearRing(points);
With:
GEOSGeometry* rloop = GEOSGeom_createLinearRing(points);
const GEOSGeometry* ploop = GEOSGeom_createPolygon(rloop, NULL, 0);
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
}
I am trying to use OpenCV (java) to do template matching and use the max min values to determine whether the object found or not.
I am using the following java/opencv code but the problem is it returns 0.0 for min values for both best match as well as for the scenarios where no match found.
So this template matching seems unreliable to determine whether the object found or not. Am I doing anything wrong in this code or I need to go for any other techniques?
Thanks in advance.
int templateMatchMethod = Imgproc.TM_SQDIFF_NORMED;
Mat largeImage = Highgui.imread(largeUrl);
Mat smallImage = Highgui.imread(smallUrl);
boolean isMaxTypleMethod = true;
double TEMPLATE_MATCH_THRESHOLD = 0.8;
int result_cols = largeImage.cols() - smallImage.cols() + 1;
int result_rows = largeImage.rows() - smallImage.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_8U);
Imgproc.matchTemplate(largeImage, smallImage, result, templateMatchMethod);
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
MinMaxLocResult mmr = Core.minMaxLoc(result);
Point matchLoc;
double minMaxValue = 1;
if (templateMatchMethod == Imgproc.TM_SQDIFF || templateMatchMethod == Imgproc.TM_SQDIFF_NORMED)
{
matchLoc = mmr.minLoc;
isMaxTypleMethod = false;
TEMPLATE_MATCH_THRESHOLD = 0.4;
minMaxValue = mmr.minVal;
}
else
{
matchLoc = mmr.maxLoc;
minMaxValue = mmr.maxVal;
}
Core.rectangle(largeImage, matchLoc, new Point(matchLoc.x + smallImage.cols(),
matchLoc.y + smallImage.rows()), new Scalar(0, 255, 0));
System.out.println("minMaxValue : "+minMaxValue);
if(isMaxTypleMethod && TEMPLATE_MATCH_THRESHOLD < minMaxValue)
{
System.out.println("Match found");
}
else if (!isMaxTypleMethod && TEMPLATE_MATCH_THRESHOLD > minMaxValue)
{
System.out.println("Match found");
}
this looks pretty suspicious:
Mat result = new Mat(result_rows, result_cols, CvType.CV_8U); // better use CvType.CV_32F here
Imgproc.matchTemplate(largeImage, smallImage, result, templateMatchMethod);
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat()); // normalizing a uchar mat into [0..1] can only result in garbage.
again, it will work much nicer, if you use float type for result and skip the normalize
Dont normalize the result, i mean remove this line from your code,
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat()); // normalizing a uchar mat into
this will work fine and will give you the proper value of minmax,