This code is for Merkle trees and the full code can be accesed on this link https://github.com/weichaoguo/merkle-tree/blob/master/merkle_tree.c
The part that confuses me is within these block of code:
So I was wondering why is there (1 << a->tree_height)-1 and all the other lines that contain <<. What is << used here for?
//compare two merkle trees from node i
//make sure the two trees in same height
//return different data block number
//if no differnece return 0
int tree_cmp(merkle_tree *a, merkle_tree *b, size_t i) {
int cmp;
if (i > (1<<a->tree_height)-1)
return -1;
if (memcmp(a->nodes[i].hash, b->nodes[i].hash, a->hash_size) != 0) {
if (i<<1 > (1<<a->tree_height)-1)
return i - (1 << (a->tree_height - 1)) + 1;
else {
cmp = tree_cmp(a, b, i<<1);
if (cmp == 0)
return tree_cmp(a, b, (i<<1)+1);
else
return cmp;
}
}
else
return 0;
}
// set tree data with specific block number
//
int set_tree_data(merkle_tree *mt, size_t block_num, char *data) {
if (block_num > mt->data_blocks)
return -1;
size_t i = (1 << (mt->tree_height - 1)) + block_num - 1;
if (mt->nodes[i].data)
free(mt->nodes[i].data);
mt->nodes[i].data = data;
if (hash_node(mt, i) == -1)
return -1;
for (i>>=1; i>0; i>>=1)
if (hash_node(mt, i) == -1)
return -1;
return 0;
}
It's a bitshift. (1 << x) - 1 has x ones set.
Related
I want to implement a function to check if a BST (of int values) contains more odds it should return 2, if it contains more evens return 1 and 0 otherwise - recursively.
I was trying to create help function with inputs of even and odd counter but the function returns wrong output.
My code:
int evenOdd(Tnode* root) {
if (root == NULL)
return 0 ;
return eVenOddHelp(root , 0 , 0) ;
}
int eVenOddHelp(Tnode* root , int even , int odd) {
if (root == NULL) {
if (even > odd)
return 1 ;
else if (odd > even)
return 2 ;
return 0 ;
}
else {
if (root->data % 2 == 0) {
eVenOddHelp(root->left , even + 1 , odd) ;
eVenOddHelp(root->right , even + 1 , odd) ;
}
else {
eVenOddHelp(root->left , even , odd + 1) ;
eVenOddHelp(root->right , even , odd + 1) ;
}
}
}
IMO the easiest way is to use the return value, if return positive there are more evens, if negative there are more odds, 0 otherwise:
int evenOdd(Tnode* root) {
int result = eVenOddHelp(root);
if(result > 1) return 1; // More evens
else if(result == 0) return 0; // the same
else return 2; // More odds
}
int eVenOddHelp(Tnode* root) {
if (root != NULL) {
int isEven = (root->data % 2 == 0) ? 1 : -1;
return eVenOddHelp(root->left) + eVenOddHelp(root->right) + isEven;
}
return 0;
}
Comparing like this:
if (root == NULL) {
if (even > odd)
return 1 ;
else if (odd > even)
return 2 ;
return 0 ;
}
Will produce wrong values because there is several times where the root == NULL is true, you will comparing evens and odds in different subtrees. And not at the end of the entire tree.
There's an easier way to do this by using counters passed in as mutable pointers:
void modCounter(Tnode* node, int* even, int* odd) {
if ((node->data % 2) == 0) {
(*even)++;
}
else {
(*odd)++;
}
if (node->left) {
modCounter(node->left, even, odd);
}
if (node->right) {
modCounter(node->right, even, odd);
}
}
Note that it just alters the pointed values, so you call it like this:
int evenOdd(Tnode* root) {
if (root == NULL)
return 0;
int even = 0;
int odd = 0;
modCounter(root, &even, &odd);
if (even > odd) {
return 1;
}
if (odd > even) {
return 2;
}
return 0;
}
To use a more C-based approach you could even pass in an array of two int values, as in:
void modCounter(Tnode* node, int* counters, int mod) {
++counters[node->data % mod];
// ...
}
Where you call it like this:
int counters[2];
modCounter(root, &counters[0], 2);
I have been working on a chess engine recently, and I am ready to implement some kind of AI to actually play the game (search positions). I have written an alpha-beta pruning algorithm, but it doesn't return the best moves when i test it.
The code for the alpha-beta search is:
float Search::alphabeta(S_BOARD* pos, S_SEARCHINFO *info, int depth, float alpha, float beta){
if (depth == 0) {
info->nodes++;
return eval::staticEval(pos);
}
info->nodes++;
S_MOVELIST list;
MoveGeneration::validMoves(pos, list);
float value = 0;
S_MOVE bestMove;
bestMove.move = NOMOVE;
bestMove.score = 0;
float prevBound = (pos->whitesMove == WHITE) ? alpha : beta;
int pvMove = TT::probeMove(pos);
if (pvMove != NOMOVE) {
for (int i = 0; i < list.count; i++) {
if (list.moves[i].move == pvMove) {
list.moves[i].score = 20000000;
break;
}
}
}
if (pos->whitesMove == WHITE) {
value = -INFINITE;
for (int moveNum = 0; moveNum < list.count; moveNum++) {
pickNextMove(moveNum, &list);
MoveGeneration::makeMove(*pos, list.moves[moveNum].move);
value = max(value, alphabeta(pos, info, depth - 1, alpha, beta));
MoveGeneration::undoMove(*pos);
if (value > alpha) {
if (value >= beta) {
if (moveNum == 0) {
info->fhf++;
}
info->fh++;
break;
}
alpha = value;
bestMove = list.moves[moveNum];
}
}
if (pos->is_checkmate) {
return -MATE + pos->ply;
}
else if (pos->is_stalemate) {
return 0;
}
if (alpha != prevBound) {
TT::storePvMove(pos, bestMove);
}
return value;
}
else {
value = INFINITE;
for (int moveNum = 0; moveNum < list.count; moveNum++) {
pickNextMove(moveNum, &list);
MoveGeneration::makeMove(*pos, list.moves[moveNum].move);
value = min(value, alphabeta(pos, info, depth - 1, alpha, beta));
MoveGeneration::undoMove(*pos);
if (value < beta){
if (beta <= alpha) {
if (moveNum == 0) {
info->fhf++;
}
info->fh++;
break;
}
beta = value;
bestMove = list.moves[moveNum];
}
}
if (pos->is_checkmate) {
return MATE - pos->ply;
}
else if (pos->is_stalemate) {
return 0;
}
if (beta != prevBound) {
TT::storePvMove(pos, bestMove);
}
return value;
}
(MoveGeneration is a namespace, so it isn't a problem with calling functions outside of object instances.)
I run the function inside an iterative deepening function, which is as follows:
float Search::searchPosition(S_BOARD* pos, S_SEARCHINFO *info){
clearForSearch(pos, info);
float score = -INFINITE;
int bestMove = NOMOVE;
int pvMoves = 0;
// Iterative deepening.
for (int currDepth = 1; currDepth <= info->depth; currDepth++){
auto start = std::chrono::high_resolution_clock::now();
score = alphabeta(pos, info, currDepth, -INFINITE, INFINITE);
auto end = std::chrono::high_resolution_clock::now();
pvMoves = TT::getPvLine(pos, currDepth);
bestMove = pos->pvArray[0];
std::chrono::duration<double> elapsed = end - start;
std::cout << "[+] Depth: " << currDepth << " score: " << score << " move: " << printMove(bestMove)
<< " nodes: " << info->nodes << " kN/s: " << (info->nodes/elapsed.count())/1000 << std::endl;
std::cout << "pv";
for (int i = 0; i < pvMoves; i++){
std::cout << " " << printMove(pos->pvArray[i]);
}
std::cout << std::endl;
std::cout << "Ordering: " << info->fhf/info->fh << std::endl;
}
return score;}
Can anyone please help me by pointing out potential errors i have made?
Thank you for your help, and just tell me if i need to upload more of my code.
it doesn't return a move since you are only returning the value at the bottom of your alpha/beta function. In the original call, put this:
move, score = alphabeta(pos, info, currDepth, -INFINITE, INFINITE);
In your depth == 0, checkmate and stalemate you return:
return None, eval
At the end of your two player functions (minimizing and maximizing player) you return:
return move, value
Finally, when you make the recursive calls from your two player functions, you need to only obtain the value. I am not sure about your programming language, but in e.g. Python you put a [1] at the end to just get the value and not the move, something like this:
value = max(value, alphabeta(pos, info, depth - 1, alpha, beta))[1]
My code is below :
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int* new = (int*)malloc(sizeof(int) * (nums1Size+nums2Size));
int i = 0;
int count1 = 0;
int count2 = 0;
if(nums1Size+nums2Size == 1){
if(nums1Size == 1)
return *nums1;
else
return *nums2;
}
else if(nums1Size == 0){
if((nums2Size & 0x1) == 0)
return (double)(nums2[nums2Size/2-1]+nums2[nums2Size/2])/2;
else
return (double)nums2[nums2Size/2];
}
else if(nums2Size == 0){
if((nums1Size & 0x1) == 0)
return (double)(nums1[nums1Size/2-1]+nums1[nums1Size/2])/2;
else
return (double)nums1[nums1Size/2];
}
while(i != (nums1Size+nums2Size))
{
if((nums1[count1 == nums1Size ? count1-1:count1] > nums2[count2 == nums2Size ? count2-1:count2]
&& (count2) != nums2Size)
|| (count1) == nums1Size)
{
*(new+i) = *(nums2+count2);
count2++;
}
else{
*(new+i) = *(nums1+count1);
count1++;
}
i++;
}
if(((nums1Size+nums2Size) & 0x1) == 0){
return (double)(new[(nums1Size+nums2Size)/2 - 1] + new[(nums1Size+nums2Size)/2]) / 2;
}
else
return (double)new[(nums1Size+nums2Size)/2];
}
And below is the submissions's runtime distribution on Leetcode :
The Question is, even if there are a lot of submitted codes with O(log (m+n)) in C but I think my code's Time complexity is O(m+n). so it doesn't make sense that my code is top 2% on Leetcode according to the distribution graph. of course linear is faster than log to a small amount of inputs but the test-cases are enough big to get beaten by O(log (m+n)). I don't know why my code get passed with that rate.
will greatly appreciate your comments!
From my top comment: You allocate new at the start of the function. If any of the "early escape" return statements are executed, you'll leak memory.
So do I have to put free() in every return statement? or how can i fix my code?
Don't do the malloc until after the top block of early escapes.
And, do the free at the bottom. To do this, you'll need an extra variable to hold the return value so you can safely do the free(new) (e.g. double retval;)
Side note: It's usually cleaner to replace (e.g.) *(new + i) with new[i]. Also, holding the code to <= 80 chars / line is also a good style.
Here's one way to fix your code [please pardon the gratuitous style cleanup]:
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
int *new;
int i;
int count1 = 0;
int count2 = 0;
double retval;
if (nums1Size + nums2Size == 1) {
if (nums1Size == 1)
return *nums1;
else
return *nums2;
}
if (nums1Size == 0) {
if ((nums2Size & 0x1) == 0)
return (double) (nums2[nums2Size / 2 - 1] +
nums2[nums2Size / 2]) / 2;
else
return nums2[nums2Size / 2];
}
if (nums2Size == 0) {
if ((nums1Size & 0x1) == 0)
return (double) (nums1[nums1Size / 2 - 1] +
nums1[nums1Size / 2]) / 2;
else
return (double) nums1[nums1Size / 2];
}
// allocate this only when you're sure you'll use it
new = malloc(sizeof(int) * (nums1Size + nums2Size));
for (i = 0; i != (nums1Size + nums2Size); ++i) {
if ((nums1[count1 == nums1Size ? count1 - 1 : count1] >
nums2[count2 == nums2Size ? count2 - 1 : count2] &&
(count2) != nums2Size)
|| (count1) == nums1Size) {
new[i] = nums2[count2];
count2++;
}
else {
new[i] = nums1[count1];
count1++;
}
}
if (((nums1Size + nums2Size) & 0x1) == 0) {
retval = (double) (new[(nums1Size + nums2Size) / 2 - 1] +
new[(nums1Size + nums2Size) / 2]) / 2;
}
else
retval = (double) new[(nums1Size + nums2Size) / 2];
free(new);
return retval;
}
But, personally, I dislike multiple return statements in a function. It's harder to debug [using gdb] because you'd have to set a breakpoint on each return.
Here's a version that uses a do { ... } while (0); as a "once through" loop that allows us to eliminate the if/else "ladder" logic [which I also personally dislike] and have only a single return at the bottom. YMMV ...
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
int *new = NULL;
int i = 0;
int count1 = 0;
int count2 = 0;
double retval;
do {
if (nums1Size + nums2Size == 1) {
if (nums1Size == 1)
retval = *nums1;
else
retval = *nums2;
break;
}
if (nums1Size == 0) {
if ((nums2Size & 0x1) == 0)
retval = (double) (nums2[nums2Size / 2 - 1] +
nums2[nums2Size / 2]) / 2;
else
retval = nums2[nums2Size / 2];
break;
}
if (nums2Size == 0) {
if ((nums1Size & 0x1) == 0)
retval = (double) (nums1[nums1Size / 2 - 1] +
nums1[nums1Size / 2]) / 2;
else
retval = (double) nums1[nums1Size / 2];
break;
}
// allocate this only when you're sure you'll use it
new = malloc(sizeof(int) * (nums1Size + nums2Size));
for (; i != (nums1Size + nums2Size); ++i) {
if ((nums1[count1 == nums1Size ? count1 - 1 : count1] >
nums2[count2 == nums2Size ? count2 - 1 : count2] &&
(count2) != nums2Size)
|| (count1) == nums1Size) {
new[i] = nums2[count2];
count2++;
}
else {
new[i] = nums1[count1];
count1++;
}
}
if (((nums1Size + nums2Size) & 0x1) == 0) {
retval = (double) (new[(nums1Size + nums2Size) / 2 - 1] +
new[(nums1Size + nums2Size) / 2]) / 2;
}
else
retval = (double) new[(nums1Size + nums2Size) / 2];
} while (0);
if (new != NULL)
free(new);
return retval;
}
UPDATE:
thanks! I understood. your code is more clear than mine for real!. but what do you think about the performance between them? ( if/else and do{...}while(0)). because if we assume the compiler would work as we generally expect, if/else is faster than if if which is in do{...} in the revised code. thanks a lot again!
Actually, if we disassemble both versions [compiled with -O2], the do/while version is 4 assembly instructions shorter.
But, in order to tune it, you have to measure it.
The optimizer will pretty much make them similar.
The main bulk of the time of the function is spent in the for loop, which is the same for both. The speed of the loop dwarfs any extra overhead of do/while which might be an assembler instruction or two [but, again the do/while has fewer instructions].
So, tuning/optimizing the prolog/epilog code of the function isn't [usually] worth it. Speeding up the loop is.
To tune/optimize, either do profiling to determine where the code spends the most amount of time [or for something this simple, it's obviously the loop], or add timestamping and get elapsed time on the function [or various subparts].
As I mentioned, it's hard to add a breakpoint for a function that has multiple return statements.
Also, sometimes you can't attach a debugger. Or, it's difficult to find a meaningful place to put a breakpoint. For example, if you have a program that runs fine for (e.g.) days, and then aborts after (e.g.) 63 hours, you may need to do internal benchmarking and printf style debugging:
#ifdef DEBUG
#define dbgprint(_fmt) \
do { \
printf(_fmt); \
} while (0)
#else
#define dbgprint(_fmt) \
do { \
} while (0)
#endif
double
findMedianSortedArrays(int *nums1, int nums1Size, int *nums2, int nums2Size)
{
double retval;
dbgprint("findMedianSortedArrays: ENTER nums1Size=%d nums2Size=%d\n",
nums1Size,nums2Size);
// ... the code
dbgprint("findMediaSortedArrays: EXIT retval=%g\n",retval);
return retval;
}
It's much easier to insert the debug print statements with the second version.
BTW, I do this sort of thing all the time. And, one of my fortes is fast code and performance improvement [as I do a lot of realtime coding].
I need to write a recursive function that returns 1 if digits of a whole number are ascending (left to right), return -1 if descending or return 0 if neither.
My solution attempt returns 0 every time and I know why but I don't know how to get around it.
Here's my code:
#include <stdio.h>
int check_order(int n)
{
if (n % 10 > n / 10 % 10)
{
return check_order(n / 10);
if (n == 0)
{
return 1;
}
}
else if (n % 10 < n / 10 % 10)
{
return check_order(n / 10);
if (n == 0)
{
return -1;
}
}
else
{
return 0;
}
}
int main()
{
int n;
printf("enter a whole number (n > 9):");
scanf_s("%d", &n);
printf("function returned: %d\n", check_order(n));
}
Here's a simple recursion:
int f(int n){
if (n < 10)
return 0;
int dr = n % 10; // rightmost digit
n = n / 10;
int dl = n % 10; // second digit from the right
int curr = dl < dr ? 1 : -1; // current comparison
if (dl == dr) curr = 0; // keep strict order
if (n < 10)
return curr;
return curr == f(n) ? curr : 0; // are the comparisons consistent?
}
Explain your algorithm?
Suppose you use the following:
You are given a number.
You need to turn that number into a sequence of digits.
If you are given a number, you can convert that number to a sequence of digits.
If you are given a sequence of digits, use
that.
Compare each pair of digits -> ascending, descending, or neither.
Combine the results from each pair, sequentially/recursively.
We can use a string to make the digit comparisons easier, and accept very long sequences of digits.
We can use an enum(erated) type to represent the ordering.
How do you combine the results? Define a function that combines the order of two adjacent, overlapping pairs, then you can combine results.
#include <stdio.h>
#include <string.h>
typedef enum { descending=-1, other=0, ascending=1 } order_t;
order_t pair_order(int a, int b) {
if( a < b ) return ascending;
if( a > b ) return descending;
return other;
}
//strict (increasing/decreasing)
order_t strict_order( order_t x, order_t y ) {
if( x == y ) return x;
return other;
}
//monotone (increasing/decreasing)
order_t monotone_order( order_t x, order_t y ) {
if( x == y ) return x;
if( other == x ) return y;
if( other == y ) return x;
return other;
}
order_t check_order( char* p, int remain ) {
//printf("p:%s\n",p); //uncomment to watch progress
if( remain<2 ) return other;
if( remain==2 ) return pair_order(p[0], p[1]);
return strict_order( pair_order(p[0], p[1]), check_order(p+1, remain-1) );
//return monotone_order( pair_order(p[0], p[1]), check_order(p+1, remain-1) );
}
char* order_name[] = {
"descending",
"other",
"ascending"
""
};
int main()
{
char line[666] = "none";
while ( strlen(line) > 0 ) {
printf("enter a number (at least 2 digits):");
fgets(stdin,line,sizeof(line)-1);
if( strlen(line) > 0 && line[strlen(line)-1] == '\n' )
line[strlen(line)-1] = '\0';
order_t order = check_order(line);
printf("function returned: (%d)%s\n", order, order_name[order+1]);
}
}
I think you were started on the right track but need to flesh out your code more. My solution borrows on that of #ChuckCottrill as I like his enum but I don't like that he doesn't play the ball as it lays (i.e. converts to a string instead of dealing with the int.) I also borrow the nice test examples of #ggorlen but I don't like that solution either as it can take multiple passes through the number to figure out the answer when only one pass should be needed:
#include <stdio.h>
typedef enum { descending=-1, other=0, ascending=1 } order_t; // a la #ChuckCottrill
order_t check_order(int n)
{
if (n > 9) {
int right = n % 10;
int left = n / 10 % 10;
if (right > left) {
n /= 10;
if (n > 9) {
return (ascending == check_order(n)) ? ascending : other;
}
return ascending;
}
if (right < left) {
n /= 10;
if (n > 9) {
return (descending == check_order(n)) ? descending : other;
}
return descending;
}
}
return other;
}
int main() { // a la #ggorlen
printf("12345: %d\n", check_order(12345));
printf("54321: %d\n", check_order(54321));
printf("54323: %d\n", check_order(54323));
printf("454321: %d\n", check_order(454321));
printf("1: %d\n", check_order(1));
printf("12: %d\n", check_order(12));
printf("21: %d\n", check_order(21));
}
OUTPUT
> ./a.out
12345: 1
54321: -1
54323: 0
454321: 0
1: 0
12: 1
21: -1
>
A version that works for any length since it takes the string as parameter.
And feeding the recursive function with previous status (ascending or descending) allows for some shorter code and less functions.
int check_order(char *str, int index, int previous) {
char current = str[index]; // char at index
char next = str[index+1]; // char at index+1
if (current == 0 || next == 0) {
return previous; // End of string
}
// Ascending or descending?
int status = next > current ? 1 : (next < current ? -1 : 0);
if (status == 0 || index > 0 && status != previous) {
// If neither -1/1 nor status == previous (while not initial call)
return 0;
}
return check_order(str, index+1, status); // Check from next index
}
The main function must ensure the string is at least 2 chars
int main(int argc, char **argv) {
char *str = *++argv;
// Some optional checks on str here... (like this is a number)
int status = 0; // Default value if string length < 2
if (strlen(str) >= 2) {
status = check_order(str, 0, 0);
}
printf("Check order for %s is %d\n", str, status);
return 0;
}
Code after a return statement like this is unreachable:
return check_order(n / 10);
if (n == 0)
{
return -1;
}
Beyond this, you're on the right track of checking the current digit against the next digit, but I don't see a clear base case (when n < 10, that is, a single digit).
Trying to check ascending and descending in one recursive function is difficult to manage. In particular, communicating state between stack frames and determining which cases are still valid at a given call suggests that the return value is overworked.
To save having to return a struct or use an enum or magic numbers as flags, I'd write two general helper functions, ascending_digits and descending_digits.
#include <stdbool.h>
#include <stdio.h>
bool ascending_digits(int n) {
if (n < 10) return true;
if (n % 10 < n / 10 % 10) return false;
return ascending_digits(n / 10);
}
bool descending_digits(int n) {
if (n < 10) return true;
if (n % 10 > n / 10 % 10) return false;
return descending_digits(n / 10);
}
int check_order(int n) {
if (ascending_digits(n)) return 1;
if (descending_digits(n)) return -1;
return 0;
}
int main() {
printf("12345: %d\n", check_order(12345));
printf("54321: %d\n", check_order(54321));
printf("54323: %d\n", check_order(54323));
printf("454321: %d\n", check_order(454321));
printf("1: %d\n", check_order(1));
printf("12: %d\n", check_order(12));
printf("21: %d\n", check_order(21));
return 0;
}
Output:
12345: 1
54321: -1
54323: 0
454321: 0
1: 1
12: 1
21: -1
Not only are these functions easier to understand and maintain individually, they're also more reusable than if they were inseparably tied together.
This doesn't handle negative numbers--you could apply abs and go from there if you want. Same goes for handling equal values; this implementation accepts numbers such as 1223 but you could use <= to enforce strict ordering.
I'd like to ask the following misunderstandings of C language, which I see I'm having.
I'm sorry if the code is not properly indented, I tried as much as I could but there are not so many guides on the internet.
The program asked given a starting number 'val' and a Even-Odd or Odd-Even alternating sequence (which stops whenever this rules is violated) to print the greater prime number with 'val'.
I tried with two functions and the main: one to control the GCD between two given numbers and the other to keep tracks of the greatest one, but I think I miss something in the code or in the conception of C function,
Because when compiled it returns me 0 or great number which I'm not entering.
One example to understand what I should do:
If my sequence was 10, 7, 8, 23 and my val was 3, I had to print 23, because it is the greatest integer prime with 3.
Here's the code :
#include <stdio.h>
int mcd(int a, int b)
{ // Gcd function
if (a == 0)
return b;
else
return mcd(b % a, b);
}
int valuta(int val, int h) // Valuing Max function
{
int temp = 0;
if (mcd(val, h) == 1 && h > temp)
temp = h;
return temp;
}
int main()
{
int val, d, x, y, z, t, contatore = 1;
scanf("%d", &val);
scanf("%d%d", &x, &y);
if (x > y && mcd(val, x) == 1)
{ // Two options
t = x;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
}
if ((x % 2 == 0 && y % 2 == 0) || (x % 2 == 1 && y % 2 == 1))
{ // Bad case
if (x > y && mcd(val, x) == 1)
{
t = x;
contatore = 0;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
contatore = 0;
}
}
else
{
while (contatore == 1)
{
scanf("%d", &z);
t = valuta(val, z);
if (x % 2 == 0 && z % 2 == 0)
{ // Even- Odd - Even
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 0)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
if (x % 2 == 1 && z % 2 == 1)
{ //Odd- Even- Odd
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 1)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
}
}
printf("%d\n", t);
return 0;
}
PS. Is there any way to reduce the number of lines of code or to reduce the effort in coding? I mean, a straightforward solution will be helpful.
Your valuta() function is flawed in that it needs to return the maximum qualifying value so far but has no knowledge of the previous maximum - temp is always zero. The following takes the previous maximum as an argument:
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) == 1 && h > previous ) ? h : previous ;
}
And is called from main() thus:
t = valuta( val, x, t ) ;
The test mcd(val, h) == 1 is flawed, because mcd() only ever returns the value of parameter b which is not modified in the recursion, so will never return 1, unless the argument b is 1. Since I have no real idea what mcd() is intended to do, I cannot tell you how to fix it. It appear to be a broken implementation of Euclid's greatest common divisor algorithm, which correctly implemented would be:
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
But I cannot see how that relates to:
"[...] he greatest integer prime with 3 [...]
The odd/even even/odd sequence handling can be drastically simplified to the extent that it is shorter and simpler than your method (as requested) - and so that it works!
The following is a clearer starting point, but may not be a solution since it is unclear what it is it is supposed to do.
#include <stdio.h>
#include <stdbool.h>
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) && h > previous ) ? h : previous ;
}
int main()
{
int val, x, t ;
printf( "Enter value:") ;
scanf("%d", &val);
typedef enum
{
EVEN = 0,
ODD = 1,
UNDEFINED
} eOddEven ;
eOddEven expect = UNDEFINED ;
bool sequence_valid = true ;
printf( "Enter sequence in odd/even or even/odd order (break sequence to exit):\n") ;
while( sequence_valid )
{
scanf("%d", &x);
if( expect == UNDEFINED )
{
// Sequence order determined by first value
expect = (x & 1) == 0 ? EVEN : ODD ;
}
else
{
// Switch expected odd/even
expect = (expect == ODD) ? EVEN : ODD ;
// Is new value in the expected sequence?
sequence_valid = (expect == ((x & 1) == 0 ? EVEN : ODD)) ;
}
// If the sequence is valid...
if( sequence_valid )
{
// Test if input is largest qualifying value
t = valuta( val, x, t ) ;
}
}
// Result
printf("Result: %d\n", t);
return 0;
}