I know my code is extremely close I have all of my functions working except the moveKnight() function if you do not know what knights Tour is, it's a program we are writing to help learn recursion in class. The knight is suppose to touch every space on the 8*8 chessboard only once and then prints out the move number that it took to get there. It currently only prints out the first position board[0][0]=1
but does not give "No solution".
I can not figure out where I should start looking for the problem any help is greatly appreciated.
#include <iostream>
using namespace std;
//Global Variables
//Defining the 8 possible Moves in the order from class
int yMove[8] = { 1,2, 2, 1,-1,-2,-2,-1 };
int xMove[8] = { 2,1,-1,-2,-2,-1, 1, 2 };
int board[8][8];
int startx, starty = 0;
int movecount = 1;
//checks if move is safe
bool checkSafe(int x, int y)
{
return (x >= 0 && x < 8 && y >= 0 && y < 8 && board[x][y] == 0);
}
//Prints Current board
void printBoard(int board[8][8])
{
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
cout << " " << board[x][y] << " ";
cout << endl;
}
}
bool moveKnight(int x, int y, int movecount)
{
if (!checkSafe(x, y))
{
board[x][y] = movecount;
return true;
}
//end condition
if (movecount == 64)
return true;
if (moveKnight(x + xMove[1], y + yMove[1], movecount + 1))
return true;
else if (moveKnight(x + xMove[0], y + yMove[0], movecount + 1))
return true;
else if (moveKnight(x + xMove[2], y + yMove[2], movecount + 1))
return true;
else if (moveKnight(x + xMove[3], y + yMove[3], movecount + 1))
return true;
else if (moveKnight(x + xMove[4], y + yMove[4], movecount + 1))
return true;
else if (moveKnight(x + xMove[5], y + yMove[5], movecount + 1))
return true;
else if (moveKnight(x + xMove[6], y + yMove[6], movecount + 1))
return true;
else if (moveKnight(x + xMove[7], y + yMove[7], movecount + 1))
return true;
else
{
board[x][y] = 0;
return false;
}
}
int KnightTour()
{
//creating board
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
board[x][y] = 0;
}
board[startx][starty] = 1;
movecount + 1;
//No possible moves
if (!moveKnight(startx, starty, movecount))
cout << "Not possible";
else
{
//yes possible now print
printBoard(board);
}
//exits
return 0;
}
int main()
{
//calls knights tour
KnightTour();
cout << endl;
system("pause");
return 0;
}
Your moveKnight function returns immediately because it determines the very first position is not a valid move. The reason is you initialized the board with a non-zero value at the start position.
Remove these two lines from main:
board[startx][starty] = 1;
movecount + 1;
The first one breaks your recursion, and the second one does nothing at all.
Additionally, the logic after calling checkSafe() is screwy, because at the moment when you determine a move is either out-of-bounds or already-played, you are writing a value to the board. That's going to result in undefined behavior.
Correcting these things, and also simplifying the recursive calls:
bool moveKnight(int x, int y, int movecount)
{
if (checkSafe(x, y))
{
board[x][y] = movecount;
if (movecount == 64)
return true;
for (int i = 0; i < 8; i++)
{
if (moveKnight(x + xMove[i], y + yMove[i], movecount + 1))
return true;
}
board[x][y] = 0;
}
return false;
}
This is the Triangle problem from Codility:
A zero-indexed array A consisting of N integers is given.
A triplet (P, Q, R) is triangular if 0 ≤ P < Q < R < N and:
A[P] + A[Q] > A[R],
A[Q] + A[R] > A[P],
A[R] + A[P] > A[Q].
Write a function:
int solution(vector<int> &A);
that, given a zero-indexed array A consisting of N integers, returns 1
if there exists a triangular triplet for this array and returns 0
otherwise.
For example, given array A such that:
A[0] = 10, A[1] = 2, A[2] = 5, A[3] = 1, A[4] = 8, A[5] = 20
Triplet (0, 2, 4) is triangular, the function should return 1.
Given array A such that:
A[0] = 10, A[1] = 50, A[2] = 5, A[3] = 1
function should return 0.
Assume that:
N is an integer within the range [0..100,000];
each element of array A is an integer within the range
[−2,147,483,648..2,147,483,647].
And here is my solution in C++:
int solution(vector<int> &A) {
if(A.size()<3) return 0;
sort(A.begin(), A.end());
for(int i=0; i<A.size()-2; i++){
//if(A[i] = A[i+1] = A[i+2]) return 1;
if(A[i]+A[i+1]>A[i+2] && A[i+1]+A[i+2]>A[i] && A[i+2]+A[i]>A[i+1]){
return 1;
}
}
return 0;
}
I've checked the comments there and all the solutions seems similar to mine.
However, while others claimed to have gotten 100%, I only got a 93% score.
I got all the tests cases correct EXCEPT for one:
extreme_arith_overflow1
overflow test, 3 MAXINTs
I assume this case has some input like this:
[2147483647, 2147483647, 2147483647]
So I add this to the custom test case, and the answer turns out to be 0 when it clearly should be 1.
I also tried [1900000000, 1900000000, 1900000000], and the answer is still 0.
However, [1000000000, 1000000000, 1000000000] is correct with answer of 1.
Can anyone clue me in on why this result occured?
Greatly appreciated.
My solution in Java with 100/100 and time complexity of O(N*log(N))
With comments explaining the logic
// you can also use imports, for example:
// import java.util.*;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
import java.util.Arrays;
class Solution {
public int solution(int[] A) {
int N = A.length;
if (N < 3) return 0;
Arrays.sort(A);
for (int i = 0; i < N - 2; i++) {
/**
* Since the array is sorted A[i + 2] is always greater or equal to previous values
* So A[i + 2] + A[i] > A[i + 1] ALWAYS
* As well ass A[i + 2] + A[i + 1] > A[i] ALWAYS
* Therefore no need to check those. We only need to check if A[i] + A[i + 1] > A[i + 2]?
* Since in case of A[i] + A[i + 1] > MAXINT the code would strike an overflow (ie the result will be greater than allowed integer limit)
* We'll modify the formula to an equivalent A[i] > A[i + 2] - A[i + 1]
* And inspect it there
*/
if (A[i] >= 0 && A[i] > A[i + 2] - A[i + 1]) {
return 1;
}
}
return 0;
}
Basically when you check X + Y value of integers, that is greater than integer limit the code will fail on overflow. so instead of checking if X + Y > Z, we can simply check the equivalent statement if X > Z - Y (simple math isn't it?). Alternatively you could always use long but it will be a worse solution memory wise.
Also make sure you skip the negatives as a triangle cannot have a negative side value.
Cheers
Java 100 %:
public int solution(int[] A){
Arrays.sort(A);
for(int i=0;i<A.length-2;i++){
if(
((long)A[i] + (long)A[i+1] > A[i+2]) &&
((long)A[i+1] + (long)A[i+2] > A[i]) &&
((long)A[i] + (long)A[i+2] > A[i+1])
)
return 1;
}
return 0;
}
Here's my clean solution in Python. I got a 100% in Codility.
This logic can be adapted to any other programming language.
Note: If the array is sorted, you only have to check that the sum of two consecutive elements is greater than the next element (A[i] + A[i+1] > A[i+2]), because in that case, the other two conditions (A[i+1]+A[i+2] > A[i], A[i]+A[i+2] > A[i+1]) will always be true.
I hope it helps.
def solution(A):
#edge case check
if len(A) < 3:
return 0
A.sort()
for i in range(len(A)-2):
if A[i]+A[i+1] > A[i+2]:
return 1
return 0
There are couple of issues here
Side of a triangle can't be 0, since it is a length. You have to add that check or you'll fail that corner case. i.e. Wouldn't get 100%.
Since you can have an input array of all INT_MAX or LONG_MAX (see http://www.cplusplus.com/reference/climits/), you need to store the sum in a double or long long.
You don't have to check all three conditions here i.e.
A[P] + A[Q] > A[R],
A[Q] + A[R] > A[P],
A[R] + A[P] > A[Q].
If you have sorted the array than
A[Q] + A[R] > A[P] &&
A[R] + A[P] > A[Q]
are always true because 0 ≤ P < Q < R i.e. R is greater than P and Q.
So you should only check for A[P] + A[Q] > A[R].
You have already placed a check for A.size() < 3 so that is good.
I have added a C implementation at https://github.com/naveedrasheed/Codility-Solutions/blob/master/Lesson6_Sorting/triangle.c.
You can compare it with solution.
I have used 3 for loop here( without sorting the array) to solve this problem.
public static int solution(int[] A) {
for (int p = 0; p < A.length; p++) {
for (int q = p + 1; q < A.length; q++) {
for (int r = q + 1; r < A.length; r++) {
if ((A[p] + A[q] > A[r]) && (A[q] + A[r] > A[p]) && (A[r] + A[p] > A[q])) {
System.out.println(A[p] + " " + A[q] + " " + A[r]);
return 1;
}
}
}
}
return 0;
}
the trick is to find a number on the array that is less the sum of the other two on the array so sorting the array then searching for that number will solve it. casting to long that on sometimes the value of summation wil exceed the allowed integer
public int solution(int[] A) {
int n = A.length;
if(n<3){
return 0;
}
Arrays.sort(A);
for(int i=2; i<n; i++){
if(A[i]<(long)A[i-1]+(long)A[i-2])
return 1;
}
return 0;
}
My solution in C# with 100 score.
using System;
class Solution {
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
if(A.Length) <3)
return 0;
Array.Sort(A);
int p,q,r;
for(int i=A.Length-1;i>1; i--){
p = A[i];
q = A[i-1];
r = A[i-2];
if(p+q>r && q+r > p && r+p > q)
return 1;
}
return 0;
}
}
Straightforward solution in JavaScript.
Note: I excluded the options where any side could be 0 or less. The rest is the same.
function solution(A) {
if (A.length < 3) return 0;
A.sort((a, b) => (a - b));
for (i = A.length - 1; i >= 0; i--) {
if (A[i - 2] <= 0) return 0;
if (
A[i] + A[i - 1] > A[i - 2] &&
A[i] + A[i - 2] > A[i - 1] &&
A[i - 1] + A[i - 2] > A[i]
) return 1;
}
return 0;
}
javascript 100% on codility
function solution(a) {
if (a.length < 3) {
return 0;
}
a.sort((a, b) => a - b);
for (let i = 0; i < a.length - 2; i++) {
if (a[i] + a[i + 1] > a[i + 2]) {
return 1;
}
}
return 0;
}
My solution to this problem, written in Swift.
public func Triangle(_ A : inout [Int]) -> Int {
A.sort()
for i in 1..<A.count-1 {
if(A[i] + A[i-1] > A[i+1]) {
print("Triangle has edges: \(A[i-1]), \(A[i]), \(A[i+1])")
return 1
}
}
return 0
}
A = [10,2,5,1,8,20]
print("Triangle: ", Triangle(&A))
Or you can change the if clause, like below
if(A[i]>A[i+2]-A[i+1] && A[i+1]>A[i]-A[i+2] && A[i+2]>A[i+1]-A[i])
using subtraction instead of addition.
Works 100%, tested with different scenario's.
I think all the possibilities are not covered above solution
Combination with
P,Q,R
A[0] = 10, A[1] = 2, A[2] = 5, A[3] = 1, A[4] = 8, A[5] = 20
index combination
0+1>2, 1+2>0, 2+0>1
1+2>3, 2+3>1, 3+1>2
....
These are combinations needed to achieve this problem.
//Triangle
/**
* A[P] + A[Q] > A[R],
A[Q] + A[R] > A[P],
A[R] + A[P] > A[Q]
*/
public int triangleSolution(int[] A) {
int status = 0;
for(int i=0; i<A.length; i++) {
int[] B = removeTheElement(A, i);
for(int j=0; j<B.length; j++) {
int[] C = removeTheElement(B, j);
for(int k=0; k<C.length; k++) {
if((A[i] + B[j] > C[k]) &&
(B[j] + C[k] > A[i]) &&
(C[k] + A[i] > B[j])) {
return 1;
}
}
}
}
return status;
}
// Function to remove the element
public int[] removeTheElement(int[] arr, int index)
{
// Create another array of size one less
int[] anotherArray = new int[arr.length - 1];
// Copy the elements except the index
// from original array to the other array
for (int i = 0, k = 0; i < arr.length; i++) {
// if the index is
// the removal element index
if (i == index) {
continue;
}
// if the index is not
// the removal element index
anotherArray[k++] = arr[i];
}
//Java >8
//IntStream.range(0, arr.length).filter(i -> i != index).map(i -> arr[i]).toArray();
return anotherArray;
}
//My solution in C++ it avoid overflow
inline int Triangle(vector<int> &A) {
if(A.size() < 3) return 0;
sort(A.begin(), A.end());
for(int i = 0; i < (int)A.size() - 2; ++i){
int P = A[i], Q = A[i + 1], R =A[i + 2];
if(( R - P - Q < 0) && ( P - Q - R < 0) && (Q - R - P < 0))
return 1;
}
return 0;
}
Ruby 100% solution
def solution(a)
arr = a.select{|x| x >=0 }.sort
arr.each_with_index do |p, pi|
arr[(pi+1)..-1].each_with_index do |q, qi|
arr[(qi+pi+2)..-1].each do |r|
break if p+q <=r
break if p+r <=q
break if r+q <=p
return 1
end
end
end
0
end
It's javascript solution(TC: O(N*log(N)) though, in case you guys want :).
function solution(A) {
if(A.length<3) return 0;
A.sort((a,b)=>b - a);
for(let i = 0,j = i+1;j < A.length-1;j++){
let p = A[j],q = A[j+1],r = A[i]
if(r - p > q) i++;
else if(r - p < q) return 1;
}
return 0;
}
Sorting does not work now, It was a bug it was fixed by Codility. Now, I am using this piece of code to get 93%
You can see the results below:
Codility test Results
0 <= P < Q < R < N
public static int solution(int[] unfilteredArray) {
int[] array = filterLessThanOneElements(unfilteredArray);
for(int i = 0; i <= (array.length - 3) ; i++) {
long p = array[i];
for(int j = i+1; j <= (array.length - 2); j++) {
long q = array[j];
for(int k = j+1; k <= (array.length - 1); k++) {
long r = array[k];
if((p + q > r) && (q + r > p) && (r + p > q)) {
return 1;
}
}
}
}
return 0;
}
// The mose efficient way to remove duplicates
// TIME COMPLEXITY : O(N)
private static int[] filterLessThanOneElements(int[] unfilteredArray) {
int k = 0;
for(int i = 0; i < unfilteredArray.length; i++) {
if(unfilteredArray[i] > 0) {
unfilteredArray[k++] = unfilteredArray[i];
}
}
return Arrays.copyOfRange(unfilteredArray, 0, k);
}
Simple change: First, you observe that negative integers cannot be part of a triangular triplet. That means you can cast all ints to unsigned int, and there can’t be any overflow anymore.
100/100 JavaScript solution
function solution(A) {
let l = A.length;
if (l < 3) {
return 0;
}
A.sort((a, b) => a - b);
for (let i = 0; i < l - 2; i++) {
let [p, q, r] = [A[i], A[i + 1], A[i + 2]];
if (p + q > r && q + r > p && r + p > q) {
return 1;
}
}
return 0;
}
If you don't want to use Array.sort, the following works with 100% correctness and 100% performance with a complexity that codility detects at O(N*log(N)).
class Solution {
public int solution(int[] A) {
int ans = 0;
int p1 = -1;
int p2 = -1;
int p1Pos = 0;
int p2Pos = 1;
int cur = -1;
if(A.length > 2){
p1 = A[0];
p2 = A[1];
for(int i = p2Pos + 1; i < A.length; i++){
if(p1 > p2){
p2 = A[p1Pos];
p1 = A[p2Pos];
A[p2Pos] = p2;
A[p1Pos] = p1;
}
cur = A[i];
//System.out.println(p1 + " " + p2 + " " + cur);
if(p1 > -1 && p2 > -1){
//the test for a triangle
if (cur > -1 &&
((p1 == p2 && p2 == cur) ||
((p1 + p2 > cur) && (p1 + cur > p2) && ( cur + p2 > p1)))){
return 1;
//bubble sort...sort of
}else if (p2 > cur){
A[p2Pos] = cur;
A[i] = p2;
if(p1 < cur){
p1 = cur;
p1Pos = p2Pos;
}
p2Pos = i;
} else if(cur > -1
&&(p1 + p2 <= cur) ){
p2Pos++;
p1Pos++;
p1=p2;
p2=cur;
}
}else{
//find the first two positive numbers
if((p2 < 0 || p1 < 0) && cur > -1){
if(p1 < 0){
p1 = cur;
p1Pos = i;
}else{
p2 = A[i];
p2Pos = i;
}
}
}
}
}
return ans;
}
}
When I was making this I thought that maybe I could solve this while doing a modified Bubble sort. I chose two pivots (p1 and p2), while making sure p2 > p1.
As I iterated through the array, I made sure that p2 would bubble up if p2 > cur and that p1 would additionally bubble up if p1 > cur. I Furthermore, I noticed that any combination of three points that have a negative number cannot be a triangle. So I ignored negatives. I also realized that if the array happened to hold three and only maximal integers that I would have an issue. To solve this I tested for p1 == p2 == cur. Admittingly, it might be better to use BigInteger to solve it.
My 100% JavaScript solution with O(N*log(N)) time complexity:
function solution(A) {
A.sort((a, b) => a - b);
for (let i = 0, len = A.length - 2; i < len; i++) {
const [P, Q, R] = [A[i], A[i + 1], A[i + 2]];
if (P + Q > R && Q + R > P && R + P > Q) {
return 1;
}
}
return 0;
}
One would think that sorting the array first will violate the condition 0<=P<Q<R. But the question is does such a triple exist. For the example we find [10,2,5,1,8,20]. After sorting we still find the values 10, 5, and 8 as the triple, but in a different order.
A Python 3 solution with 100% score at Codility:
def triangle(A):
n = len(A)
if n < 3:
return 0
a = list(A)
if 0 not in a:
a.append(0)
a.sort()
#print(a)
n = len(a)
p_a = a[a.index(0)+1:n]
#print(p_a)
n = len(p_a)
for i in range(n-2):
p = p_a[i]
q = p_a[i+1]
r = p_a[i+2]
if (p+q>r):
return (1)
return 0
Better solutions for C++ is to change a little algorithm. Make subtraction instead of adding, here is an example:
int solution(vector<int> &A) {
if (A.size() < 3)
return 0;
sort(A.begin(), A.end());
for (int i = 0; i < A.size() - 2; i++) {
if (A[i] > 0 && (A[i] > A[i + 2] - A[i + 1]))
return 1;
}
return 0;
}
It's because of integer overflow.
Try out this one:
int a1 = 1900000000;
int a2 = 1900000000;
int sum = a1+a2; // sum will be -494967296
Edit: Use long long int.
long long int sum01 = A[i] + A[i+1];
long long int sum12 = A[i+1] + A[i+2];
long lont int sum02 = A[i] + A[i+2];
if (sum01 > A[i+2] && sum12 > A[i] && sum02 > A[i+1])
return 1;
My java Solution 100/100 Instead of comparing the Addition we compare the subtraction as we can have an Integer.MAX_VALUE an we will be getting corrupted data.
public static int solution(int[] A) {
int isATriangle = 0;
Arrays.sort(A);
if (A.length >= 3) {
for (int i = 0; i < A.length - 2; i++) {
if (A[i] > A[i + 2] - A[i + 1]
&& A[i + 2] > A[i] - A[i + 1]
&& A[i + 2] > A[i + 1] - A[i])
isATriangle = 1;
}
}
return isATriangle;
}
I am trying to create a maze generator using recursive backtracking and have come across a problem that I just can't get my head around. For some reason my move function is returning the value "18446744073709551615". This is (of course) leading to a segmentation fault. Why is my move function returning such a large value when my move function can only increase or decrease the value by 2?
bool maze::generate(size_t x, size_t y) {
//mark the position as visited
labyrinth.s[y][x] = true;
//print to see progress
//this->print();
//if the position is not out of bounds
if (x < 0 || x > labyrinth.MAXWIDTH - 1 || y < 0 || y > labyrinth.MAXHIGHT - 1) {
//if the position is the endpoint return true
if (labyrinth.v[y][x - 1] == 'W' || labyrinth.v[y][x + 1] == 'W' || labyrinth.v[y - 1][x] == 'W' || labyrinth.v[y + 1][x] == 'W') {
return true;
}
}
//pick a random direction
do {
d = size_t(rand() % 4);
} while(!this->pos_test(x, y, d));
std::cout << x << ' ' << y << std::endl;
if (d == UP) {
y = move(x, y, UP);
}
else if (d == DOWN) {
y = move(x, y, DOWN);
}
else if (d == RIGHT) {
x = move(x, y, RIGHT);
}
else if (d == LEFT) {
x = move(x, y, LEFT);
}
else{
}
std::cout << x << ' ' << y << std::endl;
//recursively generate the maze
if (this->generate(x, y)) {
return true;
}
}
void maze::initialize(size_t x, size_t y) {
//set the maxhight and the maxwidth to y and x
labyrinth.MAXHIGHT = y;
labyrinth.MAXWIDTH = x;
//set all elements in the vector to #
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<char> temp;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp.push_back(labyrinth.wall);
}
labyrinth.v.push_back(temp);
}
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
if (j % 2 == 1 && i % 2 == 1 && j != labyrinth.MAXWIDTH - 1 && j != 0 && i != labyrinth.MAXHIGHT - 1 && i != 0) {
labyrinth.v[j][i] = labyrinth.path;
}
}
}
//set all posistions to unvisited
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<bool> temp2;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp2.push_back(false);
}
labyrinth.s.push_back(temp2);
}
//setup the start point
labyrinth.v[0][1] = 'S';
//setup the endpoint
labyrinth.v[labyrinth.MAXHIGHT - 2][labyrinth.MAXWIDTH - 1] = 'W';
}
//if a position has been visited or if not possible to go to return true
bool maze::pos_test(size_t x, size_t y, size_t d) const {
//if the position is out of bounds return false
if (x < 0 || y < 0 || x > labyrinth.MAXWIDTH - 1 || y > labyrinth.MAXHIGHT - 1) {
return true;
}
else if (x == 1 && d == LEFT) {
return true;
}
else if (y == 1 && d == UP) {
return true;
}
else if (x == labyrinth.MAXWIDTH - 1 && d == RIGHT) {
return true;
}
else if (y == labyrinth.MAXHIGHT - 1 && d == DOWN) {
return true;
}
else if (d == UP) {
return labyrinth.s[y - 2][x];
}
else if (d == DOWN) {
return labyrinth.s[y + 2][x];
}
else if (d == RIGHT) {
return labyrinth.s[y][x + 2];
}
else if (d == LEFT) {
return labyrinth.s[y][x - 2];
}
else {
return true;
}
}
size_t maze::move(size_t x, size_t y, size_t d) {
//if the position is out of bounds return without modifying
if (x < 0 || x > labyrinth.MAXWIDTH - 1) {
return x;
}
else if (y < 0 || y > labyrinth.MAXHIGHT - 1) {
return y;
}
else if (d == UP) {
labyrinth.v[y - 1][x] = labyrinth.path;
return y = y - 2;
}
else if (d == DOWN) {
labyrinth.v[y + 1][x] = labyrinth.path;
return y = y + 2;
}
else if (d == RIGHT) {
labyrinth.v[y][x + 1] = labyrinth.path;
return x = x + 2;
}
else if (d == LEFT) {
labyrinth.v[y][x - 1] = labyrinth.path;
return x = x - 2;
}
else {
}
}
You are underflowing your unsigned 64-bit return type size_t.
You are checking whether x and y are below zero, but that's not enough, because 0 and 1 will still be too low because you are subtracting 2!
The number you get is 0xFFFFFFFFFFFFFFFF in hexadecimal. This is the highest possible value for an unsigned 64-bit integer.
It comes from calculating 1 - 2. Yes, this is supposed to be -1, but because your move function doesn't return a signed number but an unsigned one (check the docs on size_t), it can't be negative! Instead, it wraps around to the highest possible number.
You can imagine this in the same way you would get ...99999999999 when you try to calculate 1 - 2 on paper ignoring the "you can't subtract a higher number from a smaller one on paper" rule.
As a side note: I guess the negative result is undesired anyway, because actually your huge number, once added to a pointer, will in turn overflow back into positive, so basically it will work the same is a real -1 in your case and the segmentation fault comes from accessing something right before the beginning of your buffer, not far beyond it, but it comes down to the same thing.
Apart from that, there is no need to do return y = y - 2 and such. Just return y - 2.
Given two strings (s1, s2), Levenshtein Distance is the minimum number of operations needed to change s1 to s2 or vice versa.
I want to show the result of changing s1 to s2. For example, changing Sunday to Saturday needs 3 operations. I need to show S++u+day. "+" is for each operations needed.
Here is a javascript snippet that returns what you want. If you are familiar with the dynamic programming algorithm you should be able follow this code. All the string operations/manipulation of the return string r and handling of min/curMin are what's changed from the original version.
function edits(t, s) {
var r = "";
if (s === t) {
return s;
}
var n = s.length, m = t.length;
if (n === 0 || m === 0) {
return "+".repeat(n + m);
}
var x, y, a, b, c, min = 0;
var p = new Array(n);
for (y = 0; y < n;)
p[y] = ++y;
for (x = 0; x < m; x++) {
var e = t.charCodeAt(x);
c = x;
b = x + 1;
var currMin = min;
min = n + 1;
for (y = 0; y < n; y++) {
a = p[y];
if (a < c || b < c) {
b = (a > b ? b + 1 : a + 1);
}
else {
if (e !== s.charCodeAt(y)) {
b = c + 1;
}
else {
b = c;
}
}
if (b < min) {
min = b;
}
p[y] = b;
c = a;
}
if (min > currMin) {
r += "+";
}
else {
r += t[x];
}
}
return r;
}
EDIT: The implementation above is an version optimized for speed and space so might be harder to read. The implemetation below is a modified version of the JS version from Wikipedia and should be easier to follow.
function getEditDistance(a, b) {
if(a.length === 0) return "+".repeat(b.length);
if(b.length === 0) return "+".repeat(a.length);
var matrix = [];
// increment along the first column of each row
var i;
for(i = 0; i <= b.length; i++){
matrix[i] = [i];
}
// increment each column in the first row
var j;
for(j = 0; j <= a.length; j++){
matrix[0][j] = j;
}
var r = "", min = 0;;
// Fill in the rest of the matrix
for(i = 1; i <= b.length; i++){
var currMin = min;
min = a.length + 1;
for(j = 1; j <= a.length; j++){
if(b.charAt(i-1) == a.charAt(j-1)){
matrix[i][j] = matrix[i-1][j-1];
} else {
matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
Math.min(matrix[i][j-1] + 1, // insertion
matrix[i-1][j] + 1)); // deletion
}
if (matrix[i][j] < min) {
min = matrix[i][j];
}
}
if (min > currMin) {
r += "+";
}
else {
r += b[i-1];
}
}
return r;
}
EDIT2: Added explanation of the algorithm and example output
Below is the levenshtein matrix from the input strings "kitten" and "sitting". What I changed in the original algorithm is that I added a check if the current rows minimum value is larger then the previous rows minimum, and if it is, there is an edit in the current row and thus adding a "+". If not and the " edit cost" for the current row is the same as the previous. Then there is no edit necessary and we just add the current character to the result string. You can follow the algorithm row by row in the image (starting at row 1, and column 1)
Examples:
> getEditDistance("kitten", "sitting");
'+itt+n+'
> getEditDistance("Sunday", "Saturday");
'S++u+day'
I need to place numbers within a grid such that it doesn't collide with each other. This number placement should be random and can be horizontal or vertical. The numbers basically indicate the locations of the ships. So the points for the ships should be together and need to be random and should not collide.
I have tried it:
int main()
{
srand(time(NULL));
int Grid[64];
int battleShips;
bool battleShipFilled;
for(int i = 0; i < 64; i++)
Grid[i]=0;
for(int i = 1; i <= 5; i++)
{
battleShips = 1;
while(battleShips != 5)
{
int horizontal = rand()%2;
if(horizontal == 0)
{
battleShipFilled = false;
while(!battleShipFilled)
{
int row = rand()%8;
int column = rand()%8;
while(Grid[(row)*8+(column)] == 1)
{
row = rand()%8;
column = rand()%8;
}
int j = 0;
if(i == 1) j= (i+1);
else j= i;
for(int k = -j/2; k <= j/2; k++)
{
int numberOfCorrectLocation = 0;
while(numberOfCorrectLocation != j)
{
if(row+k> 0 && row+k<8)
{
if(Grid[(row+k)*8+(column)] == 1) break;
numberOfCorrectLocation++;
}
}
if(numberOfCorrectLocation !=i) break;
}
for(int k = -j/2; k <= j/2; k++)
Grid[(row+k)*8+(column)] = 1;
battleShipFilled = true;
}
battleShips++;
}
else
{
battleShipFilled = false;
while(!battleShipFilled)
{
int row = rand()%8;
int column = rand()%8;
while(Grid[(row)*8+(column)] == 1)
{
row = rand()%8;
column = rand()%8;
}
int j = 0;
if(i == 1) j= (i+1);
else j= i;
for(int k = -j/2; k <= j/2; k++)
{
int numberOfCorrectLocation = 0;
while(numberOfCorrectLocation != i)
{
if(row+k> 0 && row+k<8)
{
if(Grid[(row)*8+(column+k)] == 1) break;
numberOfCorrectLocation++;
}
}
if(numberOfCorrectLocation !=i) break;
}
for(int k = -j/2; k <= j/2; k++)
Grid[(row)*8+(column+k)] = 1;
battleShipFilled = true;
}
battleShips++;
}
}
}
}
But the code i have written is not able to generate the numbers randomly in the 8x8 grid.
Need some guidance on how to solve this. If there is any better way of doing it, please tell me...
How it should look:
What My code is doing:
Basically, I am placing 5 ships, each of different size on a grid. For each, I check whether I want to place it horizontally or vertically randomly. After that, I check whether the surrounding is filled up or not. If not, I place them there. Or I repeat the process.
Important Point: I need to use just while, for loops..
You are much better of using recursion for that problem. This will give your algorithm unwind possibility. What I mean is that you can deploy each ship and place next part at random end of the ship, then check the new placed ship part has adjacent tiles empty and progress to the next one. if it happens that its touches another ship it will due to recursive nature it will remove the placed tile and try on the other end. If the position of the ship is not valid it should place the ship in different place and start over.
I have used this solution in a word search game, where the board had to be populated with words to look for. Worked perfect.
This is a code from my word search game:
bool generate ( std::string word, BuzzLevel &level, CCPoint position, std::vector<CCPoint> &placed, CCSize lSize )
{
std::string cPiece;
if ( word.size() == 0 ) return true;
if ( !level.inBounds ( position ) ) return false;
cPiece += level.getPiece(position)->getLetter();
int l = cPiece.size();
if ( (cPiece != " ") && (word[0] != cPiece[0]) ) return false;
if ( pointInVec (position, placed) ) return false;
if ( position.x >= lSize.width || position.y >= lSize.height || position.x < 0 || position.y < 0 ) return false;
placed.push_back(position);
bool used[6];
for ( int t = 0; t < 6; t++ ) used[t] = false;
int adj;
while ( (adj = HexCoord::getRandomAdjacentUnique(used)) != -1 )
{
CCPoint nextPosition = HexCoord::getAdjacentGridPositionInDirection((eDirection) adj, position);
if ( generate ( word.substr(1, word.size()), level, nextPosition, placed, lSize ) ) return true;
}
placed.pop_back();
return false;
}
CCPoint getRandPoint ( CCSize size )
{
return CCPoint ( rand() % (int)size.width, rand() % (int)size.height);
}
void generateWholeLevel ( BuzzLevel &level,
blockInfo* info,
const CCSize &levelSize,
vector<CCLabelBMFont*> wordList
)
{
for ( vector<CCLabelBMFont*>::iterator iter = wordList.begin();
iter != wordList.end(); iter++ )
{
std::string cWord = (*iter)->getString();
// CCLog("Curront word %s", cWord.c_str() );
vector<CCPoint> wordPositions;
int iterations = 0;
while ( true )
{
iterations++;
//CCLog("iteration %i", iterations );
CCPoint cPoint = getRandPoint(levelSize);
if ( generate (cWord, level, cPoint, wordPositions, levelSize ) )
{
//Place pieces here
for ( int t = 0; t < cWord.size(); t++ )
{
level.getPiece(wordPositions[t])->addLetter(cWord[t]);
}
break;
}
if ( iterations > 1500 )
{
level.clear();
generateWholeLevel(level, info, levelSize, wordList);
return;
}
}
}
}
I might add that shaped used in the game was a honeycomb. Letter could wind in any direction, so the code above is way more complex then what you are looking for I guess, but will provide a starting point.
I will provide something more suitable when I get back home as I don't have enough time now.
I can see a potential infinite loop in your code
int j = 0;
if(i == 1) j= (i+1);
else j= i;
for(int k = -j/2; k <= j/2; k++)
{
int numberOfCorrectLocation = 0;
while(numberOfCorrectLocation != i)
{
if(row+k> 0 && row+k<8)
{
if(Grid[(row)*8+(column+k)] == 1) break;
numberOfCorrectLocation++;
}
}
if(numberOfCorrectLocation !=i) break;
}
Here, nothing prevents row from being 0, as it was assignd rand%8 earlier, and k can be assigned a negative value (since j can be positive). Once that happens nothing will end the while loop.
Also, I would recommend re-approaching this problem in a more object oriented way (or at the very least breaking up the code in main() into multiple, shorter functions). Personally I found the code a little difficult to follow.
A very quick and probably buggy example of how you could really clean your solution up and make it more flexible by using some OOP:
enum Orientation {
Horizontal,
Vertical
};
struct Ship {
Ship(unsigned l = 1, bool o = Horizontal) : length(l), orientation(o) {}
unsigned char length;
bool orientation;
};
class Grid {
public:
Grid(const unsigned w = 8, const unsigned h = 8) : _w(w), _h(h) {
grid.resize(w * h);
foreach (Ship * sp, grid) {
sp = nullptr;
}
}
bool addShip(Ship * s, unsigned x, unsigned y) {
if ((x <= _w) && (y <= _h)) { // if in valid range
if (s->orientation == Horizontal) {
if ((x + s->length) <= _w) { // if not too big
int p = 0; //check if occupied
for (int c1 = 0; c1 < s->length; ++c1) if (grid[y * _w + x + p++]) return false;
p = 0; // occupy if not
for (int c1 = 0; c1 < s->length; ++c1) grid[y * _w + x + p++] = s;
return true;
} else return false;
} else {
if ((y + s->length) <= _h) {
int p = 0; // check
for (int c1 = 0; c1 < s->length; ++c1) {
if (grid[y * _w + x + p]) return false;
p += _w;
}
p = 0; // occupy
for (int c1 = 0; c1 < s->length; ++c1) {
grid[y * _w + x + p] = s;
p += _w;
}
return true;
} else return false;
}
} else return false;
}
void drawGrid() {
for (int y = 0; y < _h; ++y) {
for (int x = 0; x < _w; ++x) {
if (grid.at(y * w + x)) cout << "|S";
else cout << "|_";
}
cout << "|" << endl;
}
cout << endl;
}
void hitXY(unsigned x, unsigned y) {
if ((x <= _w) && (y <= _h)) {
if (grid[y * _w + x]) cout << "You sunk my battleship" << endl;
else cout << "Nothing..." << endl;
}
}
private:
QVector<Ship *> grid;
unsigned _w, _h;
};
The basic idea is create a grid of arbitrary size and give it the ability to "load" ships of arbitrary length at arbitrary coordinates. You need to check if the size is not too much and if the tiles aren't already occupied, that's pretty much it, the other thing is orientation - if horizontal then increment is +1, if vertical increment is + width.
This gives flexibility to use the methods to quickly populate the grid with random data:
int main() {
Grid g(20, 20);
g.drawGrid();
unsigned shipCount = 20;
while (shipCount) {
Ship * s = new Ship(qrand() % 8 + 2, qrand() %2);
if (g.addShip(s, qrand() % 20, qrand() % 20)) --shipCount;
else delete s;
}
cout << endl;
g.drawGrid();
for (int i = 0; i < 20; ++i) g.hitXY(qrand() % 20, qrand() % 20);
}
Naturally, you can extend it further, make hit ships sink and disappear from the grid, make it possible to move ships around and flip their orientation. You can even use diagonal orientation. A lot of flexibility and potential to harness by refining an OOP based solution.
Obviously, you will put some limits in production code, as currently you can create grids of 0x0 and ships of length 0. It's just a quick example anyway. I am using Qt and therefore Qt containers, but its just the same with std containers.
I tried to rewrite your program in Java, it works as required. Feel free to ask anything that is not clearly coded. I didn't rechecked it so it may have errors of its own. It can be further optimized and cleaned but as it is past midnight around here, I would rather not do that at the moment :)
public static void main(String[] args) {
Random generator = new Random();
int Grid[][] = new int[8][8];
for (int battleShips = 0; battleShips < 5; battleShips++) {
boolean isHorizontal = generator.nextInt(2) == 0 ? true : false;
boolean battleShipFilled = false;
while (!battleShipFilled) {
// Select a random row and column for trial
int row = generator.nextInt(8);
int column = generator.nextInt(8);
while (Grid[row][column] == 1) {
row = generator.nextInt(8);
column = generator.nextInt(8);
}
int lengthOfBattleship = 0;
if (battleShips == 0) // Smallest ship should be of length 2
lengthOfBattleship = (battleShips + 2);
else // Other 4 ships has the length of 2, 3, 4 & 5
lengthOfBattleship = battleShips + 1;
int numberOfCorrectLocation = 0;
for (int k = 0; k < lengthOfBattleship; k++) {
if (isHorizontal && row + k > 0 && row + k < 8) {
if (Grid[row + k][column] == 1)
break;
} else if (!isHorizontal && column + k > 0 && column + k < 8) {
if (Grid[row][column + k] == 1)
break;
} else {
break;
}
numberOfCorrectLocation++;
}
if (numberOfCorrectLocation == lengthOfBattleship) {
for (int k = 0; k < lengthOfBattleship; k++) {
if (isHorizontal)
Grid[row + k][column] = 1;
else
Grid[row][column + k] = 1;
}
battleShipFilled = true;
}
}
}
}
Some important points.
As #Kindread said in an another answer, the code has an infinite loop condition which must be eliminated.
This algorithm will use too much resources to find a solution, it should be optimized.
Code duplications should be avoided as it will result in more maintenance cost (which might not be a problem for this specific case), and possible bugs.
Hope this answer helps...