Logic of Ugly Numbers in C - c

Following from here, I am trying to develop my own logic to generate a sequence of ugly numbers. But every time all the numbers are printed.
I am determining if the first 3 prime factors of the number are 2, 3 and 5 and placing them in a count variable determining the total count of prime factors of a number x.
If the count is greater than 3, the number is not ugly.
Here is the code:
/* To generate a sequence of Ugly numbers
Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, …
shows the first 11 ugly numbers. By convention, 1 is included.
*/
#include<stdio.h>
#include<math.h>
int isprime(int x)
{
int i;
for(i=2;i<=sqrt(x);i++)
if(x%i==0)
return 0;
return 1;
}
int isUgly(int x)
{
int count=0; //To maintain the count of the prime factors. If count > 3, then the number is not ugly
int i;
for(i=2;i<=sqrt(x);i++)
{
if(isprime(i) && x%i==0)
{
count++;
if(count > 3)
return 0; // Not ugly
}
}
return 1;
}
int main(void)
{
int i,n=10;
printf("\n The ugly numbers upto %d are : 1 ",n);
for(i=2;i<=n;i++)
{
if(isUgly(i))
printf(" %d ",i);
}
return 0;
}

Here's a version of isUgly() that seems to work for me.
int isUgly(int x)
{
int i;
static int factors[] = {2, 3, 5};
// Boundary case...
// If the input is 2, 3, or 5, it is an ugly number.
for ( i = 0; i < 3; ++i )
{
if ( factors[i] == x )
{
return 1;
}
}
if ( isprime(x) )
{
// The input is not 2, 3, or 5 but it is a prime number.
// It is not an ugly number.
return 0;
}
// The input is not a prime number.
// If it is divided by 2, 3, or 5, call the function recursively.
for ( i = 0; i < 3; ++i )
{
if ( x%factors[i] == 0 )
{
return isUgly(x/factors[i]);
}
}
// If the input not a prime number and it is not divided by
// 2, 3, or 5, then it is not an ugly number.
return 0;
}

Try this one:
#include<stdio.h>
long int n, count=1;
void check(long int i)
{
if(i==1){
++count;
return;
}
else if(i%2==0)
check(i/2);
else if(i%3==0)
check(i/3);
else if(i%5==0)
check(i/5);
else
return;
}
void main(){
for(n=1;;n++){
check(n);
if(count==1000){
printf("%ldth no is %ld\n",count,n);
break;
}
}
}

Related

What is wrong with my code here? I am getting the right output for test cases, I tested for different self made test cases, it passes those also

