Getting different answer on Windows vs Linux - c

I'm trying to solve this problem https://www.hackerrank.com/challenges/flowers
When I run my code in Visual Studio 2013 on Windows 7 on my machine I get the correct answers but on the site (I'm pretty sure they use Linux and I'm positive this is the compiler they use gcc 4.9.2, C99 standard) I get very large numbers for answers, specifically 12588576 (instead of 13) for the first test case and 1395920336 (instead of 15) for the second test case. I'm guessing it has something to do with the qsort call.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int comp_desc(const void * a, const void * b)
{
int * aPtr = (int*)a;
int * bPtr = (int*)b;
return *bPtr - *aPtr;
}
int main()
{
int flowersNeeded, numFriends, i;
scanf("%d %d", &flowersNeeded, &numFriends);
getchar();
int flowerCosts[100];
memset(flowerCosts, 0, 100);
for (i = 0; i < flowersNeeded; ++i)
{
scanf("%d", &flowerCosts[i]);
}
qsort(flowerCosts, 100, sizeof(int), comp_desc);
int flowersBought = 0;
int moneySpent = 0;
int multiplier = 1;
for (i = 0; i < flowersNeeded; ++i)
{
moneySpent += flowerCosts[i] * multiplier;
multiplier = (++flowersBought / numFriends) + 1;
}
printf("%d\n", moneySpent);
return 0;
}

memset(flowerCosts, 0, 100);
The 100 should be sizeof(flowerCosts). The 100 doesn't fill the whole array because it's the size in bytes.
qsort(flowerCosts, 100, sizeof(int), comp_desc);
You probably want to sort only the entries you filled in (flowersNeeded) rather than all 100 of them.
As a result of these two bugs, you're sorting garbage values in the uninitialized part of your array.

Related

How can I make a 2-D array in C using user inputs

I tried to make a 2-D array given the numbers of rows and columns as the user input.
int main(void)
{
int nx, ny;
scanf_s("%d", &nx);
scanf_s("%d", &ny);
int array[nx][ny];
return 0;
}
But VSC is telling me that I must have constants in the parenthesis [].
Is there any way I can convert 'nx' and 'ny' as constant?
Or is there any other way to declare 2-D or N-D arrays without converting their dtype?
You should use malloc or for educational purposes declare MAX size matrix and work only within nx-ny region
#define MAX 1000
int main(void)
{
int nx, ny;
int array[MAX][MAX];
scanf_s("%d", &nx);
scanf_s("%d", &ny);
if(nx > MAX || ny > MAX) return 1; // valid range check
// work with array
return 0;
}
This is would be a way of doing it:
int main(void)
{
int nx=0, ny=0;#intialize some random values to the variable
scanf_s("%d", &nx);
scanf_s("%d", &ny);
int array[nx][ny];
return 0;
}
C99 introduced "Variable Length Arrays" ("VLAs"), but I would strongly discourage their use.
Your best bet is to use good old malloc()
EXAMPLE:
https://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/
#include <stdio.h>
#include <stdlib.h>
int main()
{
int r = 3, c = 4; //Taking number of Rows and Columns
int *ptr, count = 0, i;
ptr = (int *)malloc((r * c) * sizeof(int)); //Dynamically Allocating Memory
for (i = 0; i < r * c; i++)
{
ptr[i] = i + 1; //Giving value to the pointer and simultaneously printing it.
printf("%d ", ptr[i]);
if ((i + 1) % c == 0)
{
printf("\n");
}
}
free(ptr);
}
ADDENDUM:
MSVS might support VLAs in version 16.8 or higher: https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-arriving-in-msvc/

Too large of an array leads to a stack overflow error in Visual Studio and a block in Atom

