recursive function C ranking - c

#include <stdio.h>
#include <stdlib.h>
int cnt = 0; Count // global variable declaration
int find_max(int n, int arr[]); // (Recursive) function declaration circulation
int main() {
// Insert code here ...
int number; // Generate sequence number
int * score; // Declare the game
int i; // Loop variable
int max; // Function return value
scanf("% d \ n", &number); // Input (number of sequence)
score = (int *)malloc(sizeof(int) * number); // Allocate memory scores
for (i = 0; i < number; i++) {
scanf("% d", &score[i]);
} // Scores input
max = find_max(number, score); // Recursive function call.
printf("% d% d \ n", max, cnt); // Count value and second value, etc.
return 0;
}
int find_max(int n, int arr[]) {
int maxnum1 = 0; // Maximum value of the partial sequence 1
int maxnum2 = 0; // Maximum value of the partial sequence 2
int max = 0; // Maximum value
int secondMax = 0; // 2 deunggap
int * s1, *s2, sn1, sn2; // Memory allocation variables
int i, j; // Loop variable
cnt++; // If the sequence number is not zero and the count + 1.
if (n == 1) {
return arr[0]; // The number of returns a value of 1 when the sequence.
}
else if (n % 2 == 0) {// if even
s1 = (int *)malloc(sizeof(int) * n / 2); // Split assignment
for (i = 0; i < n / 2; i++) {
s1[i] = arr[i];
} // Where assigned sequences into storage
sn1 = n / 2;
s2 = (int *)malloc(sizeof(int) * n / 2); // Split assignment
for (j = 0; j < n / 2; j++)
{
s2[j] = arr[i];
i++;
} // Where assigned sequences into storage
sn2 = n / 2;
}
else {
s1 = (int *)malloc(sizeof(int) * (n + 1) / 2); // Split assignment
for (i = 0; i < ((n + 1) / 2); i++) {
s1[i] = arr[i];
} // Where assigned sequences into storage
sn1 = ((n + 1) / 2);
i = ((n + 1) / 2);
s2 = (int *)malloc(sizeof(int) * (n - 1) / 2); // Split assignment
for (j = 0; j < ((n - 1) / 2); j++)
{
s2[j] = arr[i];
i++;
} // Where assigned sequences into storage
sn2 = ((n - 1) / 2);
}
maxnum1 = find_max(sn1, s1); // Partial recursive sequence maximum value twirl
maxnum2 = find_max(sn2, s2); // Partial recursive sequence maximum value twirl
for (i = 0; i < n; i++) {
// If the value of the current index is greater than the maximum value
if (arr[i] > = max) {
// Sets the maximum value previously stored before the update of the maximum value.
secondMax = max;
// Maximum updates
max = arr[i];
}
else if ((arr[i] > secondMax && arr[i] < max) || max == secondMax) {// if the value is greater than ten thousand and one memories of the calculated value max
secondMax = arr[i];
}
}
if (secondMax == 0) {
return max;
}
else {
return secondMax; // 2 deunggap return
}
}
I'll use recursive function in c, ranking for second. not first.
but, input and output are
4
9 0 0 0
9(score) 7(recursive function count)
However , output is 9. I don't want to this result.
Not first, second is 0
Correct result is 0 7.
How do i for correct result 0 7.
help me please.

This is an extraordinarily complicated way of finding the second highest integer in an array, but I think the problem is here. The second highest value is 0, but you discard it in favour of the highest value. If you had initialised max and secondMax to -1 (and test for -1) that would solve it.
if (secondMax == 0) {
return max;
}
else {
return secondMax;
}
Here is a simpler way:
#include<stdio.h>
#include<limits.h>
int main(void)
{
int i, max1 = INT_MIN, max2 = INT_MIN;
int score[] = { 9, 0, 0, 0 };
int number = sizeof(score) / sizeof(score[0]);
for (i=0; i<number; i++) {
if (max1 < score[i])
max1 = score[i];
if (max2 < score[i] && max1 > score[i])
max2 = score[i];
}
if (max2 == INT_MIN)
max2 = max1;
printf ("max1 = %d, max2 = %d\n", max1, max2);
return 0;
}
Program output:
max1 = 9, max2 = 0

The problem is that secondMax and max are initialized with a number you can find in the array.
You can avoid this problem by using the first number in the array to initialize max and secondMax, and then start the loop with the second number of the array. The last loop of you function could be:
max = arr[0];
secondMax = max;
for (i = 1; i < n; i++) {
// If the value of the current index is greater than the maximum value
if (arr[i] > = max) {
// Sets the maximum value previously stored before the update of the maximum value.
secondMax = max;
// Maximum updates
max = arr[i];
}
else if ((arr[i] > secondMax && arr[i] < max) || max == secondMax) {// if the value is greater than ten thousand and one memories of the calculated value max
secondMax = arr[i];
}
}
if (secondMax == max) {
return max;
}
else {
return secondMax; // 2 deunggap return
}

