6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Wed Apr 24, 2024 9:10 pm

All times are UTC




Post new topic Reply to topic  [ 37 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Christmas Challenge
PostPosted: Sun Dec 19, 2021 12:06 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
via Stardot, a rather nice small-but-not-too-small programming challenge.

The rules are quite nice: no sharing your code, or even your score, until the contest closes (which is tonight), and you can submit only once.

And you can use Basic or machine code, and even use the platform of your choice.

The challenge, then, is to produce exactly this output:
Image


Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Sun Dec 19, 2021 3:16 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1396
Location: Scotland
A good simple challenge - I've entered ... in BCPL on my Ruby '816, of-course ;-)

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Sun Dec 19, 2021 7:46 pm 
Offline

Joined: Sun Sep 19, 2021 11:21 am
Posts: 23
Me too. Using the Kowalski 6502 Simulator. :D


Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 12:54 am 
Offline

Joined: Wed Nov 11, 2020 10:42 pm
Posts: 96
Location: Kelowna Canada
May not be too late for me?
I sent in my Fig-forth entry using Plasmo's CRC65.


Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 2:08 am 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
I got 75 bytes using RLE compression centered on a 40-col text screen.
De-compressor not included. Must decompress by hand.

76 bytes using Applesoft

I am pretty sure I am not the smallest, or even if I was, I would not be the first to enter the smallest code.


Last edited by IamRob on Mon Dec 20, 2021 2:40 am, edited 3 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 2:13 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
I entered as well.

He did not say what time the contest closes.


Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 5:40 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1925
Location: Sacramento, CA, USA
I'm pretty sure I missed the deadline, but I offered an Apple 1 solution in 76 bytes of self-modifying machine code ... just instructions, no tables:

https://retrocomputingforum.com/t/chris ... hael_barry

WozMon doesn't guarantee a clean RTS back from the R command, so I had to spend six extra bytes for that, and at least four bytes to make it re-runnable.

I have a feeling I should have used a small table instead of employing an algorithmic approach, but it is what it is.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Last edited by barrym95838 on Mon Dec 20, 2021 7:58 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 6:47 am 
Offline

Joined: Wed Oct 07, 2020 6:43 pm
Posts: 6
C64, asm, 46 bytes.


Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 7:50 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1925
Location: Sacramento, CA, USA
laubzega wrote:
C64, asm, 46 bytes.

Wow ... beat me like a rented mule!

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 8:14 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
I'm sure it would be interesting and informative for us to share our efforts, no matter if they are as good as the best or far from the best.

Now the deadline for submission has past, I see solutions are beginning to appear over on the stardot thread. And I see 6502 programs ranging from 54 down to a remarkable 44 bytes.

My own effort comes in at 69 bytes:
Code:
DIM tree 99
FOR i=0 TO 2 STEP 2
P%=tree
[ OPT i
        LDA#1:JSRrow4
        LDA#3:JSRrow4
        LDA#5:JSRrow4
        LDA#3:JSRrow
        LDA#3:JMProw
.row4   INCbump+1:INCbump+1:JSRrow2
.row2   JSRrow
.row    PHA:PHA:LSR A:TAX
.space  LDA#32:JSR&FFEE
        INX:CPX#20:BNEspace
        PLA:TAX
.star   LDA#42:JSR&FFEE
        DEX:BNEstar
        JSR&FFE7
        PLA:CLC:.bump ADC#0
        RTS
        ]
        NEXT
        PRINT P%-tree;" bytes"
        CALL tree


Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 12:38 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
barrym95838 wrote:
laubzega wrote:
C64, asm, 46 bytes.

Wow ... beat me like a rented mule!

