finding count of minima or maxima in a set of numbers - c

The user inputs n number of datas to be followed in the next line and
then it inputs n numbers a1,a2,...,an. These numbers are heights of a
some mountains. The set of these numbers is "ACCEPTABLE" if there is
only one maxima or minima. for example "1 2 3 2 1", has only one
maxima which is 3. Also "1 2 3 4" has one maxima. but "1 10 9 8 7 6 5
6 7" is not acceptable because it has two maxima (10 and 7) or two
minima (1 and 5).
In other word, the set is acceptable if and only if it is in one of
this forms:
a1<=a2<=a3 ... <= ai > a(i+1) > ... >an
or
a1>=a2>=a3 ... >= ai < a(i+1) < ... < an.
I must submit the answer in a judge system which tests it with unknown test cases. Using any type of Array or Vector is completely prohibited.
My solution is this:
//C code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,temp;
scanf("%d",&n);
if (n==1)
{
int l;
scanf("%d",&l);
printf("Yes");
}
else
{
int a,b;
int last;
int changes =0;
int dec =0 , inc =0; //flag: checking if the set is incremental or decremental till now
scanf("%d %d",&a,&b);
if (a>b)
{
dec=1;
}
else if (a<b)
{
inc = 1;
}
else
{
inc =1;
dec = 1;
}
last = b;
for (int i =2;i<n;i++)
{
scanf("%d",&temp);
if (temp>last && dec==1)
{
inc = 1;
dec= 0;
changes++;
}
if (temp<last && inc==1)
{
inc =0;
dec=1;
changes++;
}
if (!(inc==1 && dec==1) && temp == last)
{
changes++;
}
last = temp;
last = temp;
}
if (changes <=1)
{
printf("Yes");
}
else
{
printf("No");
}
}
return 0;
}
It gets the right answer for the examples that are in the question but it fails on some unknown test cases. Any idea how to fix this? Can anyone give me a test case that is not solved right in this code?
P.1:
I added
if (!(inc==1 && dec==1) && temp == last)
{
changes++;
}
and it accepted one of the failing test cases but still one remains.
P.2:
This is my other algorithm which fails on some test cases but the judge accepts its answers on the failing test cases of the first one:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
int inc=0;
int dec=0;
int peak=0;
int valley=0;
int last = -1;
int a;
scanf("%d",&n);
for (int i =0;i<n;i++)
{
if (last!=-1)
{
last =a;
}
scanf("%d",&a);
if (last!=-1)
{
if (a>last)
{
if (!(inc==1))
{
valley++;
inc =1;
dec=0;
}
}
if (a<last)
{
if (!(dec==1))
{
peak++;
dec=1;
inc =0;
}
}
}
last =0;
}
if (valley<=1 && peak<=1)
{
// printf("valley: %d , peak:%d",valley,peak);
printf("Yes");
}
else
{
printf("No");
}
return 0;
}
P.3
New algorithm:
#include <stdio.h>
#include <stdlib.h>
int main()
{
long long int n,temp;
scanf("%lld",&n);
if (n==1)
{
long long int l;
scanf("%lld",&l);
printf("Yes");
}
else
{
long long int a,b;
long long int last;
long long int changes =0;
int dec =0 , inc =0; //flag: checking if the set is incremental or decremental till now
scanf("%lld %lld",&a,&b);
if (a>b)
{
dec=1;
}
else if (a<b)
{
inc = 1;
}
else
{
inc =1;
dec = 1;
}
last = b;
for (long long int i =2;i<n;i++)
{
scanf("%lld",&temp);
if (temp>last && dec==1)
{
inc = 1;
dec= 0;
changes++;
}
if (temp<last && inc==1)
{
inc =0;
dec=1;
changes++;
}
if (changes>=1 && temp == last)//new change
{
changes+=100;
}//end of new change
last = temp;
}
if (changes <=1)
{
printf("Yes");
}
else
{
printf("No");
}
}
return 0;
}

scanf("%d",l); should be scanf("%d", &l);, scanf requires the address of the variable.
So the test cases with n == 1 failed.
Always have a look at the compiler warnings: https://ideone.com/MKq3WK