Related

How to fix 'time limit exceeded' in some test cases when using the for loop?

We have a series of numbers which is the sum of numbers from 1 to n.(1,3,6,10,...)
The question wants me to find the smallest number in this series which has k divisors.
My code works properly on all test cases but it exceeds the time limits.
It has one while loop and one for loop inside it.
int main()
{
int k, sum, counter = 0, n = 1;
scanf("%d", &k);
while (counter != k) {
counter = 0;
sum = n*(n + 1) / 2; //sum of numbers from 1 to n.(formula)
for (int i = 1; i <= sum / 2; i++) //counts the divisors
if (sum%i == 0)counter++;
counter++; //adds one to the counter because of number 1
n++;
}
printf("%d",sum);
return 0;
}
And here is a example:
Input:k=4
Output:6
What should I do to have a faster and better program?
Did not find a good dup. Here is a solution with O(sqrt(n)) complexity. It's taken from https://www.geeksforgeeks.org/count-divisors-n-on13/
// function to count the divisors
int countDivisors(int n)
{
int cnt = 0;
for (int i = 1; i <= sqrt(n); i++) {
if (n % i == 0) {
// If divisors are equal,
// count only one
if (n / i == i)
cnt++;
else // Otherwise count both
cnt = cnt + 2;
}
}
return cnt;
}
On the same site, there is one that runs in O(n^(1/3)) that is slightly more complex. It's for C++, but just add #include <stdbool.h> and it should work.
void SieveOfEratosthenes(int n, bool prime[],
bool primesquare[], int a[])
{
// Create a boolean array "prime[0..n]" and initialize all entries as
// true. A value in prime[i] will finally be false if i is Not a prime,
// else true.
for (int i = 2; i <= n; i++)
prime[i] = true;
// Create a boolean array "primesquare[0..n*n+1]" and initialize all
// entries it as false. A value in squareprime[i] will finally be true
// if i is square of prime, else false.
for (int i = 0; i <= (n * n + 1); i++)
primesquare[i] = false;
// 1 is not a prime number (Look it up if you doubt it)
prime[1] = false;
for (int p = 2; p * p <= n; p++) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true) {
// Update all multiples of p
for (int i = p * 2; i <= n; i += p)
prime[i] = false;
}
}
int j = 0;
for (int p = 2; p <= n; p++) {
if (prime[p]) {
// Storing primes in an array
a[j] = p;
// Update value in primesquare[p*p], if p is prime.
primesquare[p * p] = true;
j++;
}
}
}
// Function to count divisors
int countDivisors(int n)
{
// If number is 1, then it will have only 1
// as a factor. So, total factors will be 1.
if (n == 1)
return 1;
bool prime[n + 1], primesquare[n * n + 1];
int a[n]; // for storing primes upto n
// Calling SieveOfEratosthenes to store prime factors of n and to store
// square of prime factors of n
SieveOfEratosthenes(n, prime, primesquare, a);
// ans will contain total number of distinct divisors
int ans = 1;
// Loop for counting factors of n
for (int i = 0;; i++) {
// a[i] is not less than cube root n
if (a[i] * a[i] * a[i] > n)
break;
// Calculating power of a[i] in n.
int cnt = 1; // cnt is power of prime a[i] in n.
while (n % a[i] == 0) // if a[i] is a factor of n
{
n = n / a[i];
cnt = cnt + 1; // incrementing power
}
// Calculating number of divisors. If n = a^p * b^q then total
// divisors of n are (p+1)*(q+1)
ans = ans * cnt;
}
// if a[i] is greater than cube root of n
// First case
if (prime[n])
ans = ans * 2;
// Second case
else if (primesquare[n])
ans = ans * 3;
// Third casse
else if (n != 1)
ans = ans * 4;
return ans; // Total divisors
}
If the above is not enough, you should look into some kind of dynamic programming. Both of the above method is calculating each number from scratch. But if you're going to do it for several numbers, it is quite possible that you can use information from previous numbers. Just to give an idea for how it works, here is an algorithm calculating all primes from 2 to n:
#include <stdbool.h>
#include <stdio.h>
#include <math.h>
// After running this function, prime[n] will be true iff n is a prime
void createPrimeArray(bool *prime, size_t size)
{
prime[0] = prime[1] = false;
for(size_t i=2; i<size; i++)
prime[i] = true;
for(size_t i=2; i<sqrt(size); i++) {
size_t j=i;
while(!prime[j])
j++;
for(size_t k=2*j; k<size; k+=j)
prime[k] = false;
}
}
int main(void)
{
bool prime[200];
createPrimeArray(prime, 200);
for(int i=0; i<200; i++) {
if(prime[i])
printf("%d ", i);
}
}
The above can possibly be optimized further. It's purpose is to show how you can reuse information. After the first run in the second for loop in createPrimeArray we have marked all numbers that are dividable by 2 as non-primes, and thus we don't have to care about those anymore.

