Page 1 of 2

Posted: Mon 26 Nov 2012, 17:27
by technosaurus
rcrsn51 wrote:
technosaurus wrote:

Code: Select all

switch (n%15){
Very nice. Doing three divisions is clearly overkill. Doing one division is better.
Its not exactly a duff's device, but that is what I was recalling as a template.

Posted: Mon 26 Nov 2012, 17:39
by GustavoYz
@technosaurus: Nice, thanks. :D

Posted: Tue 27 Nov 2012, 08:30
by jamesbond
rcrsn51 wrote:Very nice. Doing three divisions is clearly overkill. Doing one division is better.
I have one that does not use division at all; but surprisingly it is slower :shock:

Code: Select all

for ((a=1,b=2,c=4;a<101;a++,b--,c--));do d=$a;((\!b && \!c))&&d=FizzBuzz b=3 c=5;((\!b))&&d=Fizz b=3;((\!c))&&d=Buzz c=5;echo $d; done

Posted: Tue 27 Nov 2012, 16:12
by rcrsn51
jamesbond wrote:I have one that does not use division at all; but surprisingly it is slower
Is this an example of "loop unwinding"? Where the amount of processing needed to manage the loop is more than what's required to execute the contents of the loop?

So maybe three divisions is not a bad thing if it reduces the total amount of processing.

Posted: Tue 27 Nov 2012, 20:05
by technosaurus
here is an example how less comparisons can actually be bad

Code: Select all

#include <stdio.h>
	
int void main(){ 
int a=0,b=0,max=100;
char buf[500];
while(b<max/15){ //if max > 15 do blocks of 15 first
 printf("%d\t%d\tFizz\t%d\tBuzz\nFizz\t%d\t%d\tFizz\tBuzz\n%d\tFizz\t%d\t%d\tFizzBuzz\n",
		a+1,a+2,a+4,a+7,a+8,a+11,a+13,a+14);
 a=++b*15;
}
/* now do the remainder, but in order to do 1 comparison, we must reverse
 * this is _much_ slower than the comparisons so don't use it
 * - just an example of how using less comparisons can be slower
 * especially if doing so requires using additional slower functions
 * we don't always know what the compiler will do
*/
switch(max%15){
case 14 : sprintf(buf,"%d",a+14);
case 13 : sprintf(buf,"%d\t%s",a+13,buf);
case 12 : sprintf(buf,"Fizz\t%s",buf);
case 11 : sprintf(buf,"%d\t%s",a+11,buf);
case 10 : sprintf(buf,"Buzz\n%s",buf);
case 9 :  sprintf(buf,"Fizz\t%s",buf);
case 8 :  sprintf(buf,"%d\t%s",a+8,buf);
case 7 : sprintf(buf,"%d\t%s",a+7,buf);
case 6 : sprintf(buf,"Fizz\t%s",buf);
case 5 : sprintf(buf,"Buzz\n%s",buf);
case 4 : sprintf(buf,"%d\t%s",a+4,buf);
case 3 : sprintf(buf,"Fizz\t%s",buf);
case 2 : sprintf(buf,"%d\t%s",a+2,buf);
case 1 : sprintf(buf,"%d\t%s",a+1,buf);
default : break
}
printf("%s",buf);
} 

	return 0;
}
as opposed partial unwinding to something like:

Code: Select all

#include <stdio.h>
	
int main(){ 
int a=0,b=0,max=100;
while(b<max/15){ //if max > 15 do blocks of 15 first
	printf("%d\t%d\tFizz\t%d\tBuzz\nFizz\t%d\t%d\tFizz\tBuzz\n%d\tFizz\t%d\t%d\tFizzBuzz\n",a+1,a+2,a+4,a+7,a+8,a+11,a+13,a+14);
	a=++b*15;
}
while (a++ < 100){ 
	switch (a%15){ 
		case 3 : case 6 : case 9 : case 12 : printf("Fizz\t");break; 
		case 5 : case 10 : printf("Buzz\n"); break; 
		default : printf("%d\t",a);break;
	} 
} 

	return 0;
}
btw, you can do this same algorithm in shell

