Matrix Traversal to print all and shortest path - infinite loop - c++

#include<iostream>
#include<random>
#include<ctime>
#include<cstdlib>
#include<vector>
#include<algorithm>
using namespace std;
int path_checker(vector<pair<int,int> > path, int i, int j)
{
//cout<<"path_checker"<<endl;
std::vector<pair<int, int> >::iterator it;
for(it = path.begin(); it!=path.end();it++)
if(it->first == i && it->second ==j)
return 1;
return 0;
}
int isVertex(int i, int j, int n)
{
//cout<<"isVertex"<<endl;
if((i>=0) && (j>=0))
{
if((i <= n) && (j <= n))
return 1;
}
return 0;
}
void printAllPathsU(int *array, int i, int j, int n, vector<pair<int,int> > path,int index)
{
// cout<<"PrintAllPathsU_first"<<endl;
// vector<pair<int,int>> path2 = {0};
if((i == n) && (j == n))
{
if((path_checker(path,i,j)))
{
cout<<"Inside printing path"<<endl;
//vector<pair<int,int> >::iterator it;
for(int i = 0; i < path.size();i++)
cout<<"a["<<path[i].first<<"]["<<path[i].second<<"] ";
return;
}
else
{
path.push_back(make_pair(i,j));
cout<<"Inside printing path"<<endl;
//vector<pair<int,int> >::iterator it;
for(int i = 0; i < path.size();i++)
cout<<"a["<<path[i].first<<"]["<<path[i].second<<"] ";
return;
}
}
if((*((array+i*n)+j) == 1) && (!path_checker(path,i,j)))
{
//cout<<path.size()<<endl;
path.push_back(make_pair(i,j));
index++;
//len++;
if(isVertex(i,j-1,n))
printAllPathsU((int *)array,i,j-1,n,path,index);
if(isVertex(i-1,j,n))
printAllPathsU((int *)array,i-1,j,n,path,index);
if(isVertex(i,j+1,n))
printAllPathsU((int *)array,i,j+1,n,path,index);
if(isVertex(i+1,j,n))
printAllPathsU((int *)array,i+1,j,n,path,index);
}
else if((*((array+i*n)+j) == 1) && (path_checker(path,i,j)))
{
//cout<<"inside second else"<<endl;
return;
}
else if(*((array+i*n)+j) == 0)
{
// cout<<"inside third else"<<endl;
return;
}
}
void printAllPaths(int *array, int n)
{
vector<pair<int,int> > path;
//cout<<"PrintALLPaths"<<endl;
printAllPathsU(array, 0, 0, n, path, 0);
}
int main()
{ //populating matrix
int n;
cout << "Enter value of n (for n x n matrix): ";
cin >> n;
int i;
int j;
int k;
int test=1;
int array[n][n];
int randomval;
int total_elements = n*n;
int counter_0 = 0;
int max_0 = 0.2 * total_elements;
cout << "Number of zeros(20% of n*n) in matrix: ";
cout<<max_0<<endl;
int count=0;
srand(time(0));
for(i = 0;i < n;i++)
{
for(j = 0;j<n;j++)
{
array[i][j]=-1;
}
}
while(count < total_elements)
{
i=rand()%n;
j=rand()%n;
if(array[i][j]==1 || array[i][j]==0)
{
continue;
}
else if(array[i][j] == -1)
{
count+=1;
if(i==0 && j==0)
{
array[i][j]=1;
}
else if (counter_0 < max_0)
{
counter_0+=1;
array[i][j] = 0;
}
else if(counter_0 >= max_0)
{
test+=1;
array[i][j] = 1;
}
}
else{continue;}
}
cout<<"# of 1s:"<<test<<" & # of 0s:"<<counter_0<<endl;
cout<<"Elements Populated:"<<count<<endl;
cout<<"Total Elements in matrix:"<<total_elements<<endl;
if(counter_0 < max_0)
{ cout<<"adding more zeros"<<endl;
while(k < (max_0 - counter_0))
{
i = rand()%n;
j = rand()%n;
if(array[i][j] == 0)
{
}
else
{
array[i][j] = 0;
k+=1;
}
}
}
for(i = 0;i < n;i++)
{
for(j = 0;j<n;j++)
{
cout<<array[i][j]<<" ";
}
cout<<endl;
}
//printing paths
if(array[1][0]==0 && array[0][1]==0)
{
cout<<"No Possible paths homie #snorlaxiseverywhere";
}else
{
//printing paths
printAllPaths((int *)array, n);
}
return 0;
}
The question is to traverse through a n * n matrix populated with 1s and 0s, with the number of 0s in the matrix being 20% of the total number of elements, and print all paths and then the shortest path from the [0][0] to [n][n], using four direction: up,down,left and right.
So far I have tried to implement printing all possible paths. However, I am stuck in an infinite loop in the
else if((*((array+i*n)+j) == 1) && (!path_checker(path,i,j)))
{
...
}
I cout the path.size() to check what the size is becoming in each instance, and the output is somewhat like :
35
48
37
...and so on infinitely (values ranging approx between 30-50)
Any ideas how to correct this?
EDIT : Changed up some logic, not stuck infinite loop. But all of the function calls exit through the "second else" and the "third else" inside the function - printAllPathsU(...).
Thanks!

