This is my first time posting here so I apologize if I'm not following the right etiquette. I also tried searching for answers but to no avail.
Basically, I have this function for a greedy coin change algorithm which takes as input some int. In my function I return a malloc'd array containing each coin. While it works for the most part, for some reason any coin value which produces 5, 9, ... (+4) coins as optimal distribution, ie, 9 would be (5 + 1 + 1 +1 + 1), or 650 which is 13 coins of 50 each, causes the program to abort with this message:
hello: malloc.c:2401: sysmalloc: Assertion `(old_top == initial_top (av) &&
old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse
(old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Aborted (core dumped)
However, every coin distribution that isn't 5 or 5+4+... works. Not sure what to do.
This is the function:
int* greedyAlg(int value)//computes and returns the optimal (minimum) number of denominations for a given value for US currency
{
//denominations
int one = 1, five = 5, ten = 10, twenty = 20, fifty = 50;
int x5 = 0, x4 = 0, x3 = 0, x2 = 0, x1 = 0;
int count = 0;
//int[] denom;
while(value != 0)
{
if(value >= fifty)
{
value -= fifty;
count++;
x5++;
/*while(value >= fifty)
{
// int *i = &fifty;
value-=fifty;
count++;
x5++;
}*/
}
else if(value < fifty && value >= twenty)
{
value -= twenty;
count++;
x4++;
}
else if(value < twenty && value >= ten)
{
value -= ten;
count++;
x3++;
}
else if(value < ten && value >= five)
{
value -= five;
count++;
x2++;
}
else if(value < five && value >= one)
{
value -= one;
count++;
x1++;
}
}
//printf("Optimal denominations: ");
int* denom = malloc(sizeof(int)*(count + 1));
//int* denom = (int *)calloc(count + 1,sizeof (int));
denom[0]=count;
for(int i = 1; i<= (x5 + 1); i++){
denom[i] = fifty;
}
for(int i= (x5 + 1); i<=(x5 + x4) + 1; i++){
denom[i] = twenty;
}
for(int i = (x5 + x4) + 1; i <= ( x5 + x4 +x3 ) + 1; i++){
denom[i] = ten;
}
for(int i = (x5 + x4 + x3) + 1; i <= (x5 + x4 + x3 + x2) + 1; i++){
denom[i] = five;
}
for(int i = (x5 + x4 + x3 + x2) + 1; i <= (x5 + x4 + x3 + x2 + x1) + 1; i++){
denom[i]=one;
}
return denom;
free(&denom);
//return count;
}
And this is how I'm printing it:
//prints elements of array created by (greedy) coin change algorithm
void printGreedyArr(int arr[], size_t count)
{
for(int i = 1; i <= count; i++)
{
printf("%s%d%s, ","[",arr[i],"]");
}
printf("\n%s %d\n","count was",count);
}
I call it with the 0th index which holds the length like so:
printGreedyArr(greedyAlg(x),greedyAlg(x)[0]);
(In my code I set up a loop with x as user input to test)
I can post any other relevant details if need be.
Assuming count equals x5+x4+x3+x2+x1, you've got an off-by-one error:
for(int i=(x5+x4+x3+x2)+1; i<=(x5+x4+x3+x2+x1)+1; i++){
Should probably be:
for(int i=(x5+x4+x3+x2)+1; i<(x5+x4+x3+x2+x1)+1; i++){
Also similarly for the other for loops. Note the termination condition has changed from <= to <.
Also:
return denom;
free(&denom);
That free() will never be executed, and also the & should be removed from before the denom if you place it elsewhere.
Related
In line 10 I cannot find out where my problem is at first. I place int a[100][100]={0} but the cpu speed is stuck.
Then, I try to change it into a[n][n] but no output is shown.
Last, I try to change it again as if it resembles the original ones.
However, nothing works instead of a new question.
#include<stdio.h>
int main() {
int n;
while (scanf("%d", &n)) {
n *= 2;
int x = 0, y = 0, num = 1;
int a[n][n] = {0};
a[x][y] = num++;
while (n * n >= num) //定義陣列
{
while (y + 1 < n && !a[x][y + 1]) //向右
a[x][++y] = num++;
while (x + 1 < n && !a[x + 1][y]) //向下
a[++x][y] = num++;
while (y - 1 >= 0 && !a[x][y - 1]) //向左
a[x][--y] = num++;
while (x - 1 >= 0 && !a[x - 1][y]) //向上
a[--x][y] = num++;
}
for (x = 0; x < n; x++) //print 陣列
{
for (y = 0; y < n; y++) {
if (y != n - 1) {
printf("%d ", a[x][y]);
} else {
printf("%d", a[x][y]);
}
}
printf("\n");
}
break;
}
return 0;
}
At least this problem:
Variable Length Arrays (VLA) cannot be initialized via the C standard.
Alternate, assign via memset() after defining a.
// int a[n][n]={0};
int a[n][n];
memset(a, 0, sizeof a);
We are asked to write some code that takes a 4 digit number as input, and does the following:
Take any four-digit number, using at least two different digits.
Arrange the digits in descending and then in ascending order to get two four-digit numbers
Subtract the smaller number from the bigger number.
Go back to step 2 and repeat.
The end result will always freeze at kaprekar's constant 1674 and we must print the algorithm's resulting number each and every time . In the end we also have to print the number of times we had to run the algorithm to get there .
I worked it out as loop , storing the digits in 2 arrays and sorting the first in ascending order and the second in descending order over and over again till i get to 1674 but for some reason the "process" loop won't stop . Any help would be appreciated .
#include <stdio.h>
#include <stdlib.h>
int main()
{
long int pow1(int x, int n)
{
int i, result = 1;
for (i = 0; i < n; i++)
{ // Power Function //
result *= x;
}
return (result);
}
int a, s;
int val[] = {
0,
0,
0,
0};
int value[] = {
0,
0,
0,
0};
int ex = 0;
scanf(" %d", &a);
if (a / 1000 != 0 && a / 1000 < 10)
{
// Extracting the digits and storing them in the arrays .
for (int i = 0; i <= 3; ++i)
{
value[i] = val[i] = (a % pow1(10, i + 1) - a % pow1(10, i)) / pow1(10, i);
if (i > 0)
{
if (val[i] == val[i - 1])
{
ex++;
}
}
}
if (ex == 3)
{
printf("Wrong input");
exit(0);
}
int j = 0, k = a;
// Start of process
while (k != 6174)
{
while (1)
{
s = 0;
for (int i = 0; i <= 3; i++)
{
if (val[i] > val[i + 1])
{
int temp = val[i];
val[i] = val[i + 1];
val[i + 1] = temp;
s = 1;
}
}
if (s == 0)
{
break;
}
}
while (1)
{
s = 0;
for (int i = 0; i <= 3; i++)
{
if (value[i] < value[i + 1])
{
int temp = value[i];
value[i] = value[i + 1];
value[i + 1] = temp;
s = 1;
}
}
if (s == 0)
{
break;
}
}
j++;
printf("max:%d min: %d ", value[0] * 1000 + value[1] * 100 + value[2] * 10 + value[3], val[0] * 1000 + val[1] * 100 + val[2] * 10 + val[3]);
k = value[0] * 1000 + value[1] * 100 + value[2] * 10 + value[3] - (val[0] * 1000 + val[1] * 100 + val[2] * 10 + val[3]);
printf("diff:%d\n", k);
for (int i = 0; i <= 3; ++i)
{
value[i] = val[i] = (k % pow1(10, i + 1) - k % pow1(10, i)) / pow1(10, i);
}
}
printf("Took %d turns", j);
}
else
{
printf("Wrong input");
}
return 0;
}
You have defined val and value as 4 element [0..3], yet in your loops you access and modify both over [0..4] eg: val[i+1] = temp.
I proper sized them (int val[5] = {0}, value[5] = {0}), and your test yielded:
max:2211 min: 112 diff:2099
max:9920 min: 229 diff:9691
max:9961 min: 1699 diff:8262
max:8622 min: 2268 diff:6354
max:6543 min: 3456 diff:3087
max:8730 min: 378 diff:8352
max:8532 min: 2358 diff:6174
Took 7 turns
Because your sort isn't quite right.
If you change your sort to be:
for (int i = 1; i < 4; i++)
{
if (val[i-1] > val[i])
{
int temp = val[i];
val[i] = val[i - 1];
val[i - 1] = temp;
s = 1;
}
}
it will respect its boundaries, and be correct; so you can go back to len 4 vectors. Remember to change the other one as well.
ps: It is more work for me to complain that you didn't put a main wrapper in your example than to put one in. That doesn't excuse not doing the least you can do.
I've been trying to improve my recursion skills in C and I came across this question. I've tried to solve it, yet the code doesn't seem to work properly.
For example, there are 108 options for the knight to move from (1,1) to (8,8) in 6 moves and in my code the result is completely different. The question asks how many ways are there to move a knight from (1,1) to (8,8) in n moves(n given from the user) in 8x8 board. here's my code:
#include <stdio.h>
#define SIZE 8
//x,y coordinates of the knight.
int knightsTour(int x, int y, int num);
void main() {
int n;
int result;
do {
scanf(" %d", &n);
result = knightsTour(1,1,n);
printf("%d\n", result);
} while (n > 0);
}
int knightsTour(int x,int y,int num) {
int result = 0;
int i, j;
if (num == 0) {
return 0;
}
if (((x > 8) || (y > 8))||((x == 8) && (y == 8))) {
return 0;
}
for (i = 1; i <= SIZE; i++) {
for (j = 1; j <= SIZE; j++) {
if ((i != y) && (j != x) && ((i != y + j) && (j != x + i)) && ((i != y + j) && (j != x - i))
&& ((i != y - j) && (j != x + i)) && ((i != y - j) && (j != x - i))) {
result += knightsTour(i, j, num - 1) + 1;
}
}
}
return result;
}
Your code has several problems:
You add one to the results unconditionally when you call your recursivev function. You should only count paths that land on h8 after 6 moves, for which you can check only after you have jumped to the new position.
When you want to find possible moves, it is wasteful to check all squares on the board. You know the rank and file of the knight, so you also know the eight possible moves. You must take care not to jump off the board. It is easier to verify that rank and file are valid at the beginning of the function.
One approach would be the following recursive method:
Are rank and file valid? If not, return 0.
Have we reached the desired number of moves? If so, return 1 if the current square is h8, and 0 otherwise.
Return the sum of the number of valid moves the knight can make with one fewer move for the eight possible moves from the current positions. You don't need to check here, because the validity of a move will be checked at the beginning of the function.
Putting this together:
#include <stdio.h>
#define SIZE 8
int knightsTour(int x, int y, int num)
{
if (x < 1 || x > SIZE) return 0;
if (y < 1 || y > SIZE) return 0;
if (num == 0) return (x == SIZE && y == SIZE);
return knightsTour(x + 2, y + 1, num - 1)
+ knightsTour(x + 1, y + 2, num - 1)
+ knightsTour(x - 1, y + 2, num - 1)
+ knightsTour(x - 2, y + 1, num - 1)
+ knightsTour(x - 2, y - 1, num - 1)
+ knightsTour(x - 1, y - 2, num - 1)
+ knightsTour(x + 1, y - 2, num - 1)
+ knightsTour(x + 2, y - 1, num - 1);
}
int main(void)
{
int result = knightsTour(1, 1, 6);
printf("%d\n", result);
return 0;
}
This code is straightforward and it determines the 108 possible moves.
I have run this program and get the error expression result unused. I may be doing something simple wrong, but I have spent the day trying to figure it out to no avail. Any help you can provide is greatly appreciated.
#include <stdio.h>
#include <cs50.h>
int main()
{
int x, y = 0;
printf("Enter the amount of change ");
x = GetFloat() * 100;
while (x != 0)
{
if (x >= 25)
{
x - 25;
y = y + 1;
}
if (x >= 10 && x < 25)
{
x - 10;
} y = y + 1;
if (x >= 5 && x < 10)
{
x - 5;
} y = y + 1;
if (x >= 1 && x < 5)
{ x - 1;
y= y + 1;
}
}
printf("The number of coins neccessary is %d", y);
}
if (x >= 25)
{
x - 25; // This accomplishes nothing
y = y + 1;
}
if (x >= 10 && x < 25)
{
x - 10; // This accomplishes nothing
} y = y + 1;
if (x >= 5 && x < 10)
{
x - 5; // This accomplishes nothing
} y = y + 1;
if (x >= 1 && x < 5)
{
x - 1; // This accomplishes nothing
y= y + 1;
}
In each of those lines you're subtracting a number from x, but you're doing nothing with the result. If you're trying to update x with the result, you need to do just like you're doing with y, and put x = in front of the expression.
So if you want x to go down by 25, you should write:
x = x - 25;
Alternatively, you can write the shorthand:
x -= 25; // Note the equal sign
All the 4 statements x - 25, x- 10, x- 5, x - 1 will turn out to be useless unless you assign that value to x;
Because you are trying to subtract the value from x, but you are not assigning the new value to x.
Here is the solution of your problem:
#include <stdio.h>
#include <cs50.h>
int main()
{
int x, y = 0;
printf("Enter the amount of change ");
x = GetFloat() * 100;
while (x != 0)
{
if (x >= 25)
{
x = x - 25; //or x-=25;
y = y + 1;
}
if (x >= 10 && x < 25)
{
x = x - 10; //or x-=10;
y = y + 1;
}
if (x >= 5 && x < 10)
{
x = x - 5; //or x-=5;
y = y + 1;
}
if (x >= 1 && x < 5)
{
x = x - 1; //or x-=1; or x--; or --x; :)
y = y + 1;
}
}
printf("The number of coins neccessary is %d", y);
}
I would remain to be convinced about your loop structure. There's the division operator that can be used to good effect:
int total = 0;
int ncoins;
int amount = GetFloat() * 100;
assert(amount >= 0);
ncoins = amount / 25;
total += ncoins;
amount -= ncoins * 25;
assert(amount < 25);
ncoins = amount / 10;
total += ncoins;
amount -= ncoins * 10;
assert(amount < 10);
ncoins = amount / 5;
total += ncoins;
amount -= ncoins * 5;
assert(amount < 5);
total += amount;
That's written out longhand; you could devise a loop, too:
int values[] = { 25, 10, 5, 1 };
enum { N_VALUES = sizeof(values) / sizeof(values[0]) };
int total = 0;
int ncoins;
int amount = GetFloat() * 100;
assert(amount >= 0);
for (int i = 0; i < N_VALUES && amount > 0; i++)
{
ncoins = amount / values[i];
total += ncoins;
amount -= ncoins * values[i];
}
assert(amount == 0);
I'm working on a program which is going to be used to sort students test scores and eventually retrieve the mean, median, and the mode of the scores. For some strange reason my bubble sort is not working.. I'm unsure why.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3
int main (void)
{
char vStudents[N][15], trans = 'y', vTemp2;
int vScores[N], vTemp, x, i = 0, j=0, NewN;
printf("\t\tWhatsamatta U Scores System\n\n");
do
{
printf("Please Enter Students Name: ");
gets(vStudents[i]);
trans = 'N';
while (trans == 'N')
{
printf("Enter Students Score: ");
scanf("%d", &vScores[i]);
fflush(stdin);
if (vScores[i] >= 0 & vScores[i] <= 100)
trans = 'y';
else
printf("Score is invalid, please re-enter score.\n");
}
i++;
j++;
} while (j != N);
for(x = 0; x < N - 1; x++)
{
if ((x < N - 1) && (vScores[i] > vScores[i + 1]))
{
vTemp = vScores[i];
vScores[i] = vScores[i + 1];
vScores[i + 1] = vTemp;
x = -1;
}
}
printf("%d %d %d\n\n", vScores[0], vScores[1], vScores[2]);
system("Pause");
return 0;
Any help would be useful, thanks in advance!
At least one error:
for(x = 0; x < vScores[N] - 1; x++)
{
if ((x < vScores[N] - 1) && (vScores[N] > vScores[N + 1]))
{
should be
for(x = 0; x <N - 1; x++)
{
if ((x < N - 1) && (vScores[N] > vScores[N + 1]))
{
//^^you should not compare index x with array elements
N is always 3. if we replace N in your code with 3, does it still make sense?
for(x = 0; x < vScores[3] - 1; x++)
{
if ((x < vScores[3] - 1) && (vScores[3] > vScores[3 + 1]))
{
vTemp = vScores[3];
vScores[3] = vScores[3 + 1];
vScores[3 + 1] = vTemp;
x = -1;
}
}
Ok, now that it is this:
for(x = 0; x < N - 1; x++)
{
if ((x < N - 1) && (vScores[i] > vScores[i + 1]))
{
vTemp = vScores[i];
vScores[i] = vScores[i + 1];
vScores[i + 1] = vTemp;
x = -1;
}
}
Ask, when does i change?