Smallest odd number in given array

This code is supposed to find the smallest odd number in given array and store it in min but when I try to print min it always prints 0.
int smallestodd(int x[5]){
int j;
int k[5];
int p = 0;
int r = 0;
for(int h =0; h<5;h++){
j = x[h] % 2;
if(j == 1){
int temp =x[h];
k[p] =temp;
p++;
}
}
int min = k[0];
while(k[r] !=0){
if(k[r] < min ){
min = k[r];
r++;
}
}
return min;
}
Assuming there is an odd number in the array -- let's say trying to find the minimum odd number in an array with just even numbers (or no numbers) is UB :)
index = 0;
while (arr[index] % 2 == 0) index++; // skip even numbers
min = arr[index++]; // first odd number
while (index < length) {
if (arr[index] % 2) {
if (arr[index] < min) min = arr[index];
}
index++;
}
this code avoid overflow in search and return 1 when found or 0 if array has only even numbers.
int getMinOdd(int arr[], int length, int *value) {
int found = 0;
for(int idx=0; idx < length; idx++) {
if (arr[idx] % 2) {
if (!found || *value > arr[idx]) {
*value = arr[idx];
}
found = 1;
}
}
return found;
}
It's quite simple actually. You need to just check 2 conditions on your array.
int smallestOdd(int arr[]){
int min = 99999; //Some very large number
for(int i = 0; i < (length of your array); i++) {
if(arr[i]%2 != 0 && arr[i] < min) { //Check if number is odd and less than the current minimum value
min = arr[i];
}
}
return min;
}
Use this using statement as first :
Using System Linq;
Console.WriteLine(myArray.Where(i => i%2 == 1).Min());

Can't print out sociable numbers properly

I have a code that finds the sum of the divisors of a number, but I can't get it to apply on my increasing n and print all the numbers respectively.
The code is
long div(int n) {
long sum = 0;
int square_root = sqrt(n);
for (int i = 1; i <= square_root; i++) {
if (n % i == 0) {
sum += i;
if (i * i != n) {
sum += n / i;
}
}
}
return sum - n;
}
On my main() I need to have a c number that starts from 1 and goes to my MAXCYC which is 28. The n goes from 2 to MAXNUM which is 10000000. The program needs to find all perfect, amicable and sociable numbers and print them with their respective pairs.
Sample output:
Cycle of length 2: 12285 14595 12285
Cycle of length 5: 12496 14288 15472 14536 14264 12496
for (int n = 2; n <= MAXNUM; n++) {
long sum = div(n);
long res = div(sum);
if (res <= MAXNUM) { // Checking if the number is just sociable
int c = 0;
while (c <= MAXCYC && n != res) {
res = div(sum);
c++;
}
if (c <= MAXCYC) {
printf("Cycle of length %d: ", c);
printf("%ld ", sum);
do {
printf("%ld ", res);
res = div(res);
}
while (sum < res);
printf("%ld ", sum);
c += c - 2;
printf("\n");
}
}
}
I only get pairs of cycle length of 1, 2 and nothing above that. Also it doesn't even print it correctly since it says Cycle of length 0: in all of the results without increasing. I think the problem is in the f before the first print but I can't get it to work in a way that as long as my
(n == sum) it prints Cycle of length 1: x x pairs
(n == res && sum < res) it prints Cycle of length 2: x y x pairs
(res <= MAXNUM) it prints Cycle of length c: x y z ... x (c amount of pairs including first x)
What do you guys think I should change?
Ok, this code should work if I understood well your requirement.
#include <stdio.h>
#include <stdlib.h>
int div_sum(int n)
{
long sum = 0;
int square_root = sqrt(n);
for (int i = 1; i <= square_root; i++)
{
if (n % i == 0)
{
sum += i;
if (i * i != n)
{
sum += n / i;
}
}
}
return sum - n;
}
int MAX_N = 10000000;
int MAX_CYCLES = 28;
int main()
{
int cycles;
for(int n = 2; n < MAX_N; n++){
int found = 0;
for(int c = 1; !found && c <= MAX_CYCLES; c++){
cycles = c;
int aliquote = n;
while(cycles--) aliquote = div_sum(aliquote);
//it is a cycle of length c
cycles = c;
if(n == aliquote){
printf("Cycle of length %d: %d", c, n);
while(cycles--){
aliquote = div_sum(aliquote);
printf(" %d", aliquote);
}
printf("\n");
found = 1;
}
}
}
return 0;
}

