C programming. The FizzBuzz program [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
I had a quiz and I wrote this code:
Print Fizz if it is divisible by 3 and it prints Buzz if it is
divisible by 5. It prints FizzBuss if it is
divisible by both. Otherwise, it will print the numbers between 1 and 100.
But after I arrived home, I wondered if could have
writen it with less code. However, I could not come out
with a shorter code.
Can I do it with a shorter code? Thanks.
This is what I wrote and I think it works well. But can I have done it
with less code.
#include <stdio.h>
int main(void)
{
int i;
for(i=1; i<=100; i++)
{
if(((i%3)||(i%5))== 0)
printf("number= %d FizzBuzz\n", i);
else if((i%3)==0)
printf("number= %d Fizz\n", i);
else if((i%5)==0)
printf("number= %d Buzz\n", i);
else
printf("number= %d\n",i);
}
return 0;
}

You could also do:
#include <stdio.h>
int main(void)
{
int i;
for(i=1; i<=100; ++i)
{
if (i % 3 == 0)
printf("Fizz");
if (i % 5 == 0)
printf("Buzz");
if ((i % 3 != 0) && (i % 5 != 0))
printf("number=%d", i);
printf("\n");
}
return 0;
}
A few lines shorter, and a lot easier to read.

I'm not sure when you'd start calling it unreadable, but there's this.
#include <stdio.h>
int main(void)
{
int i = 1;
for (; i<=100; ++i) {
printf("number= %d %s%s\n", i, i%3?"":"Fizz", i%5?"":"Buzz");
}
return 0;
}

If a number is divisible by both 3 and 5, then it's divisible by 15, so:
for each number 1 to 100:
if number % 15 == 0:
print number, "fizzbuzz"
else if number % 5 == 0:
print number, "buzz"
else if number % 3 == 0:
print number, "fizz"
else:
print number
Other than that, you probably won't get it much shorter, at least in a conventional language like C (and I'm assuming you don't want the normal code-golf style modifications that make your code unreadable).
You could also get the whole thing into two lines if you packed the entire main function onto a single large line, but I would hope you wouldn't be after that sort of trickery either.
You can possibly get it faster (though you should check all performance claims for yourself) with something like:
static const char *xyzzy[] = {
"", "", "fizz", "", "buzz",
"fizz", "", "", "fizz", "buzz",
"", "fizz", "", "buzz", "fizzbuzz",
// Duplicate those last three lines to have seven copies (7x15=105).
};
for (int i = 1; i <= 100; i++)
printf ("%d %s\n", i, xyzzy[i-1]);
As an aside, that array of char pointers is likely to be less space-expensive than you think, thanks to constant amalgamation - in other words, it will be likely that there will only be one of each C string.
As I say, whether it's faster should be tested. In addition, your original specs only called for the shortest code so it may be irrelevant.

#include <stdio.h>
char const * template[] = {
"%i",
"Buzz",
"Fizz",
"FizzBuzz"
};
const int __donotuseme3[] = { 2, 0, 0 };
const int __donotuseme5[] = { 1, 0, 0, 0, 0 };
#define TEMPLATE(x) (template[__donotuseme3[(x) % 3] | __donotuseme5[(x) % 5]])
int
main(void) {
int i;
for (i = 1; i <= 100; i++) {
printf(TEMPLATE(i), i);
putchar('\n');
}
return 0;
}

I would say that modulo is expensive while comparisons are cheap so only perform the modulo once. That would yield something like this.
int i;
for( i = 0; i!=100; ++i ) {
bool bModThree = !(i % 3);
bool bModFive = !(i % 5);
if( bModThree || bModFive ) {
if( bModThree ) {
printf( "Fizz" );
}
if( bModFive ) {
printf( "Buzz" );
}
} else {
printf( "%d", i );
}
printf( "\n" );
}

This one avoids some code repetition but requires a temporary variable char t
void FizzBuzz( ) {
char t = 0;
for (unsigned char i = 1; i <= 100; ++i, t = 2) {
(i % 3) ? --t : printf("Fizz");
(i % 5) ? --t : printf("Buzz");
if (!t) printf("%d", i);
printf("\n");
}
}

i would write something like that
main(){
if (i % 3 == 0){
cout<<"Fizz";
}
if (i % 5 == 0){
cout<<"Buzz";
}
// So if both are true, it will print “FizzBuzz” and augment the two strings
}

I'd go with a helper function :-)
#include <stdio.h>
int fbindex(int n) {
int i = 0;
if (n % 3 == 0) i += 1;
if (n % 5 == 0) i += 2;
return i;
}
int main(void) {
const char *fb[] = {"%d\n", "Fizz\n", "Buzz\n", "FizzBuzz\n"};
for (int i = 1; i <= 100; i++) printf(fb[fbindex(i)], i);
}

void main()
{
int i = 0;
char h[4];
while (++i <= 100)
{
sprintf(h, "%d", i);
printf("%s%s%s\n", i%3 ? "" : "fizz", i%5 ? "" : "buzz", (i%3 && i%5) ? h: "");
}
}

You can do it using a String:
String s="";
if(num%3==0)
s+="fizz";
if(num%5==0)
s+="buzz";
if(s.length()==0)
s+=num+"";

Obfuscated form of Mr Lister's answer
main(int i){while(i++<100){printf("number= %d %s%s",i,i%3?"":"Fizz",i%5?"":"Buzz");}}

Related

How do I generate 4 random variables and only printing if it doesn't contain the int 0

this is my code, I want to make a function that when it is called will generate a number between 1111 to 9999, I don't know how to continue or if I've written this right. Could someone please help me figure this function out. It suppose to be simple.
I had to edit the question in order to clarify some things. This function is needed to get 4 random digits that is understandable from the code. And the other part is that i have to make another function which is a bool. The bool needs to first of get the numbers from the function get_random_4digits and check if there contains a 0 in the number. If that is the case then the other function, lets call it unique_4digit, should disregard of that number that contained a 0 in it and check for a new one to use. I need not help with the function get_random_4digitsbecause it is correct. I need helt constructing a bool that takes get_random_4digits as an argument to check if it contains a 0. My brain can't comprehend how I first do the get_random_4digit then pass the answer to unique_4digits in order to check if the random 4 digits contains a 0 and only make it print the results that doesn't contain a 0.
So I need help with understanding how to check the random 4 digits for the integer 0 and not let it print if it has a 0, and only let the 4 random numbers print when it does not contain a 0.
the code is not suppose to get more complicated than this.
int get_random_4digit(){
int lower = 1000, upper = 9999,answer;
answer = (rand()%(upper-lower)1)+lower;
return answer;
}
bool unique_4digits(answer){
if(answer == 0)
return true;
if(answer < 0)
answer = -answer;
while(answer > 0) {
if(answer % 10 == 0)
return true;
answer /= 10;
}
return false;
}
printf("Random answer %d\n", get_random_4digit());
printf("Random answer %d\n", get_random_4digit());
printf("Random answer %d\n", get_random_4digit());
Instead of testing each generated code for a disqualifying zero just generate a code without zero in it:
int generate_zero_free_code()
{
int n;
int result = 0;
for (n = 0; n < 4; n ++)
result = 10 * result + rand() % 9; // add a digit 0..8
result += 1111; // shift each digit from range 0..8 to 1..9
return result;
}
You can run the number, dividing it by 10 and checking the rest of it by 10:
int a = n // save the original value
while(a%10 != 0){
a = a / 10;
}
And then check the result:
if (a%10 != 0) printf("%d\n", n);
Edit: making it a stand alone function:
bool unique_4digits(int n)
{
while(n%10 != 0){
n = n / 10;
}
return n != 0;
}
Usage: if (unique_4digits(n)) printf("%d\n", n);
To test if the number doesn't contain any zero you can use a function that returns zero if it fails and the number if it passes the test :
bool FourDigitsWithoutZero() {
int n = get_random_4digit();
if (n % 1000 < 100 || n % 100 < 10 || n % 10 == 0) return 0;
else return n;
}
"I need not help with the function get_random_4digits because it is correct."
Actually the following does not compile,
int get_random_4digit(){
int lower = 1000, upper = 9999,answer;
answer = (rand()%(upper-lower)1)+lower;
return answer;
}
The following includes modifications that do compile, but still does not match your stated objectives::
int get_random_4digit(){
srand(clock());
int lower = 1000, upper = 9999,answer;
int range = upper-lower;
answer = lower + rand()%range;
return answer;
}
" I want to make a function that when it is called will generate a number between 1111 to 9999,"
This will do it using a helper function to test for zero:
int main(void)
{
printf( "Random answer %d\n", random_range(1111, 9999));
printf( "Random answer %d\n", random_range(1111, 9999));
printf( "Random answer %d\n", random_range(1111, 9999));
printf( "Random answer %d\n", random_range(1111, 9999));
return 0;
}
Function that does work follows:
int random_range(int min, int max)
{
bool zero = true;
char buf[10] = {0};
int res = 0;
srand(clock());
while(zero)
{
res = min + rand() % (max+1 - min);
sprintf(buf, "%d", res);
zero = if_zero(buf);
}
return res;
}
bool if_zero(const char *num)
{
while(*num)
{
if(*num == '0') return true;
num++;
}
return false;
}

I need help about arrays

Program Explain:
1/2/3
2 3 5
2 9 4
2 5 7
if i write 1in up it give me 2+9+7
if i write 2in up it give me 5+9+2
if i write 3in up it give me (2+9+7)-(5+9+2)
(BUT IT GIVES WARING:
* stack smashing detected *: unknown terminated
Aborted (core dumped)
)
#include <stdio.h>
#include <math.h>
int main()
{
int whatUDo;
int square[2][2];
int counter1 = 0, counter2 = 0, counter3 = 0;
int threeTime = 3;
scanf("%d", &whatUDo);
while (counter1 < 3)
{
scanf("%d", &square[0][counter1]);
counter1++;
}
while (counter2 < 3)
{
scanf("%d", &square[1][counter2]);
counter2++;
}
while (counter3 < 3)
{
scanf("%d", &square[2][counter3]);
counter3++;
}
int first = square[0][0] + square[1][1] + square[2][2];
int second = square[0][2] + square[1][1] + square[2][0];
int third = first - second;
if (whatUDo == 1)
{
printf("%d", first);
}
else if (whatUDo == 2)
{
printf("%d", second);
}
else if (whatUDo == 3)
{
printf("%d", third);
}
return 0;
}
TL;DR
The size of your array is wrong.
For the code you have provided, you have to declare your array as
int square[3][3];
Because the boundaries you are handling are from 0..2 and 0..2, respectively. The number you specify when declaring the array is the size, not the maximum index allowed.
In other way, if you declare:
int myarray[5];
The items of your array are accessed from 0 to 4, and your array has a capacity of 5 items accessed by the indices 0, 1, 2, 3 and 4.

Specific dice to reroll in C

I am working on a game of Yahtzee and one part of the game is the user can choose which dice out of 5 they wish to re-roll. I don't really know how to approach this besides writing a ton of if if-else statements, but there has to be a more efficient way to re-roll the specific die/ dice. I wrote out a snippet of what I am trying to accomplish, its not exactly like this in my actual code, but hopefully it is enough to answer the question :)
#include<stdio.h>
int main(void)
{
int die1 = 0, die2 = 0, die3 = 0, die4 = 0, die5 = 0;
int *ptr_die1 = &die1, *ptr_die2 = &die2, *ptr_die3 = &die3, *ptr_die4 = &die4, *ptr_die5 = &die5;
int choice = 0;
int die[5] = { 0 };
for (int i = 0; i < 5; i++)
{
die[i] = rand() % 6 + 1;
}
printf("Die[1] = %d\n", die[0]);
printf("Die[2] = %d\n", die[1]);
printf("Die[3] = %d\n", die[2]);
printf("Die[4] = %d\n", die[3]);
printf("Die[5] = %d\n", die[4]);
choice = printf("Please select which die to reroll\n");
scanf("%d", &choice);
printf("%d\n", choice);
for (int i = 0; i < 5; i++)
{
die[choice-1] = rand() % 6 + 1;
}
printf("Die[1] = %d\n", die[0]);
printf("Die[2] = %d\n", die[1]);
printf("Die[3] = %d\n", die[2]);
printf("Die[4] = %d\n", die[3]);
printf("Die[5] = %d\n", die[4]);
return 0;
}
after this I am really lost on how to change the die because the user could want to change just 1, or all 5 or any combination in between...
You have way too many variables that are not really needed.
int main(int argc, char **argv)
{
int i;
int choice;
int dices[5];
srand(time(NULL));
while(1){
for (i = 0; i < 5; i++)
dices[i] = rand() % 6 + 1;
choice = printf("Please select which die to reroll (or enter 0 to quit)");
scanf("%d", &choice);
if (choice == 0) // end the game
break;
if (choice < 1 || choice > 5 ){ // make sure that input is valid
fprintf(stderr, "error, input should be between 1 to 5 (inclusive)\n");
return -1;
}
printf("dice shows: %d", dices[choice-1]);
}
return 0;
}
You need to ask the user for the ending it, e.g. "Enter 0 to end the game". Otherwise it would be an infinite loop.
You could have the user input a comma-separatd list of die, instead of a single integer, which it looks like you're doing now. Then just parse the input, check that you have between 1 and 5 valid integers less than 6, and index into each die.
Or you could do like kaylum suggested and loop until the user inputs a special string indicating they're done, or prompt for 1, 2, ... 5 and ask for a yes or no answer to each.
Just use an array of int values to represent the set of dice:
#define DICE_COUNT 6
void rollDice(int* diceArray, size_t diceIndex) {
assert( 0 <= diceIndex && diceIndex < DICE_COUNT );
diceArray[ diceIndex ] = rand() % 6 + 1;
}
int main(int argc, char* argv[]) {
// Seed the RNG:
srand( (unsigned)time(&t) );
int dice[DICE_COUNT];
for(size_t i = 0; i < DICE_COUNT; i++) {
rollDice( dice, i );
}
while( true ) {
printf("Please select which die to reroll. Enter -2 to quit. (%d to %d inclusive)", 1, DICE_COUNT);
int selection = -1;
scanf("%d", &selection);
if( selection == -2 ) break;
if( 1 <= selection && selection <= DICE_COUNT ) {
selection--; // convert from 1-6 to 0-5.
rollDice( dice, selection );
}
}
return EXIT_SUCCESS;
}
I don't see any if..else statements in your code above. I will say, in this chunk of code:
for (int i = 0; i < 5; i++)
{
die[choice-1] = rand() % 6 + 1;
}
You don't need the for loop. You are not using the index, and rand() should work the first time through. I know rand() isn't the best written function, but if you seed it first, it should give you a pseudo-random number.
#include <time.h>
...
/* initialize random seed: */
srand ( time(NULL) );
...
die[choice-1] = rand() % 6 + 1;
Hope this was helpful, if you are still even working on that project!

Pi spigot, implemented in C, segfaults when number of digits is too high [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I have made an implementation of a spigot algorithm in C, however, it segfaults (SIGSEGV) when the number of decimals to calculate is too high. The number of digits the error occurs at is slightly different on a few different windows computers I have, but it happens around 156210. I would give only the relevant code, but I honestly don't really understand the error, so I will give you my full code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int held[20]; //I wont have 19 consecutive 9's in pi, right?
int held_length = sizeof(held)/sizeof(int);
FILE *f;
void releaseDigits() {
int c;
for(c = held_length-1; c >= 0; c--) {
if(held[c] != -1) {
//printf("release: %i\n", held[c]); //debugging output
fprintf(f, "%i", held[c]);
}
}
}
void incHeld() {
int c;
for(c = held_length-1; c >= 0; c--) {
if(held[c] != -1) {
held[c]++;
}
}
}
void blankHeld() {
int c;
for(c = held_length-1; c >= 0; c--) {
held[c] = -1;
}
/*for(c = 0; c < held_length; c++) {
printf("BLANK_%i:%i\n", c, held[c]);
}*/ //debugging output
}
void deleteLast() {
int c = held_length-1;
while(held[c] != -1) {
c--;
}
held[c+1] = -1;
}
void holdDigit(int hold) {
int c = held_length-1;
while(held[c] != -1) {
c--;
}
held[c] = hold;
for(c = 0; c < held_length; c++) {
//printf("held_%i:%i\n", c, held[c]); //debugging output
}
}
void main() {
time_t start, end;
int n; //decimals of pi, 156207 max if printf, 156210 if fprintf, higher = sivsegv
printf("Decimal places of pi to calculate (max 156210 for now): ");
scanf("%i", &n);
start = clock();
f = fopen("pi.txt", "w"); //open file
if (f == NULL) {
printf("Error opening file!\n");
exit(1);
}
n++; //overcompensate for odd ending digit error
//initial array of 2,2,2,...2
int rem[((10*n)/3)+2]; //sizeof(one)/sizeof(int);
int init_count;
for(init_count = 0; init_count < ((10*n)/3)+2; init_count++) {
rem[init_count] = 2;
}
//main digit loop
int carry;
int decimal;
int pi_digit;
for(decimal = 0; decimal <= n; decimal++) {
carry = 0;
int sum;
int i;
for(i = (10*n)/3 + 1; i >= 1; i--) {
sum = (rem[i]*10)+carry;
rem[i] = sum % ((2*i)+1);
carry = ((sum-rem[i])/((2*i)+1))* i;
//printf("decimal:%i i:%i B:%i carry:%i sum:%i rem:%i\n", decimal, i, (2*i)+1, carry, sum, rem[i]); //debugging output
}
sum = (rem[0]*10)+carry;
rem[0] = sum % 10;
pi_digit = (sum - rem[0])/10;
//printf("sum:%i rem:%i\n",sum, rem[i]); //debugging output
if(pi_digit != 10) {
if(pi_digit != 9) {
if(decimal > 0) {
releaseDigits();
}
if(decimal == 1) {
fprintf(f, "."); //shove a point up in that shit
}
blankHeld();
holdDigit(pi_digit);
}
else {
holdDigit(pi_digit);
}
}
else {
incHeld();
releaseDigits();
blankHeld();
holdDigit(0);
}
printf("\r%i/%i decimal places done... ", decimal-1, n-1);
}
deleteLast(); //hide overcompensation
releaseDigits();
fclose(f);
end = clock();
int raw_seconds = (end - start)/1000.;
int seconds = raw_seconds % 60;
int minutes = (raw_seconds - seconds)/60;
printf("\n\nSuccessfully calculated %i decimal places of pi in %i minutes and %i seconds!\nSaved to pi.txt\nPress ENTER to exit the program.\n", n-1, minutes, seconds);
while(getch()!=0x0d);
}
What is happening here?
I used Valgrind, the famous memory checking tool, on your code. Relatively small values (i.e., 10, 100, 1000, even 10000) were no problem. Attempting 156210 instantly made Valgrind complain. It looks like the problem starts with this line:
int rem[((10*n)/3)+2];
The problem is that allocating storage in this manner asks for memory from the stack and this computed value ((10 * 156210 / 3 + 2) = 520702, sizeof(int) = 4 on Windows, so 520702 * 4 = about 2MB) is far more than the machine is prepared to give you from the stack.
If you need this much memory, better to allocate it from the heap using malloc() (don't forget to free() it afterwards).

UVA's 3n+1 wrong answer although the test cases are correct . . .?

UVA problem 100 - The 3n + 1 problem
I have tried all the test cases and no problems are found.
The test cases I checked:
1 10 20
100 200 125
201 210 89
900 1000 174
1000 900 174
999999 999990 259
But why I get wrong answer all the time?
here is my code:
#include "stdio.h"
unsigned long int cycle = 0, final = 0;
unsigned long int calculate(unsigned long int n)
{
if (n == 1)
{
return cycle + 1;
}
else
{
if (n % 2 == 0)
{
n = n / 2;
cycle = cycle + 1;
calculate(n);
}
else
{
n = 3 * n;
n = n + 1;
cycle = cycle+1;
calculate(n);
}
}
}
int main()
{
unsigned long int i = 0, j = 0, loop = 0;
while(scanf("%ld %ld", &i, &j) != EOF)
{
if (i > j)
{
unsigned long int t = i;
i = j;
j = t;
}
for (loop = i; loop <= j; loop++)
{
cycle = 0;
cycle = calculate(loop);
if(cycle > final)
{
final = cycle;
}
}
printf("%ld %ld %ld\n", i, j, final);
final = 0;
}
return 0;
}
The clue is that you receive i, j but it does not say that i < j for all the cases, check for that condition in your code and remember to always print in order:
<i>[space]<j>[space]<count>
If the input is "out of order" you swap the numbers even in the output, when it is clearly stated you should keep the input order.
Don't see how you're test cases actually ever worked; your recursive cases never return anything.
Here's a one liner just for reference
int three_n_plus_1(int n)
{
return n == 1 ? 1 : three_n_plus_1((n % 2 == 0) ? (n/2) : (3*n+1))+1;
}
Not quite sure how your code would work as you toast "cycle" right after calculating it because 'calculate' doesn't have explicit return values for many of its cases ( you should of had compiler warnings to that effect). if you didn't do cycle= of the cycle=calculate( then it might work?
and tying it all together :-
int three_n_plus_1(int n)
{
return n == 1 ? 1 : three_n_plus_1((n % 2 == 0) ? (n/2) : (3*n+1))+1;
}
int max_int(int a, int b) { return (a > b) ? a : b; }
int min_int(int a, int b) { return (a < b) ? a : b; }
int main(int argc, char* argv[])
{
int i,j;
while(scanf("%d %d",&i, &j) == 2)
{
int value, largest_cycle = 0, last = max_int(i,j);
for(value = min_int(i,j); value <= last; value++) largest_cycle = max_int(largest_cycle, three_n_plus_1(value));
printf("%d %d %d\r\n",i, j, largest_cycle);
}
}
Part 1
This is the hailstone sequence, right? You're trying to determine the length of the hailstone sequence starting from a given N. You know, you really should take out that ugly global variable. It's trivial to calculate it recursively:
long int hailstone_sequence_length(long int n)
{
if (n == 1) {
return 1;
} else if (n % 2 == 0) {
return hailstone_sequence_length(n / 2) + 1;
} else {
return hailstone_sequence_length(3*n + 1) + 1;
}
}
Notice how the cycle variable is gone. It is unnecessary, because each call just has to add 1 to the value computed by the recursive call. The recursion bottoms out at 1, and so we count that as 1. All other recursive steps add 1 to that, and so at the end we are left with the sequence length.
Careful: this approach requires a stack depth proportional to the input n.
I dropped the use of unsigned because it's an inappropriate type for doing most math. When you subtract 1 from (unsigned long) 0, you get a large positive number that is one less than a power of two. This is not a sane behavior in most situations (but exactly the right one in a few).
Now let's discuss where you went wrong. Your original code attempts to measure the hailstone sequence length by modifying a global counter called cycle. However, the main function expects calculate to return a value: you have cycle = calculate(...).
The problem is that two of your cases do not return anything! It is undefined behavior to extract a return value from a function that didn't return anything.
The (n == 1) case does return something but it also has a bug: it fails to increment cycle; it just returns cycle + 1, leaving cycle with the original value.
Part 2
Looking at the main. Let's reformat it a little bit.
int main()
{
unsigned long int i=0,j=0,loop=0;
Change these to long. By the way %ld in scanf expects long anyway, not unsigned long.
while (scanf("%ld %ld",&i,&j) != EOF)
Be careful with scanf: it has more return values than just EOF. Scanf will return EOF if it is not able to make a conversion. If it is able to scan one number, but not the second one, it will return 1. Basically a better test here is != 2. If scanf does not return two, something went wrong with the input.
{
if(i > j)
{
unsigned long int t=i;i=j;j=t;
}
for(loop=i;loop<=j;loop++)
{
cycle=0;
cycle=calculate(loop );
if(cycle>final)
{
final=cycle;
}
}
calculate is called hailstone_sequence_length now, and so this block can just have a local variable: { long len = hailstone_sequence_length(loop); if (len > final) final = len; }
Maybe final should be called max_length?
printf("%ld %ld %ld\n",i,j,final);
final=0;
final should be a local variable in this loop since it is separately used for each test case. Then you don't have to remember to set it to 0.
}
return 0;
}

Resources