“4 1 1 2 1” says “No” but should say “Yes”. The code does not correctly handle the case where inc and dec are both 1 initially.
Additionally, the code must use different criteria for the first part of the sequence (up until the first change in direction is observed) and the second. In the first part, equality is permitted and does not cause any disqualification or change of state. In the second part, equality is disqualifying.
Joke
I should not do this, but sometimes one cannot resist. The following should solve the problem. Do not use it.
#include <stdio.h>
int main(void)
{
int c, n, p, s;
scanf("%d%d", &n, &c);
#define Table \
{ 1, 0, 3 }, \
{ 1, 1, 2 }, \
{ -1, -1, 2 }, \
{ 4, 3, 3 }, \
{ 4, -1, -1 }, \
for (s = 0; 0 <= s && --n; s = (int [][3]) {Table} [s] [1+(p>c)-(p<c)])
{ p = c; scanf("%d", &c); }
printf("%s\n", 0 <= s ? "Yes" : "No");
}

With the P.2 solution, "4 1 2 1 1" is accepted, but it should not, since 1 is not greater than 1!

We have to detect a change of direction of the inequality, then disallow a further change. Anyway, as long as the elements are equal, you cannot make up your mind between growing or decreasing.
I would use a state variable with six possible values:
x: no element has been input yet;
0: we don't know anything;
1: we are in the initial raising section;
-1: we are in the initial falling section;
2: we are in the final raising section;
-2: we are in the final falling section.
Considering the previous and current input values, the following transitions apply:
State x: -> 0 (unconditionally)
State 0: p < c -> 1, p > c -> -1
State 1: p > c -> -2
State -1: p < c -> 2
State 2: p >= c -> Fail
State -2: p <= c -> Fail
The initial state is x. If we never fail, success is assumed when the input has been exhausted. This can be implemented with a simple switch statement and two static variables to remember the previous value and the state.
The specifications are unclear about whether some section can be empty, so I'll leave it as is.
Python proof of concept:
Input= [1, 2, 3, 2, 1]
#Input= [1, 10, 9, 8, 7, 6, 5, 6, 7]
#Input= [1, 2, 3, 4]
#Input= [4, 1, 2, 1, 1]
def Process(c):
global p, s
if s == None:
s= 0
elif s == 0:
if p < c:
s= 1
elif p > c:
s= -1
elif s == 1:
if p > c:
s= -2
elif s == -1:
if p < c:
s= 2
elif s == 2:
if p >= c:
exit(-1)
elif s == -2:
if p <= c:
exit(-1)
p= c
s= None
for c in Input:
Process(c)

The judge finally accepted this code. The main problems was with the conditions were some numbers get equal like 111222. Also the problem statement was right and it was not <= or >= after the ai.
Code in C:
#include <stdio.h>
#include <stdlib.h>
int main()
{
long long int n,temp;
scanf("%lld",&n);
if (n==1)
{
long long int l;
scanf("%lld",&l);
printf("Yes");
}
else
{
long long int a,b;
long long int last;
int flag =1;
long long int changes =0;
int incr=0,decr=0;
int equ=0;
int dec =0 , inc =0; //flag: checking if the set is incremental or decremental till now
scanf("%lld %lld",&a,&b);
if (a>b)
{
dec=1;
}
else if (a<b)
{
inc = 1;
}
else
{
equ=1;
}
last = b;
for (long long int i =2;i<n;i++)
{
scanf("%lld",&temp);
if (temp > last && equ==1)
{
inc = 1;
dec=0;
equ=0;
}
else if (temp <last && equ==1)
{
inc = 0;
dec = 1;
equ= 0;
}
else if (temp>last && dec==1)
{
inc = 1;
dec= 0;
changes++;
incr++;
}
else if (temp<last && inc==1)
{
inc =0;
dec=1;
changes++;
decr++;
}
if (changes>=1 && temp == last && incr>=0 && decr >=0)
{
flag = 0;
changes+=100;
}
last = temp;
}
if (changes <=1&& flag)
{
printf("Yes");
}
else
{
printf("No");
}
}
return 0;
}

Related

Cycle through an array in either direction based on a bool