As long as the question is how to "print all paths", you should have an infinite loop because there are infinitely many paths. If the question is how to print all non-self-intersecting paths, then this rephrasing gives a hint on how to go about solving the problem.

Related

Difference Between Time Complexities of Different Implementations

I have implemented the following algorithms for a competitive programming problem. But for the First method, it gives a TLE (Time Limit Exceeded).
In contrast, the second implementation was accepted as the correct answer even though its time complexity is higher than the first one since it uses the .erase method inside a loop.
May I know the reason why the second implementation was faster than the first
Please refer to the first if statement inside the while(true) loop
First Implementation (TLE)
bool isEmpty (vector<int> a) {
sort(a.begin(), a.end());
return a.size() == 0 || a[a.size() - 1] == 0;
}
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int m, n, l;
cin>>n>>l;
vector<int> k;
vector<int> q;
for (int i=0; i<n; i++){
int ki;
cin>>ki;
k.push_back(ki);
}
cin>>m;
for (int i=0; i<m; i++){
int qi;
cin>>qi;
q.push_back(qi);
}
vector<int> bagsNeeded;
for (int qi:q){
if (qi % l == 0){
bagsNeeded.push_back(qi / l);
}
else {
bagsNeeded.push_back((qi / l) + 1);
}
}
sort(bagsNeeded.begin(), bagsNeeded.end());
int i = 0;
int c = 0;
while(true){
auto itr = lower_bound(bagsNeeded.begin(), bagsNeeded.end(), k[i]);
// Difference between the two implementations is inside this if statement
if (itr == bagsNeeded.end()){
if (isEmpty(bagsNeeded)) break;
else {
int bags = k[i];
int carriable = 0;
int j = bagsNeeded.size() - 1;
c++;
while(bags > 0 && j >= 0){
if (bagsNeeded[j] <= bags){
bags -= bagsNeeded[j];
bagsNeeded[j] = 0;
}
else {
bagsNeeded[j] -= bags;
bags = 0;
}
j--;
}
}
}
else if (itr == bagsNeeded.begin()){
bagsNeeded[0] -= k[i];
if (bagsNeeded[0] == 0){
bagsNeeded.erase(itr);
}
c++;
}
else {
bagsNeeded[itr - bagsNeeded.begin()] -= k[i];
if (bagsNeeded[itr - bagsNeeded.begin()] == 0){
bagsNeeded.erase(itr);
}
c++;
}
i++;
if (i == n){
i = 0;
}
}
cout<<c<<"\n";
return 0;
}
Second Implementation (Accepted)
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int m, n, l;
cin>>n>>l;
vector<int> k;
vector<int> q;
for (int i=0; i<n; i++){
int ki;
cin>>ki;
k.push_back(ki);
}
cin>>m;
for (int i=0; i<m; i++){
int qi;
cin>>qi;
q.push_back(qi);
}
vector<int> bagsNeeded;
for (int qi:q){
if (qi % l == 0){
bagsNeeded.push_back(qi / l);
}
else {
bagsNeeded.push_back((qi / l) + 1);
}
}
sort(bagsNeeded.begin(), bagsNeeded.end());
int i = 0;
int c = 0;
while(true){
auto itr = lower_bound(bagsNeeded.begin(), bagsNeeded.end(), k[i]);
if (itr == bagsNeeded.end()){
if (bagsNeeded.size() == 0) break;
else {
int bags = k[i];
int carriable = 0;
int j = bagsNeeded.size() - 1;
c++;
while(bags > 0 && j >= 0){
if (bagsNeeded[j] <= bags){
bags -= bagsNeeded[j];
bagsNeeded.erase(bagsNeeded.begin() + j);
}
else {
bagsNeeded[j] -= bags;
bags = 0;
}
j--;
}
}
}
else if (itr == bagsNeeded.begin()){
bagsNeeded[0] -= k[i];
if (bagsNeeded[0] == 0){
bagsNeeded.erase(itr);
}
c++;
}
else {
bagsNeeded[itr - bagsNeeded.begin()] -= k[i];
if (bagsNeeded[itr - bagsNeeded.begin()] == 0){
bagsNeeded.erase(itr);
}
c++;
}
i++;
if (i == n){
i = 0;
}
}
cout<<c<<"\n";
return 0;
}