Posted: Sat 05 Jan 2013, 21:58
by Ibidem
POSIX sh:

Code: Select all

for n in `seq 100`; do out=""; case $n in (*0|*5) out=Buzz ;; esac; [ 0 = $(( $n % 3 )) ] && out=Fizz$out; echo ${out:-$n}; done
Note that this uses 1 comparison (to determine divisibility by 5) and also one division; 15 is handled automatically, rather than as a special case.

Posted: Sun 06 Jan 2013, 02:21
by starhawk
Oldschool style. Even I can do this -- although it's rather embarrassing to note that working out all the (very boneheaded) bugs made the whole thing take about an hour and fifteen minutes to crank out.

Good thing I'm not paid to do this!

This was implemented (tested and working, finally!) in M$ QuickBASIC PDS 7.1. You can still download it! (I tested it using an XP box.)

Strictly speaking, there's a little fluff -- lines 10, 20, 30, 140, and 150 could all technically be eliminated w/o problem. But I think the added weight is worth it :P and yes, I know, LINE NUMBERS FOR PETE'S SAKE.

But I'm old-fashioned :D

Code: Select all

10  REM FIZZBUZZ SOLUTION BY CHRISTOPHER HAVEL, 2012
20  REM IMPLEMENTED IN QBASIC
30  PRINT
40  COUNT% = 0
50  COUNT% = COUNT% + 1
60  IF COUNT% MOD 3 = 0 THEN GOTO 100 ELSE GOTO 80
70  IF COUNT% MOD 5 = 0 THEN GOTO 120 ELSE GOTO 80
80  PRINT COUNT%
90  IF COUNT% = 100 THEN GOTO 140 ELSE GOTO 50
100 IF COUNT% MOD 5 = 0 THEN PRINT "FIZZBUZZ" ELSE PRINT "FIZZ"
110 IF COUNT% = 100 THEN GOTO 140 ELSE GOTO 50
120 IF COUNT% MOD 3 = 0 THEN PRINT "FIZZBUZZ" ELSE PRINT "BUZZ"
130 IF COUNT% < 100 THEN GOTO 50
140 PRINT
150 PRINT "ALL DONE!"
160 END

Posted: Sun 06 Jan 2013, 02:24
by jamesbond
Ibidem wrote:POSIX sh:
Note that this uses 1 comparison (to determine divisibility by 5) and also one division; 15 is handled automatically, rather than as a special case.
Speed aside, I think this is the best one-liner Image. Especially since it is POSIX, too Image Image.

Posted: Sun 06 Jan 2013, 17:17
by starhawk
Any thoughts on my attempt? Just curious to see folks' opinions...

Posted: Sun 06 Jan 2013, 18:31
by amigo
starhawk, only your omission of a 'goto' has saved you from my wrath. basic just sucks -even worse in the 21st century.

Posted: Tue 08 Jan 2013, 03:31
by starhawk
amigo wrote:starhawk, only your omission of a 'goto' has saved you from my wrath. basic just sucks -even worse in the 21st century.
Er, sorry to poke the proverbial hornet's nest... but I count nine goto's in that code! Might want to look again... or not... :P

Posted: Wed 09 Jan 2013, 04:03
by Ibidem
I suspect part of the point was to think about the interaction of functions.
ie, multiple of 15=found in both the "fizz" and the "buzz" cases.
If you think it through, you can just make the two cases handle that, but if you don't, you must use a third case.

Posted: Wed 09 Jan 2013, 05:10
by starhawk
I'm not so good with object oriented stuff. Tried to learn C++ three times. Twice in college, once from a Dummies book (which was actually before college). Didn't learn a thing. I can sort of read the stuff, but that's about it.

College professor both times could only explain the difference between Java and whatever he was trying to teach. Never took Java. Don't care to -- doesn't interest me.

So, Prof, I guess you weren't too helpful to me. Oh well.

Dummies book didn't work so well, either -- typed up a program with the included software, compiler wouldn't budge. Checked the code against the book... exact match. Decided both book and software were junk. I still have the book somewhere... dunno why...

