On 2 Nov 2010, at 19:53, Rich Mellor wrote:

> I was just reading that 99/100 job applicants for programming jobs apparently 
> cannot write a short "fizzbuzz" program when given 10 minutes to do so in an 
> interview.
> 
> The rules are simple -
> write out the values 1 to 100 on screen
> If the value is divisble by 3 write 'FIZZ' after the number
> If the value is divisble by 5 write 'BUZZ' after the number
> If the value is divisble by 3 and 5 write 'FIZZBUZZ' after the number
> 
> My inelegant machine code program (untested) is:
> 
> Sorry - made an error when typing the 68000 assembly language in - I hit a 
> key which submitted the form!
> 
> start MOVEQ #-1,D1 ;Open a screen channel
>      LEA screen,A0
>      MOVEQ #2,D3
>      MOVEQ #1,D0
>      TRAP #3 ;Uses built in ROM routine to open screen
>      BNE.S end
>      MOVEQ #6,D1
>      MOVE.L A1,$58(A6) ; make room on maths stack for 6 bytes
>      MOVE.W $11A,A2
>      JSR (A2)
>      MOVE.L $58(A6),A1
>      MOVEQ #1,D6 ;Initial Loop value
> loop  MOVE.L (A6),A1
>      LEA 2(A1),A0
>      MOVE.W D6,0(A6.A1.L) ;store value on stack
>      MOVE.W $F2,A2
>      JSR (A2)   ;convert number to ASCII
>      MOVE.W D1,D2      ; grab length of number
>      MOVEQ #7,D0
>      MOVEQ #-1,D3
>      TRAP #3
>      MOVE.L D6,D7
>      DIVU #3,D7
>      SWAP D7
>      CMPI.W #0,D7
>      BEQ.S testbuzz
>      LEA fizz,A1
>      MOVE.W $D0,A2 ; print string
>      JSR (A2)
> testbuzz MOVE.L D6,D7
>      DIVU #5,D7
>      SWAP D7
>      CMPI.W #0,D7
>      BEQ.S nwline
>      LEA buzz,A1
>      MOVE.W $D0,A2
>      JSR (A2)
> nwline MOVEQ #10,D1 ;Print a new line
>      BSR.S printchr
>      CMPI.B #100,D6
>      BEQ.S end
>      ADDQ.B #1,D6
>      BRA.S loop
> end   MOVEQ #0,D0
>      RTS
> printchr MOVEQ #-1,D3
>         MOVEQ #5,D0
>         TRAP #3
>         MOVEQ #0,D0
>         RTS
> screen DC.W 17
>       DC.B 'con_448x200a32x16',0
> fizz   DC.W #4
>       DC.B 'FIZZ'
> buzz   DC.W #4
>       DC.B 'BUZZ'
> 
> I am sure plenty can write this in SuperBASIC, but is there a simpler 
> solution in machine code?
> 

I suppose that there is always a simpler method. I would not use arithmetic to 
find whether the printed number is divisible by 3 or 5. I wrote a program which 
actually does, after correction of course, print what is asked for. To do this 
I had to open a window first (just "con") and set paper, strip and ink. Then I 
had to clear the window. What a palaver!

The actual program to do the printing was:

        moveq   #100,d7
        moveq   #12,d4         ; Lines per page - 1
        moveq   #2,d6           ; count of 3 (0,1,2)
        moveq   #4,d5           ; count of 5
        bra             lp1
lp2     moveq   #100,d1      ; find . .
        sub.w   d7,d1           ; . . the number
        bsr             prt                 ; print it (UT_MINT)
        dbf             d6,lp3          ; divisible by 3? . .
        moveq   #2,d6           ; reset count of 3
        bsr             fizz               ; print FIZZ
lp3     dbf             d5,lp4          ; divisible by 5? . .
        moveq   #4,d5           ; reset count of 5
        bsr             buzz             ; print BUZZ
lp4     moveq   #10,d0         ; to print LF (I had forgotten NL!)
        moveq   #io_sbyte,d0
        bsr             tp3                ; I prefer to use SRs so that I can 
more easily use QMON to pass Traps
        dbf             d4,lp1          ; count lines on page
        moveq   #io_fbyte,d0
        bsr             tp3                ; Pause (else the page contents are 
not seen)
        moveq   #sd_clear,d0
        bsr             tp3                 ; clear the window for the next 
pageful     
lp1     dbf             d7,lp2
        moveq   #io_fbyte,d0
        bsr             tp3                 ; a final pause
.................                              ; The program ends somehow


tp3     trap    #3
        rts

; To print the number in D1
prt     movea.w ut_mint,a2
        jmp                     (a2)

; to print FIZZ
fizz    lea     fz,a1       ; A1 -> FIZZ
        bra     bz1

; To print BUZZ
buzz:
        lea     bz,a1      ; A1 -> BUZZ
bz1     movea.w ut_mtext,a2
        jmp     (a2)

fz      dc.w            4
        dc.b                    "FIZZ"
bz      dc.w            4
        dc.b                    "BUZZ"

If I were marking attempts at programming this exercise I would give more marks 
to robustly written programs which contained slips rather than a weakly written 
program that worked. For example it is better to have a program which can 
easily be altered to produce other divisors than 3 and 5. Anyway I must confess 
that my first version had set 3 and 5 set in D6 and D5 instead of the correct 
values 2 and 4. Time to program the essential bits circa 8 minutes. Time to 
correct this and add bits which would be needed in an actual program 20 minutes.

I await with interest some really small pieces of assembler code doing the same 
thing.

This would take, I suppose, 3 minutes in S*BASIC.

George
_______________________________________________
QL-Users Mailing List
http://www.q-v-d.demon.co.uk/smsqe.htm

Reply via email to