Perfect Number Check - c

So the idea behind my code is to create a program that uses functions to check and print all perfect numbers between 1 and 1000. I've come up with this, but the issue is that nothing prints. It builds successfully, runs, and exits.
I've gone through my code 3-4 times and I can't find the gap in logic, so I'm thinking its a variable definition issue, something to do with how in-scope certain functions are. Would anyone have any input for why my program is failing to recognize a perfect number, and then print it?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*
*
*/
void perfectNumCheck(int num);
void perfectNumPrint (int perfectNum);
int main(void) {
int i;
for (i = 1; 1 <= 1000; i++)
perfectNumCheck(i);
}
void perfectNumCheck(int num) {
int i;
int temp = 0;
for (i = 0; i < num; i++) {
if (num % i == 0)
temp += i;
}
if (temp == num)
perfectNumPrint(num);
}
void perfectNumPrint(int perfectNum) {
int i;
for (i = 0; i < perfectNum; i++)
if (perfectNum % i == 0)
printf ("%d, ", i);
printf("are factors of the perfect number %d.\n", perfectNum);
}

You have a typo here:
for (i = 1; 1 <= 1000; i++)
perfectNumCheck(i);
Should be
for (i = 1; i <= 1000; i++)
perfectNumCheck(i);
Also, you're dividing by zero. Change all your i = 0 in your for loops to i = 1

boolean perfectNum(int currentNum) {
int i, sum = 0;
for (i = 1; i < currentNum; i++)
if (perfectNum % i == 0)
sum += i;
if(sum == currentNum) return ture;
return false;
}

Perfect Number Test : If the sum of all factors are equals to number itself.
public static bool IsItPerfectNumber(int input)
{
bool IsPerfectNumber = false;
//Validation and Find all Factore
List<int> myList = FindFactors(input);
//Sum if factor
int sumOfFactor = SumFactor(myList);
//Check Is Perfact Number
if (sumOfFactor == input)
{
IsPerfectNumber = true;
}
return IsPerfectNumber;
}
public static List<int> FindFactors(int input)
{
List<int> myList = new List<int>();
for (int j = 1; j < input; j++)
{
if (input % j == 0) {
myList.Add(j);
}
}
return myList;
}
public static int SumFactor(List<int> myList)
{
return myList.Sum();
}

Try this:
boolean perfectNum(int currentNum) {
int i, sum = 0;
for (i = 1; i < currentNum; i++)
if (perfectNum % i == 0)
sum += i;
if(sum == currentNum) return ture;
return false;
}

Related

Passing an array to function a looping through it in C

I know I'm asking pretty basic question here, but could anyone give me a hint how to properly loop through an array which is initialized in another function ? I tried googling, found tons of videos but I didn't manage to get it right just yet. Would anyone please help me find out, what I'm missing in my code ? I'm a struggling beginner. Thanks in advance for your time.
My code (not functioning):
#include <stdio.h>
#define ARR_RANGE 1000000
#define GREATEST_NUMBER 1000000
void sieve(int eratosthenes[]);
int main()
{
int eratosthenes[ARR_RANGE];
int n = 999;
int c;
for(i = 2; i <= arrLen; ++i)
{
if(eratosthenes[i]!= -1)
{
int c = 0;
while(n % i == 0)
{
n /= i;
++c;
}
if(c >= 2)
{
printf("%d^%d x ", i, c);
}
else if(c == 1)
{
printf("%d x ", i);
}
}
else
continue;
}
return 0;
}
void sieve(int eratosthenes[])
{
for(int i = 1; i < GREATEST_NUMBER; ++i)
{
eratosthenes[i] = i;
}
for(int i = 2; i*i < GREATEST_NUMBER; ++i)
{
if(eratosthenes[i] != -1)
{
for(int j = 2*i; j < GREATEST_NUMBER ; j += i)
eratosthenes[j] = -1;
}
}
int arrLen = sizeof eratosthenes / sizeof eratosthenes[0];
}
In the main is not visible the call of function sieve,so the array is not passed into function, to do this you have to write in the main sieve(eratosthenes); (Passage by reference)

Problems with printing output C