Why am I not able to push a pair after a limit in the vector?

The problem is to find if a given sequence of numbers can form a valid permutation or not. The problem statement is trivial for the real problem. So, I am pushing a pair of integers into the vector. The first part being the number itself and second being 0 or 1.
The code works fine till a sequence 1041 long (specific after debugging a lot). Just to debug I added a print statement after pushing each pair inside the vector. For a length of 1042, the code shows pushed 1040 and then pushed 1 (which is weird) and then just hangs on there.
I am attaching the code as well as the input and terminal output.
You can just check the main function
Code
#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>
using namespace std;
bool comparator_function(pair<int, int> a, pair<int, int> b) {
return (a.first < b.first);
}
//index_added -> the index at which the latest element was added
void set_r_array(int* r_array_ref, int* per_array_ref, int size, int* count, int index_added) {
for(int i = 1;i <= size; i++) {
count[i] = 0;
}
int temp = index_added;
while(index_added <= size) {
if(index_added == size) {
if(per_array_ref[index_added] == 0) {
r_array_ref[temp] = size;
break;
}
else {
r_array_ref[temp] = -1;
break;
}
}
else {
if(per_array_ref[index_added] == 0) {
r_array_ref[temp] = index_added;
break;
}
else {
index_added++;
}
}
}
for(int i = 1;i <= size; i++) {
if(r_array_ref[i] != -1) {
count[r_array_ref[i]]++;
}
}
}
bool check_max(int* count, int next_element, int size) {
int max_count = -1, index = 0;
for(int i = 1;i <= size; i++) {
int temp_val = count[i];
if(max_count <= temp_val) {
max_count = temp_val;
index = i;
}
}
int num = 0;
for(int i = 1;i <= size; i++) {
if(count[i] == max_count) {
num++;
}
}
//one max
if(num == 1) {
if(next_element == index) {
return true;
}
return false;
}
else {
for(int i = 1;i <= size; i++) {
if(count[i] == max_count) {
if(next_element == i) {
return true;
}
}
}
return false;
}
}
int main() {
int testCases;
cin >> testCases;
cin.ignore();
while(testCases-- > 0) {
int n, result_flag = 0;
cin >> n;
cin.ignore();
vector<pair<int, int>> per;
int temp;
for(int i = 0;i < n; i++) {
cin >> temp;
pair<int, int> temp_pair = make_pair(temp, i+1);
per.push_back(temp_pair);
//debug statement
cout << "pushed " << temp << endl;
}
auto start = std::chrono::high_resolution_clock::now();
cout << "start" << endl;
sort(per.begin(), per.end(), comparator_function);
int permutation_array[n+1], r_array[n+1], count[n+1];
for(int i = 0;i <= n; i++) {
permutation_array[i] = 0;
r_array[i] = i;
count[i] = 1;
}
cout << "end" << endl;
permutation_array[per[0].second] = per[0].first;
set_r_array(r_array, permutation_array, n, count, per[0].second);
//insertion of numbers
for(int i = 1;i < n; i++) {
//check if the next element inserted has the largest count rn or not
int next_element = per[i].second;
if(!check_max(count, next_element, n)) {
cout << "No" << endl;
result_flag = -1;
break;
}
permutation_array[per[i].second] = per[i].first;
set_r_array(r_array, permutation_array, n, count, per[i].second);
}
if(result_flag == 0) {
cout << "Yes" << endl;
}
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
cout << "Time: " << duration.count() << " microseconds" << endl;
}
}
Input 1
1
5
2 3 4 5 1
Output 1
pushed 2
pushed 3
pushed 4
pushed 5
pushed 1
start
end
Yes
Input 2
1
1042
1 2 3 4 ... so on till 1042
Output 2
pushed 1
pushed 2
.
.
.
pushed 1040
pushed 1
and then hangs, from here on
The complexity of the code is O(n^2). So, I don't think it has to do anything with that. Since the input can be at max 10^4 order. Moreover, according to the print debugging, I think the issue is with the input.
You have issue with input as you reach console line limit.
Put your input into a file should solve that issue.
Then you should be able to debug your algorithm which seems more complicated than needed.

