Skip to content

Commit

Permalink
Add twelve-days exercise (#260)
Browse files Browse the repository at this point in the history
  • Loading branch information
keiravillekode authored Jan 10, 2025
1 parent 2effbff commit 1077eff
Show file tree
Hide file tree
Showing 11 changed files with 3,774 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,14 @@
"transforming"
]
},
{
"slug": "twelve-days",
"name": "Twelve Days",
"uuid": "404a8125-db44-48b3-b981-49a368815001",
"practices": [],
"prerequisites": [],
"difficulty": 4
},
{
"slug": "atbash-cipher",
"name": "Atbash Cipher",
Expand Down
36 changes: 36 additions & 0 deletions exercises/practice/twelve-days/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Instructions

Your task in this exercise is to write code that returns the lyrics of the song: "The Twelve Days of Christmas."

"The Twelve Days of Christmas" is a common English Christmas carol.
Each subsequent verse of the song builds on the previous verse.

The lyrics your code returns should _exactly_ match the full song text shown below.

## Lyrics

```text
On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree.
On the second day of Christmas my true love gave to me: two Turtle Doves, and a Partridge in a Pear Tree.
On the third day of Christmas my true love gave to me: three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
On the fourth day of Christmas my true love gave to me: four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
On the fifth day of Christmas my true love gave to me: five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
On the sixth day of Christmas my true love gave to me: six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
On the seventh day of Christmas my true love gave to me: seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
On the eighth day of Christmas my true love gave to me: eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
On the ninth day of Christmas my true love gave to me: nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
On the tenth day of Christmas my true love gave to me: ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
On the eleventh day of Christmas my true love gave to me: eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
On the twelfth day of Christmas my true love gave to me: twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.
```
19 changes: 19 additions & 0 deletions exercises/practice/twelve-days/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"keiravillekode"
],
"files": {
"solution": [
"twelve_days.asm"
],
"test": [
"twelve_days_test.c"
],
"example": [
".meta/example.asm"
]
},
"blurb": "Output the lyrics to 'The Twelve Days of Christmas'.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song)"
}
99 changes: 99 additions & 0 deletions exercises/practice/twelve-days/.meta/example.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
default rel

section .rodata

on_the: db "On the ", 0
day_of: db " day of Christmas my true love gave to me: ", 0
gifts: db "twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.", 10, 0

offsets:
dq 0
dq 235
dq 213
dq 194
dq 174
dq 157
dq 137
dq 113
dq 90
dq 69
dq 48
dq 26
dq 0

first: db "first", 0
second: db "second", 0
third: db "third", 0
fourth: db "fourth", 0
fifth: db "fifth", 0
sixth: db "sixth", 0
seventh:
db "seventh", 0
eighth: db "eighth", 0
ninth: db "ninth", 0
tenth: db "tenth", 0
eleventh:
db "eleventh", 0
twelfth:
db "twelfth", 0

section .data

ordinals:
dq 0
dq first
dq second
dq third
dq fourth
dq fifth
dq sixth
dq seventh
dq eighth
dq ninth
dq tenth
dq eleventh
dq twelfth

section .text
global recite

append:
lodsb
stosb
test al, al
jnz append

dec rdi
ret

; extern void recite(char *buffer, int start_verse, int end_verse);
recite:
cld
lea r8, [ordinals]
lea r9, [offsets]
mov r10, rsi ; current verse

.next_verse:
lea rsi, [on_the]
call append

mov rsi, [r8 + r10 * 8] ; lookup ordinals
call append

lea rsi, [day_of]
call append

mov r11, [r9 + r10 * 8] ; lookup offsets
lea rsi, [gifts]
add rsi, r11
call append

inc r10
cmp r10, rdx
jle .next_verse

ret

%ifidn __OUTPUT_FORMAT__,elf64
section .note.GNU-stack noalloc noexec nowrite progbits
%endif
55 changes: 55 additions & 0 deletions exercises/practice/twelve-days/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[c0b5a5e6-c89d-49b1-a6b2-9f523bff33f7]
description = "verse -> first day a partridge in a pear tree"

