How to properly make a counting algorithm to count from file? - c

This is a program to find the largest even number and its times of occurring from an input file and output it to an output file. I'm having a problem with the output, there seems to be an extra iteration that messes things up.
int main(int argc, char const *argv[])
{
int n, num, i, even, count;
FILE * fptr;
FILE * fptro;
fptr =fopen("maximpar.in", "r");
fptro=fopen("maximpar.out", "w");
/*scanning the first line from the file to get n for for()*/
fscanf(fptr, "%d", &n);
count = 0;
even = INT_MIN;
for(i = 0; i < n; i++)
{
fscanf(fptr, "%d", &num);
if( (num % 2 == 0 && num > even) || (even == num) )
/*checking for largest even number,
not sure about the ..||(even == num) part of the condition*/
{
even = num;
count++;
}
}
fprintf(fptro, "%d %d", even, count);
fclose(fptr);
fclose(fptro);
return 0;
}
Input file
6
9 6 9 8 9 8
Output file
8 3
Why isn't the output file like this? I don't understand
8 2

You need to reset your count whenever you get a new larger number.
I didn't test this, but it should work:
cate = 0;
par = INT_MIN;
for (i = 0; i < n; i++) {
fscanf(fptr, "%d", &b);
// skip odd numbers
if ((b % 2) != 0)
continue;
// get new larger number
if (b > par) {
par = b;
cate = 1;
continue;
}
// increment count on existing largest number
if (b == par)
++cate;
}
UPDATE:
I dont understand why skip iterations explicitly instead of only picking out the iterations that matter? Is there some sort of advantage?
Yes, it's better style. It allows simple single level indented if statements that can have their own comments.
It avoids a messy compound if or a triple level if/else ladder.
IMO, it's a common misconception [particularly among beginning C programmers] that a complex if will execute faster [or is somehow "better"] than several simple ones.
The first if could be thought of a "skip this iteration" test. Here, there's only one. But, for more complex code, there might be several.
The multiple condtion escapes could be handled in a single if with if (c1 || c2 || c2 || ... || c10) continue; but that gets messy fast.
Herein, for properly indented if/else ladder logic, we'd need:
if (cond1)
do_stuff1;
else
if (cond2)
do_stuff2;
else
if (cond3)
do_stuff3;
If we're not in a loop, here's a "trick" to avoid if/else ladder logic, by using do { ... } while (0);:
do {
if (cond1) {
do_stuff1;
break;
}
if (cond2) {
do_stuff2;
break;
}
if (cond3) {
do_stuff3;
break;
}
} while (0);

enclose the condition
if( ( ...&&...) ||(....) )

The answer is because count was incremented from 0 to 1 when b = 6. 2 iterations later, b = 8 and now count = 2, and 2 iterations after that, b = 8 and count = 3.
I also recommend you nest your if statement in parentheses for readability. Commenting would help too :) I'm a stats guy, and I have no idea what you are doing based on your variables' names.
You need to reset your counter inside the if block if b > par.
Like:
if( num % 2 == 0 && num >= even) {
if (num > even){
even = num;
count = 1;
} else {
count++;
}
}
Thanks.
JK

Related

How do I generate a series of number with unique digits in C?

