Abort signal for Rat in a maze problem (SIGABRT) - algorithm

I was trying to solve the rat in a mze problem (https://practice.geeksforgeeks.org/problems/rat-in-a-maze-problem/1). But I am getting SIGABRT at the commented line below. I was thinking for quite a lot of time why it is happening. Can you please help? Thank you.
#include <bits/stdc++.h>
using namespace std;
class Solution{
public:
vector<string> check(int i, int j, vector<vector<int>> &m,string str , vector<string> soln,int n)
{
if(i==n-1 && j==n-1){soln.push_back(str);return soln;}
m[i][j]=0;
if(i+1<=n-1 && m[i+1][j]!=0 ){str += "D"; check(i+1,j,m,str,soln,n);}
else if(j+1<=n-1 && m[i][j+1]!=0 )
{
str += "R";
check(i,j+1,m,str,soln,n);// This is causing the SIGABRT when str = "DDRDRR"
}
else if(i-1>=0 && m[i-1][j]!=0){str += "U"; check(i-1,j,m,str,soln,n);}
else if(j-1>=0 && m[i][j-1]!=0){str += "L"; check(i,j-1,m,str,soln,n);}
}
vector<string> findPath(vector<vector<int>> &m, int n) {
vector<string> paths;
vector<string> soln;
if(m[0][0]==0)return paths;
paths = check(0,0,m,"",soln,n);
return paths;
}
};
int main() {
int t;
t=1;
while (t--) {
int n;
n=4;
vector<vector<int>> m{{1, 0, 0, 0},{1, 1, 0, 1}, {1, 1, 0, 0},{0, 1, 1, 1}};
Solution obj;
vector<string> result = obj.findPath(m, n);
sort(result.begin(), result.end());
if (result.size() == 0)
cout << -1;
else
for (int i = 0; i < result.size(); i++) cout << result[i] << " ";
cout << endl;
}
return 0;
}

There's no default case if none of the conditions match, you're simply returning void which is not a vector.
To fix it, add return soln; to the end of the check function.

Related

How fix it. Unhandled exception at 0x0099B514 in ConsoleApplication15.exe: 0xC0000094: Integer division by zero

I am trying to solve problem with c++: Find all unique elements of a two-dimensional array of integers using MPI_Scatter and MPI_Comm_split to distribute the array's rows among a set of processes, so that the set of processes is split into three groups.
Got the code
#include <iostream>
#include <unordered_set>
#include <mpi.h>
using namespace std;
int main(int argc, char* argv[])
{
int rank, size;
int rows = 0, columns = 0;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int* matrix = nullptr;
if (rank == 0)
{
cout << "Enter the number of rows: ";
cin >> rows;
cout << "Enter the number of columns: ";
cin >> columns;
matrix = new int[rows * columns];
cout << "Enter the elements of the matrix: " << endl;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
cin >> matrix[i * columns + j];
}
}
}
MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&columns, 1, MPI_INT, 0, MPI_COMM_WORLD);
int sub_size = rows / size;
int* local_matrix = new int[sub_size * columns];
MPI_Scatter(matrix, sub_size * columns, MPI_INT, local_matrix, sub_size * columns, MPI_INT, 0, MPI_COMM_WORLD);
unordered_set<int> local_set;
for (int i = 0; i < sub_size; i++)
{
for (int j = 0; j < columns; j++)
{
local_set.insert(local_matrix[i * columns + j]);
}
}
MPI_Comm sub_comm;
MPI_Comm_split(MPI_COMM_WORLD, rank / (size / 3), rank, &sub_comm);
int sub_rank, new_sub_size;
MPI_Comm_rank(sub_comm, &sub_rank);
MPI_Comm_size(sub_comm, &new_sub_size);
unordered_set<int>* global_set = nullptr;
if (sub_rank == 0)
{
global_set = new unordered_set<int>[new_sub_size];
}
MPI_Gather(&local_set, sizeof(unordered_set<int>), MPI_BYTE, global_set, sizeof(unordered_set<int>), MPI_BYTE, 0, sub_comm);
if (sub_rank == 0)
{
unordered_set<int> final_set;
for (int i = 0; i < new_sub_size; i++)
{
for (auto it = global_set[i].begin(); it != global_set[i].end(); it++) {
final_set.insert(*it);
}
}
cout << "The unique elements in the matrix are: ";
for (auto it = final_set.begin(); it != final_set.end(); it++) {
cout << *it << " ";
}
cout << endl;
delete[] global_set;
}
delete[] local_matrix;
if (rank == 0) {
delete[] matrix;
}
MPI_Finalize();
return 0;
}
After compile and input data microsoft visual studio 2019 gives an error message
Unhandled exception at 0x0099B514 in ConsoleApplication15.exe: 0xC0000094: Integer division by zero.
to this line
MPI_Comm_split(MPI_COMM_WORLD, rank / (size / 3), rank, &sub_comm);
How fix it?