My program is a very simple random number generator with arbitrary parameters. I am using Atom on Windows 10. The code is the following:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define LEN 560000
void main() {
int x[LEN];
int i;
int m = 1234234;
int a = 1245;
int c = 3;
x[0] = 1;
for (i = 1; i < LEN - 2; i++) {
x[i + 1] = a * (x[i] + c) % m;
}
printf("%lf\n", ((double)x[LEN-5]) / m); /* as check */
}
I don't receive anything from the terminal but if I change the length of the vector that I want to generate, setting LEN=500000, I immediately get the final output (that one with the comment) from the terminal. In addition if I use Visual Studio with the same code I receive an error due to overflow.
I don't understand why if I go from LEN=500000 to LEN=560000 the program is not executed.
In my humble opinion I think that there should be a cutoff of array lengths in these two compilers i.e. Atom and Visual Studio, since if I make the array a bit longer the program doesn't work.
EDIT: the second loop goes from 1 to LEN-2 but the problem remains.
You are allocating more than 2 megabytes of automatic storage in main(). It is system dependent whether this exceeds the stack space available to your application and causes a stack overflow. You are experiencing undefined behavior, which seems to manifest only when you access elements of x that have a high index value, but the mere fact that you define objects with automatic storage that exceeds available stack space is sufficient to invoke undefined behavior.
You can try and modify the initial stack size when running this program, but there is no portable way to specify it: check your system documentation for how to do it.
For a portable solution, you should allocate the array with malloc() and make x a pointer to int:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define LEN 560000
int main() {
int *x = malloc(sizeof(*x) * LEN);
int i;
if (x == NULL) {
fprintf(stderr, "memory allocation failure\n");
return 1;
}
int m = 1234234;
int a = 1245;
int c = 3;
x[0] = 1;
for (i = 1; i < LEN - 2; i++) {
x[i + 1] = a * (x[i] + c) % m;
}
printf("%lf\n", ((double)x[LEN]) / m); /* as check */
free(x);
return 0;
}

Store a large number as separate digits in an array [duplicate]

I am trying to calculate 100! (that is, the factorial of 100).
I am looking for the simplest way to accomplish this using C. I have read around but have not found a concrete answer.
If you must know, I program in Xcode in Mac os X.
If you're looking for a simple library, libtommath (from libtomcrypt) is probably what you want.
If you're looking to write a simple implementation yourself (either as a learning exercise or because you only need a very limited subset of bigint functionality and don't want to tack on a dependency to a large library, namespace pollution, etc.), then I might suggest the following for your problem:
Since you can bound the size of the result based on n, simply pre-allocate an array of uint32_t of the required size to hold the result. I'm guessing you'll want to print the result, so it makes sense to use a base that's a power of 10 (i.e. base 1000000000) rather than a power of 2. That is to say, each element of your array is allowed to hold a value between 0 and 999999999.
To multiply this number by a (normal, non-big) integer n, do something like:
uint32_t carry=0;
for(i=0; i<len; i++) {
uint64_t tmp = n*(uint64_t)big[i] + carry;
big[i] = tmp % 1000000000;
carry = tmp / 1000000000;
}
if (carry) big[len++] = carry;
If you know n will never be bigger than 100 (or some other small number) and want to avoid going into the 64-bit range (or if you're on a 64-bit platform and want to use uint64_t for your bigint array), then make the base a smaller power of 10 so that the multiplication result will always fit in the type.
Now, printing the result is just something like:
printf("%lu", (long)big[len-1]);
for(i=len-1; i; i--) printf("%.9lu", (long)big[i-1]);
putchar('\n');
If you want to use a power of 2 as the base, rather than a power of 10, the multiplication becomes much faster:
uint32_t carry=0;
for(i=0; i<len; i++) {
uint64_t tmp = n*(uint64_t)big[i] + carry;
big[i] = tmp;
carry = tmp >> 32;
}
if (carry) big[len++] = carry;
However, printing your result in decimal will not be so pleasant... :-) Of course if you want the result in hex, then it's easy:
printf("%lx", (long)big[len-1]);
for(i=len-1; i; i--) printf("%.8lx", (long)big[i-1]);
putchar('\n');
Hope this helps! I'll leave implementing other things (like addition, multiplication of 2 bigints, etc) as an exercise for you. Just think back to how you learned to do base-10 addition, multiplication, division, etc. in grade school and teach the computer how to do that (but in base-10^9 or base-2^32 instead) and you should have no problem.
If you're willing to use a library implementation the standard one seems to be GMP
mpz_t out;
mpz_init(out);
mpz_fac_ui(out,100);
mpz_out_str(stdout,10,out);
should calculate 100! from looking at the docs.
You asked for the simplest way to do this. So, here you go:
#include <gmp.h>
#include <stdio.h>
int main(int argc, char** argv) {
mpz_t mynum;
mpz_init(mynum);
mpz_add_ui(mynum, 100);
int i;
for (i = 99; i > 1; i--) {
mpz_mul_si(mynum, mynum, (long)i);
}
mpz_out_str(stdout, 10, mynum);
return 0;
}
I tested this code and it gives the correct answer.
You can also use OpenSSL bn; it is already installed in Mac OS X.
You can print factorial 1000 in C with just 30 lines of code, <stdio.h> and char type :
#include <stdio.h>
#define B_SIZE 3000 // number of buffered digits
struct buffer {
size_t index;
char data[B_SIZE];
};
void init_buffer(struct buffer *buffer, int n) {
for (buffer->index = B_SIZE; n; buffer->data[--buffer->index] = (char) (n % 10), n /= 10);
}
void print_buffer(const struct buffer *buffer) {
for (size_t i = buffer->index; i < B_SIZE; ++i) putchar('0' + buffer->data[i]);
}
void natural_mul_buffer(struct buffer *buffer, const int n) {
int a, b = 0;
for (size_t i = (B_SIZE - 1); i >= buffer->index; --i) {
a = n * buffer->data[i] + b;
buffer->data[i] = (char) (a % 10);
b = a / 10;
}
for (; b; buffer->data[--buffer->index] = (char) (b % 10), b /= 10);
}
int main() {
struct buffer number_1 = {0};
init_buffer(&number_1, 1);
for (int i = 2; i <= 100; ++i)
natural_mul_buffer(&number_1, i);
print_buffer(&number_1);
}
You will find faster but the “little” factorial(10000) is here computed ≈ instantly.
You can put it into a fact.c file then compile + execute :
gcc -O3 -std=c99 -Wall -pedantic fact.c ; ./a.out ;
If you want to execute some base conversion there is a solution, see also Fibonacci(10000), Thank You.