I'm looking for a method of looping through some array in either direction based on some passed bool value, with the same functionality as:
void Transfer(bool *_payload, int _size, bool _isLSB)
{
if (_isLSB)
{
for (int i = _size - 1; i >= 0; i--)
{
digitalWrite(dataPin, _payload[i]);
}
}
else
{
for (int i = 0; i < _size; i++)
{
digitalWrite(dataPin, _payload[i]);
}
}
}
or
void Transfer(bool *_payload, int _size, bool _isLSB)
{
int _index = 0;
if (_isLSB) _index = _size - 1;
for (;;)
{
printf("%d",_payload[_index]);
if (_isLSB) _index--;
else _index++;
if (_isLSB && _index < 0) break;
if (!_isLSB && _index >= _size) break;
}
}
Other than creating a method that reverses the array, is there a nice simplification of this?
You can define the starting and ending point and the increment conditionally:
void Transfer(bool *_payload, int _size, bool _isLSB)
{
int increment = _isLSB ? -1 : 1;
int i = _isLSB ? _size : -1; // one before the area to scan
int end = _isLSB ? -1 : _size; // one past the area
while ((i += increment) != end) // incr/decr before testing
{
digitalWrite(dataPin, _payload[i]);
}
}
We do not know in advance which way the index will be changing (incrementing or decrementing), so we can't use less-than or greater-than in the loop condition. And after processing the last item the index will be modified once more, hence the stopping point is one past the area being processed.
Similarly we need the starting point one position before the scanned area, so that after incrementing (or decrementing) the index we process the valid, first item.
You can calculate the direction and the start/end position for the for loop depending on _isLSB
void Transfer(bool* _payload, int _size, bool _isLSB) {
int dir;
int start;
int end;
if(_isLSB) {
dir = -1;
start = _size-1;
end = -1;
}else {
dir = 1;
start = 0;
end = _size;
}
for(int i = start; i != end; i+=dir) {
digitalWrite(dataPin, _payload[i]);
}
}
What you could do for example, since in C true and false are expanded to integer values in reality, is to use said integer value for calculations.
In the following example I will extract the main problem from your question which is: Looping over a size in a direction depending on a boolean value
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
int main()
{
int size = 5;
bool condition = false;
// Option #1
printf("Option #1\n");
for (int i = (size - 1) * condition; (i >= 0 && condition) || (i < size && !condition); i += 1 * pow(-1, condition))
{
printf("%d", i);
}
// Option #2
printf("\nOption #2\n");
int i = (size - 1) * condition;
for (;;)
{
printf("%d", i);
i += 1 * pow(-1, condition);
if ((i < 0 && condition) || (i >= size && !condition))
break;
}
return 0;
}
With the main function giving the following output for condition = true
Option #1
01234
Option #2
01234
And the following output for condition = false
Option #1
43210
Option #2
43210

how to see if there are 1 or 2 poker pairs in a hand in C