[1c64508a-df3d-420a-b8e1-fe408847854a]
description = "verse -> second day two turtle doves"

[a919e09c-75b2-4e64-bb23-de4a692060a8]
description = "verse -> third day three french hens"

[9bed8631-ec60-4894-a3bb-4f0ec9fbe68d]
description = "verse -> fourth day four calling birds"

[cf1024f0-73b6-4545-be57-e9cea565289a]
description = "verse -> fifth day five gold rings"

[50bd3393-868a-4f24-a618-68df3d02ff04]
description = "verse -> sixth day six geese-a-laying"

[8f29638c-9bf1-4680-94be-e8b84e4ade83]
description = "verse -> seventh day seven swans-a-swimming"

[7038d6e1-e377-47ad-8c37-10670a05bc05]
description = "verse -> eighth day eight maids-a-milking"

[37a800a6-7a56-4352-8d72-0f51eb37cfe8]
description = "verse -> ninth day nine ladies dancing"

[10b158aa-49ff-4b2d-afc3-13af9133510d]
description = "verse -> tenth day ten lords-a-leaping"

[08d7d453-f2ba-478d-8df0-d39ea6a4f457]
description = "verse -> eleventh day eleven pipers piping"

[0620fea7-1704-4e48-b557-c05bf43967f0]
description = "verse -> twelfth day twelve drummers drumming"

[da8b9013-b1e8-49df-b6ef-ddec0219e398]
description = "lyrics -> recites first three verses of the song"

[c095af0d-3137-4653-ad32-bfb899eda24c]
description = "lyrics -> recites three verses from the middle of the song"

[20921bc9-cc52-4627-80b3-198cbbfcf9b7]
description = "lyrics -> recites the whole song"
46 changes: 46 additions & 0 deletions exercises/practice/twelve-days/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
AS = nasm

CFLAGS = -g -Wall -Wextra -pedantic -Werror
LDFLAGS =
ASFLAGS = -g -F dwarf -Werror

ifeq ($(shell uname -s),Darwin)
ifeq ($(shell sysctl -n hw.optional.arm64 2>/dev/null),1)
ALL_CFLAGS = -target x86_64-apple-darwin
endif
ALL_LDFLAGS = -Wl,-pie
ALL_ASFLAGS = -f macho64 --prefix _
else
ALL_LDFLAGS = -pie -Wl,--fatal-warnings
ALL_ASFLAGS = -f elf64
endif

ALL_CFLAGS += -std=c99 -fPIE -m64 $(CFLAGS)
ALL_LDFLAGS += $(LDFLAGS)
ALL_ASFLAGS += $(ASFLAGS)

C_OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
AS_OBJS = $(patsubst %.asm,%.o,$(wildcard *.asm))
ALL_OBJS = $(filter-out example.o,$(C_OBJS) $(AS_OBJS) vendor/unity.o)

CC_CMD = $(CC) $(ALL_CFLAGS) -c -o $@ $<

all: tests
@./$<

tests: $(ALL_OBJS)
@$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -o $@ $(ALL_OBJS)

%.o: %.asm
@$(AS) $(ALL_ASFLAGS) -o $@ $<

%.o: %.c
@$(CC_CMD)

vendor/unity.o: vendor/unity.c vendor/unity.h vendor/unity_internals.h
@$(CC_CMD)

clean:
@rm -f *.o vendor/*.o tests

.PHONY: all clean
13 changes: 13 additions & 0 deletions exercises/practice/twelve-days/twelve_days.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
default rel

section .data

section .text
global recite
recite:
; Provide your implementation here
ret

%ifidn __OUTPUT_FORMAT__,elf64
section .note.GNU-stack noalloc noexec nowrite progbits
%endif
Loading

0 comments on commit 1077eff

Please sign in to comment.