C: on calculating the array length with the integer type pointer parameter

I wrote a short code which calculates mean value from an integer array. I first created a header file named mean.h which is as follows.
#ifndef MEAN_H
#define MEAN_H
double mean(int *inputs) {
int i = 0;
int len;
while((inputs[i]) != '\0') {
++i;
}
len = i;
for(i=0; i<len; i++) {
printf("%d ", *(inputs+i));
}
printf("\n");
int sum = 0;
printf("input length: %d\n", len);
for(i=0; i<len; i++) {
sum += *(inputs+i);
}
double mean = sum / len;
return mean;
}
#endif
Then, in order to check if the code is working fine, I created another code named test.c.
#include <stdio.h>
#include "mean.h"
int main(int argc, char **argv) {
int arr[5] = {94, 28, 54, 72, 89};
double meanVal = mean(arr);
int arrlen = sizeof(arr) / sizeof(arr[0]);
printf("Input length: %d\n", arrlen);
printf("Inputs: ");
int i;
for(i=0; i<5; i++) {
printf("%d ", *(arr+i));
}
printf("\n");
printf("Mean: %lf\n", meanVal);
return 0;
}
When I compiled and ran the code, it showed a really strange result like this..
94 28 54 72 89 32767 2123416711 352349365 1594502056 32767 -1876691539 32767 -1876691539 32767
input length: 14
Input length: 5
Inputs: 94 28 54 72 89
Mean: 22644032.000000
The first five elements were printed out with no problem, but I still cannot figure out where the other next 9 elements came from. I believe that probably it's this code snippet that's not proper.
while((inputs[i]) != '\0') {
++i;
}
In this case, how should I modify this in order to calculate the array length with the pointer variable parameter?
It's been pointed out in the comments that C arrays are not automatically null terminated. You have to do it yourself.
Unfortunately, this technique won't work for what you're doing. In an array of integers, null is indistinguishable from 0. Your mean function will not be able to take the mean of anything with a 0 in it. Instead it will think the list is done.
There's alternative techniques to deal with this. First is to have the caller pass in the length of the array. This is how main works. int main(int argc, char *argv[]). As you can imagine, this is inconvenient and error prone.
A better one is to use an array of floats or doubles. These allow some special values such as INFINITY and NAN (not a number). You can use NAN as your array terminator and isnan to check for it.
for( i = 0; !isnan(inputs[i]); i++ ) {
printf("%.2lf ", inputs[i]);
}
printf("\n");
Beyond that, you'd declare a struct which can remember its length.
struct {
int *array;
size_t length;
};
Then you'd have to remember to keep that length always up to date. Rather than going down that rabbit hole, it's better to use a pre-existing C library which provides this such as Gnome Lib. It provides all sorts of missing pieces for C including arrays that remember their size and can grow automatically.
#include <stdio.h>
#include <glib.h>
double mean(GArray *nums) {
int i = 0;
int sum = 0;
for( i = 0; i < nums->len; i++) {
sum += g_array_index(nums, int, i);
}
return sum / nums->len;
}
int main(int argc, char **argv) {
int _nums[] = {94, 28, 54, 72, 89};
GArray *nums = g_array_new(FALSE, FALSE, sizeof(int));
g_array_append_vals(nums, _nums, 5);
double meanVal = mean(nums);
int i;
for( i = 0; i < nums->len; i++ ) {
printf("%d ", g_array_index(nums, int, i));
}
printf("\n");
printf("Mean: %.2lf\n", meanVal);
g_array_free(nums, TRUE);
return 0;
}

What is the simplest way of implementing bigint in C?