I've been at this problem for a day now and it feels like I'm getting nowhere.
What I want to do:
Generate all possible combinations of a nine-digit number between 1-9, but no digits can be the same. In other words, my goal is to generate exactly 362880 (9!) numbers, each one unique from one another and each number must contain only one of each digits. There should be no randomness involved.
What I want:
123456789
213796485
What I DON'T want:
111111111
113456789
What I've tried:
I start by creating an array to store the digits.
float num[9];
Using the principle that I num[0] can be any of the 9 digits, and num[8] has to be the one remaining, I tried nesting loops. I'll post the code, but there's no need to point out why it doesn't work because I already know why. However, I don't know how to fix it.
for (int a = 1; a < 10; a++) {
num[0] = a;
for (int b = 1; b < 9; b++) {
if (b != a)
num[1] = b;
// The code in between follows the same pattern
for (int i = 1; i < 2; i++) {
if (i != a && i != b && i != c && i != d && i != e && i != f && i != g && i != h) {
num[8] = i;
}
}
}
}
So as you can see, the last digit will always be 1, the second digit can never be 9 and so on.
So what options do I have? I tried making it so that it loops a total of 9^9 times, which would fix the problem I mentioned, but that's of course way too inefficient (and it didn't quite work as intended either).
Any ideas? I feel like it should be an easy thing to solve but I can't seem to be able to wrap my head around it.
Here is a simple solution that generates the 362880 permutations in lexicographical order:
#include <stdio.h>
#include <string.h>
void perm9(char *dest, int i) {
if (i == 9) {
printf("%.9s\n", dest);
} else {
for (char c = '1'; c <= '9'; c++) {
if (memchr(dest, c, i) == NULL) {
dest[i] = c;
perm9(dest, i + 1);
}
}
}
}
int main(void) {
char dest[9];
perm9(dest, 0);
return 0;
}