I am trying to develop a C program that checks if there are 1 or 2 pairs in a 5 card poker hand.
I am using a 5x3 array where every line is a card (the 3rd column being for the \0 character). Every time I execute the code it always shows the "two pairs" print.
I want to make sure that each letter (i, j, a, b) representing each line is different. Any help?
P.S.: This is for a university/college project, I have only started programming a few months ago from absolute scratch, so any detailed explanations on my mistakes would be very much appreciated :)
#include <stdio.h>
#include <stdlib.h>
char (cards[5][3])=
{
"5S", "6D", "4H", "KD", "5C"
};
int main ()
{
pair (cards[5][3]);
return 0;
}
void pair (char (arg[n][0]))
{
int i,j,a,b;
if (i!=j!=a!=b)
{
if ((arg[i][0]==arg[a][0])&&(arg[b][0]!=arg[j][0]))
{
printf("2 -> pair");
}
if ((arg[i][0]==arg[a][0])&&(arg[b][0]==arg[j][0]));
{
printf("3 -> two pairs");
}
if ((arg[i][0]!=arg[a][0])&&(arg[b][0]!=arg[j][0]))
{
printf("there is no pair");
}
}
else
{
printf("there is no pair");
}
}
The posted code has several issues, both logical and syntactical, some have been pointed out in the comments.
Just to pick one, consider this line
if ((arg[i][0]==arg[a][0])&&(arg[b][0]==arg[j][0]));
{
// This body will never be executed ^
}
I'd suggest to restart from scratch and to proceed in small steps. See, for instance, the following minimal implementation
// Include all the needed header files, not the unneeded ones.
#include <stdio.h>
// Declare the functions prototype before their use, they will be defined after.
int count_pairs(int n, char const cards[][3]);
// Always specify the inner size, ^ when passing a multidimensional array
void show_score(int n_pairs);
int have_the_same_value(char const *a, char const *b);
int main (void)
{
char hand[5][3] = {
// ^^^^^^ You could omit the 5, here
"5S", "6D", "4H", "KD", "5C"
};
int n_pairs = count_pairs(5, hand);
// Always pass the size ^ if there isn't a sentinel value in the array
show_score(n_pairs);
return 0;
}
// This is a simple O(n^2) algorithm. Surely not the best, but it's
// a testable starting point.
int count_pairs(int n, char const cards[][3])
{
// Always initialize the variables.
int count = 0;
// Pick every card...
for (int i = 0; i < n; ++i)
{
// Compare (only once) with all the remaining others.
for (int j = i + 1; j < n; ++j)
{ // ^^^^^
if ( have_the_same_value(cards[i], cards[j]) ) {
++count;
}
}
}
return count;
}
int have_the_same_value(char const *a, char const *b)
{
return a[0] == b[0];
}
// Interpret the result of count_pairs outputting the score
void show_score(int n_pairs)
{
switch (n_pairs)
{
case 1:
printf("one pair.\n");
break;
case 2:
printf("two pairs.\n");
break;
case 3:
printf("three of a kind.\n");
break;
case 4:
printf("full house.\n");
break;
case 6:
printf("four of a kind.\n");
break;
default:
printf("no pairs.\n");
}
}
Note that my count_pairs function counts every possible pair, so if you pass three cards of the same kind, it will return 3 (given AC, AS, AD, all the possible pairs are AC AS, AC AD, AS AD).
How to correctly calculate all the poker ranks is left to the reader.
Major improvements can be made to the pair function to make it slimmer. However, this answers your questions and solves several corner cases:
#include <stdio.h>
#include <stdlib.h>
void pairCheck(char hand[][2])
{
int pairCount = 0;
int tmpCount = 0;
char tmpCard = '0';
char foundPairs[2] = {0};
// Check Hand One
for(int i =0; i < 5; i++)
{
tmpCard = hand[i][0];
for(int j = 0; j < 5; j++)
{
if(tmpCard == hand[j][0] && i != j)
{
tmpCount++;
}
if(tmpCount == 1 && (tmpCard != foundPairs[0] && tmpCard != foundPairs[1]))
{
foundPairs[pairCount] = tmpCard;
pairCount++;
}
tmpCount = 0;
}
}
printf("Pair Count Hand One: %i\r\n",pairCount);
//Reset Variables
foundPairs[0] = 0;
foundPairs[1] = 0;
tmpCard = '0';
pairCount = 0;
// Check Hand One
for(int i =0; i < 5; i++)
{
tmpCard = hand[i][1];
for(int j = 0; j < 5; j++)
{
if(tmpCard == hand[j][1] && i != j)
{
tmpCount++;
}
if(tmpCount == 1 && (tmpCard != foundPairs[0] && tmpCard != foundPairs[1]))
{
foundPairs[pairCount] = tmpCard;
pairCount++;
}
tmpCount = 0;
}
}
printf("Pair Count Hand Two: %i",pairCount);
}
int main ()
{
char cards[5][2] = { {'5','H'},{'6','D'},{'4','H'},{'K','D'},{'5','C'}};
pairCheck(cards);
return 0;
}
This function will treat three, four, or five of a kind as a single pair. If you want a different behavior the change should be easy.

Checking array for identical numbers and their value