Beats my 52 bytes too...like a drum...
Code:
 0050                     00001 ScreenWidth equ 80
                          00002
                          00003 *-----------------------------------------------------------------------------
                          00004 *
                          00005 * FLEX entry points
                          00006 *
                          00007 * Change OSBase to $C000 for 6809 FLEX
                          00008 *
                          00009 * Note: 6809 version is one byte bigger, leax 1,X instead of inx
                          00010 *
 A000                     00011 OSBase   equ    $A000
                          00012
 AD03                     00013 WARMS    equ    OSBase+$D03 ; Return to FLEX
 AD18                     00014 PUTCHR   equ    OSBase+$D18 ; Put Character
 AD24                     00015 PCRLF    equ    OSBase+$D24 ; Print Carriage Return and Line Feed
                          00016
                          00017 *-----------------------------------------------------------------------------
                          00018 *
                          00019 * Encoded tree
                          00020 *
 0000                     00021 Data
 0000 01                  00022          fcb    1         *                *
 0001 03                  00023          fcb    3         *               ***
 0002 05                  00024          fcb    5         *              *****
 0003 07                  00025          fcb    7         *             *******
 0004 03                  00026          fcb    3         *               ***
 0005 07                  00027          fcb    7         *             *******
 0006 0B                  00028          fcb    11        *           ***********
 0007 0F                  00029          fcb    15        *         ***************
 0008 05                  00030          fcb    5         *              *****
 0009 0B                  00031          fcb    11        *           ***********
 000A 11                  00032          fcb    17        *        *****************
 000B 17                  00033          fcb    23        *     ***********************
 000C 03                  00034          fcb    3         *               ***
 000D 03                  00035          fcb    3         *               ***
 000E 00                  00036          fcb    0         *
                          00037
                          00038 *-----------------------------------------------------------------------------
                          00039 *
                          00040 * Draw the tree
                          00041 *
 000F                     00042 Tree
 000F CE 0000         [3] 00043          ldx    #Data     ; Address the encoded tree
                          00044
 0012                     00045 TreeLoop
 0012 BD AD24         [9] 00046          jsr    PCRLF     ; Print Carriage Return and Line Feed
                          00047
 0015 8D 0A (0021)    [8] 00048          bsr    EmitSpaces
 0017 8D 11 (002A)    [8] 00049          bsr    EmitStars
                          00050
 0019 08              [4] 00051          inx              ; Address the next row
                          00052
 001A 6D 00           [7] 00053          tst    ,X        ; More rows?
 001C 26 F4 (0012)    [4] 00054          bne    TreeLoop  ; Yes
                          00055
 001E 7E AD03         [3] 00056          jmp    WARMS     ; Return to FLEX
                          00057
                          00058 *-----------------------------------------------------------------------------
                          00059 *
                          00060 * Emit a run of spaces
                          00061 *
                          00062 * X = address of run information
                          00063 *
 0021                     00064 EmitSpaces
 0021 86 20           [2] 00065          ldaa   #' '
 0023 C6 50           [2] 00066          ldab   #ScreenWidth
 0025 E0 00           [5] 00067          subb   ,X        ; Number of spaces on the line
                          00068
 0027 54              [2] 00069          lsrb             ; Put half of them on the left
                          00070
 0028 20 04 (002E)    [4] 00071          bra    DoRunRun
                          00072
                          00073 *-----------------------------------------------------------------------------
                          00074 *
                          00075 * Emit a run of stars
                          00076 *
                          00077 * X = address of run information
                          00078 *
 002A                     00079 EmitStars
 002A 86 2A           [2] 00080          ldaa   #'*'
 002C E6 00           [5] 00081          ldab   ,X
                          00082
                          00083 * Fall through
                          00084 * bra DoRunRun
                          00085
                          00086 *-----------------------------------------------------------------------------
                          00087 *
                          00088 * Emit a run of characters
                          00089 *
                          00090 * A = the character
                          00091 * B = length of the run
                          00092 *
 002E                     00093 DoRunRun
 002E BD AD18         [9] 00094          jsr    PUTCHR    ; Put Character
                          00095
 0031 5A              [2] 00096          decb             ; Finished with the run?
 0032 26 FA (002E)    [4] 00097          bne    DoRunRun  ; No
                          00098
 0034 39              [5] 00099          rts
                          00100
 000F                     00101          end    Tree


Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 12:46 pm 
Offline

Joined: Sun Sep 19, 2021 11:21 am
Posts: 23
OK, my effort came in at 68 bytes including the data on the stack and a temporary 1-byte variable (53 bytes of instructions if you ignore data/temp variable). Probably a lot could be done to refine/reduce, but I didn't have the time to spend before getting my submission in.

Most system also have different ways of "printing" so I'm not sure how the impact of that on the length of code is taken into account.

BTW - if you like these kinds of programming challenges at Christmas, then head over to the Advent of Code. :)

Code:
; Draw A Christmas Tree.
; DRG 19/12/2021.
; Runs on the Kowalski 6502 Simulator in 65C02 mode.
; X = number of spaces to print.
; Y = number of stars to print.
; C = temporary variable.
; Data pre-populated on the stack.

    .ORG $01F1
tree
    .BYTE $01, $03, $05, $07, $03, $07, $0B
    .BYTE $0F, $05, $0B, $11, $17, $03, $03, $00
   
    .ORG $200
start   
    STZ IO_AREA                    ; Clear the "screen".
    LDX #$F0
    TXS                            ; Set the stack pointer to our data.
   
loop1
    PLA                            ; Get the number of stars.
    BEQ exit                       ; $00 was the value for no more stars - so exit.
    TAY                            ; Y = A.
    AND #$FE                       ; Same as A -> A - 1 for odd numbers as it clears bit 0.
    LSR                            ; Half it.
    STA C                          ; C = A.
    LDA #$0C                       ; A = 12.
    SEC                            ; Set carry flag.
    SBC C                          ; 12 - C.
    TAX                            ; X = A.  This is the number of spaces to print.
   