basic k way merge: terminate called after throwing an instance of 'std::logic_error'

I am trying to implement basic merge k sorted array algorithm but with strings.
I am getting the following error.
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
The code works fine if the names vector has just 2 sub vectors, but when I add another list in the names vector I am getting the above error.
Whats wrong with the code?
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string> merge_2_names(vector<string> a, vector<string> b){
int i = 0 ; int j = 0;
vector<string> res;
while(i < a.size() && j < b.size()){
if (a[i].compare(b[j]) < 0){
res.push_back(a[i]);
i++;
}else{
res.push_back(b[j]);
j++;
}
}
while (i < a.size()){
res.push_back(a[i]);
i++;
}
while(j < a.size()){
res.push_back(b[j]);
j++;
}
return res;
}
vector<string> merge_k_names(vector<vector<string>> names){
vector<string> result;
cout << names.size() << "\n";
for (string s: names[0]){
result.push_back(s);
}
for(int i=1;i<names.size();i++)
{
result=merge_2_names(result,names[i]);
}
return result;
}
int main() {
vector<vector<string>> names {{"adam" , "raja" , "zync"},
{"edam" , "some" , "zian"},
{"mike" , "jimm" , "pame"}};
cout << names.size() << "\n";
vector<string> res = merge_k_names(names);
for (string s: res){
cout << s << " ";
}
return 0;
}

Permutation and Combination c++ logical error

This is my assignment, i finished writing my code and it does compile but it is not giving the right answer. So i know there is some logical error but i cannot find out what.
Plz check and tell me, simple code to calculate permutations and combinations
#include <iostream>
using namespace std;
int factorial(int n)
{
if (n == 0 or n == 1)
{
return 1;
}
else
{
return n * factorial(n - 1);
}
}
int permutation(int a, int b)
{
//factorial(a);
int perm = factorial(a) / factorial(a - b);
return perm;
}
int combination(int a, int b)
{
int permutation(int a, int b);
int factorial(int n);
return permutation(a, b) / factorial(b);;
}
int main()
{
int n;
int r;
cout << "Enter n: " << endl;
cin >> n;
cout << "Enter r: " << endl;
cin >> r;
int factorial(int n);
int permutation(int n, int r);
int combination(int n, int r);
if (n >= r)
{
cout << "Permutuation: " << permutation << endl;
cout << "Combination: " << combination << endl;
}
else
{
cout << "Invalid" << endl;
}
return 0;
}
The answer given by the console
Enter n:
6
Enter r:
5
Permutuation: 00AC1375
Combination: 00AC133E
There are a number of errors in your code. First, you should not re-declare your 'permutation' and 'combination' functions inside other functions.
EDIT: Actually, this is not an error but, in my opinion, very bad practice. You could accidentally 'hide' the actual function declaration, which is already provided as you have defined both before any of the calling functions.
Second, your cout << permutation << endl; code is printing a function! This will be taken as meaning the address of that function, which is what you are seeing (HEX addresses).
Here's a 'fixed' version that works (with comments).
#include <iostream>
#include <iso646.h> // Need this in order to use "or" in place of "||"
using namespace std;
int factorial(int n)
{
if (n == 0 or n == 1) {
return 1;
}
else {
return n * factorial(n - 1);
}
}
int permutation(int a, int b)
{
//factorial(a);
int perm = factorial(a) / factorial(a - b);
return perm;
}
int combination(int a, int b)
{
// int permutation(int a, int b); // You don't need to redeclare function inside another one ...
// int factorial(int n);
return permutation(a, b) / factorial(b);;
}
int main()
{
int n, r;
cout << "Enter n: " << endl;
cin >> n;
cout << "Enter r: " << endl;
cin >> r;
// int factorial(int n);
int p = permutation(n, r); // This is how to call your functions ...
int c = combination(n, r); // and assign their returns to values.
if (n >= r) {
cout << "Permutuation: " << p << endl; // Output the values ...
cout << "Combination: " << c << endl; // ...from the functions
}
else {
cout << "Invalid" << endl;
}
return 0;
}
Feel free to ask for further explanations if there's anything I've done that you don't understand.