As part of a program that I have to make, one of the function that I need to program should check if the array has any identical numbers that are the same, and if one of them is bigger/equals to a given number.
The given number is also the amount of numbers in the array
This is what I have so far:
int checkarray(int *arr, int num)
{
int check = num;
int check2 = num;
int *lor;
int *poi;
int *another;
another = arr;
lor = arr;
poi = arr;
int check3 = num;
for ( ; num > 1; num--) {
for ( ; check3 >= 0; check3--) {
if (*arr == *poi)
return 0;
poi++;
}
arr++;
poi = another;
}
for ( ; check2 > 0; check2--) {
if (*lor >= check)
return 0;
lor++;
}
return 1;
}
I know that I made too many pointers/int for the function, but that's not the problem..
The part of checking for a given value works fine if I'm not mistaken so I think you can ignore that part (that's the last 'for' loop)
I know it should be easy but for some reason I just can't get it to work...
Edit:
I'll give an example: If the array is 0 1 2 3 1 the function will return 0, cause the second and the last number are identical. The function will also return 0 if the given number is 5, and one of the numbers is bigger or equals to 5, for example 0 1 2 5 4.
Otherwise, the function returns 1.
I create a new array where I'm going to save the numbers so I can check if you have a repeat number in the array. I also have one more argument in the function to know the size of the array.
#include <stdio.h>
#include <stdlib.h>
int checkArray(int *arr, int size, int number){
int i,j;
int *countArray = calloc(size,sizeof(int));
for(i=0;i<size;i++){
if(arr[i]>=number){ //Check >= number
free(countArray);
return 0;
}
for(j=0;j<i;j++){ //Check repeat number
if(countArray[j]==arr[i]){
free(countArray);
return 0;
}
}
countArray[j]=arr[i]; //no repeat number so we save it.
}
free(countArray);
return -1; //Error
}
int main(){
int arr[6] = {0,8,2,3,4,1};
printf("Result %d",checkArray(arr,6,5));
}
I hope this can help you.
Update without new array
int checkArray(int *arr, int size, int number){
int i,j;
for(i=0;i<size;i++){
if(arr[i]>=number){
return 0;
}
for(j=0;j<i;j++){
if(arr[i]==arr[j]){
return 0;
}
}
}
return -1; //Error
}
Change your upper for loop to:
for ( ; num > 0; num--) {
if(arr[i]>=number){
return 0;
}
int check3 = num;
poi=arr+1;
for ( ; check3 > 0; check3--) {
if (*arr == *poi)
return 0;
poi++;
}
arr++;
}
and remove the bottom one.
The mistakes here are as following:
1- You need to change the lines:
int check3 = num;
for ( ; num > 1; num--) {
to be:
for ( ; num > 1; num --) {
int check3 = check; // Move to inside loop to reset each time for a fresh inner loop and use check instead of num to reset the value
2- You need to change the line:
for ( ; check3 >= 0; check3--) {
To be
for ( ; check3 > 0; check3--) { // Because `>=0` means attempting to read past the array
3- poi should be initialised every time in the loop as arr+1 to skip comparing the same member of the array to itself, and to skip re-comparing members more than one time.
I suggest re-writing the method with better code style to enable easier detection of such errors and typos

Prime no between m and n

I tried a prime no generating question in SPOJ(link : http://www.spoj.com/problems/PRIME1/) .
I'm using seive algorithm . I get the SIGSEGV error when i use spoj gcc . But when i compiled using my ubuntu gcc it works for all the test cases.
Here is my source code . Plz Help
float sqroot( float x)
{
float a , b;
a = x; // copy given value to 'a'
do
{
b = a; // copy value of 'a' to 'b' before 'a' is modify
a = (a + x/a) / 2; // modify 'a' value until we reach sqroot result
}
while( a!= b); // execute loop until a == b
return( a); // 'a ' or 'b' is sqroot of 'x'
}
int main()
{
int prime[4000];
int prime_index=0;
bool find_prime[100001];
int i,j;
int m,n;
int iremainder;
int T,t_index;
int PRIME_FLAG=1;
float square;
int limit;
prime_index++;
prime[prime_index]=2;
for(i=3;i<=32000;i=i+2)
{
PRIME_FLAG=1;
square = sqroot((float)i);
limit = ((int)(square))+1;
for(j=1;j<=prime_index,prime[j]<=limit;j++)
{
if(prime[j]!=0)
{
if((i%prime[j]) == 0)
{
PRIME_FLAG = 0;
break;
}
}
}
if(PRIME_FLAG)
{
prime_index++;
prime[prime_index]=i;
printf("%d\n",i);
}
}
printf("Enter the no of test cases:");
scanf("%d",&T);
if(T<=10)
{
for(t_index=1;t_index<=T;t_index++)
{
printf("Enter the values of m and n :");
scanf("%d%d",&m,&n);
if((m>=1) && (n<=1000000000) && ((n-m)<=100000))
{
if(m == 1)
m=2;
//Set all numbers from m to n as prime
for(i=m;i<=n;i++)
find_prime[i]=true;
//Find the prime numbers between m to n
square = sqroot((float)n);
limit = ((int)(square))+1;
for(i=1;i<=prime_index,prime[i]<=limit;i++)
{
if(m>=prime[i])
{
if(prime[i]!=0)
iremainder=m%prime[i];
j=prime[i]*iremainder;
}
else
{
iremainder=prime[i]-m;
if(m+iremainder == prime[i])
j=2*(m+iremainder);
else
j=m+iremainder;
}
for(;j<=n;j=j+prime[i])
find_prime[j]=false;
}
//Print all prime no's
for(i=m;i<=n;i++)
{
if(find_prime[i])
printf("%d\n",i);
}
}
}
}
return 0;
}
your for loops are wrong.
for(j=1;j<=prime_index,prime[j]<=limit;j++)
should be
for(j=1;(j<=prime_index)&&(prime[j]<=limit);j++)
the first condition will be executed, but the result will be ignored.
So it is luck, that you find a number in the uninitialized array that is larger than limit before you go out of range of the array, which will lead to a SIGSEGV.
for(i=1;i<=prime_index,prime[i]<=limit;i++)
has the same problem.
Click here for more details

C programming. The FizzBuzz program [closed]

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");}}

Resources