Below is the code I am referring to, and the first recursive call # checkDirections(grid, i - 1, j) is giving me a StackOverFlow error. I understand that this means the code is not hitting the base case, but I do not understand why.
class Solution {
public int orangesRotting(int[][] grid) {
int rowLength = grid.length;
int colLength = grid[0].length;
int minMinutes = 0;
for (int i = 0; i < rowLength; i++) {
for (int j = 0; j < colLength; j++) {
if (grid[i][j] == 2) {
checkDirections(grid, i, j);
}
}
}
return minMinutes;
}
public void checkDirections(int[][] grid, int i, int j) {
if ((i < 0 || i > grid.length || j < 0 || j > grid[0].length) || grid[i][j] == 0) {
return;
} else if (grid[i][j] == 1) {
grid[i][j] = 2;
return;
}
//check left
checkDirections(grid, i - 1, j);
//check right
checkDirections(grid, i + 1, j);
//check up
checkDirections(grid, i, j - 1);
//check down
checkDirections(grid, i, j + 1);
}
}
Input
T- test cases
N-no of nodes
N-1 lines follow
x y - there is an edge between x and y
1
5
1 2
2 5
1 3
3 4
Output
Path 1 3 4
Path 1 2 5
Approach
First I do a BFS on the tree and store all the parent values for every
node.Then, for every leaf node, I backtrack to the root using the
parent values.I push them to a path vector and print the path vector.
However, I think the solution is very time inefficient. Can you
suggest a better way?
My code- it is getting TLE
void bfs(vector<int> adj[], int start, int n, int val[], int mod[]) {
int parent[n + 1];
bool visited[n + 1];
memset(visited, false, sizeof(visited));
for (int i = 1; i <= n; ++i)
{
/* code */
parent[i] = -1;
}
queue<int> q;
q.push(start);
parent[start] = -1;
visited[start] = true;
while (!q.empty()) {
int x;
x = q.front();
q.pop();
for (auto u : adj[x]) {
if (!visited[u]) {
q.push(u);
parent[u] = x;
visited[u] = true;
}
}
}
vector<int> leaf;
//check if a leaf node
for (int i = 1; i <= n; i++) {
if (adj[i].size() == 1)
leaf.pb(i);
}
for (auto x : leaf) {
vector<int> path;
for (int v = x; v != -1; v = parent[v])
path.push_back(val[v]);
cout<<"Path"<<" ";
for(auto x:path)
cout<<x<<" ";
cout<<endl;
}
}
int main(){
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
std::vector<int> adj[n + 1];
int edges = n - 1;
while (edges--) {
int x, y;
cin >> x >> y;
adj[x].pb(y);
adj[y].pb(x);
}
int val[n + 1];
int mod[n + 1];
for (int i = 1; i <= n; i++) {
/* code */
cin >> val[i];
}
for (int i = 1; i <= n; i++) {
/* code */
cin >> mod[i];
}
bfs(adj, 1, n, val, mod);
cout<<endl;
return 0;
}
Currently I'm trying to replicate this wonderful project https://www.youtube.com/watch?v=u8pwmzUVx48, though with more minimum hardware, in which for the classification i'm using a neural network embbeded inside the arduino uno which had been trained offline in more stronger PC. The code of the classifier is here
#include <math.h>
#include <Wire.h>
double dataMagnitude[100];
double feature[7];
double feat_hid[10];
double output[4];
int classi;
const double w_hid[8][10] =
{
{18.9336670380822,11.9186055569093,-5.40114594311576,-21.1410711100689,-49.7798510124792,-14.8215222433047,-34.7308138535581,118.348601654702,-13.6275407707706,-11.6090487951753},
{-21.4994463865001,72.0672467700052,4.05328299052883,21.4875491464005,51.1604296852446,-15.8459578543758,6.30350750703905,-152.565733734759,12.8648040583067,13.8199895673734},
{8.66214515599865,-200.488705071393,-5.86973559011113,-23.4805286444925,-1.11016147795671,-3.04686605995311,-93.4143749063794,-73.8925691072615,-6.18427236042285,-10.9872535411407},
{-12.317892447947,-37.2154526807162,3.83978412266769,2.12866508710205,-11.9740446238331,10.2198116665101,41.9369083083022,63.2036147993661,1.40768362243561,15.4978881385563},
{7.58319670243546,161.895072542918,-2.3654701067923,1.91708846557259,-2.87224127392426,-16.5850302581614,45.2372430254377,34.255971511768,-2.30234070310014,-7.8952356779332},
{0.603971580989218,128.0244079393,0.628535912033608,-1.25788426737745,-0.204480047424961,-41.3372322514891,3.26860448943873,4.163893213914,0.443532051478394,-0.276136697942473},
{-3.63944154925129,18.3802540188974,0.975095285922393,-0.326187652485656,1.25521855841132,39.4877166809573,-15.3542772116519,-14.9546824078715,0.965532742621277,3.72386985716534},
{5.93321854314305,12.673690719929,-3.36580252980446,-21.2089241183081,-10.8980644878121,-7.29095431091201,-30.2240843969778,-2.48980394834853,-5.4167647620581,-5.68671825319015}
}, w_out[11][4] =
{
{1.07887052819228,-21.9615926704441,105.450147012522,-84.5674248703326},
{0.0344508533215184,0.551350792323934,-0.96380329372866,0.37800164808339},
{-99.251397621058,23.1671754381478,7.53147169676884,68.5527504861813},
{-5.0354869957171,4.36918523413481,0.408725687040089,0.257576074543764},
{-27.4478368365984,7.00659524306471,1.74370945871769,18.6975321348269},
{-0.213736004615516,-0.784795805217531,0.0732416484342244,0.925290161399087},
{8.62052547929066,-45.9408034639393,116.959261953552,-79.6389839689755},
{-8.5317661802465,45.4251911929737,-117.146523754862,80.2530987422069},
{127.053878005091,-29.4397580015468,-9.33919798608733,-88.2749220175082},
{1.11869995358251,-21.5111648695486,105.002356379838,-84.6098914639344},
{-5.81786935588552,3.78305066207264,0.11556429335063,-0.0807455995360207}
};
double S, Sig, Sigma, Sigma1, Sigma2, MAV, RMS, VAR, SDT, WL, ZC, SSC, Xn, accum, accumi;
char analogpin = 0, N=100;
void setup()
{
/* add setup code here */
Serial.begin(9600);
Wire.begin();
}
void loop()
{
do{
//data acqusition
for( int i = 0; i<100;i++)
{
Xn = (analogRead(analogpin))-510;
dataMagnitude[i]=Xn;
delayMicroseconds(830);
// Serial.println(dataMagnitude[i]);
}
S = 0;
for (size_t i = 0; i < N; i++)
{
S = S + dataMagnitude[i];
}
Sig = 0;
Sigma = 0;
Sigma1 = 0;
Sigma2 = 0;
for (size_t i = 0; i < N; i++)
{
Sig = Sig + abs(dataMagnitude[i]);
Sigma = Sigma + pow(dataMagnitude[i], 2);
Sigma1 = Sigma1 + pow((dataMagnitude[i] - S / N), 2);
}
for (size_t i = 0; i < N - 1; i++)
{
Sigma2 = Sigma2 + abs(dataMagnitude[i + 1] - dataMagnitude[i]);
}
//featureextract
MAV = (((1 / (double)N)*Sig-27.67)*2/(272.02-27.67))-1;
RMS = (sqrt((1 / (double)N)*Sigma)-34.91002721)*2/(284.1419012-34.91002721)-1;
VAR = (((1 / (double)(N))*Sigma1)-698.4139)*2/(52178.5691-698.4139)-1;
SDT = (sqrt((1 / (double)(N)) * Sigma1)-26.42752164)*2/(228.4262881-26.42752164)-1;
WL = (Sigma2-1621)*2/(11273-1621)-1;
//ZC = 0;
for (size_t i = 0; i < N - 1; i++)
{
if (dataMagnitude[i] == 0 && dataMagnitude[i] != dataMagnitude[i + 1])
{
ZC++;
}
}
ZC = (ZC-0)*2/(39-0)-1;
//SSC = 0;
for (size_t i = 0; i < N - 2; i++)
{
if (dataMagnitude[i]>dataMagnitude[i + 1] && dataMagnitude[i + 1]<dataMagnitude[i + 2])
{
SSC++;
}
else if (dataMagnitude[i]<dataMagnitude[i + 1] && dataMagnitude[i + 1]>dataMagnitude[i + 2])
{
SSC++;
}
}
SSC = (SSC-48)*2/(78-48)-1;
double feature[] = { MAV, RMS, VAR, SDT, WL, ZC, SSC };
//neural network construction
//first-hidden layer
for (int i = 0; i < 10; i++)
{
accum = w_hid[7][i];
for (int j = 0; j < 7; j++)
{
accum += (feature[j] * w_hid[j][i]);
}
feat_hid[i] = tanh(accum);
}
for (int i = 0; i < 4; i++)
{
accumi = w_out[10][i];
for (int j = 0; j < 10; j++)
{
accumi += (feat_hid[j] * w_out[j][i]);
}
output[i] = round(accumi);
}
//Classify the output
if (output[0] == 1 && output[1] < 1 && output[2] < 1 && output[3] < 1)
{
classi = 1;
}
else if (output[0] < 1 && output[1] == 1 && output[2] < 1 && output[3] < 1)
{
classi = 2;
}
else if (output[0] < 1 && output[1] < 1 && output[2] == 1 && output[3] < 1)
{
classi = 3;
}
else if (output[0] < 1 && output[1] < 1 && output[2] < 1 && output[3] == 1)
{
classi = 4;
}
else
{
classi = 0;
}
Wire.beginTransmission(5);
Wire.write(classi);
//Wire.write(int(output[2]));
Wire.endTransmission();
Serial.println("wew");
Serial.println(output[0]);
Serial.println(output[1]);
Serial.println(output[2]);
Serial.println(output[3]);
//Serial.println(classi);
//Serial.println(feature[1]);
//Serial.println(feature[2]);
//Serial.println(feature[3]);
//Serial.println(feature[4]);
//Serial.println(feature[5]);
//Serial.println(feature[6]);
for (size_t i = 0; i < 10; i++)
{
feat_hid[i] = 0;
}
for (size_t i = 0; i < 4; i++)
{
output[i] = 0;
}
}while(analogRead(analogpin)>0);
}
But the real time implementation is rather dissatisfying, in which the output always mismatched, though by offline implementation is quite better.
My assumption is that the data capturing when online is rather bad, or maybe because any other things?
Thanks for any feedback
How did you train the network offline?
If you have used Matlab to train the network (i.e. to identify the weight and bias values) and then implement the same network on Arduino.
In such case we have problems with number precision. Matlab by default works on 64 bit precision whereas Arduino works on 32 bit.
Difference in the way the numbers are represented creates the Error.
This dynamic programming algorithm is returning unhandled exception error probably due to the two dimensional arrays that I am using for various (and very large) number of inputs. I can't seem to figure out the issue here. The complete program as follows:
// A Dynamic Programming based solution for 0-1 Knapsack problem
#include<stdio.h>
#include<stdlib.h>
#define MAX 10000
int size;
int Weight;
int p[MAX];
int w[MAX];
// A utility function that returns maximum of two integers
int maximum(int a, int b) { return (a > b) ? a : b; }
// Returns the maximum value that can be put in a knapsack of capacity W
int knapSack(int W, int wt[], int val[], int n)
{
int i, w;
int retVal;
int **K;
K = (int**)calloc(n+1, sizeof(int*));
for (i = 0; i < n + 1; ++i)
{
K[i] = (int*)calloc(W + 1, sizeof(int));
}
// Build table K[][] in bottom up manner
for (i = 0; i <= n; i++)
{
for (w = 0; w <= W; w++)
{
if (i == 0 || w == 0)
K[i][w] = 0;
else if (wt[i - 1] <= w)
K[i][w] = maximum(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w]);
else
K[i][w] = K[i - 1][w];
}
}
retVal = K[n][W];
for (i = 0; i < size + 1; i++)
free(K[i]);
free(K);
return retVal;
}
int random_in_range(unsigned int min, unsigned int max)
{
int base_random = rand();
if (RAND_MAX == base_random) return random_in_range(min, max);
int range = max - min,
remainder = RAND_MAX % range,
bucket = RAND_MAX / range;
if (base_random < RAND_MAX - remainder) {
return min + base_random / bucket;
}
else {
return random_in_range(min, max);
}
}
int main()
{
srand(time(NULL));
int val = 0;
int i, j;
//each input set is contained in an array
int batch[] = { 10, 20, 30, 40, 50, 5000, 10000 };
int sizeOfBatch = sizeof(batch) / sizeof(batch[0]);
//algorithms are called per size of the input array
for (i = 0; i < sizeOfBatch; i++){
printf("\n");
//dynamic array allocation (variable length to avoid stack overflow
//calloc is used to avoid garbage values
int *p = (int*)calloc(batch[i], sizeof(int));
int *w = (int*)calloc(batch[i], sizeof(int));
for (j = 0; j < batch[i]; j++){
p[j] = random_in_range(1, 500);
w[j] = random_in_range(1, 100);
}
size = batch[i];
Weight = batch[i] * 25;
printf("| %d ", batch[i]);
printf(" %d", knapSack(Weight, w, p, size));
free(p);
free(w);
}
_getch();
return 0;
}
Change this:
for (i = 0; i < size + 1; i++)
free(K[i]);
free(K);
return K[size][Weight];
To this:
int retVal;
...
retVal = K[size][Weight];
for (i = 0; i < size + 1; i++)
free(K[i]);
free(K);
return retVal;
I'm trying to take to the following input:
1
4
47 2 4 43577
The part of my code that deals with this is:
for (scanf("%d", &t); t --; )
{
int count = 0;
scanf("%d",&n);
for (int i = 0, x; i < n; ++ i)
{
scanf("%d",&x);
str = to_string(x);
f4[i] = get_count(str,'4');
f7[i] = get_count(str,'7');
}
However, with this I get a runtime error, which shows an access violation in the file free.c.
But, when I try to debug it, it runs well in the debug mode and gives the correct answer.
Also, when I output the variable x right after I input it, the program works well in runtime as well. This is shown in the following code, which runs fine in runtime as well:
for (scanf("%d", &t); t --; )
{
int count = 0;
scanf("%d",&n);
for (int i = 0, x; i < n; ++ i)
{
scanf("%d",&x);
cout<<"A"<<i<<" is "<<x<<'\n';
str = to_string(x);
f4[i] = get_count(str,'4');
f7[i] = get_count(str,'7');
}
Any idea why this may be happening?
Some of the stackoverflow users are saying that the code runs fine. I'm using VS 2012. Can this be something that is compiler specific?
The complete code:
#include<iostream>
#include<conio.h>
#include<string>
#include<math.h>
using namespace std;
int get_count(string s, char x)
{
int count = 0;
int l = s.length();
for(int i = 0; i < l;i++)
{
if (s[i] == x)
count++;
}
return count;
}
void main()
{
int * f4 = new int;
int * f7 = new int;
string * back = new string;
int n = 0;
int t = 0;
string str;
for (scanf("%d", &t); t --; )
{
int count = 0;
scanf("%d",&n);
for (int i = 0, x; i < n; ++ i)
{
scanf("%d",&x);
str = to_string(x);
f4[i] = get_count(str,'4');
f7[i] = get_count(str,'7');
}
for(int i = 0;i < n;i++)
{
for(int j = i; j < n;j++)
{
int c4 = 0;
int c7 = 0;
for(int k = i; k <= j;k++)
{
c4 += f4[k];
c7 += f7[k];
}
double value = pow((double)c4,(double)c7);
if(value <= (double)(j - i + 1)&&(c4!=2)&&(c7!=2))
{
count++;
//cout<<"yes"<<'\t';
}
}
}
cout<<"Ans: "<<count<<'\n';
}
//getch();
}
There are no other variable assignments apart from those in this code.
The exact error that I get with runtime is:
Unhandled exception at 0x7794E3BE (ntdll.dll) in Practice1.exe: 0xC0000005: Access violation reading location 0x38389246.
You did not include the "get_count" function. I think it has something to do with that function. I rewrote that function to return some number and I don't get that error. Try to assert that you are not attempting to use a null pointer in that function.
Works fine on my machine:
Here's what I changed
for (int i = 0, x; i < n; ++ i)
{
scanf("%d",&x);
stringstream ss;
ss << x;
str = ss.str();
f4[i] = get_count(str,'4');
f7[i] = get_count(str,'7');
}
Output:
1
4
47 2 4 43577
Ans: 5