Why do I keep getting TLE for POJ 1984 -- Navigation Nightmare?

#include <iostream>
#include <vector>
#include <cassert>
#include <queue>
using namespace std;
struct vectors{
int x;
int y;
bool visited;
vectors(int x = 0, int y = 0){
this -> x = x;
this -> y = y;
visited = false;
}
bool isNotFound(){
return visited == false;
}
void setZero(){
x = 0;
y = 0;
}
vectors operator+(vectors others){
return vectors(x + others.x, y + others.y);
}
vectors operator*(int others){
return vectors(x * others, y * others);
}
};
struct node{
int adjFarm;
int length;
char direction;
node(int f, int l, char d){
adjFarm = f;
length = l;
direction = d;
}
};
int num_villages;
char inverse_direction(char d){
assert(d == 'N' || d == 'E' || d == 'W' || d == 'S' );
switch(d){
case 'S': return 'N';
case 'N': return 'S';
case 'E': return 'W';
case 'W': return 'E';
}
}
void AddToPaths(int farm1, int farm2, char direction, int length, vector< vector<node> > &pathGraph){
pathGraph.at(farm1).push_back(node(farm2, length, direction));
pathGraph.at(farm2).push_back(node(farm1, length, inverse_direction(direction)));
}
vectors directionVector(int d){
switch(d){
case 'N': return vectors(0, 1);
case 'E': return vectors(1, 0);
case 'W': return vectors(- 1, 0);
case 'S': return vectors(0, - 1);
}
}
void print_coords(vector< vectors > coords){
for(int i = 1; i < num_villages + 1; i ++){
cout << "farm: " << i << " coordinates x at farm: " << coords.at(i).x << " coordinated y at farm: " << coords.at(i).y << endl;
}
}
void update(char direction, int newFarm, int length, int currentFarm, vector <vectors> &coords){
vectors directions = directionVector(direction);
coords.at(newFarm) = coords.at(currentFarm) + directions * length;
coords.at(newFarm).visited = true;
}
void computeCoords(vector <vectors> &coords, vector< vector<node> > &pathGraph){
queue <int> frontier;
frontier.push(1);
coords.at(1).visited = true;
while(!frontier.empty()){
int currentFarm = frontier.front();
frontier.pop();
for(int i = 0; i < pathGraph.at(currentFarm).size(); i ++){
node options = pathGraph.at(currentFarm).at(i);
if(coords.at(options.adjFarm).isNotFound()){
update(options.direction, options.adjFarm, options.length, currentFarm, coords);
frontier.push(options.adjFarm);
}
}
}
}
struct UnionFind{
vector<int> L;
UnionFind(int num_villages){
L.resize(num_villages + 1);
for(int i = 1; i <= num_villages; i ++){
L.at(i) = i;
}
}
int find(int x){
if(x == L.at(x)) return x;
int root = find(L.at(x));
L.at(x) = root;
return root;
}
int Union(int x, int y){
int root1 = find(x);
int root2 = find(y);
L.at(y) = root1;
}
};
int pos;
int query(int start, int destination, int order, UnionFind &reachables, vector<vectors> &coords, vector<vector<int> > &source_destination_order){
while(pos <= order){
reachables.Union(reachables.find(source_destination_order.at(pos).at(0)), reachables.find(source_destination_order.at(pos).at(1)));
pos ++;
}
if(reachables.find(start) == reachables.find(destination)){
return abs(coords.at(start).x - coords.at(destination).x) + abs(coords.at(start).y - coords.at(destination).y);
}
else{
return -1;
}
}
int main(void){
int num_roads;
cin >> num_villages;
cin >> num_roads;
vector <vector<node> > pathGraph(num_villages + 1);
vector <vectors > coords(num_villages + 1);
vector <vector <int> > source_destination_order(num_villages + 1, vector<int> (2));
//Adding inforamtion about the farms
int farm1;
int farm2;
char direction;
int length;
int source;
for(int i = 0; i < num_roads; i ++){
cin >> farm1;
cin >> farm2;
cin >> length;
cin >> direction;
AddToPaths(farm1, farm2, direction, length, pathGraph);
source_destination_order.at(i + 1).at(0) = farm1;
source_destination_order.at(i + 1).at(1) = farm2;
}
computeCoords(coords, pathGraph);
int numQueries;
cin >> numQueries;
int start;
int destination;
int order;
int result;
UnionFind reachables(num_villages);
pos = 1;
for(int i = 0; i < numQueries; i ++){
cin >> start;
cin >> destination;
cin >> order;
result = query(start, destination, order, reachables, coords, source_destination_order);
cout << result << endl;
}
}
I tried to create an undirected acyclic graph with the farms as the vertices and the roads as the edges, and then use BFS to compute the coordinates of each farm relative to the first farm. Afterwards I used the union find structure to create disjoint sets of farms that are reachable from each other at the time of the query. However, it seems like my code takes too long to run, how should I fix it?