loop2
    LDA #' '                       ; Space character.
    STA IO_AREA+1                  ; Print it.
    DEX                            ; Decrement space counter.
    BNE loop2                      ; If not done, do more.
       
loop3   
    LDA #'*'                       ; Star character.
    STA IO_AREA+1                  ; Print it.
    DEY                            ; Decrement star counter.
    BNE loop3                      ; If not done, do more.
    LDA #$0D                       ; Carriage return.
    STA IO_AREA+1                  ; Print it.
    LDA #$0A                       ; Line feed.
    STA IO_AREA+1                  ; Print it.
   
    JMP loop1                      ; Keep going...
       
exit   
    BRK
   
C
    .BYTE $00


Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 1:56 pm 
Offline

Joined: Tue Sep 03, 2002 12:58 pm
Posts: 293
Since I've now got my 65020 running on an FPGA, I thought I've have a go. It could definitely be improved. 46 ... somethings. I'm still not sure what counts as a 'byte' on this system.
Code:
0000e99c:                        102 tree
0000e99c: 00a2 000f              103    ldr x0, #15
0000e99e: 20a2 0014              104    ldr x1, #20
0000e9a0: 40a2 0020              105    ldr x2, #32
0000e9a2: 60a2 002a              106    ldr x3, #'*
0000e9a4: 20a0 000d              107    ldr y1, #13
0000e9a6: 02a0 4221 0643         108    ldr.l y0, #$06424321
0000e9a9: 90f0 0003              109    bra.l branches
0000e9ab: 02a0 2d48 02a7         110    ldr.l y0, #$022da748
0000e9ae:                        111 branches
0000e9ae: d0a8                   112    mov a2, y0
0000e9af: 503c                   113    and a2, x0
0000e9b0: 00f0 0017              114    beq done
0000e9b2: 248a                   115    mov a1, x1
0000e9b3: a8fc                   116    sub a1, a2
0000e9b4: 088a                   117    mov a0, x2
0000e9b5: 90f0 000d              118    bra.l row
                                 119
0000e9b7: c87c                   120    add a2, a2
0000e9b8: 18ca                   121    dec a2
0000e9b9: a8a8                   122    mov a1, a2
0000e9ba: 0c8a                   123    mov a0, x3
0000e9bb: 90f0 0007              124    bra.l row
                                 125
0000e9bd: 94a8                   126    mov a0, y1
0000e9be: 90f0 07a9              127    bra.l chrout
0000e9c0: 2242 0004              128    lsr.l y0, #4
0000e9c2: 80f0 00ea              129    bra branches
0000e9c4:                        130 row
0000e9c4: 90f0 07a3              131    bra.l chrout
0000e9c6: 14ca                   132    dec a1
0000e9c7: 00d0 00fb              133    bne row
0000e9c9:                        134 done
0000e9c9: 0060                   135    rts

It's a 6502 with 16 bit 'bytes'. If the top half of the opcode is all 0, it behaves like the original 6502 instruction. The extra bits are used to select data size, data register, index register, and alternate operations (for example, turning ADC into ADD without carry). I've renamed many of the instructions, so it looks a lot less 6502ish than it really is (although having lots of registers and register-to-register operations goes the other way, making it feel even less like a 6502).
'LDR' is "Load Register", and includes the old LDA, LDX, and LDY. It can load any of the 12 general purpose registers A0-A3, X0-X3, and Y0-Y3. An optional suffix on the instruction controls the size of the data, with the default being 8 bit. LDR.L is a 32 bit load.
One of the extra bits on the branch instructions is used to select a different set of conditions, and one of those conditions is 'always'. Another bit (signalled by .L on the instruction) makes it push the current PC before branching. That gives an alternative to JSR with short (16 bit) offsets.
As there are lots more registers than the 6502, I've added register-to-register versions of the instructions that could use them. The various TAX, TXS, etc. instructions have all been renamed MOV, and extended to allow any register to be copied to any other.


Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 2:13 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1396
Location: Scotland
I did it in a high level language; BCPL. Runs on my Ruby '816 board - 65c816 + 512KB of RAM at 16Mhz. Images of Ruby '816 and a screenshot of the code and output below. I wish I'd thought more about seeing if I could do it algorithmically. I also note that my submission was incorrect as I mis-counted one row, however this is correct - not that it matters now!

Attachment:
IMG_20200625_212146_DRO.jpg
IMG_20200625_212146_DRO.jpg [ 405.08 KiB | Viewed 5144 times ]


Attachment:
tree3.png
tree3.png [ 22.31 KiB | Viewed 5134 times ]