Check whether all the pairs in an array are divisible by k

Given an array of integers and a number k, write a function that returns true if given array can be divided into pairs such that sum of every pair is divisible by k.
This code is producing correct results for all test cases except one I cannot find the glitch in it.
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int k;
cin >> k;
int flag[n] = {0};
int p = 0;
int q = 0;
if (n % 2 != 0) {
cout << "False" << endl;
} else {
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if ((arr[i] + arr[j]) % k == 0 && flag[j] == 0) {
p = 1;
flag[j] = 1;
}
}
if (p == 0) {
q = 1;
cout << "False" << endl;
break;
}
}
if (q == 0) {
cout << "True" << endl;
}
}
}
return 0;
}
One of the big sources of bugs in code is messy code. So how do we clean up code? We modularize it. This means breaking up the code so that each portion of the code does one job well. Let's see what that looks like.
Function to check if something is divisible by k:
bool isDivisible(int number, int divisor) {
return number % divisor == 0;
}
Function to check all pairs:
The logic is as follows:
Take the first number in the list; call in n0.
For every remaining number n1, check if that plus the first number is divisible by k
When we find n1 such that n0 + n1 is divisible by k,
a. If the remaining numbers left over can also be split into divisible pairs, return true
b. Otherwise, continue searching
4.If we've searched through all the numbers, return false.
bool pairsDivisible(int* nums, int count, int k) {
if(count == 0) return true;
if(count % 2 != 0) return false; // count must be even
// 1.
int n0 = nums[0];
// 2.
for(int i = 1; i < count; i++) {
int n1 = nums[i];
// 3.
if(isDivisible(n0 + n1, k)) {
// Move the ith number so it's now nums[1]
std::swap(nums[1], nums[i]);
if(pairsDivisible(nums + 2, count - 2, k)) {
return true; // 3.a
} else {
// Reset the array
std::swap(nums[1], nums[i]);
}
}
}
return false;
}

LRU c++ program