So I have to write a code for school. I did, but my outputs are not the way they asked for. This code gives me prime number between 2 different numbers. So i have to print those numbers in rows. But yeah there are getting zeros between the answers below you can see what I mean. How can I fix this?
#include <stdio.h>
int is_prime (int number)
{
int is_prime= 1, i;
if (number < 2)
{
is_prime = 0;
}
else
{
for(i = 2; (i * i) <= number; i++)
{
if ((number % i) == 0)
{
is_prime = 0;
break;
}
else
{
is_prime = 1;
}
}
}
return is_prime;
}
int main (void)
{
int lower_limit, upper_limit, i;
scanf("%d\n%d", &lower_limit, &upper_limit);
for(i = lower_limit; i <= upper_limit; i++)
{
if (is_prime (i))
{
printf("\n%d", i);
}
else
{
printf("\n%d", is_prime(i));
}
}
return 0;
}
Output
0
11
0
13
0
0
0
17
0
19
0
Reference
11
13
17
19
It's in this if block:
if (is_prime (i))
{
printf("\n%d", i);
}
else
{
printf("\n%d", is_prime(i));
}
What this says is "if the number is prime print it, otherwise print whether it is prime (which at this point you've established it's not)".
Just get rid of the else block.
If the number is prime number just print it. No else needed - even worse it is incorrect.
You can simplyfy the the is_prime function
int is_prime (int number)
{
int is_prime = number > 1, i;
for(i = 2; (i * i) <= number; i++)
{
if ((number % i) == 0)
{
is_prime = 0;
break;
}
}
return is_prime;
}
int main (void)
{
int lower_limit, upper_limit, i;
scanf("%d\n%d", &lower_limit, &upper_limit);
for(i = lower_limit; i <= upper_limit; i++)
{
if (is_prime (i))
{
printf("\n%d", i);
}
}
return 0;
}
https://godbolt.org/z/4d8qhx
Another problem: overflow.
Avoid int overflow in i*i, which is undeifned behavior (UB).
This can happen when number is a prime near INT_MAX.
// for(i = 2; (i * i) <= number; i++)
for(i = 2; i <= number/i; i++)
A good compiler will see the nearby number%i and number/i and emit efficient code for the two of them, thus not incurring an expensive 2nd operation.
The below also overflows when upper_limit == INT_MAX
for(i = lower_limit; i <= upper_limit; i++)
Perhaps
for(i = lower_limit; i - 1 < upper_limit; i++)
OK as long as lower_limit > INT_MIN.

How to find the nth number?

For an assignment, I have to write code which accepts as input an integer n and outputs the nth 'superunusual' number.
The first few su-numbers are: 22, 23, 26, 33, ... So when the input is 1, the output should be 22. 2 gives 23 and 3 gives 26.
I already have a code that checks if the input number is a su-number, but I can't find a way to calculate the nth number.
So when I now input 22, it says that 22 is a superunusual number.
The code:
/* calculates largest prime factor */
int lprime(int n) {
int max = -1;
while (n % 2 == 0) {
max = 2;
n /= 2;
}
for (int i = 3; i*i <= n; i += 2) {
while (n % i == 0) {
max = i;
n = n / i;
}
}
if (n > 2) {
max = n;
}
return max;
}
/* check unusual number */
int unus(int n) {
/* find largest prime of number */
int factor = lprime(n);
/* Check if largest prime > sqrt(n) */
if ((factor*factor) > n) {
return 1; /* true */
}
else {
return 0; /* false */
}
}
/* delete digit from number */
int del(int num, int n) {
int d = log10(num)+1; /* checks amount of digits */
int revnew = 0;
int new = 0;
for (int i = 0; num != 0; i++) {
int dig = num % 10;
num = num / 10;
if(i == (d - n)) {
continue;
} else {
revnew = (revnew * 10) + dig;
}
}
for (int i = 0; revnew != 0; i++) {
new = (new*10) + (revnew % 10);
revnew = revnew / 10;
}
return new;
}
/* driver code */
int main(int argc, char* v[]) {
int m=22, n;
int x = 0;
int i = 1;
int counter = 0;
scanf("%d", &n);
int d = log10(m)+1;
while (counter < n) {
if (unus(m++)) {
counter++;
}
}
for(unus(m); i < d; i++) {
int nmin = del(m, i);
if (unus(nmin)) {
continue;
} else {
printf("%d is not supurunusual\n", (m-1));
x++;
}
}
if(x==0) {
printf("%d is superunusual!\n", (m-1));
}
return 0;
}
I hope you can understand my code. Otherwise I will explain it better.
Also, I'm quite new to coding, so please don't be to harsh...
You have a function to determine whether a number is unusual, but you do the check whether a number is super-unusual in the body of the main routine. If you extract that code into a proper function:
int is_superunusual(int m)
{
int d = log10(m) + 1;
if (unus(m) == 0) return 0;
for(int i = 0; i < d; i++) { // see footnote
int nmin = del(m, i);
if (unus(nmin) == 0) return 0;
}
return 1;
}
then you can use Eugene's code:
while (counter < n) {
if (is_superunusual(m++)) {
counter++;
}
}
printf("The su number #%d is %d\n", n, m - 1);
Your code tested for unusual numbers, not super-unusual numbers.
Footnote: If you take del(num, n) to mean "remove the nth digit from the end", you can do away with the log10 call in del. You must check all deletions anyway, so the order doesn't really matter here.