Back to BASIC. Simple, procedural code. Does what it needs to. No, I never knew that much. Yes, I'm rusty with what I do know. But I know it better than any of that newfangled object oriented stuff for sure.

It's good enough for me.

I even wrote a game in BASIC. Search this section of the forum -- IIRC I did post it at some point (if not, or if the link's dead, tell me and I'll put it [back] up). It's called QUICKGEM. You'll need DOSbox if you don't have real DOS... I didn't say BASIC was a new language, did I? ;)

Someday I'll mess around with QB64, which is crossplatform, and rewrite QUICKGEM for it. Or not. QUICKGEM was a real mess. No parser, just discrete IF...THEN statements. Yeah, I know -- very very bad. If someone can show me a simple-to-type REAL parser for BASIC, I'll rewrite the game for it. Haven't had that happen yet, though.

Before someone brings up Visual BASIC... I've used it. VB5 or 6, courtesy of MS, in college. Not bad... but... memorable for a big minus: the editor suggested commands and such because there were too many commands for one programmer to remember. Too fancy all around, particularly for me.

"...the more they overtech the plumbing, the easier it is to stop up the drain." Montgomery Scott, Star Trek III: The Search For Spock

Posted: Wed 09 Jan 2013, 11:58
by vovchik
Dear starhawk,

You might want to give BaCon a try. It is very structured and makes using GTK easy with its HUG API.

Check out http://www.basic-converter.org.

With kind regards,
vovchik

PS If you use proper compile strings in Bacon, such as:

Code: Select all

bacon -o -s -o -Os -o -fdata-sections -o -ffunction-sections -o -Wl,--gc-sections "$myfile"
and then strip and upx the binary, you will get an executable (with GTK gui) of some 18-25k. With QB64, you get ridiculous binaries in the 1 MB range, which I find generally unacceptable, in spite of the cross-platform feature. BaCon compiles on any *nix (including OSX), and people have also succeded in getting it running in Windows using Cygwin.

And fizzbuzz in BaCon by Joe and myself: http://basic-converter.proboards.com/in ... thread=399

Posted: Wed 09 Jan 2013, 18:32
by starhawk
Hmmm... Cygwin and I tend to have bad reactions to each other... but I might give it a chance.

So how do I use BaCon? Does it come with an editor, or is it a BASIC-to-C adapter only? Does it automatically run gcc after it's done the crossover?

...and I'd love to see instructions on how to write a text parser in BASIC. Keep it simple, I'm stupid :P well, when programming, anyways.

Posted: Wed 09 Jan 2013, 20:36
by vovchik
Dear starhawk,

It has a command-line converter that also runs gcc and a gui version that also runs gcc and has syntax highlighting....

With kind regards,
vovchik

Posted: Thu 10 Jan 2013, 17:54
by GustavoYz
starhawk wrote:But I'm old-fashioned :D

Code: Select all

10  REM FIZZBUZZ SOLUTION BY CHRISTOPHER HAVEL, 2012
20  REM IMPLEMENTED IN QBASIC
30  PRINT
40  COUNT% = 0
50  COUNT% = COUNT% + 1
60  IF COUNT% MOD 3 = 0 THEN GOTO 100 ELSE GOTO 80
70  IF COUNT% MOD 5 = 0 THEN GOTO 120 ELSE GOTO 80
80  PRINT COUNT%
90  IF COUNT% = 100 THEN GOTO 140 ELSE GOTO 50
100 IF COUNT% MOD 5 = 0 THEN PRINT "FIZZBUZZ" ELSE PRINT "FIZZ"
110 IF COUNT% = 100 THEN GOTO 140 ELSE GOTO 50
120 IF COUNT% MOD 3 = 0 THEN PRINT "FIZZBUZZ" ELSE PRINT "BUZZ"
130 IF COUNT% < 100 THEN GOTO 50
140 PRINT
150 PRINT "ALL DONE!"
160 END
By some reason, they still teach Basic (Pascal too) to programmers in some Universities here... :roll:
Didn't knew people still "GOTO" voluntarily... :P