I'm working on an assignment for a programming class and am having an issue with a program. The goal is to take in a set of user defined values, store them in an array, then find the closest pair of numbers (the numbers with the smallest difference). The numbers don't have to have consecutive indices. Also, the array size of 50 is defined in the assignment by the professor.
The problem I'm running into is that the program will compile in both Linux (Ubuntu 14.xx) and Windows 10, however, when I run the result in Linux, it works fine but in Windows it outputs nothing.
This is the first time I've had this issue and as far as I know I didn't use any system specific commands. Any help provided would be appreciated.
Code:
#include <stdio.h>
int main()
{
int i, j, a, b, temp, mindiff, count;
int numarray[50];
count = 0;
for (i = 0; i < 50; i++)
{
scanf("%d", &numarray[i]);
count++;
if (numarray[i] == -1)
{
numarray[i] = 0;
count--;
break;
}
}
mindiff = 100;
for (i = 0; i < count; i++)
{
for (j = 0; j < count; j++)
{
a = numarray[i];
b = numarray[j];
if (a != b)
if (a > b)
temp = a - b;
else
temp = b - a;
if (temp < mindiff)
mindiff = temp;
}
}
for (i = 0; i < count; i++)
{
for (j = 0; j < count; j++)
{
a = numarray[i];
b = numarray[j];
if (a != b)
{
if (a > b && (a - b) == mindiff)
{
printf("Closest pair: %d and %d, Difference: %d\n", a, b, mindiff);
return 0;
}
}
}
}
return 0;
}
There are at least two major problems:
Your code has undefined behavior because you use temp even if it has not been set (you should start a block after if (a != b)). undefined behavior means anything can happen, including apparent success on Linux and failure on Windows.
You initialize mindiff to 100. If all numbers are farther apart from each other, mindiff will not be changed and the second loop will not print anything.
Here is a simpler version:
#include <stdio.h>
int main(void) {
int count, i, j, mina, minb, mindiff;
int numarray[50];
for (count = 0; count < 50; count++) {
if (scanf("%d", &numarray[count]) != 1 || numarray[count] == -1)
break;
}
mindiff = mina = minb = 0;
for (i = 0; i < count; i++) {
for (j = 0; j < count; j++) {
int a = numarray[i];
int b = numarray[j];
if (a > b) {
int diff = a - b;
if (mindiff == 0 || mindiff > diff) {
mindiff = diff;
mina = a;
minb = b;
}
}
}
}
if (mindiff == 0) {
if (count == 0) {
printf("No numbers input\n");
} else {
printf("The numbers are all identical\n");
}
} else {
printf("Closest pair: %d and %d, Difference: %d\n",
mina, minb, mindiff);
}
return 0;
}
You have the following problem:
Note: temp is considered a stack variable under the main function and since you do not initialize it, it becomes garbarge (for example a large negative number):
int i, j, a, b, temp, mindiff, count;
Then if temp is a large negative number, mindiff = the garbarge value of mindiff,
if (temp < mindiff)
mindiff = temp;
And the following if statement is always false.
if (a > b && (a - b) == mindiff)
And nothing gets printed.
Related
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)
I want to find all the decompositions of a number using only odd numbers and up to N numbers max.
For example for the number 7 and N = 3, I can only get 1+1+5, 1+3+3, 7. I can't get 1+1+1+1+3 because it's greater then N.
They hint us to use backtracking.
I strated writing the code and I am stuck. If someone can explian to me how to solve this problem it will be great.
int T(int n, int k)
{
if (k == 0)
{
return;
}
int arr[N];
int f;
for (f = 0; f < N; f++)
{
arr[f] = 0;
}
int sum = 0;
int j = 1;
int i = 1;
int c = 0;
while (j < k) {
sum = sum + i;
arr[c] = i;
if (sum == n)
{
for (f = 0; f < N; f++)
{
if (arr[f] != 0)
{
printf("%d ", arr[f]);
}
}
printf("\n");
}
else if (sum > n)
{
arr[c] = 0;
sum = sum - i;
i = i - 2;
}
else
{
i = i + 2;
j++;
c++;
}
}
T(n, k - 1);
}
Please compile with warnings (-Wall) and fix all of them (-Werror helps make sure you do this). I didn't build your code, but int T(int n, int k) says it returns an int, yet the function code is void.
With backtracking, you can't print at each node because the current node in the graph might not actually lead to a solution. It's premature to commit anything to the result set until you actually reach it.
It's best not to print in functions that perform logical tasks anyway, but it can make the coding easier while developing the logic so I'll stick wiith it.
The backtracking suggestion is a good one. Here's the logic:
The "found result" base case is when n == 0 && k >= 0, if you're decrementing n and k and using them to represent the remaining value to reach the goal and the number of choices left. If you're incrementing variables to count up to n and k, that's fine too, in which case the base case is current_total == n && taken_so_far <= k.
Next, the "failure" base case is k < 0 || n < 0 because we've either overshot n or run out of numbers to take.
After that, the recursive case is, in English, "try taking each odd number i up to n, recursing on the possibility that i might be part of the solution". Per your spec, we don't accept any sequence of descending numbers which prunes the recursion tree a bit.
Here's the code; again, returning a result is an exercise. I'm using a k-sized array to store potential results, then dumping it to stdout only when a result was found.
#include <stdio.h>
#include <stdlib.h>
void odd_decomposition_search(
int n, const int k, int taken_length, int *taken
) {
if (n == 0 && taken_length <= k && taken_length > 0) {
for (int i = 0; i < taken_length - 1; i++) {
printf("%d+", taken[i]);
}
printf("%d\n", taken[taken_length-1]);
}
else if (n > 0 && taken_length < k) {
int i = taken_length ? taken[taken_length-1] : 1;
for (; i <= n; i += 2) {
taken[taken_length] = i;
odd_decomposition_search(n - i, k, taken_length + 1, taken);
}
}
}
void odd_decomposition(const int n, const int k) {
if (n <= 0 || k <= 0) {
return;
}
int taken[k];
odd_decomposition_search(n, k, 0, taken);
}
int main() {
int n = 7;
int k = 3;
odd_decomposition(n, k);
return 0;
}
If you're having trouble understanding the call stack, here's a visualizer you can run in the browser:
const oddDecomp = (n, k, taken=[]) => {
console.log(" ".repeat(taken.length), `[${taken}]`);
if (n === 0 && taken.length <= k && taken.length) {
console.log(" ".repeat(taken.length), "-> found result:", taken.join("+"));
}
else if (n > 0 && taken.length < k) {
for (let i = taken.length ? taken[taken.length-1] : 1; i <= n; i += 2) {
taken.push(i);
oddDecomp(n - i, k, taken);
taken.pop(i);
}
}
};
oddDecomp(7, 3);
I'm having problem with some homework here. I'm totally newbie in programming, so anything should be helpful. I don't know how to fix C2109 error in C.
As you see, I have a float array that I have to sort, and look for the number 55.5
#include <stdio.h>
#include <conio.h>
#include <math.h>
main() {
float mr1[30], pom = 0;
int i, indeks = -1, j, n, start, end, mid;
printf("Enter length of array n<=30:\n");
scanf("%d", &n);
printf("Enter numbers of array mr1:\n");
for (i = 0; i < n; i++) {
scanf("%f", &mr1[i]);
}
for (i = 0; i <n - 1; i++) {
for (j = i + 1; j < n; j++)
if (mr1[i] > mr1[j]) {
mr1[i] = pom;
mr1[i] = mr1[j];
mr1[j] = mr1[i];
}
}
start = 0;
end = n - 1;
do {
mid = (start + end) / 2
if (mr1[mid] == 55.5) {
indeks = mid;
} else {
if (mr1[mid] < 55.5) {
start = mid + 1;
} else {
kraj = mid - 1;
}
}
} while (poc <= kraj && indeks < 0);
printf("Number 55.5 is on indeks:\n");
printf("%d", indeks);
}
There are multiple issues in the code:
The swapping code is incorrect. It should read:
pom = mr1[i];
mr1[i] = mr1[j];
mr1[j] = pom;
you did not translate all poc as start and kraj as end.
There is a missing ; after mid=(start+end)/2
main() is an obsolete prototype for the main function, you should specify the return type int.
the do / while loop will not handle an empty array correctly. You should use a while loop instead. As a rule of thumb, do / while loop are very often incorrect, sometimes in subtile ways.
Here is a corrected version:
#include <stdio.h>
int main() {
float mr1[30];
int n, i, j, index, start, end, mid;
printf("Enter length of array n<=30:\n");
if (scanf("%d", &n) != 1 || n < 0 || n > 30) {
printf("invalid length\n");
return 1;
}
printf("Enter numbers of array mr1:\n");
for (i = 0; i < n; i++) {
if (scanf("%f", &mr1[i]) != 1) {
printf("invalid input\n");
return 1;
}
}
/* sort the array with simplistic swap sort */
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
if (mr1[i] > mr1[j]) {
/* swap entries */
float pom = mr1[i];
mr1[i] = mr1[j];
mr1[j] = pom;
}
}
}
/* try and locate 55.5 with binary search */
index = -1;
start = 0;
end = n - 1;
while (start <= end) {
mid = (start + end) / 2;
if (mr1[mid] == 55.5) {
index = mid;
break;
} else {
if (mr1[mid] < 55.5) {
start = mid + 1;
} else {
end = mid - 1;
}
}
}
if (index >= 0) {
printf("Number 55.5 is at index %d\n", index);
} else {
printf("Number 55.5 is not present\n");
}
return 0;
}
Note also that 55.5 happens to have an exact representation as a float, but comparing floating point values with == may yield surprising results when the approximate value is not exactly identical to the expected value.
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;
}
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