Largest palindrome made from the product of two 3-digit numbers with C

The code is trying to find the largest palindrome made from the product of two 2-digit numbers. The answer is 91*99 = 9009 but I keep getting 990, which is not even a palindrome. I really appreciate the help!
#include <stdio.h>
int main()
{
int i = 10;
int j = 10;
int a = 0;
int b = 0;
int array[100] = {0};
int divider = 10;
int num;
int great;
int product;
int n;
int flag;
/*Loop through first 2 digit number and second 2 digit number*/
while (i<100)
{
while (j < 100)
{
product = i*j;
array [a] = product % 10;
n = product / divider;
while (n != 0)
{
a++;
num = n%10;
divider *=10;
array[a]=num;
n = product/divider;
}
flag = 0;
while (b<a)
{
if (array[b] != array[a])
{
flag = 1;
}
b++;
a--;
}
if (flag == 0)
{
great = product;
}
j++;
a = 0;
b = 0;
}
i++;
}
printf("The largest palindrome is %d \n", great);
return 0;
}
Here is a code snippet you can try.
#include <stdio.h>
void main()
{
int a = 1; // first integer
int b = 1; // second integer
int currentNumber;
int currentPalin; if a palindrome is found, its stored here
while (a<100){ //loop through the first number
while (b<100){ // loop through the second number
currentNumber = a*b;
if (currentNumber == reverse(currentNumber) ){ //check for palindrome
currentPalin = currentNumber;
}
b = b+1; //increment the second number
}
b = a; // you could have set b=1 but it would not be an efficient algorithm because
//some of the multiplication would occur twice. eg- (54*60) and (60*54)
a = a +1; //increment the first number
}
printf ("Largest palindrom is %d \n", currentPalin);
getchar();
}
// method for finding out reverse
int reverse(int n){
int reverse = 0;
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
// when you divide a number by 10, the
//remainder gives you the last digit. so you are reconstructing the
//digit from the last
n = n/10;
}
return reverse;
}
Update:- As suggested by M Oehm, I have modified the code to make it more general.
#include <stdio.h>
void main()
{
int a = 1;
int b = 1;
int currentNumber;
int currentPalin=0;
while (a<100){
while (b<100){
currentNumber = a*b;
if (currentNumber == reverse(currentNumber) ){
if (currentNumber>currentPalin){
currentPalin = currentNumber;
}
}
b = b+1;
}
b = 1;
a = a +1;
}
if (currentPalin==0){
printf("No Palindrome exits in this range");
}
else {
printf ("Largest palindrome is %d \n", currentPalin);
}
getchar();
}
int reverse(int n){
int reverse = 0;
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
n = n/10;
}
return reverse;
}
An alternative approach to solve the problem.
#include<stdio.h>
int reverse(int num)
{
int result = 0;
while( num > 0)
{
result = result * 10 + (num%10);
num/=10;
}
return result;
}
int main()
{
int last_best = 1;
int best_i=1;
int best_j = 1;
const int max_value = 99;
for( int i = max_value ; i > 0 ; --i)
{
for(int j = i ; j > 0 ; --j){
int a = i * j;
if( last_best > a )
break;
else if ( a == reverse(a) )
{
last_best = a;
best_i = i;
best_j = j;
}
}
}
printf("%d and %d = %d\n", best_i,best_j,last_best);
}
And it is quite simple to follow.
It seems that you do not reinitialize variables at the beginning of loop. They keeps values from previous iterations. For example, j and divider. Put
j = 10;
before starting "j" loop, i.e.:
j = 10;
while (j < 100) ...
The same for divider:
...
j = 10;
while (j < 100) {
divider = 10;
...
If you were using for loops you would avoid this problem naturally:
for(i=10; i<100; i++) {
for(j=10; j<100; j++) {
...
}
}

How come my straight counter remains at a value of zero?

I am making a program in the C90 standard using GCC in Ubuntu 10.04, that randomly generates a hand of 5 card structs and calculates if the hand is a flush, straight, etc.
My function to calculate straights is:
int isStraight(card hand[]) {
int i, count = 1, result = 0;
for (i = 0; i < HAND_SIZE-1; i++) {
if (hand[i].pips == ((hand[i+1].pips) + 1)) {
count++;
}
}
if (count == HAND_SIZE)
result = 1;
return result;
}
My main function:
int main(void) {
int i, j;
int numHands = 0;
int flushCount = 0;
int straightCount = 0;
int xOfAKindCount = 0;
int straightFlushCount = 0;
int fullHouseCount = 0;
int isTwoPairCount = 0;
card deck[DECKSZ] = {0};
card hand[HAND_SIZE] = {0};
stack deckStack = {0};
stack handStack = {0};
initDeck(deck);
shuffleDeck(deck);
reset(&deckStack);
for (i = 0; i < DECKSZ; i++) {
push(deck[i], &deckStack);
}
do {
reset(&handStack);
for (i = 0; i < HAND_SIZE; i++) {
push(pop(&deckStack), &handStack);
if (isEmpty(&deckStack)) {
reset(&handStack);
shuffleDeck(deck);
reset(&deckStack);
for (j = 0; j < DECKSZ; j++) {
push(deck[j], &deckStack);
}
}
hand[i] = handStack.s[i];
}
numHands += 1;
arrangeHand(hand);
flushCount += isFlush(hand);
straightCount += isStraight(hand);
xOfAKindCount += isXOfAKind(hand, 2, 0);
straightFlushCount += isStraightFlush(hand);
fullHouseCount += isFullHouse(hand);
isTwoPairCount += isTwoPair(hand);
printf("Flushes:%d Straights:%d SF's:%d Number of Hands:%d\r",
flushCount, straightCount, straightFlushCount, numHands);
} while (1);
printf("\n");
return EXIT_SUCCESS;
}
My issue is my variable declared inside my function, result, is never set to 1 to indicate whether or not the hand is a straight, which therefore means my straightCount variable always remains at a value of zero. I do not have access to a debugger and in my mind the code I have makes sense. I'm new to programming in C, so if anybody could help me point out what is wrong with my function, I'd appreciate it. Thanks!
int isStraight(card hand[]) {
int step = 0;
for(int i = 1;i < HAND_SIZE; i++)
if(hand[i].pip != hand[i-1].pip+1)
/* Substitute step with i!=1 if over-edge invalid */
if(step || hand->pip != 1 || hand[i].pip != hand[i-1].pip+13-HAND_SIZE)
return 0;
else
step = 1;
return 1;
}
Right, after reading the code again, there are not enogh cards...
for (i = 0; i < HAND_SIZE-1; ++i)
Then you care counting pairs, not just individual cards, so
If (count == HAND_SIZE-1)
for (i = 0; i < HAND_SIZE-1; i++) { means that you are testing HAND_SIZE-1 pairs (which is correct), with i from from 0 to HAND_SIZE-2, so count will never be HAND_SIZE.
You just need to change your test to if (count == HAND_SIZE-1)
Assuming that (a) pip values are 1=Ace, 2=Deuce, ... and (b) the hand is sorted before being passed to the function, and (c) hands are exactly five cards, here's a quick one:
int isStraight(card hand[]) {
int i;
// Handle Broadway special case
if (hand[0].pips == 13 && hand[1].pips == 12 && hand[2].pips == 11 &&
hand[3].pips == 10 && hand[4].pips == 1) return 1;
// This will handle the rest
for (i = 0; i < (HAND_SIZE-1); i += 1) {
if (hand[i].pips != hand[i+1].pips) return 0;
}
return 1;
}
Also, I wouldn't use a structure for cards. Using a single integer is much faster and more versatile. Check out http://etceterology.com/blog/2013/5/23/representing-playing-cards-in-software

Resources