algorithm for finding unique any size combination of numbers in c [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I need a clean c code to find out combination of numbers.
Any number of numbers and any size of combination.
Such as for {1,2,3}
output should be {1,2,3,12,13,23,123}, note 23 and 32 as same.
Is there any clean c program for that ?
Best regards,
There are many ways of doing this. Here's a way using bit manipulation.
Let the given set be a.
The code for this is pretty small. Understand the following and you will understand how that tiny snippet of code works.
The first thing you have to realize here is that you are finding the (2n - 1) subset of the given set.
Any set has 2n subsets and here, you have excluded the null set. Hence (2n - 1)
Now, to generate these subsets we need an algorithm.
Observe the following:
001 --- 1
010 --- 2
011 --- 3
100 --- 4
101 --- 5
110 --- 6
111 --- 7
The left digits constitute the binary representation of the right decimal numbers.
If we write out for binary numbers with 4 digits, there would be 15 combinations. Notice that I am excluding the combination where all digits are zero in the above example.
In general, for n-bit binary numbers, there are (2n - 1) different combinations of the digits. We can use this to generate the subsets, in a very simple fashion.
For every element in the set, you are allowed to:
Choose the element for the current subset.
Don't choose that element for the current subset.
Leave out the situation where you choose none.
(Hence, there are (2n - 1) subsets)
Now, I say do the following:
for i in [1,2^n - 1]:
Let b = binary representation of i.
for every jth bit in b:
if the jth bit is set:
print a[j]
print a newline character.
Here is the C code:
// include your headers
int isJthBitSet(int i,int j)
{
// returns 1 if jth bit is set in the binary representation of i.
return (i & (1 << j));
}
int main()
{
int n = 3; // The size of the set for example.
int a[] = {1,2,3}; // the given set, for example.
for(int i = 1; i < (1 << n); i++) // i is from 1...2^n - 1
{
for(int j = 0; j < n; j++) // for every jth bit in the n-bit representation of i
{
if(isJthBitSet(i,j)) // if the bit is set
printf("%d ", a[j]); // print the corresponding element
}
printf("\n");
}
return 0;
}
And that would be pretty much it.
While I normally frown upon showing complete solutions, based on a few relatively recent similar questions and their answers, it seems that some examples of how to solve these types of combinatorics problems are warranted.
An easy way to construct all unique sets with k elements out of n elements, is to use k nested loops, where the loop indexes are always in increasing order. For example, to print all unique 3 char triplets, from a set of N chars, you could use
const char all[N] = ...;
char set[4];
size_t i, j, k;
set[3] = '\0'; /* End of string mark */
for (i = 0; i < N-2; i++) {
set[0] = all[i];
for (j = i+1; j < N-1; j++) {
set[1] = all[j];
for (k = j+1; k < N; k++) {
set[2] = all[k];
puts(set);
}
}
}
Now, the OP wants all unique subsets with up to k elements out of a set of n elements, which means we need cannot use nested loops as above (since we don't know the maximum k). Explicitly, anyway. Instead, we need to think of how to rewrite that.
To get a better grip on the construction, let's look at say the three-out-of-five case. The ten result sets are
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
There is clear order, and clear logic: increase the rightmost, unless it would become too large. Then, find the next index to the left that we can increment without going over (keeping enough elements for those on its right side). If we cannot increment even the leftmost without going over, we have produced all sets. (If you think about it, this is also quite a straightforward implementation of variably-nested loops.) After incrementing, set the elements to the right in ascending order.
In most cases, we'd like some sort of structure or object that keep tracks of the state and the current subset, with functions to initialize, free, and to switch to the next subset. Here is one possibility:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
typedef struct {
char *buffer; /* Symbol buffer */
size_t length; /* Number of symbols to choose */
size_t *index; /* Index of each symbol */
char *symbol; /* Array of symbols */
size_t symbols; /* Number of symbols to choose from */
} generator;
void generator_free(generator *const g)
{
if (g) {
free(g->buffer);
free(g->index);
free(g->symbol);
g->buffer = NULL;
g->length = 0;
g->index = NULL;
g->symbol = NULL;
g->symbols = 0;
}
}
const char *generator_current(generator *const g, const char *const none)
{
return (g && g->buffer) ? g->buffer : none;
}
int generator_init(generator *const g, const char *const symbol, const size_t choose)
{
const size_t symbols = (symbol) ? strlen(symbol) : 0;
size_t i;
if (!g || symbols < 1 || choose < 1 || choose > symbols)
return EINVAL;
g->buffer = malloc(choose + 1);
g->index = malloc((choose + 1) * sizeof g->index[0]);
g->symbol = malloc(symbols + 1);
if (!g->buffer || !g->index || !g->symbol) {
free(g->buffer);
free(g->index);
free(g->symbol);
g->buffer = NULL;
g->length = 0;
g->index = NULL;
g->symbol = NULL;
g->symbols = 0;
return ENOMEM;
}
memcpy(g->buffer, symbol, choose);
g->buffer[choose] = '\0';
g->length = choose;
for (i = 0; i < choose; i++)
g->index[i] = i;
g->index[choose] = symbols;
memcpy(g->symbol, symbol, symbols);
g->symbol[symbols] = '\0';
g->symbols = symbols;
return 0;
}
int generator_next(generator *const g)
{
size_t i;
if (!g || !g->buffer || g->length < 1 || !g->index)
return EINVAL;
if (g->index[0] >= g->symbols - g->length)
return ENOENT;
if (++g->index[g->length - 1] >= g->symbols) {
i = g->length - 1;
while (i > 0 && g->index[i] + 1 >= g->symbols - i)
i--;
g->index[i]++;
if (!i && g->index[0] > g->symbols - g->length) {
memset(g->buffer, '\0', g->length + 1);
return ENOENT;
}
while (i++ < g->length)
g->index[i] = g->index[i-1] + 1;
}
for (i = 0; i < g->length; i++)
g->buffer[i] = g->symbol[g->index[i]];
g->buffer[g->length] = '\0';
return 0;
}
generator_current() provides the current set (as a string). Instead of returning NULL when there is no valid set, it returns the string you specify as the second parameter. (It's just for convenience, no real reason behind this.)
generator_free() discards the generator, generator_init() initializes a new generator, and generator_next() advances the generator to the next subset.
Note that generator_init() also initializes the first subset; the one where the elements are chosen consecutively. (Although the ->symbol is only a character array containing all characters in the overall set, the function appends an end-of-string mark, so you can treat it as a string, too.)
The first if clause in generator_next() just makes sure the generator is initialized; it's just a sanity check. The second one checks if the generator is complete.
The third if clause in generator_next() increments the rightmost index, changing the last element in the subset. If it runs out of valid elements, the while loop searches for the index i for an index that can be incremented without running out of elements. Note that because the indexes are in ascending order (that ensures unique subsets), this must remember to account for the elements needed for the rest of the position.
If i becomes zero and overflows, there are no more subsets, and the ->buffer member is cleared to an empty string (just in case).
Otherwise, the second while loop fills in the indexes to the right of i with consecutive values. (See the above example for three-out-of-five, the case where the first element changes from 1 to 2, for illustration of why this is needed.)
Finally, the for loop is used to copy the elements from the ->symbol array, according to the indexes, to ->buffer.
For the askers case, the size of the subsets varies, so to generate all subsets, a loop is needed. For example:
generator g;
size_t i;
for (i = 1; i <= 2; i++) {
if (generator_init(&g, "123", i)) {
fprintf(stderr, "generator_init() failed!\n");
exit(EXIT_FAILURE);
}
do {
/* Print the set and a newline */
puts(generator_current(&g, ""));
} while (!generator_next(&g));
generator_free(&g);
}
For testing, I used the following helper function and main():
int parse_size(const char *s, size_t *const dst)
{
const char *endptr = NULL;
unsigned long value;
size_t result;
int skip = -1;
if (!s || !*s)
return EINVAL;
errno = 0;
value = strtoul(s, (char **)&endptr, 0);
if (errno)
return errno;
if (!endptr || endptr == s)
return EEXIST;
(void)sscanf(endptr, " %n", &skip);
if (skip > 0)
endptr += skip;
if (*endptr)
return EEXIST;
result = (size_t)value;
if ((unsigned long)result != value)
return EDOM;
if (dst)
*dst = result;
return 0;
}
int main(int argc, char *argv[])
{
generator g;
size_t symbols, length, len;
if (argc != 3 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s [ -h | --help ]\n", argv[0]);
fprintf(stderr, " %s DIGITS LENGTH\n", argv[0]);
fprintf(stderr, "\n");
fprintf(stderr, "This will print each unique set of LENGTH characters from DIGITS,\n");
fprintf(stderr, "one set per line.\n");
fprintf(stderr, "\n");
return EXIT_FAILURE;
}
symbols = (argv[1]) ? strlen(argv[1]) : 0;
if (symbols < 1) {
fprintf(stderr, "No DIGITS specified.\n");
return EXIT_FAILURE;
}
if (parse_size(argv[2], &length) || length < 1 || length > symbols) {
fprintf(stderr, "%s: Invalid LENGTH.\n", argv[2]);
return EXIT_FAILURE;
}
for (len = 1; len <= length; len++) {
if (generator_init(&g, argv[1], len)) {
fprintf(stderr, "Generator initialization failed.\n");
return EXIT_FAILURE;
}
do {
puts(generator_current(&g, ""));
} while (!generator_next(&g));
generator_free(&g);
}
return EXIT_SUCCESS;
}
In Linux, I prefer to compile the above using gcc -Wall -Wextra -ansi -pedantic -O2 main.c -o example. The original question asked for
./example 123 2
which outputs
1
2
3
12
13
23
A larger example is much more interesting. For example,
./example 12345 3
lists all one, two, and three-digit sets from the set of first five digits. The output is
1
2
3
4
5
12
13
14
15
23
24
25
34
35
45
123
124
125
134
135
145
234
235
245
345
Questions?

Optimizing I/O(Output) in C code + a loop

I have a code which reads around (10^5) int(s) from stdin and then after performing ## i output them on stdout. I have taken care of the INPUT part by using "setvbuf" & reading lines using "fgets_unlocked()" and then parsing them to get the required int(s).
I have 2 issues which i am not able to come over with:
1.) As i am printing int(s) 5 million on stdout its taking lot of time : IS THERE ANY WAY TO REDUCE THIS( i tried using fwrite() but the o/p prints unprintable characters due to the reason using fread to read into int buffer)
2.) After parsing the input for the int(s) say 'x' i actually find the no of divisors by doing %(mod) for the no in a loop.(See in the code below): Maybe this is also a reason for my code being times out:
Any suggestions on this to improved.
Many thanks
This is actually a problem from http://www.codechef.com/problems/PD13
# include <stdio.h>
# define SIZE 32*1024
char buf[SIZE];
main(void)
{
int i=0,chk =0;
unsigned int j =0 ,div =0;
int a =0,num =0;
char ch;
setvbuf(stdin,(char*)NULL,_IOFBF,0);
scanf("%d",&chk);
while(getchar_unlocked() != '\n');
while((a = fread_unlocked(buf,1,SIZE,stdin)) >0)
{
for(i=0;i<a;i++)
{
if(buf[i] != '\n')
{
num = (buf[i] - '0')+(10*num);
}
else
if(buf[i] == '\n')
{
div = 1;
for(j=2;j<=(num/2);j++)
{
if((num%j) == 0) // Prob 2
{
div +=j;
}
}
num = 0;
printf("%d\n",div); // problem 1
}
}
}
return 0;
}
You can print far faster than printf.
Look into itoa(), or write your own simple function that converts integers to ascii very quickly.
Here's a quick-n-dirty version of itoa that should work fast for your purposes:
char* custom_itoa(int i)
{
static char output[24]; // 64-bit MAX_INT is 20 digits
char* p = &output[23];
for(*p--=0;i/=10;*p--=i%10+0x30);
return ++p;
}
note that this function has some serious built in limits, including:
it doesn't handle negative numbers
it doesn't currently handle numbers greater than 23-characters in decimal form.
it is inherently thread-dangerous. Do not attempt in a multi-threaded environment.
the return value will be corrupted as soon as the function is called again.
I wrote this purely for speed, not for safety or convenience.
Version 2 based on suggestion by #UmNyobe and #wildplasser(see above comments)
The code execution took 0.12 seconds and 3.2 MB of memory on the online judge.
I myself checked with 2*10^5 int(input) in the range from 1 to 5*10^5 and the execution took:
real 0m0.443s
user 0m0.408s
sys 0m0.024s
**Please see if some more optimization can be done.
enter code here
/** Solution for the sum of the proper divisor problem from codechef **/
/** # author dZONE **/
# include <stdio.h>
# include <math.h>
# include <stdlib.h>
# include <error.h>
# define SIZE 200000
inline int readnum(void);
void count(int num);
int pft[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709};
unsigned long long int sum[SIZE];
int k = 0;
inline int readnum(void)
{
int num = 0;
char ch;
while((ch = getchar_unlocked()) != '\n')
{
if(ch >=48 && ch <=57)
{
num = ch -'0' + 10*num;
}
}
if(num ==0)
{
return -1;
}
return num;
}
void count(int num)
{
unsigned int i = 0;
unsigned long long tmp =0,pfac =1;
int flag = 0;
tmp = num;
sum[k] = 1;
for(i=0;i<127;i++)
{
if((tmp % pft[i]) == 0)
{
flag =1; // For Prime numbers not in pft table
pfac =1;
while(tmp % pft[i] == 0)
{
tmp =tmp /pft[i];
pfac *= pft[i];
}
pfac *= pft[i];
sum[k] *= (pfac-1)/(pft[i]-1);
}
}
if(flag ==0)
{
sum[k] = 1;
++k;
return;
}
if(tmp != 1) // For numbers with some prime factors in the pft table+some prime > 705
{
sum[k] *=((tmp*tmp) -1)/(tmp -1);
}
sum[k] -=num;
++k;
return;
}
int main(void)
{
int i=0,terms =0,num = 0;
setvbuf(stdin,(char*)NULL,_IOFBF,0);
scanf("%d",&terms);
while(getchar_unlocked() != '\n');
while(terms--)
{
num = readnum();
if(num ==1)
{
continue;
}
if(num == -1)
{
perror("\n ERROR\n");
return 0;
}
count(num);
}
i =0;
while(i<k)
{
printf("%lld\n",sum[i]);
++i;
}
return 0;
}
//Prob 2 Is your biggesr issue right now.... You just want to find the number of divisors?
My first suggestion will be to cache your result to some degree... but this requires potentially twice the amount of storage you have at the beginning :/.
What you can do is generate a list of prime numbers before hand (using the sieve algorithm). It will be ideal to know the biggest number N in your list and generate all primes till his square root. Now for each number in your list, you want to find his representation as product of factors, ie
n = a1^p1 * a1^p2 *... *an^pn
Then the sum of divisors will be.
((a1^(p1+1) - 1)/(a1 - 1))*((a2^(p2+1) - 1)/(a2-1))*...*((an^(pn+1) - 1)/(an-1))
To understand you have (for n = 8) 1+ 2 + 4 + 8 = 15 = (16 - 1)/(2 - 1)
It will drastically improve the speed but integer factorization (what you are really doing) is really costly...
Edit:
In your link the maximum is 5000000 so you have at most 700 primes
Simple decomposition algorithm
void primedecomp(int number, const int* primetable, int* primecount,
int pos,int tablelen){
while(pos < tablelen && number % primetable[pos] !=0 )
pos++;
if(pos == tablelen)
return
while(number % primetable[pos] ==0 ){
number = number / primetable[pos];
primecount[pos]++;
}
//number has been modified
//too lazy to write a loop, so recursive call
primedecomp(number,primetable,primecount, pos+1,tablelen);
}
EDIT : rather than counting, compute a^(n+1) using primepow = a; primepow = a*primepow;
It will be much cleaner in C++ or java where you have hashmap. At the end
primecount contains the pi values I was talking about above.
Even if it looks scary, you will create the primetable only once. Now this algorithm
run in worst case in O(tablelen) which is O(square root(Nmax)). your initial
loop ran in O(Nmax).

UVA's 3n+1 wrong answer although the test cases are correct . . .?

UVA problem 100 - The 3n + 1 problem
I have tried all the test cases and no problems are found.
The test cases I checked:
1 10 20
100 200 125
201 210 89
900 1000 174
1000 900 174
999999 999990 259
But why I get wrong answer all the time?
here is my code:
#include "stdio.h"
unsigned long int cycle = 0, final = 0;
unsigned long int calculate(unsigned long int n)
{
if (n == 1)
{
return cycle + 1;
}
else
{
if (n % 2 == 0)
{
n = n / 2;
cycle = cycle + 1;
calculate(n);
}
else
{
n = 3 * n;
n = n + 1;
cycle = cycle+1;
calculate(n);
}
}
}
int main()
{
unsigned long int i = 0, j = 0, loop = 0;
while(scanf("%ld %ld", &i, &j) != EOF)
{
if (i > j)
{
unsigned long int t = i;
i = j;
j = t;
}
for (loop = i; loop <= j; loop++)
{
cycle = 0;
cycle = calculate(loop);
if(cycle > final)
{
final = cycle;
}
}
printf("%ld %ld %ld\n", i, j, final);
final = 0;
}
return 0;
}
The clue is that you receive i, j but it does not say that i < j for all the cases, check for that condition in your code and remember to always print in order:
<i>[space]<j>[space]<count>
If the input is "out of order" you swap the numbers even in the output, when it is clearly stated you should keep the input order.
Don't see how you're test cases actually ever worked; your recursive cases never return anything.
Here's a one liner just for reference
int three_n_plus_1(int n)
{
return n == 1 ? 1 : three_n_plus_1((n % 2 == 0) ? (n/2) : (3*n+1))+1;
}
Not quite sure how your code would work as you toast "cycle" right after calculating it because 'calculate' doesn't have explicit return values for many of its cases ( you should of had compiler warnings to that effect). if you didn't do cycle= of the cycle=calculate( then it might work?
and tying it all together :-
int three_n_plus_1(int n)
{
return n == 1 ? 1 : three_n_plus_1((n % 2 == 0) ? (n/2) : (3*n+1))+1;
}
int max_int(int a, int b) { return (a > b) ? a : b; }
int min_int(int a, int b) { return (a < b) ? a : b; }
int main(int argc, char* argv[])
{
int i,j;
while(scanf("%d %d",&i, &j) == 2)
{
int value, largest_cycle = 0, last = max_int(i,j);
for(value = min_int(i,j); value <= last; value++) largest_cycle = max_int(largest_cycle, three_n_plus_1(value));
printf("%d %d %d\r\n",i, j, largest_cycle);
}
}
Part 1
This is the hailstone sequence, right? You're trying to determine the length of the hailstone sequence starting from a given N. You know, you really should take out that ugly global variable. It's trivial to calculate it recursively:
long int hailstone_sequence_length(long int n)
{
if (n == 1) {
return 1;
} else if (n % 2 == 0) {
return hailstone_sequence_length(n / 2) + 1;
} else {
return hailstone_sequence_length(3*n + 1) + 1;
}
}
Notice how the cycle variable is gone. It is unnecessary, because each call just has to add 1 to the value computed by the recursive call. The recursion bottoms out at 1, and so we count that as 1. All other recursive steps add 1 to that, and so at the end we are left with the sequence length.
Careful: this approach requires a stack depth proportional to the input n.
I dropped the use of unsigned because it's an inappropriate type for doing most math. When you subtract 1 from (unsigned long) 0, you get a large positive number that is one less than a power of two. This is not a sane behavior in most situations (but exactly the right one in a few).
Now let's discuss where you went wrong. Your original code attempts to measure the hailstone sequence length by modifying a global counter called cycle. However, the main function expects calculate to return a value: you have cycle = calculate(...).
The problem is that two of your cases do not return anything! It is undefined behavior to extract a return value from a function that didn't return anything.
The (n == 1) case does return something but it also has a bug: it fails to increment cycle; it just returns cycle + 1, leaving cycle with the original value.
Part 2
Looking at the main. Let's reformat it a little bit.
int main()
{
unsigned long int i=0,j=0,loop=0;
Change these to long. By the way %ld in scanf expects long anyway, not unsigned long.
while (scanf("%ld %ld",&i,&j) != EOF)
Be careful with scanf: it has more return values than just EOF. Scanf will return EOF if it is not able to make a conversion. If it is able to scan one number, but not the second one, it will return 1. Basically a better test here is != 2. If scanf does not return two, something went wrong with the input.
{
if(i > j)
{
unsigned long int t=i;i=j;j=t;
}
for(loop=i;loop<=j;loop++)
{
cycle=0;
cycle=calculate(loop );
if(cycle>final)
{
final=cycle;
}
}
calculate is called hailstone_sequence_length now, and so this block can just have a local variable: { long len = hailstone_sequence_length(loop); if (len > final) final = len; }
Maybe final should be called max_length?
printf("%ld %ld %ld\n",i,j,final);
final=0;
final should be a local variable in this loop since it is separately used for each test case. Then you don't have to remember to set it to 0.
}
return 0;
}

C Arrays and unbroken lists

/edit: thanks for the help so far, however I haven't got any of the solutions to take the sample input and give the sample output. My description isn't the clearest, sorry.
I have an array composed of binary data. What I want to do is determine how long each unbroken segment of 1s or 0s is.
Say I have this data:
0111010001110
In an array binaryArray which I need to translate to:
0100110
stored in nwArray where 0 represents a narrow (less than 3 digits long) and 1 represents wide (>3 digits long). I am not concerned with the binary value but with the length of each component. I'm not sure if that explanation makes sense.
This is what I have; it doesn't work, I can see why, but I can't think of a good solution.
for(x=0;x<1000;x++){
if(binaryArray[x]==binaryArray[x+1]){
count++;
if(count>=3){
nwArray[y]=1;
y++;
count=0;
}
}else{
if(barcodeArray[x]){
nwArray[y]=0;
}
}
}
Does this do it?
int count = 0;
for (x=0; x<1000;x++)
{
if (binaryArray[x] != binaryArray[x+1])
{
if (count < 3)
nwArray[y]=0;
else
nwArray[y]=1;
y++;
count = 0;
}
else
count++;
}
One problem you have is that you compare count with 3 too early. Wait until you see a change in the bitstream. Try a while loop until the bit flips then compare the count.
Modified #MikeW's answer:
int count = 0;
int nwSize = 0;
const int ilast = SIZEOF(binaryArray) - 1;
for (int i = 0; i <= ilast; ++i)
if (i == ilast || binaryArray[i] != binaryArray[i+1]) {
nwArray[nwSize++] = (count > 1); /* true for '1110'; false for '110' */
count = 0;
}
else
++count;
assert(count == 0);

Resources