Return which digit occurs the most times

I have to return which digit in a number occurs the most frequently ( though not how many times it occurs )
So far I can only get this, I don't know how to isolate the digit, only to show how many times each digit occurs.
#include <stdio.h>
int frequentDigit(int);
int main()
{
frequentDigit(123032333);
return 0;
}
int frequentDigit(int arg)
{
int tmp; int i; int myArr[9] = { 0 };
tmp = (arg < 0) ? -arg : arg;
do
{
myArr[tmp % 10]++;
tmp /= 10;
} while (tmp != 0);
for (i = 0; i < 9; i++) { printf("\nThere are %d occurances of digit %d", myArr[i], i); }
}
The array where you are storing the frequency of the digits, i.e myArr[]. Its suppose to hold the frequency of all the number from 0...9. And since there are 10 numbers, you would need an array of lenght 10.
int myArr[10];
Later, you need to traverse through the array once, checking for the max element, and saving the index accordingly, to find which number has occured most number of times.
To traverse, the for loop should go till 9
for (i = 0; i <= 9; i++)
Edited
As someone commented, you can find the max value while you are computing the frequencies itself.
int max = -1, max_num = -1;
do
{
myArr[tmp % 10]++;
if( myArr[tmp % 10] > max)
{
max = myArr[tmp % 10];
max_num = tmp % 10;
}
tmp /= 10;
} while (tmp != 0);
printf("%d", max_num);
Its simple. At the end of your code you have an array of frequencies, if you find the max of that you get the most common element
Just use a loop to find the max and print that:
int max = myArr[0]; // start with max = first element
int max_position=0;
for(int i = 1; i<9; i++)
{
if(myArr[i] > max){
max = myArr[i];
max_position=i;
}
}
printf("\The max is %d occuring %d times ", max_position, max_position)

Project Euler Problem 4