I've been working on a program in one of my college classes. I have been having trouble with the implementation of my LRU code as it is not displaying any errors or anything, but compiles. There are two parts. The main that we input the values into, which we then specify which algorithm we want to use to find page faults. I know the main works, along with the FIFO algorithm, but I'm not getting anything with my LRU code (It compiles and "runs" but displays nothing as if I did not click to use the algorithm). Can anyone help me figure out what is wrong?
main.cpp
#include <iostream>
#include <string>
//#include "fifo.cpp"
#include "lru.cpp"
//#include "optimal.cpp"
using namespace std;
int main() {
// List of different variables
string pagestring;
int fs,pn[50], n;
// Prompt for page references
cout<<"Virtual Memory Simulation\nBy blah\n----------\nEnter the number of pages : " << endl;
cin >> n;
cout<<"\n-------------\nPlease enter a list of page numbers separated by commas.\n"<< endl;
cin>>pagestring;
// algorithm to use
char algo;
while (true) {
// Prompt algorithm to use
cout<<"----------\nPlease select an algorithm to use.\n\n1: First-In-First-Out (FIFO)\n2: Least-Recently-Used (LRU)\n3: Optimal\n0: Quit\n"<<endl;
cin>>algo;
if (algo == '1') {
//fifo(pagestring);
}
else if (algo == '2'){
LRU_Execute(pagestring, n);
}
else if (algo == '3'){
cout<<"Optimal Not yet coded"<<endl;
}
else if (algo == '0'){
break;
}
else {
cout<<"Invalid choice. Please try again."<<endl;
}
}
cout<<"Goodbye!!"<<endl;
};
LRU.cpp
#include <iostream>
#include <string>
using namespace std;
class pra
{
int fs,z;
int frame[50], frame1[50][2], pn[50], n, cnt, p, x;
public:
pra();
void init(string pagestring);
void getdata(string pagestring, int n);
void lru(int* pn, int n, string pagestring);
};
pra::pra()
{
int i;
for (i = 0; i < fs; i++)
{
frame[i] = -1;
}
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
p = 0;
cnt = 0;
}
void pra::init(string pagestring)
{
int i;
for (i = 0; i < fs; i++)
{
frame[i] = -1;
}
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
p = 0;
cnt = 0;
}
void pra::getdata(string pagestring, int n)
{
fs=3;
// index to loop through input string
int i = 0;
// current input string character
char z = pagestring[i];
int x = 0;
//cout << "\nEnter the page numbers : ";
while (z != '\0'){
// skip over commas and spaces
if (!(z == ',')) {
pn[x] = z;
x++;
// cout<<pn[x]<<"-This is pn[x]\n";
}
z = pagestring[++i];
}
//cout<<pn[x]<<"-This is pn[x] AGAIN\n";
this->lru(pn, n, pagestring);
}
void pra::lru(int* pn, int n, string pagestring)
{
init(pagestring);
int ind = 0, fault = 0, pi = 0, j, fn;
char i, z;
p = 0;
cnt = 0;
int min;
cout<<n<<"---"<<i<<" - "<<j<<" - "<<" - "<<fn<<" - "<<z;
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
pi = 0;
for (i = 0; i < n; i++)
{
j = 0;
if (ind > fs - 1)
ind = 0;
fault = 1;
min = 999;
while (j < fs)
{
if (frame1[j][0] = pn[pi])
{
fault = 0;
p++;
frame1[j][1] = p;
goto l2;
}
if (frame1[j][1] < min)
{
min = frame1[j][1];
fn = j;
}
j++;
}
j = 0;
while (j < fs)
{
if (frame1[j][0] = -1)
{
fault = 1;
fn = j;
goto l2;
}
j++;
}
ind++;
l2:
if (fault == 1)
{
p++;
frame1[fn][0] = pn[pi];
frame1[fn][1] = p;
cnt++;
}
cout << "\nElement: " << pn[pi];
pi++;
for (z = 0; z < fs; z++)
{
cout << "\t" << frame1[z][0];
}
if (fault == 1)
cout << "\t**Page Fault**";
else
cout << "\t--No Page Fault--";
}
cout << "\nTotal number of page faults: " << cnt;
cout << "\n";
}
void LRU_Execute(string pagestring, int n)
{
pra p;
int j, fault = 0, i, pi, z, fn, ind = 0, ans, ch;
p.getdata(pagestring, n);
//p.lru();
while (ans == 1);
//return 1;
}

