Difference between revisions of "Christmas Star"

From SizeCoding
Jump to: navigation, search
m (The challenge: minor language edit)
(Added post deadline32 byte C64 version)
Line 55: Line 55:
 
Serato's entry was provided with the following comments:
 
Serato's entry was provided with the following comments:
 
  <nowiki>The required octogram may be constructed as the union of four right triangles reflected four ways in x and y axes. The central loop renders one row of the triangle, plus its horizontal mirror image. The outer loop iterates over normal and mirror image screen rows. The result is all four triangles being rendered on top of each other. Saved a byte with unintended 6502 opcode ISC which combines INC and SBC to both increment a counter and load (16 minus) its value into A.</nowiki>
 
  <nowiki>The required octogram may be constructed as the union of four right triangles reflected four ways in x and y axes. The central loop renders one row of the triangle, plus its horizontal mirror image. The outer loop iterates over normal and mirror image screen rows. The result is all four triangles being rendered on top of each other. Saved a byte with unintended 6502 opcode ISC which combines INC and SBC to both increment a counter and load (16 minus) its value into A.</nowiki>
 +
==Optimized post-deadline versions==
 +
===34 bytes version for C64===
 +
This shorter C64 version by Serato renders the union of four triangles rotated 90 degrees. To save space it iterates 256 times. It also uses a trick where the carry flag state is set by the loop comparison causing the active row to advance automatically at the end of each column.
 +
<syntaxhighlight lang="6502">
 +
        plot = $E50C    ; Kernal routine moves cursor to (y,x)
 +
        sys_h = $15
 +
        pnt = $d1
 +
        tblx = $d6
 +
* = $c00
 +
        lda #22
 +
loop2  tay
 +
loop1  sbc #3
 +
        tax
 +
        jsr plot
 +
        lda #'*'
 +
        sta (pnt),y
 +
        tya
 +
        eor #$1f
 +
        ldy tblx
 +
        dec $2
 +
        bne loop1
 +
        dey
 +
        cpy #10
 +
        bcs loop1
 +
        dec sys_h
 +
        bpl loop2
 +
        rts
 +
</syntaxhighlight>

Revision as of 03:19, 31 December 2022

The challenge

During the Vintage Computing Christmas Challenge 2022, the goal was to create the shape of a given Christmas star with as few bytes as possible. All platforms and languages were allowed. The star should look exactly like the one shown below.

              *       *
              **     **
              ***   ***
              **** ****
          *****************
           ***************
            *************
             ***********
              *********
             ***********
            *************
           ***************
          *****************
              **** ****
              ***   ***
              **     **
              *       *

There were mainly two kinds of approaches:

  • draw character by character
  • mirror triangles

Winning Entries

Winning entry for C64

The shortest entry for the C64 was submitted by Serato with 34 bytes:

		chrout = $FFD2	; Kernal routine outputs char in A
		plot = $E50C	; Kernal routine moves cursor to (y,x)
		pnt = $d1     	; Pointer to the start of the current screen line
		row = $b3		; zp var that always starts at 3
*       = $1000
do_2nd	ldx row			; render "upside down" triangles
do_line	ldy #9			; render one row of triangle, and its x-mirror image
		jsr plot		; move cursor to column 9 on row x
		ldy #17			; start x-mirrored image in column 17
		lda #'*'		; the star of the show
do_asks	jsr chrout		; print star, advancing kernal cursor to right
		sta (pnt),y		; write x-mirrored star with mirrored cursor
		dey				; advance mirrored cursor to left
		cpy row			; test against line y=x to form diagonal
		bne do_asks		
		cpx row			; check if these weere "upside down" triangles
		bne do_2nd		; if not, draw the upside down ones
sys		lda #$10		; entry point of routine, start with y mirrored
		sec				; wish this could be avoided, feels like a wasted byte
		isc row			; increment bottom row counter and put (16 - row) in A
		tax				; we need in x register
		bpl do_line		; repeat until row < 0, then fall through
		rts

Serato's entry was provided with the following comments:

The required octogram may be constructed as the union of four right triangles reflected four ways in x and y axes. The central loop renders one row of the triangle, plus its horizontal mirror image. The outer loop iterates over normal and mirror image screen rows. The result is all four triangles being rendered on top of each other. Saved a byte with unintended 6502 opcode ISC which combines INC and SBC to both increment a counter and load (16 minus) its value into A.

Optimized post-deadline versions

34 bytes version for C64

This shorter C64 version by Serato renders the union of four triangles rotated 90 degrees. To save space it iterates 256 times. It also uses a trick where the carry flag state is set by the loop comparison causing the active row to advance automatically at the end of each column.

        plot = $E50C    ; Kernal routine moves cursor to (y,x)
        sys_h = $15
        pnt = $d1
        tblx = $d6
* = $c00
        lda #22
loop2   tay
loop1   sbc #3
        tax
        jsr plot
        lda #'*'
        sta (pnt),y
        tya
        eor #$1f
        ldy tblx
        dec $2
        bne loop1
        dey
        cpy #10
        bcs loop1
        dec sys_h
        bpl loop2
        rts