0

Hello! I was extremely bored and stumbled accross this website: Hackerrank
It's a website that contains lots of programming challenges of various types.
I signed up and looked at some of the challenges, lots of them are quite over my head since I'm not that skilled or any expert by any means so I thought I would try some of these challenges.

I stumbled across one called "FizzBuzz", the details are here: Click Here

So I program in D myself so I wrote my attempt in D but any feedback in C/C++ is also helpful because I know those as well.

So essentially the goal is to write the described goal in the shortest amount of characters possible which I attempted doing here:

import std.stdio;alias writeln w;void main(){int i;for(i=1;i<=100;i++){if(i%3==0&&i%5!=0)w("Fizz");if(i%3!=0&&i%5==0)w("Buzz");if(i%3==0&&i%5==0)w("FizzBuzz");if(i%3!=0&&i%5!=0)w(i);}}

I'm thinking you can't get it much shorter than this, I managed 184 characters and the site gave me a score of 0.08.
I peeked at the leader boards before I submitted only to see there are highscores of 15.20 which must be an extremely short program! Most of these people are writing in C/C++, I'm just curious if anyone has this mystical knowlege of minimizing the length of programs? This really surprises me a lot, I've never tried anything like this so any information would be appreciated, thanks everyone!

4
Contributors
20
Replies
50
Views
4 Years
Discussion Span
Last Post by NardCake
Featured Replies
0

For a start, some compilers allow a declaration of a variable inside a for loop, eg for(int i=0;.... Also, you can cut out comparisons with 0 like if(i%3==0&&i%5!=0). If i%3 is 0, then it is effectively a boolean with value FALSE, otherwise it's a boolean TRUE. Also, you don't need three conditions, just two:

  • i%3 == 0 then printf("Fizz")
  • i%5 == 0 then printf"Buzz"
  • else printf("%d",i)
  • printf("\n")

This way you can cut the size down a wee bit

Edited by Assembly Guy

0

EDIT: Deleted because of buggy untested code

Edited by Assembly Guy: Deleted post's content because of buggy untested code

0

Great so with that brilliant advice I'm now down to 134 characters!

import std.stdio;alias write w;void main(){for(int i=1;i<=100;i++){if(i%3==0)w("Fizz");if(i%5==0)w("Buzz");if(i%3&&i%5)w(i);w("\n");}}

I don't really see anything else though...

0

Does D allow the use of int main(). That'd save one byte...

Instead of repeating sequences like ); and i%, see if making an alias for those could help. Also use <101 instead of <=100. Also, you've started to apply my thinking on the boolean logic, but you've not fully applied it, I can still see some comparisons with 0 in your code.

Edited by Assembly Guy

0

"Does D allow the use of int main()" Yes it does but the return declaration would be necessary and that would be more wasted space.

0

Would it simply not compile at all, or would there be a warning? While it's strictly 'illegal', a C compiler will sit there and frown at you for a bit, but end up compiling fine.

0

In that case, just go for other things I mentioned, such as if(!i%3) instead of if(i%3==0), as well as i<101 instead of i<=100. While its only a byte here or there, it'll soon add up...

Also, instead of repeating w(, could you alias w to equal write(? The same applies for ); - alias it for a letter you're not using, like q.

Edited by Assembly Guy

0

I guess I lied when I said it threw an error. It compiles fine but it doesn't work as expected, it doesn't return true ever. !i%3

1

I that a while after I wrote. It's performing the ! operation on i, then the modulo. It'd need brackets for example !(i%3). This puts it to the same length as i%3==0.

0

Oh! Good point! I never thought about that, especially tired at this time of night.

0

First, you should use i<101 instead of i<=100. Also, your for-loop could be like this for(int i=0;++i<101;). That's two characters saved. However, D allows for range-based for-loops too, so you could write foreach(i;1..101), that is 4 more characters saved.

Then, you can, in general, replace almost any sequence of if-statements with short-circuit logical OR or AND. For example, this code:

if(i%3==0) w("Fizz");

is equivalent to:

i%3||w("Fizz");

Then, you also forgot that you have the ternary ?: operator in your toolbox, you can use that to save the second comparison:

    i%3||w("Fizz");
    i%5?i%3&&w(i):w("Buzz");
    w("\n");

The final, indented version is this:

import std.stdio;
alias write w;
void main(){
  foreach(i;1..101){
    i%3||w("Fizz");
    i%5?i%3&&w(i):w("Buzz");
    w("\n");
  }
}

That takes the total down to 110 characters. And the score is 0.45.

Just for fun, I came up with this C90 version (C90, because C99 does not allow inferred-type main() function, in other words, a C90 compiler is required to tolerate this program, a C99 compiler will probably throw it out). And, it cannot be C++ because it relies on a tail-recursion on the main() function, which C++ does not allow, but C does.

C90:

#include<stdio.h>
#define w printf
main(i){
  i%3||w("Fizz");
  i%5?i%3&&w("%d",i):w("Buzz");
  w("\n");
  i<100&&main(i+1);
}

That's 110 characters, I don't know how it could possibly be much shorter. That gives me a score of 0.435.

Edited by mike_2000_17: some errors

0

The scores the preview/test mode gives are crap, I was being told I would get a 0.4-something, but upon submission, I got an 8.

Edited by Assembly Guy

0

Yeah, I think that the scores on the preview are normalized to 1. The maximum is 20 (with 0 characters), so, you take your number (e.g., 0.45) and multiply by 20 to get the real score (e.g., 9).

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.