Finding bridges in graph without recursion

I have this code to find bridges in a connected graph:
void dfs (int v, int p = -1) {
used[v] = true;
tin[v] = fup[v] = timer++;
for (size_t i=0; i<g[v].size(); ++i) {
int to = g[v][i];
if (to == p) continue;
if (used[to])
fup[v] = min (fup[v], tin[to]);
else {
dfs (to, v);
fup[v] = min (fup[v], fup[to]);
if (fup[to] > tin[v])
printf("%d %d", v, to);
}
}
}
How to rewrite it without using recursion? I know, it's possible to do it and I should use stack, but this line must be executed after recursive call of dfs() and I can't achieve with a stack:
fup[v] = min(fup[v], fup[to])
So, how to rewrite my algorithm iteratively?
You want to make a "stack frame" structure
struct Frame {
Frame(int v, int p, int i, Label label);
int v;
int p;
int i;
};
// constructor here
and, as you say, a stack<Frame>. Between all of these fields, it's possible to simulate the call stack (untested code to give the general idea).
void dfs(int v, int p = -1) {
stack<Frame> st;
st.push(Frame(v, p, 0));
do {
Frame fr(st.top());
st.pop();
v = fr.v;
p = fr.p;
int i(fr.i);
if (i > 0) {
int to(g[v][i - 1]);
fup[v] = min(fup[v], fup[to]);
if (fup[to] > tin[v]) { printf("%d %d", v, to); }
if (i == g[v].size()) { continue; }
} else if (i == 0) {
used[v] = true;
tin[v] = fup[v] = timer++;
}
int to(g[v][i]);
if (to == p) { continue; }
if (used[to]) {
fup[v] = min(fup[v], tin[to]);
} else {
st.push(Frame(to, v, 0));
}
st.push(Frame(v, p, i + 1));
} while (!st.empty());
}
Sorry for the late reply.
Change code of previous answer and now it works fine.
Tested in contest task to find all bridges in connected Graph.
Hope it will help you.
// Copyright 2020 Kondratenko Evgeny
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
struct Frame {
Frame(int v, int p, int i) : v(v), p(p), i(i) {
}
int v;
int p;
int i;
};
void DFS(int n,
const std::vector<std::vector<int>> &G,
const std::vector<std::vector<int>> &weights) {
std::vector<bool> used(n + 1, false);
std::vector<int> ret(n + 1); // the same as tup
std::vector<int> enter(n + 1); // the same as tin
std::stack<Frame> s;
s.push(Frame(1, -1, 0));
int time = 1;
while (!s.empty()) {
Frame f = s.top();
s.pop();
int v = f.v;
int p = f.p;
int i = f.i;
if (i == 0) {
enter[v] = ret[v] = time++;
used[v] = true;
}
// First part works befor DFS call
if (i < G[v].size()) {
int to = G[v][i];
s.push(Frame(v, p, i + 1));
if (to != p) {
if (used[to]) {
ret[v] = std::min(ret[v], enter[to]);
} else {
s.push(Frame(to, v, 0));
}
}
}
/*
Generally here is virtual DFS recursive call, which we are simulate now
*/
// Second part after DFS call
if (i > 0 && i <= G[v].size()) {
int to = G[v][i - 1];
if (to != p) {
ret[v] = std::min(ret[v], ret[to]);
if (ret[to] > enter[v]) {
std::cout << "bridge between: " << v << " and " << to;
std::cout << ", with weight: " << weights[v][i - 1] << std::endl;
}
}
}
}
}
int main() {
int n, m; // n - number of vertex, m - number of edges
std::cin >> n >> m;
std::vector<std::vector<int>> G(n + 1, std::vector<int>()); // your Graph
std::vector<std::vector<int>> weights(n + 1, std::vector<int>());
for (int i = 0; i < m; ++i) { // read edges with weigths
int u, v, w;
std::cin >> u >> v >> w;
G[u].push_back(v);
G[v].push_back(u);
weights[u].push_back(w);
weights[v].push_back(w);
}
DFS(n, G, weights);
return 0;
}

Resources