Skip to content

Commit

Permalink
Add leap exercise (#66)
Browse files Browse the repository at this point in the history
  • Loading branch information
keiravillekode authored Oct 18, 2024
1 parent f430e7f commit 8be5c39
Show file tree
Hide file tree
Showing 13 changed files with 3,524 additions and 4 deletions.
12 changes: 8 additions & 4 deletions config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"track_id": "arm64-assembly",
"language": "ARM64 Assembly",
"slug": "arm64-assembly",
"active": false,
Expand Down Expand Up @@ -31,7 +30,6 @@
]
},
"exercises": {
"concept": [],
"practice": [
{
"slug": "hello-world",
Expand All @@ -43,11 +41,17 @@
"topics": [
"strings"
]
},
{
"slug": "leap",
"name": "Leap",
"uuid": "64ff9257-ca9e-4c31-a8db-3736ff4e3284",
"practices": [],
"prerequisites": [],
"difficulty": 2
}
]
},
"concepts": [],
"key_features": [],
"tags": [
"execution_mode/compiled",
"paradigm/imperative",
Expand Down
3 changes: 3 additions & 0 deletions exercises/practice/leap/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Instructions

Your task is to determine whether a given year is a leap year.
16 changes: 16 additions & 0 deletions exercises/practice/leap/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Introduction

A leap year (in the Gregorian calendar) occurs:

- In every year that is evenly divisible by 4.
- Unless the year is evenly divisible by 100, in which case it's only a leap year if the year is also evenly divisible by 400.

Some examples:

- 1997 was not a leap year as it's not divisible by 4.
- 1900 was not a leap year as it's not divisible by 400.
- 2000 was a leap year!

~~~~exercism/note
For a delightful, four-minute explanation of the whole phenomenon of leap years, check out [this YouTube video](https://www.youtube.com/watch?v=xX96xng7sAE).
~~~~
19 changes: 19 additions & 0 deletions exercises/practice/leap/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"keiravillekode"
],
"files": {
"solution": [
"leap.s"
],
"test": [
"leap_test.c"
],
"example": [
".meta/example.s"
]
},
"blurb": "Determine whether a given year is a leap year.",
"source": "CodeRanch Cattle Drive, Assignment 3",
"source_url": "https://coderanch.com/t/718816/Leap"
}
17 changes: 17 additions & 0 deletions exercises/practice/leap/.meta/example.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.text
.globl leap_year

/* extern int leap_year(int year); */
leap_year:
mov x1, #100 /* divisor */
udiv x2, x0, x1 /* quotient, i.e. century */
msub x3, x2, x1, x0 /* remainder, i.e. year within century */
tst x3, x3 /* check if 0 */
csel x0, x2, x3, eq /* either century, or year within century */
mov x4, #0
mov x5, #1
tst x0, #3 /* check if multiple of 4 */
csel x0, x5, x4, eq
ret


37 changes: 37 additions & 0 deletions exercises/practice/leap/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# 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.

[6466b30d-519c-438e-935d-388224ab5223]
description = "year not divisible by 4 in common year"

[ac227e82-ee82-4a09-9eb6-4f84331ffdb0]
description = "year divisible by 2, not divisible by 4 in common year"

[4fe9b84c-8e65-489e-970b-856d60b8b78e]
description = "year divisible by 4, not divisible by 100 in leap year"

[7fc6aed7-e63c-48f5-ae05-5fe182f60a5d]
description = "year divisible by 4 and 5 is still a leap year"

[78a7848f-9667-4192-ae53-87b30c9a02dd]
description = "year divisible by 100, not divisible by 400 in common year"

[9d70f938-537c-40a6-ba19-f50739ce8bac]
description = "year divisible by 100 but not by 3 is still not a leap year"

[42ee56ad-d3e6-48f1-8e3f-c84078d916fc]
description = "year divisible by 400 is leap year"

[57902c77-6fe9-40de-8302-587b5c27121e]
description = "year divisible by 400 but not by 125 is still a leap year"

[c30331f6-f9f6-4881-ad38-8ca8c12520c1]
description = "year divisible by 200, not divisible by 400 in common year"
36 changes: 36 additions & 0 deletions exercises/practice/leap/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
AS = aarch64-linux-gnu-as
CC = aarch64-linux-gnu-gcc

CFLAGS = -g -Wall -Wextra -pedantic -Werror
LDFLAGS =

ALL_LDFLAGS = -pie -Wl,--fatal-warnings

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

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

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

all: tests
qemu-aarch64 -L /usr/aarch64-linux-gnu ./$<

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

%.o: %.s
@$(AS) -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
5 changes: 5 additions & 0 deletions exercises/practice/leap/leap.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.text
.globl leap_year

leap_year:
ret
67 changes: 67 additions & 0 deletions exercises/practice/leap/leap_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "vendor/unity.h"

extern int leap_year(int year);

void setUp(void) {
}

void tearDown(void) {
}

void test_year_not_divisible_by_4_in_common_year(void) {
TEST_ASSERT_FALSE(leap_year(2015));
}

void test_year_divisible_by_2_not_divisible_by_4_in_common_year(void) {
TEST_IGNORE();
TEST_ASSERT_FALSE(leap_year(1970));
}

void test_year_divisible_by_4_not_divisible_by_100_in_leap_year(void) {
TEST_IGNORE();
TEST_ASSERT_TRUE(leap_year(1996));
}

void test_year_divisible_by_4_and_5_is_still_a_leap_year(void) {
TEST_IGNORE();
TEST_ASSERT_TRUE(leap_year(1960));
}

void test_year_divisible_by_100_not_divisible_by_400_in_common_year(void) {
TEST_IGNORE();
TEST_ASSERT_FALSE(leap_year(2100));
}

void test_year_divisible_by_100_but_not_by_3_is_still_not_a_leap_year(void) {
TEST_IGNORE();
TEST_ASSERT_FALSE(leap_year(1900));
}

void test_year_divisible_by_400_is_leap_year(void) {
TEST_IGNORE();
TEST_ASSERT_TRUE(leap_year(2000));
}

void test_year_divisible_by_400_but_not_by_125_is_still_a_leap_year(void) {
TEST_IGNORE();
TEST_ASSERT_TRUE(leap_year(2400));
}

void test_year_divisible_by_200_not_divisible_by_400_in_common_year(void) {
TEST_IGNORE();
TEST_ASSERT_FALSE(leap_year(1800));
}

int main(void) {
UNITY_BEGIN();
RUN_TEST(test_year_not_divisible_by_4_in_common_year);
RUN_TEST(test_year_divisible_by_2_not_divisible_by_4_in_common_year);
RUN_TEST(test_year_divisible_by_4_not_divisible_by_100_in_leap_year);
RUN_TEST(test_year_divisible_by_4_and_5_is_still_a_leap_year);
RUN_TEST(test_year_divisible_by_100_not_divisible_by_400_in_common_year);
RUN_TEST(test_year_divisible_by_100_but_not_by_3_is_still_not_a_leap_year);
RUN_TEST(test_year_divisible_by_400_is_leap_year);
RUN_TEST(test_year_divisible_by_400_but_not_by_125_is_still_a_leap_year);
RUN_TEST(test_year_divisible_by_200_not_divisible_by_400_in_common_year);
return UNITY_END();
}
Loading

0 comments on commit 8be5c39

Please sign in to comment.