I am trying to find the minimum number of steps required to reach to the destination from the source. For this, I am using BFS algorithm of graph traversal. I think I have applied the correct logic for BFS algorithm but I am not getting the correct answer when the destination node cannot be reached from source. Can, anyone check what I have done wrong in the code.
int shortestDistance(int N, int M, vector<vector<int>> A, int X, int Y) {
vector<vector<int>>visited(N, vector<int>(M, 0));
visited[0][0] = 1;
queue<pair<int, int>>qe;
pair<int, int>pr;
pr.first = 0;
pr.second = 0;
qe.push(pr);
queue<int>count;
count.push(0);
while(!qe.empty()){
pair<int, int>pr1 = qe.front();
qe.pop();
int a = pr1.first;
int b = pr1.second;
int cnt = count.front();
count.pop();
if(a == X && b == Y){
return cnt;
}
if(a-1 >= 0 && A[a][b] == 1 && visited[a-1][b] == 0){
visited[a-1][b] = 1;
pair<int, int>pr2;
pr2.first = a-1;
pr2.second = b;
qe.push(pr2);
count.push(cnt+1);
}
if(a+1 < N && A[a][b] == 1 && visited[a+1][b] == 0){
visited[a+1][b] = 1;
pair<int, int>pr2;
pr2.first = a+1;
pr2.second = b;
qe.push(pr2);
count.push(cnt+1);
}
if(b-1 >= 0 && A[a][b] == 1 && visited[a][b-1] == 0){
visited[a][b-1] = 1;
pair<int, int>pr2;
pr2.first = a;
pr2.second = b-1;
qe.push(pr2);
count.push(cnt+1);
}
if(b+1 < M && A[a][b] == 1 && visited[a][b+1] == 0){
visited[a][b+1] = 1;
pair<int, int>pr2;
pr2.first = a;
pr2.second = b+1;
qe.push(pr2);
count.push(cnt+1);
}
}
return -1;
}
}
Related
I've been trying to solve this problem (from school) for just about a week now. We're given two numbers, from -(10^100000) to +that.
Of course the simplest solution is to implement written addition, so that's what I did. I decided, that I would store the numbers as strings, using two functions:
int ti(char a) { // changes char to int
int output = a - 48;
return output;
}
char tc(int a) { // changes int to char
char output = a + 48;
return output;
}
This way I can store negative digits, like -2. With that in mind I implemented a toMinus function:
void toMinus(std::string &a) { // 123 -> -1 -2 -3
for (auto &x : a) {
x = tc(-ti(x));
}
}
I also created a changeSize function, which adds 0 to the beginning of the number until they are both their max size + 1 and removeZeros, which removes leading zeros:
void changeSize(std::string &a, std::string &b) {
size_t exp_size = std::max(a.size(), b.size()) + 2;
while (a.size() != exp_size) {
a = '0' + a;
}
while (b.size() != exp_size) {
b = '0' + b;
}
}
void removeZeros(std::string &a) {
int i = 0;
for (; i < a.size(); i++) {
if (a[i] != '0') {
break;
}
}
a.erase(0, i);
if (a.size() == 0) {
a = "0";
}
}
After all that, I created the main add() function:
std::string add(std::string &a, std::string &b) {
bool neg[2] = {false, false};
bool out_negative = false;
if (a[0] == '-') {
neg[0] = true;
a.erase(0, 1);
}
if (b[0] == '-') {
neg[1] = true;
b.erase(0, 1);
}
changeSize(a, b);
if (neg[0] && !(neg[1] && neg[0])) {
toMinus(a);
}
if(neg[1] && !(neg[1] && neg[0])) {
toMinus(b);
}
if (neg[1] && neg[0]) {
out_negative = true;
}
// Addition
for (int i = a.size() - 1; i > 0; i--) {
int _a = ti(a[i]);
int _b = ti(b[i]);
int out = _a + _b;
if (out >= 10) {
a[i - 1] += out / 10;
} else if (out < 0) {
if (abs(out) < 10) {
a[i - 1]--;
} else {
a[i - 1] += abs(out) / 10;
}
if (i != 1)
out += 10;
}
a[i] = tc(abs(out % 10));
}
if (ti(a[0]) == -1) { // Overflow
out_negative = true;
a[0] = '0';
a[1]--;
for (int i = 2; i < a.size(); i++) {
if (i == a.size() - 1) {
a[i] = tc(10 - ti(a[i]));
} else {
a[i] = tc(9 - ti(a[i]));
}
}
}
if (neg[0] && neg[1]) {
out_negative = true;
}
removeZeros(a);
if (out_negative) {
a = '-' + a;
}
return a;
}
This program works in most cases, although our school checker found that it doesn't - like instead of
-4400547114413430129608370706728634555709161366260921095898099024156859909714382493551072616612065064
it returned
-4400547114413430129608370706728634555709161366260921095698099024156859909714382493551072616612065064
I can't find what the problem is. Please help and thank you in advance.
Full code on pastebin
While I think your overall approach is totally reasonable for this problem, your implementation seems a bit too complicated. Trying to solve this myself, I came up with this:
#include <iostream>
#include <limits>
#include <random>
#include <string>
bool greater(const std::string& a, const std::string& b)
{
if (a.length() == b.length()) return a > b;
return a.length() > b.length();
}
std::string add(std::string a, std::string b)
{
std::string out;
bool aNeg = a[0] == '-';
if (aNeg) a.erase(0, 1);
bool bNeg = b[0] == '-';
if (bNeg) b.erase(0, 1);
bool resNeg = aNeg && bNeg;
if (aNeg ^ bNeg && (aNeg && greater(a, b) || bNeg && greater(b, a)))
{
resNeg = true;
std::swap(a, b);
}
int i = a.length() - 1;
int j = b.length() - 1;
int carry = 0;
while (i >= 0 || j >= 0)
{
const int digitA = (i >= 0) ? a[i] - '0' : 0;
const int digitB = (j >= 0) ? b[j] - '0' : 0;
const int sum = (aNeg == bNeg ? digitA + digitB : (bNeg ? digitA - digitB : digitB - digitA)) + carry;
carry = 0;
if (sum >= 10) carry = 1;
else if (sum < 0) carry = -1;
out = std::to_string((sum + 20) % 10) + out;
i--;
j--;
}
if (carry) out = '1' + out;
while (out[0] == '0') out.erase(0, 1);
if (resNeg) out = '-' + out;
return out;
}
void test()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(-std::numeric_limits<int32_t>::max(), std::numeric_limits<int32_t>::max());
for (int i = 0; i < 1000000; ++i)
{
const int64_t a = dis(gen);
const int64_t b = dis(gen);
const auto expected = std::to_string(a + b);
const auto actual = add(std::to_string(a), std::to_string(b));
if (actual != expected) {
std::cout << "mismatch expected: " << expected << std::endl;
std::cout << "mismatch actual : " << actual << std::endl;
std::cout << " a: " << a << std::endl;
std::cout << " b: " << b << std::endl;
}
}
}
int main()
{
test();
}
It can potentially be further optimized, but the main points are:
If the sign of both numbers is the same, we can do simple written addition. If both are negative, we simply prepend - at the end.
If the signs are different, we do written subtraction. If the minuend is greater than the subtrahend, there's no issue, we know that the result will be positive. If, however, the subtrahend is greater, we have to reformulate the problem. For example, 123 - 234 we would formulate as -(234 - 123). The inner part we can solve using regular written subtraction, after which we prepend -.
I test this with random numbers for which we can calculate the correct result using regular integer arithmetic. Since it doesn't fail for those, I'm pretty confident it also works correctly for larger inputs. An approach like this could also help you uncover cases where your implementation fails.
Other than that, I think you should use a known failing case with a debugger or simply print statements for the intermediate steps to see where it fails. The only small differences in the failing example you posted could point at some issue with handling a carry-over.
I need to make a program that will check whether or not the number typed in (a) and its mirrored self (a1) are both prime numbers. I got it to work up to the point where I input a multiplier of 10, in which case it declares it as a prime number, which it clearly isn't.
I've already tried setting the condition:
if ( a % 10 = 0 ) {//declare it as non prime}
After having done that, I would always get a return value of 0 after entering the number. Also tried declaring :
if ( a == 1 ) {//declare it as a non prime}
which fixed it for multipliers of 10 up to 100, but the rest would give me the previously stated error.
My go at it:
#include <iostream>
using namespace std;
int main() {
int a, a1, DN;
cin >> a;
DN = a;
a1 = 0;
for (; a != 0;) {
a1 *= 10;
a1 = a1 + a % 10;
a /= 10;
}
int este_prim, i, este_prim2;
este_prim = 1;
i = 2;
este_prim2 = 1;
while (i < DN && i < a1) {
if (DN % i == 0) {
este_prim = 0;
}
++i;
}
if (a1 > i && a1 % i == 0) {
este_prim2 = 0;
}
++i;
if (a == 1) {
este_prim = 0;
}
if (a1 == 1) {
este_prim2 = 0;
}
if (este_prim2 == 1 && este_prim == 1) {
cout << "DA";
} else {
cout << "NU";
}
return 0;
}
I'm a complete newbie at this so any help would be appreciated. Cheers!
Your loop checks if DN is prime, but it doesn't check if a1 is prime. And this block of code is something I do not understand.
if (a1 > i && a1 % i == 0) {
este_prim2 = 0;
}
So just remove that.
Use this worthy helper function to detect if a positive number is prime:
bool isPrime(int x)
{
if (x <= 1)
return false;
// 2 is the only even prime
if (x == 2)
return true;
// any other even number is not prime
if ((x % 2) == 0)
return false;
// try dividing by all odd numbers from 3 to sqrt(x)
int stop = sqrt(x);
for (int i = 3; i <= stop; i += 2)
{
if ((x % i) == 0)
return false;
}
return true;
}
And then your code to detect if DN and it's mirror, a1 are both prime is this:
int main() {
int a, a1, DN;
cin >> a;
DN = a;
a1 = 0;
for (; a != 0;) {
a1 *= 10;
a1 = a1 + a % 10;
a /= 10;
}
bool este_prim, este_prim2;
este_prim = isPrime(DN);
este_prim2 = isPrime(a1);
if (este_prim2 && este_prim) {
cout << "DA";
} else {
cout << "NU";
}
}
I'm trying to solve this problem in C++:
"Given a sequence S of integers, find a number of increasing sequences I such that every two consecutive elements in I appear in S, but on the opposite sides of the first element of I."
This is the code I've developed:
#include<iostream>
#include<set>
#include<vector>
using namespace std;
struct Element {
long long height;
long long acc;
long long con;
};
bool fncomp(Element* lhs, Element* rhs) {
return lhs->height < rhs->height;
}
int solution(vector<int> &H) {
// set up
int N = (int)H.size();
if (N == 0 || N == 1) return N;
long long sol = 0;
// build trees
bool(*fn_pt)(Element*, Element*) = fncomp;
set<Element*, bool(*)(Element*, Element*)> rightTree(fn_pt), leftTree(fn_pt);
set<Element*, bool(*)(Element*, Element*)>::iterator ri, li;
for (int i = 0; i < N; i++) {
Element* e = new Element;
e->acc = 0;
e->con = 0;
e->height = H[i];
rightTree.insert(e);
}
//tree elements set up
ri = --rightTree.end();
Element* elem = *ri;
elem->con = 1;
elem->acc = 1;
while (elem->height > H[0]) {
Element* succ = elem;
ri--;
elem = *ri;
elem->con = 1;
elem->acc = succ->acc + 1;
}
rightTree.erase(ri);
elem->con = elem->acc;
leftTree.insert(elem);
sol += elem->acc;
// main loop
Element* pE = new Element;
for (int j = 1; j < (N - 1); j++) {
// bad case
if (H[j] < H[j - 1]) {
///////
Element* nE = new Element;
nE->height = H[j];
pE->height = H[j - 1];
rightTree.erase(nE);
leftTree.insert(nE);
///////
li = leftTree.lower_bound(pE);
long ltAcc = (*li)->acc;
li--;
///////
ri = rightTree.lower_bound(pE);
long rtAcc = 0;
if (ri != rightTree.end()) rtAcc = (*ri)->acc;
ri--;
///////
while (ri != (--rightTree.begin()) && (*ri)->height > H[j]) {
if (fncomp(*ri, *li)) {
(*li)->con = rtAcc + 1;
(*li)->acc = rtAcc + 1 + ltAcc;
ltAcc = (*li)->acc;
--li;
}
else {
(*ri)->con = ltAcc + 1;
(*ri)->acc = ltAcc + 1 + rtAcc;
rtAcc = (*ri)->acc;
--ri;
}
}
while ((*li)->height > H[j]) {
(*li)->con = rtAcc + 1;
(*li)->acc = rtAcc + 1 + ltAcc;
ltAcc = (*li)->acc;
--li;
}
(*li)->con = rtAcc + 1;
(*li)->acc = rtAcc + 1 + ltAcc;
sol += (*li)->acc;
}
// good case
else {
Element* nE = new Element;
nE->height = H[j];
ri = rightTree.upper_bound(nE);
li = leftTree.upper_bound(nE);
rightTree.erase(nE);
if (li == leftTree.end() && ri == rightTree.end()) {
nE->con = 1;
nE->acc = 1;
}
else if (li != leftTree.end() && ri == rightTree.end()) {
nE->con = 1;
nE->acc = 1 + (*li)->acc;
}
else if (li == leftTree.end() && ri != rightTree.end()) {
nE->con = (*ri)->acc + 1;
nE->acc = nE->con;
}
else {
nE->con = (*ri)->acc + 1;
nE->acc = nE->con + (*li)->acc;
}
leftTree.insert(nE);
sol += nE->acc;
}
}
// final step
li = leftTree.upper_bound(*rightTree.begin());
while (li != leftTree.end()) {
sol++;
li++;
}
sol++;
return (int)(sol % 1000000007);
}
int main(int argc, char* argv[]) {
vector<int> H = { 13, 2, 5 };
cout << "sol: " << solution(H) << endl;
system("pause");
}
The main function calls solution(vector<int> H). The point is, when the argument has the particular value of H = {13, 2, 5} the VC++ compiled program give an output value of 7 (which is the correct one), but the GNU g++ compiled program give an output value of 5 (also clang compiled program behave like this).
I'm using this website, among others, for testing different compilers
http://rextester.com/l/cpp_online_compiler_gcc
I've tried to figure out the reason for this wierd behaviour but didn't found any relevant info. Only one post treat a similar problem:
Different results VS C++ and GNU g++
and that's why I'm using long long types in the code, but the problem persists.
The problem was decrementing the start-of-sequence --rightTree.begin()
As I found VC++ and GNU g++ does not behave the same way on above operation. Here is the code that shows the difference, adapted from http://www.cplusplus.com/forum/general/84609/:
#include<iostream>
#include<set>
using namespace std;
struct Element {
long long height;
long long acc;
long long con;
};
bool fncomp(Element* lhs, Element* rhs) {
return lhs->height < rhs->height;
}
int main(){
bool(*fn_pt)(Element*, Element*) = fncomp;
set<Element*, bool(*)(Element*, Element*)> rightTree(fn_pt);
set<Element*, bool(*)(Element*, Element*)>::iterator ri;
ri = rightTree.begin();
--ri;
++ri;
if(ri == rightTree.begin()) cout << "it works!" << endl;
}
I am using a simple backtracking algorithm to find all the paths but it does not give the right answer. I am not able to figure out the mistake. We can move up, down, left and right from a given position.
Int path(int a[][200],int n,int m,int r,int c)
{
if(n == r - 1 && m == c-1) {
return 1;
}
else if(n >= r || m >= c || n < 0 || m < 0) {
return 0;
}
else if(vis[n][m] == 1) {
return 0;
}
else {
vis[n][m] = 1;
int x = path(a,n+1,m,r,c);
int y = path(a,n,m+1,r,c);
int u = path(a,n-1,m,r,c);
int v = path(a,n,m-1,r,c);
vis[n][m] = 0;
return (x+y+u+v);
}
}
To find the paths or count the paths are not exactly the same thing. I will assume you want to just count the paths (because the title of your question), and that you can only move right or move down.
For this you don't really need a matrix (representing the grid) as a parameter. The following is a simple (although not efficient) recursive solution that also will work for a n*m grid:
int countPaths(int m, int n) {
if (m == 0 || n == 0)
return 1;
return countPaths(m-1, n) + countPaths(m, n-1);
}
The mathematical solution for the general n*n grid is:
(2n choose n) = (2*n)!/(n!*n!)
Then, comparing results with the formula:
countPaths(1, 1) == 2 // (2*1)!/(1!*1!)=2
countPaths(2, 2) == 6 // (2*2)!/(2!*2!)=6
countPaths(3, 3) == 20 // (2*3)!/(3!*3!)=20
Your backtracking approach will give the same results, but with some considerations. For example, consider when n=2, you will need a 3x3 matrix (and in general a (n+1)x(n+1) matrix) to represent/explore (and mark with 1) all the paths for the 2x2 grid:
int countPaths(int a[][3],int n, int m, int r, int c) {
if(n == r-1 && m == c-1) {
return 1;
}
else if(n >= r || m >= c || n < 0 || m < 0) {
return 0;
}
else if(vis[n][m] == 1) {
return 0;
}
else {
vis[n][m] = 1;
int x = countPaths(a,n+1,m,r,c);
int y = countPaths(a,n,m+1,r,c);
vis[n][m] = 0;
return (x+y);
}
}
Then:
countPaths(vis, 0, 0, 3, 3) == 6 // (2*2)!/(2!*2!)=6
here is my code:
// PPT.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#define LOWER_BOUND 1
#define UPPER_BOUND 20
struct ppt
{
int v1;
int v2;
int v3;
ppt *next;
};
typedef struct ppt PPT;
typedef PPT *ppt_ptr;
void insert_ppt(ppt_ptr *h_ptr, ppt_ptr *t_ptr, int u1, int u2, int u3);
void print_ppt(ppt_ptr curr_ptr);
int is_prime(int n);
int is_pythagorean_triplet(int v1, int v2, int v3);
int different_triples(int v1, int v2, int v3, int u1, int u2, int u3);
int are_exact_multiples(int p, int q, int r, int l, int m, int n);
int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3);
//====================================================================
int _tmain(int argc, _TCHAR* argv[])
{
ppt_ptr head_ptr = NULL;
ppt_ptr tail_ptr = NULL;
for (int a = LOWER_BOUND; a <= UPPER_BOUND; a++)
{
for (int b = LOWER_BOUND; b <= UPPER_BOUND; b++)
{
for (int c = LOWER_BOUND; c <= UPPER_BOUND; c++)
{
if(is_pythagorean_triplet(a,b,c) == 1)
{
if(head_ptr == NULL)
{
//printf("%d %d %d",a,b,c);
insert_ppt(&head_ptr,&tail_ptr,a,b,c);
}
//printf("%d %d %d",a,b,c);
if(is_unique_and_insertable(tail_ptr,a,b,c) == 1)
{
//printf("%d %d %d\n",a,b,c);
insert_ppt(&head_ptr,&tail_ptr,a,b,c);
}
}
}
}
}
//print_ppt(head_ptr);
getchar();
getchar();
return 0;
}
this function inserts a new node at end of list
void insert_ppt(ppt_ptr *h_ptr, ppt_ptr *t_ptr, int u1, int u2, int u3)
{
ppt_ptr new_ptr;
new_ptr = ppt_ptr( malloc( sizeof(PPT) ) );
if(new_ptr != NULL)
{
new_ptr->v1 = u1;
new_ptr->v2 = u2;
new_ptr->v3 = u3;
new_ptr->next = NULL;
if(*h_ptr == NULL)
{
*h_ptr = new_ptr;
}
else
{
(*t_ptr)->next = new_ptr;
}
*t_ptr = new_ptr;
}
else
{
printf("%d %d %d not inserted. No memory available.\n",u1,u2,u3);
}
}
this function prints list
void print_ppt(ppt_ptr curr_ptr)
{
if(curr_ptr == NULL)
{
printf("List is empty.\n\n");
}
else
{
while(curr_ptr != NULL)
{
printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
curr_ptr = curr_ptr->next;
}
}
}
this function determines if a number is prime
// Function 1
int is_prime(int n)
{
int num_of_factors = 0;
int i = 1;
for (i=1; i<=n; i++)
{
if (n % i == 0)
{
num_of_factors ++;
}
}
if (num_of_factors == 2)
{
return 1;
}
else
{
return 0;
}
}
this function determines if a triplet is pythagorean
// Function 2
int is_pythagorean_triplet(int v1, int v2, int v3)
{
if ( (v1*v1 + v2*v2 == v3*v3) || (v2*v2 + v3*v3 == v1*v1) || (v1*v1 + v3*v3 == v2*v2) )
{
return 1;
}
else
{
return 0;
}
}
this function determines if a triplet is unique and this is the function that i am having trouble with
int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3)
{
if(curr_ptr == NULL)
{
//printf("List is empty.\n\n");
}
else
{
if(curr_ptr != NULL)
{
//printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
int u1 = curr_ptr->v1;
int u2 = curr_ptr->v2;
int u3 = curr_ptr->v3;
if( (different_triples(v1,v2,v3,u1,u2,u3)) &&
(!are_exact_multiples(v1,v2,v3,u1,u2,u3) ) )
{
printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
return 1;
}
//printf("yoyoyo");
curr_ptr = curr_ptr->next;
}
}
return 0;
}
this function determines if a triple is unique
// Definition: This function checks if <v1,v2,v3> and <u1,u2,u3> are different triplets
// or not. If they are different triplets, it returns 1.
int different_triples(int v1, int v2, int v3, int u1, int u2, int u3)
{
if (v1==u1 && v2==u2 && v3==u3)
return 0;
else if (v1==u1 && v2==u3 && v3==u2)
return 0;
else if (v1==u2 && v2==u1 && v3==u3)
return 0;
else if (v1==u2 && v2==u3 && v3==u1)
return
else if (v1==u3 && v2==u2 && v3==u1)
return 0;
else if (v1==u3 && v2==u1 && v3==u2)
return 0;
else
return 1;
}
this function determines if a triplet is a multiple of a triplet
// This function tests if the triplet <p,q,r> is an exact multiple of <l,m,n> in any order
// (arrangement/permutation)
int are_exact_multiples(int v1, int v2, int v3, int u1, int u2, int u3)
{
if (v1%u1==0 && v2%u2==0 && v3%u3==0)
return 1;
else if (u1%v1==0 && u2%v2==0 && u3%v3==0)
return 1;
else if (v1%u1==0 && v2%u3==0 && v3%u2==0)
return 1;
else if (u1%v1==0 && u2%v3==0 && u3%v2==0)
return 1;
else if (v1%u2==0 && v2%u1==0 && v3%u3==0)
return 1;
else if (v1%u2==0 && v2%u3==0 && v3%u1==0)
return 1;
else if (u1%v2==0 && u2%v1==0 && u3%v3==0)
return 1;
else if (u1%v2==0 && u2%v3==0 && u3%v1==0)
return 1;
else if (v1%u3==0 && v2%u2==0 && v3%u1==0)
return 1;
else if (v1%u3==0 && v2%u1==0 && v3%u2==0)
return 1;
else if (u1%v3==0 && u2%v2==0 && u3%v1==0)
return 1;
else if (u1%v3==0 && u2%v1==0 && u3%v2==0)
return 1;
else
return 0;
}
I know that the algorithm is not optimized... i will do that later. Can somebody please help me get this code to work.
Your function is_unique_and_insertable presumably should check whether an equivalent triple (the same numbers in different order) is already present in the list or the new triple is a multiple (modulo permutations) of a triple in the list. But it only compares the new triple to the first list element, there is no looping statement or recursion in the function.
int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3)
{
if(curr_ptr == NULL)
{
//printf("List is empty.\n\n");
}
else
{
if(curr_ptr != NULL)
{
//printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
int u1 = curr_ptr->v1;
int u2 = curr_ptr->v2;
int u3 = curr_ptr->v3;
if( (different_triples(v1,v2,v3,u1,u2,u3)) &&
(!are_exact_multiples(v1,v2,v3,u1,u2,u3) ) )
{
printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
return 1;
}
//printf("yoyoyo");
curr_ptr = curr_ptr->next;
}
}
return 0;
}
You would get it to compare to more than just the first element if you used a while(curr_ptr != NULL). However, it would still have the wrong logic, it would return true (1) as soon as it finds a different triple the new one is not a multiple of.
The logic must be the other way round, if an equivalent triple (or a triple the new one is a multiple of) is encountered, then you return false (0), only if the entire list is traversed without encountering such a triple should you return true:
int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3)
{
while(curr_ptr != NULL)
{
int u1 = curr_ptr->v1;
int u2 = curr_ptr->v2;
int u3 = curr_ptr->v3;
if (!different_triples(v1, v2, v3, u1, u2, u3) || are_exact_multiples(v1, v2, v3, u1, u2, u3))
{
return 0;
}
curr_ptr = curr_ptr->next;
}
return 1;
}
That takes you closer to a correct program, but your are_exact_multiples function is faulty, it would declare (15, 36, 39) to be a multiple of (3, 4, 5), although it isn't.
You would get a much simpler and easier to get right program if you only considered triples (a, b, c) with a <= b <= c (actually, a < b < c, since a Pythagorean triple can't have two equal components).
You said you would treat efficiency later, but please do that soon, your is_prime function is painfully inefficient. You should stop as soon as you found the first nontrivial divisor, and you can stop when you've reached the square root:
int is_prime(int n)
{
if (n < 2) return 0;
if (n%2 == 0) return n == 2;
for(int d = 3; d*d <= n; d += 2)
{
if (n%d == 0) return 0;
}
return 1;
}