I've created a solution to problem 4 on Project Euler.
However, what I find is that placing the print statement (that prints the answer) in different locations prints different answers. And for some reason, the highest value of result is 580085. Shouldn't it be 906609? Is there something wrong with my isPalindrome() method?
#include <stdio.h>
#include <stdbool.h>
int isPalindrome(int n);
//Find the largest palindrome made from the product of two 3-digit numbers.
int main(void)
{
int i = 0;
int j = 0;
int result = 0;
int palindrome = 0;
int max = 0;
//Each iteration of i will be multiplied from j:10-99
for(i = 100; i <= 999; i++)
{
for(j = 100; j <= 999; j++)
{
result = i * j;
if(isPalindrome(result) == 0)
{
//printf("Largest Palindrome: %d\n", max); //906609
//printf("Result: %d\n", result); //580085
if(result > max)
{
max = result;
//printf("Largest Palindrome: %d\n", max); //927340
}
printf("Largest Palindrome: %d\n", max); //906609
}
}
}
//printf("Largest Palindrome: %d\n", max); //998001
system("PAUSE");
return 0;
} //End of main
//Determines if number is a palindrome
int isPalindrome(int num)
{
int n = num;
int i = 0;
int j = 0;
int k = 0;
int count = 0;
int yes = 0;
//Determines the size of numArray
while(n/10 != 0)
{
n%10;
count++;
n = n/10;
}
int numArray[count];
//Fill numArray with each digit of num
for(i = 0; i <= count; i++)
{
numArray[i] = num%10;
//printf("%d\n", numArray[i]);
num = num/10;
}
//Determines if num is a Palindrome
while(numArray[k] == numArray[count])
{
k = k + 1;
count = count - 1;
yes++;
}
if(yes >= 3)
{
return 0;
}
}//End of Function
I remember doing that problem a while ago and I simply made a is_palindrome() function and brute-forced it. I started testing from 999*999 downwards.
My approach to detect a palindrome was rather different from yours. I would convert the given number to a string and compare the first char with the nth char, second with n-1 and so on.
It was quite simple (and might be inefficient too) but the answer would come up "instantly".
There is no problem in the code in finding the number.
According to your code fragment:
.
.
}
printf("Largest Palindrome: %d\n", max); //906609
}
}
}
//printf("Largest Palindrome: %d\n", max); //998001
system("PAUSE");
.
.
.
you get the result as soon as a palindrome number is found multiplying the number downwards.
You should store the palindrome in a variable max and let the code run further as there is a possibility of finding a greater palindrome further.
Note that for i=800,j=500, then i*j will be greater when compare with i=999,j=100.
Just understand the logic here.
A few issues in the isPalindrome function :
the first while loop doesn't count the number of digits in the number, but counts one less.
as a result, the numArray array is too small (assuming that your compiler supports creating the array like that to begin with)
the for loop is writing a value past the end of the array, at best overwriting some other (possibly important) memory location.
the second while loop has no properly defined end condition - it can happily compare values past the bounds of the array.
due to that, the value in yes is potentially incorrect, and so the result of the function is too.
you return nothing if the function does not detect a palindrome.
//Determines if number is a palindrome
bool isPalindrome(int num) // Change this to bool
{
int n = num;
int i = 0;
int j = 0;
int k = 0;
int count = 1; // Start counting at 1, to account for 1 digit numbers
int yes = 0;
//Determines the size of numArray
while(n/10 != 0)
{
// n%10; <-- What was that all about!
count++;
n = n/10;
}
int numArray[count];
//Fill numArray with each digit of num
for(i = 0; i < count; i++) // This will crash if you use index=count; Array indices go from 0 to Size-1
{
numArray[i] = num%10;
//printf("%d\n", numArray[i]);
num = num/10;
}
//Determines if num is a Palindrome
/*
while(numArray[k] == numArray[count-1]) // Again count-1 not count; This is really bad though what if you have 111111 or some number longer than 6. It might also go out of bounds
{
k = k + 1;
count = count - 1;
yes++;
}
*/
for(k = 1; k <= count; k++)
{
if(numArray[k-1] != numArray[count-k])
return false;
}
return true;
}//End of Function
That's all I could find.
You also need to change this
if(isPalindrome(result) == 0)
To
if(isPalindrome(result))
The Code's Output after making the modifications: Link
The correct printf is the one after the for,after you iterate through all possible values
You are using int to store the value of the palidrome but your result is bigger then 65536,
you should use unsigned
result = i * j;
this pice of code is wrong :
while(n/10 != 0) {
n%10;
count++;
n = n/10;
}
it should be:
while(n != 0) {
count++;
n = n/10;
}
As well as the changes that P.R sugested.
You could do something like this to find out if the number is palindrome:
int isPalindrom(unsigned nr) {
int i, len;
char str[10];
//convert number to string
sprintf(str, "%d", nr);
len = strlen(str);
//compare first half of the digits with the second half
// stop if you find two digits which are not equal
for(i = 0; i < len / 2 && str[i] == str[len - i - 1]; i++);
return i == len / 2;
}
I converted the number to String so I'd be able to go over the number as a char array:
private static boolean isPalindrom(long num) {
String numAsStr = String.valueOf(num);
char[] charArray = numAsStr.toCharArray();
int length = charArray.length;
for (int i = 0 ; i < length/2 ; ++i) {
if (charArray[i] != charArray[length - 1 - i]) return false;
}
return true;
}
I got correct answer for the problem, but I want to know is my coding style is good or bad from my solution. I need to know how can I improve my coding,if it is bad and more generic way.
#include<stdio.h>
#define MAX 999
#define START 100
int main()
{
int i,j,current,n,prev = 0;
for(i = START;i<=MAX;i++)
{
for(j=START;j<=MAX;j++)
{
current = j * i;
if(current > prev) /*check the current value so that if it is less need not go further*/
{
n = palindrome(current);
if (n == 1)
{
printf("The palindrome number is : %d\n",current);
prev = current; // previous value is updated if this the best possible value.
}
}
}
}
}
int palindrome(int num)
{
int a[6],temp;
temp = num;
/*We need a array to store each element*/
a[5] = temp % 10;
a[4] = (temp/10) %10;
a[3] = (temp/100) %10;
a[2] = (temp/1000) %10;
a[1] = (temp/10000) %10;
if(temp/100000 == 0)
{
a[0] = 0;
if(a[1] == a[5] && a[2] == a[4])
return 1;
}
else
{
a[0] = (temp/100000) %10;
if(a[0] == a[5] && a[1] == a[4] && a[2] == a[3])
return 1;
else
return 0;
}
}
No, the largest should be: 906609.
Here is my program:
def reverse_function(x):
return x[::-1]
def palindrome():
largest_num = max(i * x
for i in range(100, 1000)
for x in range(100, 1000)
if str(i * x) == reverse_function(str(i * x)))
return str(largest_num)
print(palindrome())

Resources