I was tring to solve this question, "You are given an integer N. Consider the sequence containing the integers {1, 2,....,N} in increasing order (each exactly once). Find the maximum length of its contiguous subsequence with an even sum.
This is the code that I came up with,
#include <stdio.h>
int Nsum(int n);
int main(void) {
int t, n;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
int z = Nsum(n);
printf("%d\n", z);
// printf("%d\n", sum);
}
return 0;
}
int Nsum(int n) {
int count = 0;
int sum = 0;
for(int i = 1; i <= n; i++)
{
sum = sum + i;
count++;
}
if (sum % 2 == 0)
{
return count;
}
else (Nsum(n - 1));
}
Consider these cases:
N
Sequence
Sum of elements
A maximum subsequence with even sum
Its length
0
{ }
0
{ 0 }
0
1
{ 1 }
1
{ }
0
2
{ 1, 2 }
3
{ 2 }
1
3
{ 1, 2, 3 }
6
{ 1, 2, 3 }
3
4
{ 1, 2, 3, 4
10
{ 1, 2, 3, 4
4
5
{ 1, 2, 3, 4, 5 }
15
{ 2, 3, 4, 5 }
4
6
{ 1, 2, 3, 4, 5, 6 }
21
{ 2, 3, 4, 5, 6 }
5
7
{ 1, 2, 3, 4, 5, 6, 7 }
28
{ 1, 2, 3, 4, 5, 6, 7 }
7
We can easily see patterns here. One pattern is that when the sum is even, the whole sequence { 1,… N } is the maximum subsequence with an even sum, and, when the sum is odd, chopping off the 1 to make { 2,… N } gives a maximum subsequence with an even sum.
Another pattern is that whenever N is even, the parity (evenness/oddness) of the sum of { 1,… N } stays the same from the previous N, since adding an even number does not change it. Whenever N is odd, the parity changes. So, the pattern is:
N’s parity
Sum’s parity
even
stay the same
odd
changes
even
say the same
odd
changes
It takes two changes to bring parity back to what it was. Two changes occur every two odd numbers, so they occur every four steps. Therefore, the parity of the sum goes through a fully cycle as N goes through four values. So the remainder of N modulo four tells us where we are in the cycle:
N % 4
Parity of sum
Length of a maximum subsequence
0
even
N
1
odd
N−1
2
odd
N−1
3
even
N
Therefore, Nsum may be implemented:
int Nsum(int N)
{
switch (N % 4)
{
case 0: return N;
case 1: return N-1;
case 2: return N-1;
case 3: return N;
}
}
(Note that negative N are not handled.)

Finding integer divisors of a set of numbers in C language

I want to do this in a function: How do I find out in a C program if a number is divisible by 2, 3, 4, 5, 6, 8, 9, 25 and 125 without using the % operator and using the divisibility rules? the base should be 10*
To use divisibility rules, you have to work with digits. Perhaps task assumes no division (at least in explicit form - you can extract digits from string representation)
For divisibility by 2, check whether the last digit is in set 0,2,4,6,8
For divisibility by 4, check whether the last digit + doubled previous one is in set 0,4,8. If result is larger than 10, repeat (88=>2*8+8=24=>2*2+4=8)
Similar situation for 8, but sum last + 2*previous + 4*second_from_the_end (512 => 4*5+2*1+2=24=>2*2+4=8)
For divisibility by 5, check whether the last digit is in set 0,5, similar situation for 25, 125
For divisibility by 3, sum all digits, repeat process until result becomes < 10. So-called "digit root" should be in set 0,3,6,9, similar situation for divisibility by 9.
For 6 check divisibilty by both 2 and by 3
I am not strong in C, so my example perhaps is very weird (ideone check)
#include <stdio.h>
int divby3(int n) {
char s[10];
do {
sprintf(s, "%d", n); //transform 72 to char buffer "72"
n = 0;
int i = 0;
while(s[i]) //until nil (end of string) found, we can also use for loop
n += s[i++] - 0x30; //get difference of current char and char "0"
}
while (n >= 10); //until 1-digit value
return (n==0) || (n==3) || (n==6) || (n==9);
}
int divby5(int n) {
char s[10];
int len = sprintf(s, "%d", n);
n = s[len - 1] - 0x30; //last digit
return (n==0) || (n==5);
}
int main(void) {
printf("%d", divby3(72)); //try 71
return 0;
}
A function that uses the a - (a / b * b) implementation of the modulus operator: (credit #MikeCat)
bool isDivisible(int a, int b)
{
if((a - (a / b * b)) == 0) return true;
return false;
}
Usage:
int main(void)
{
int a = 8;
int b = 4;
int c = 3;
bool res = isDivisible(a,b);
bool res2 = isDivisible(a,c);
return 0;
}
EDIT - to address question in comments:
"how can i represent such a program with the divisibility rules? Thank you for your code, i forgott to mention that i have to use the divisibility rules in each function"
The following shows how to pass in divisibility rules as an argument...
const int div_1[] = {2, 3, 4, 5, 6, 8, 9, 25, 125};
const int div_2[] = {7, 5, 17, 12, 11};
int main()
{
size_t size = 0;
size = sizeof div_1/sizeof div_1[0];
bool res = isDivisible(2*3*4*5*6*8*9*25*125, div_1, size);
size = sizeof div_2/sizeof div_2[0];
bool res2 = isDivisible(125, div_2, size);
return 0;
}
// numerator divisor array array size
bool isDivisible(long a, long div_rules[], size_t size)
{
//divisibility rules
const int divisors[] = {2, 3, 4, 5, 6, 8, 9, 25, 125};
for(int i = 0; i<size;i++)
{
if((a - (a / div_rules[i] * div_rules[i])) != 0) return false;
}
return true;
}

Trying to write a program that counts the amount of even numbers in an array and returns the value

I am trying to make a program that will count the number of even numbers in the provided arrays. When I run the program now, it will return the amount of numbers in the array, but not the amount of even numbers. For some reason my count_even function doesn't work. Can anyone help?
#include <stdio.h>
int main()
{
int data_array_1[] = { 1, 3, 5, 7, 9, 11 };
int data_array_2[] = { 2, -4, 6, -8, 10, -12, 14, -16 };
int data_array_3[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int data_array_4[] = { 6, 2, 4, 5, 1, -9 };
int data_array_5[] = { 1, 3, 9, 23, 5, -2, 4 };
int result_1 = count_even(data_array_1, 6);
printf("data_array_1 has %d even numbers.\n", result_1);
int result_2 = count_even(data_array_2, 8);
printf("data_array_2 has %d even numbers.\n", result_2);
int result_3 = count_even(data_array_3, 11);
printf("data_array_3 has %d even numbers.\n", result_3);
int result_4 = count_even(data_array_4, 6);
printf("data_array_4 has %d even numbers.\n", result_4);
int result_5 = count_even(data_array_5, 7);
printf("data_array_5 has %d even numbers.\n", result_5);
return 0;
}
int count_even(int* data_array, int size)
{
int even_num = 0;
for (int i = 0; i == size; i++)
{
if (data_array[size] % 2 == 0)
{
even_num++;
}
}
return even_num;
}
The condition in your for loop is wrong.
The correct condition should say "as long as the index is smaller than size", but yours say "as long as the index equal to to size".
The condition should be i < size.
As for the result, it seems like it should return 0 (for the non-working code), not size.
Also, you are using size as an index, when you should use i.
In your count_even function, you are using the size attribute as the array index, when it should be i
int count_even(int* data_array, int size)
{
int even_num = 0
for(int i = 0; i <= size, ++i)
{
if(data_array[i] % 2 == 0)
{
even_num++;
}
}
return even_num;
}
these two lines are the root of the problems in the code:
for (int i = 0; i == size; i++)
{
if (data_array[size] % 2 == 0)
the for() statement, should be:
for (int i = 0; i < size; i++)
so the loop exits when reaching the end of the array
the if() statement is always looking at the same entry beyond the end of the array, This is undefined behaviour
The if() statement should be:
if (data_array[i] % 2 == 0)
However, the modulo operator & is not a good choice for negative numbers
a better choice would be:
if ( !(data_array[i] & 1 ) )

synchronization of position in different watch

I have tried to solve the following problem unsuccessfully:
You are given 16 clocks, all set at some position between 1 and 12. The initial configuration is:
12, 9, 3, 12, 6, 6, 9, 3, 12, 9, 12, 9, 12, 12, 6, 6
You are given a set of switch lines:
# define max_switch 10
int switchLines[max_switch][5] =
{
{0,1,2,-1,-1},
{3,7,9,11,-1},
{4,10,14,15,-1},
{0,4,5,6,7},
{6,7,8,10,12},
{0,2,14,15,-1},
{3,14,15,-1,-1},
{4,5,7,14,15},
{1,2,3,4,5},
{3,4,5,9,13}
};
Entries equal to -1 are ignored. When you press a switch, the value of the clocks listed in the switch line increases by 3.
For example pressing the first switch in the initial configuration would yield:
3, 12, 6, 12, 6, 6, 9, 3, 12, 9, 12, 9, 12, 12, 6, 6
You are allowed to press any switch any number of time in any order.
What is the minimum number of switch presses needed to set all the clocks to 12 ?
I am looking for an algorithm to solve the above problem.
Below is the solution I am trying
#include <stdio.h>
#include <stdlib.h>
int clock1[16] ={12, 9, 3, 12 ,6, 6 ,9 ,3 ,12, 9, 12, 9 ,12 ,12, 6 ,6};
int swicthApplied = 0;
#define mac_sw 10
int switchLink[mac_sw][5]=
{
{0,1,2,-1,-1},
{3,7,9,11,-1},
{4,10,14,15,-1},
{0,4,5,6,7},
{6,7,8,10,12},
{0,2,14,15,-1},
{3,14,15,-1,-1},
{4,5,7,14,15},
{1,2,3,4,5},
{3,4,5,9,13}
};
int isSwicthRequired()
{
int i=0, need = 0;
for(i=0;i<16;i++)
{
if(clock1[i] < 12)
{
need = 1;
}
}
return need;
}
int findmax(int array[], int size)
{
int maximum, c, location = 0;
maximum = array[0];
if(array[0] == 0) location = -2;
for (c = 1; c < size; c++)
{
if (array[c] > maximum)
{
maximum = array[c];
location = c ;
}
}
return location +1;
}
runSwicth(int pos)
{
int i =0;
for(i=0;i<5;i++)
{
int valu = switchLink[pos][i];
if(valu == -1 ) continue;
if(clock1 [valu] == 12)
{
// continue;
clock1 [valu] = 3;
}
else
clock1 [valu] = clock1[valu] + 3;
}
printClock(clock1,16);
swicthApplied = 1 + swicthApplied;
//exit(0);
}
int findBestMatchSwitch( void)
{
//if(maxSwicth >=10) return -1;
int maxSwicth = mac_sw,numberofSwicths = 5,i,j;
int array[10] = {0,0,0,0,0,0,0,0,0,0};
for( i = 0;i<maxSwicth;i++)
{
for(j=0;j<numberofSwicths;j++)
{
int pos = switchLink[i][j] ;
if(pos == -1) continue;
if(clock1[pos] != 12)
{
array[i] = array[i] +1;
}
}
}
int loc = findmax(array,10);
if(loc == -1) return -1;
applySwicth(loc -1);
//omitLoc[loc-1] = -1;
return 0;
//exit(0);
}
int runAlignment()
{
int need =0;
while(1)
{
need = isSwicthRequired();
if (need ==0) break;
if(findBestMatchSwitch() == -1)
{
return -1;
}
}
return need;
}
int main(void) {
runAlignment();
printf("Swicthes Required [%d]",swicthApplied);
//getClockneed();
//printClock(clockNeed,16);
return EXIT_SUCCESS;
}
By definition, a solution is a list of switches of minimum length such that, when the switches are pressed in sequence, the initial configuration is transformed into the desired one.
Note that the order in which the switches are pressed doesn't actually matter. Note also that in a minimal solution no switch is pressed more than three times.
Hence for each of ten switches, you have four choices (0 to 3 presses) to consider, i.e. the total number of possibilities to examine is 4^10 or about a million.

How do I compute the number of valleys in a sequence of numbers?

Given a sequence of digits, a valley is defined as the region in the sequence that is surrounded (to the left and right) by higher values. The task is to find the number of valleys in the sequence.
For example,
{9,8,7,7,8,9} has one valley at {7,7}
{9,8,7,7,8,6,9} has two valleys at {7,7} and {6}
{7,8,9,8,7} has no valleys
The code I have to compute the number of valleys is as follows:
#include <stdio.h>
#define SIZE 40
int main()
{
int input;
int store[SIZE];
int i = 0;
int j;
int valley = 0;
int count = 0;
printf("Enter sequence: ");
scanf("%d", &input);
while(input != -1)
{
store[i] = input;
i++;
scanf("%d", &input);
}
count = count + i;
for(i = 1; i < count; i++)
{
for(j = i; j < i + 1; j++)
{
if((store[j-1] > store[j]) && (store[j] < store[j+1]))
{
valley = valley + 1;
break;
}
}
}
printf("Number of valleys: %d", valley);
return 0;
}
I am able to display the correct answer if the input is "3 2 1 2 3". However, if in between the number is equal to another and they are side by side (for example, "3 1 1 2"), the program will compute the wrong answer.
How do I go about writing the program so that I am able to display the correct number of valleys?
Look for slope changes from down to up.
Rather than a double nested for loop, march along looking for slope changes from down to up. Consider any slope of 0 to be the same as the previous slope.
size_t Valley(const int *store, size_t count) {
size_t valley = 0;
int slope = -1;
size_t i;
// Find first down slope
for (i = 1; i < count; i++) {
if (store[i] < store[i - 1]) {
break;
}
}
for (; i < count; i++) {
int newslope = (store[i] > store[i - 1]) - (store[i] < store[i - 1]);
// Loop for slope changes
if (newslope == -slope) {
if (newslope > 0)
valley++;
slope = newslope;
}
}
return valley;
}
Test code.
void Vtest(const int *store, size_t count) {
size_t n = Valley(store, count);
printf("%zu %zu\n", count, n);
}
void Vtests(void) {
int a1[] = { 9, 8, 7, 7, 8, 9 };
Vtest(a1, sizeof a1 / sizeof a1[0]);
int a2[] = { 9, 8, 7, 7, 8, 6, 9 };
Vtest(a2, sizeof a2 / sizeof a2[0]);
int a3[] = { 7, 8, 9, 8, 7 };
Vtest(a3, sizeof a3 / sizeof a3[0]);
int a4[] = { 3, 2, 1, 2, 3 };
Vtest(a4, sizeof a4 / sizeof a4[0]);
int a5[] = { 8, 7, 7, 8, 6 };
Vtest(a5, sizeof a5 / sizeof a5[0]);
}
int main(void) {
Vtests();
return 0;
}
Output
6 1
7 2
5 0
5 1
5 1
The problem is here:
if((store[j-1] > store[j] )&&(store[j] < store[j+1]))
In both comparations you are using index j, so this program finds only valleys with length 1. Try this modification:
if((store[i-1] > store[i] )&&(store[j] < store[j+1]))
Also I am not sure, that it is right to break; in this situation. But it is not clear now, which answer is correct in case 3 1 2 3 - one (1) or two (1 and 1 2). From your first example we can see, that right answer is one, but it is not obvious from the definition.
Depending on whether you define valley as a higher value to the IMMEDIATE left/right of a given point you may need to adjust the Valley function provided by chux as follows:
size_t Valley (const int *store, size_t count) {
...
i++;
for (; i < count; i++) {
int newslope = (store[i] > store[i - 1]) - (store[i] < store[i - 1]);
if (newslope == -slope) {
if (newslope > 0)
valley++;
}
slope = newslope;
}
...
}
output:
$ ./bin/valleyt
6 0
7 1
5 0
5 1
5 0
This is a supplement to the answer provided by chux, and the input data is as he provided in his answer. This code just limits the definition of a valley to being created by 3 adjacent points. (a special case of the general answer of a change from negative to positive slope with intervening equivalent points)

Resources