Extracting a subsequence from an array

I'm trying to solve an algorithm for extracting a subsequence from an array. It should display the longest subsequence of prime numbers. I have written the whole algorithm but I still get an infinite cycle and I can't figure out where and why. I'm incrementing both indices and modifying the first index at the end, but it is still not working. Thanks a lot !!!
P.S: citire reads the array, prim detects if a number is prime or composed, afisare displays the subsequence and detSecv determines the longest subsequence.
#include <iostream>
#include <math.h>
using namespace std;
void citireSecv(int &n,int x[50])
{
cout<<"Da n: ";
cin>>n;
for(int i=1;i<=n;i++)
{
cout<<"Da un nr: ";
cin>>x[i];
}
}
int prim(int n)
{
int d=2;
while(d<=sqrt(n) && n%d!=0)
{
if(d==2)
d=3;
else
d=d+2;
}
if(d>sqrt(n)) return 1;
else return 0;
}
void afisare(int n,int x[50],int st,int f)
{
for(int i=st;i<=f;i++)
cout<<x[i]<<" ";
}
void detSecv(int n,int x[100],int &st,int &f)
{
st=1; f=0;
int i=1,j;
while(i<=n-1)
{
while(i<=n-1)
{
if(prim(x[i])==0 && prim(x[i+1])==0) i++;
}
j=i+1;
while(j<=n-1)
if(prim(x[j])==0 && prim(x[j+1])==0) j++;
if((j-i) > (f-st))
{
st=i;
f=j;
}
i=j+1;
}
}
int main()
{
int n,x[100],st,f;
citireSecv(n,x);
detSecv(n,x,st,f);
afisare(n,x,st,f);
return 0;
}
Input data:
n=2
First number is: 5
Second number is: 7
Probably just one of many issues with that code:
while(i<=n-1)
{
if(prim(x[i])==0 && prim(x[i+1])==0) i++;
}
j=i+1;
while(j<=n-1)
if(prim(x[j])==0 && prim(x[j+1])==0) j++;
There are two potential infinite loops here. If the conditions in the while don't return true on the first iteration, i (or j) will never get incremented, and you will have your infinite loop. You should almost always increment such variables outside of any conditions.
With a slight change in your code, you make it work, and one thing, you don't need to start array with index 1. you can always start with index zero.
for(int i=1;i<=n;i++)
{
cout<<"Da un nr: ";
cin>>x[i];
}
try to check for a case when no prime subsequence is found, while printing.
void detSecv(int n, int *x, int &start, int &end)
{
start = -1;
end = -1;
int i=0,j;
while(i < n) {
if(prim(x[i])) {
j = i + 1;
while(j < n)
if(prim(x[j])) j++;
else break;
} else {
i++;
continue;
}
if((j-i) > (end - start)) {
start = i;
end = j-1;
}
i=j+1;
}
}
This is a better way to verify if a number is prime or not
bool IsPrime(int number) {
int primeStep = 2;
double stepLimit = sqrt(number);
while(primeStep <= stepLimit)
{
if(number % primeStep == 0)
return false;
primeStep += 1;
}
return true;
}
And nou you can apply that function for each number in your array, and if it's prime , you add it in a new array like this:
void detSecv(int numberOfItems,int *arrayOfNumbers)
{
int arrayOfPrimeNumbers[50] = {};
int index = 0;
for(int i = 0; i < numberOfItems; i++)
{
if(IsPrime(arrayOfNumbers[i])){
arrayOfPrimeNumbers[index] = arrayOfNumbers[i];
index += 1;
}
}
int secondIndex = 0;
while(arrayOfPrimeNumbers[secondIndex] != 0)
{
cout << arrayOfPrimeNumbers[secondIndex] << " ";
secondIndex += 1;
}
}