I am trying to calculate 100! (that is, the factorial of 100).
I am looking for the simplest way to accomplish this using C. I have read around but have not found a concrete answer.
If you must know, I program in Xcode in Mac os X.
If you're looking for a simple library, libtommath (from libtomcrypt) is probably what you want.
If you're looking to write a simple implementation yourself (either as a learning exercise or because you only need a very limited subset of bigint functionality and don't want to tack on a dependency to a large library, namespace pollution, etc.), then I might suggest the following for your problem:
Since you can bound the size of the result based on n, simply pre-allocate an array of uint32_t of the required size to hold the result. I'm guessing you'll want to print the result, so it makes sense to use a base that's a power of 10 (i.e. base 1000000000) rather than a power of 2. That is to say, each element of your array is allowed to hold a value between 0 and 999999999.
To multiply this number by a (normal, non-big) integer n, do something like:
uint32_t carry=0;
for(i=0; i<len; i++) {
uint64_t tmp = n*(uint64_t)big[i] + carry;
big[i] = tmp % 1000000000;
carry = tmp / 1000000000;
}
if (carry) big[len++] = carry;
If you know n will never be bigger than 100 (or some other small number) and want to avoid going into the 64-bit range (or if you're on a 64-bit platform and want to use uint64_t for your bigint array), then make the base a smaller power of 10 so that the multiplication result will always fit in the type.
Now, printing the result is just something like:
printf("%lu", (long)big[len-1]);
for(i=len-1; i; i--) printf("%.9lu", (long)big[i-1]);
putchar('\n');
If you want to use a power of 2 as the base, rather than a power of 10, the multiplication becomes much faster:
uint32_t carry=0;
for(i=0; i<len; i++) {
uint64_t tmp = n*(uint64_t)big[i] + carry;
big[i] = tmp;
carry = tmp >> 32;
}
if (carry) big[len++] = carry;
However, printing your result in decimal will not be so pleasant... :-) Of course if you want the result in hex, then it's easy:
printf("%lx", (long)big[len-1]);
for(i=len-1; i; i--) printf("%.8lx", (long)big[i-1]);
putchar('\n');
Hope this helps! I'll leave implementing other things (like addition, multiplication of 2 bigints, etc) as an exercise for you. Just think back to how you learned to do base-10 addition, multiplication, division, etc. in grade school and teach the computer how to do that (but in base-10^9 or base-2^32 instead) and you should have no problem.
If you're willing to use a library implementation the standard one seems to be GMP
mpz_t out;
mpz_init(out);
mpz_fac_ui(out,100);
mpz_out_str(stdout,10,out);
should calculate 100! from looking at the docs.
You asked for the simplest way to do this. So, here you go:
#include <gmp.h>
#include <stdio.h>
int main(int argc, char** argv) {
mpz_t mynum;
mpz_init(mynum);
mpz_add_ui(mynum, 100);
int i;
for (i = 99; i > 1; i--) {
mpz_mul_si(mynum, mynum, (long)i);
}
mpz_out_str(stdout, 10, mynum);
return 0;
}
I tested this code and it gives the correct answer.
You can also use OpenSSL bn; it is already installed in Mac OS X.
You can print factorial 1000 in C with just 30 lines of code, <stdio.h> and char type :
#include <stdio.h>
#define B_SIZE 3000 // number of buffered digits
struct buffer {
size_t index;
char data[B_SIZE];
};
void init_buffer(struct buffer *buffer, int n) {
for (buffer->index = B_SIZE; n; buffer->data[--buffer->index] = (char) (n % 10), n /= 10);
}
void print_buffer(const struct buffer *buffer) {
for (size_t i = buffer->index; i < B_SIZE; ++i) putchar('0' + buffer->data[i]);
}
void natural_mul_buffer(struct buffer *buffer, const int n) {
int a, b = 0;
for (size_t i = (B_SIZE - 1); i >= buffer->index; --i) {
a = n * buffer->data[i] + b;
buffer->data[i] = (char) (a % 10);
b = a / 10;
}
for (; b; buffer->data[--buffer->index] = (char) (b % 10), b /= 10);
}
int main() {
struct buffer number_1 = {0};
init_buffer(&number_1, 1);
for (int i = 2; i <= 100; ++i)
natural_mul_buffer(&number_1, i);
print_buffer(&number_1);
}
You will find faster but the “little” factorial(10000) is here computed ≈ instantly.
You can put it into a fact.c file then compile + execute :
gcc -O3 -std=c99 -Wall -pedantic fact.c ; ./a.out ;
If you want to execute some base conversion there is a solution, see also Fibonacci(10000), Thank You.

Resources