(edited because I originally uploaded the one with the error in it!)

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Last edited by drogon on Mon Dec 20, 2021 2:55 pm, edited 2 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Christmas Challenge
PostPosted: Mon Dec 20, 2021 2:37 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 690
Location: North Tejas
Upon further examination, I was able to get mine down to 47 bytes.

* Inlined one subroutine
* Store the tree table upside down allowing me to get rid of the sentinel and the test for it

Code:
 0050                     00001 ScreenWidth equ 80
                          00002
                          00003 *-----------------------------------------------------------------------------
                          00004 *
                          00005 * FLEX entry points
                          00006 *
                          00007 * Change OSBase to $C000 for 6809 FLEX
                          00008 *
                          00009 * Note: 6809 version is one byte bigger, leax -1,X instead of dex
                          00010 *
 A000                     00011 OSBase   equ    $A000
                          00012
 AD03                     00013 WARMS    equ    OSBase+$D03 ; Return to FLEX
 AD18                     00014 PUTCHR   equ    OSBase+$D18 ; Put Character
 AD24                     00015 PCRLF    equ    OSBase+$D24 ; Print Carriage Return and Line Feed
                          00016
 0001                     00017          org    1         ; 1 so that decrementing X automagically sets the Z flag when done
                          00018
                          00019 *-----------------------------------------------------------------------------
                          00020 *
                          00021 * Encoded tree
                          00022 *
 0001 03                  00023          fcb    3         *               ***
 0002 03                  00024          fcb    3         *               ***
 0003 17                  00025          fcb    23        *     ***********************
 0004 11                  00026          fcb    17        *        *****************
 0005 0B                  00027          fcb    11        *           ***********
 0006 05                  00028          fcb    5         *              *****
 0007 0F                  00029          fcb    15        *         ***************
 0008 0B                  00030          fcb    11        *           ***********
 0009 07                  00031          fcb    7         *             *******
 000A 03                  00032          fcb    3         *               ***
 000B 07                  00033          fcb    7         *             *******
 000C 05                  00034          fcb    5         *              *****
 000D 03                  00035          fcb    3         *               ***
 000E 01                  00036 Data     fcb    1         *                *
                          00037
                          00038 *-----------------------------------------------------------------------------
                          00039 *
                          00040 * Draw the tree
                          00041 *
 000F                     00042 Tree
 000F CE 000E         [3] 00043          ldx    #Data     ; Address the encoded tree
                          00044
 0012                     00045 TreeLoop
 0012 BD AD24         [9] 00046          jsr    PCRLF     ; Print Carriage Return and Line Feed
                          00047
 0015 86 20           [2] 00048          ldaa   #' '
 0017 C6 50           [2] 00049          ldab   #ScreenWidth
 0019 E0 00           [5] 00050          subb   ,X        ; Number of spaces on the line
                          00051
 001B 54              [2] 00052          lsrb             ; Put half of them on the left
                          00053
 001C 8D 0C (002A)    [8] 00054          bsr    DoRunRun
                          00055
 001E 8D 06 (0026)    [8] 00056          bsr    EmitStars
                          00057
 0020 09              [4] 00058          dex              ; Address the next row
                          00059
 0021 26 EF (0012)    [4] 00060          bne    TreeLoop  ; More rows?
                          00061
 0023 7E AD03         [3] 00062          jmp    WARMS     ; Return to FLEX
                          00063
                          00064 *-----------------------------------------------------------------------------
                          00065 *
                          00066 * Emit a run of stars
                          00067 *
                          00068 * X = address of run information
                          00069 *
 0026                     00070 EmitStars
 0026 86 2A           [2] 00071          ldaa   #'*'
 0028 E6 00           [5] 00072          ldab   ,X
                          00073
                          00074 * Fall through
                          00075 * bra DoRunRun
                          00076
                          00077 *-----------------------------------------------------------------------------
                          00078 *
                          00079 * Emit a run of characters
                          00080 *
                          00081 * A = the character
                          00082 * B = length of the run
                          00083 *
 002A                     00084 DoRunRun
 002A BD AD18         [9] 00085          jsr    PUTCHR    ; Put Character
                          00086
 002D 5A              [2] 00087          decb             ; Finished with the run?
 002E 26 FA (002A)    [4] 00088          bne    DoRunRun  ; No
                          00089
 0030 39              [5] 00090          rts
                          00091
                          00092 * Total length is one less than this address because $0000 is not used
                          00093
 000F                     00094          end    Tree


Edit: Make that 48 bytes. In my hurry yesterday, I introduced an off-by-one error in accounting for the length. The length of my entry was actually 53 bytes.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 37 posts ]  Go to page 1, 2, 3  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: