Skip to content

Commit

Permalink
Add armstrong-numbers exercise
Browse files Browse the repository at this point in the history
  • Loading branch information
keiravillekode committed Nov 2, 2024
1 parent f12eac4 commit e5085d8
Show file tree
Hide file tree
Showing 12 changed files with 3,549 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@
"prerequisites": [],
"difficulty": 2
},
{
"slug": "armstrong-numbers",
"name": "Armstrong Numbers",
"uuid": "556a01ac-2d5b-4cbb-a5a5-c5a9d869c4cd",
"practices": [],
"prerequisites": [],
"difficulty": 3
},
{
"slug": "bob",
"name": "Bob",
Expand Down
14 changes: 14 additions & 0 deletions exercises/practice/armstrong-numbers/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Instructions

An [Armstrong number][armstrong-number] is a number that is the sum of its own digits each raised to the power of the number of digits.

For example:

- 9 is an Armstrong number, because `9 = 9^1 = 9`
- 10 is _not_ an Armstrong number, because `10 != 1^2 + 0^2 = 1`
- 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153`
- 154 is _not_ an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190`

Write some code to determine whether a number is an Armstrong number.

[armstrong-number]: https://en.wikipedia.org/wiki/Narcissistic_number
19 changes: 19 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"keiravillekode"
],
"files": {
"solution": [
"armstrong_numbers.s"
],
"test": [
"armstrong_numbers_test.c"
],
"example": [
".meta/example.s"
]
},
"blurb": "Determine if a number is an Armstrong number.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Narcissistic_number"
}
39 changes: 39 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/example.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.text
.globl is_armstrong_number

/* extern int is_armstrong_number(unsigned number); */
is_armstrong_number:
mov x1, #10
mov x4, x0 /* number */
mov x5, xzr /* digit count */
mov x6, xzr /* sum of digit powers */

.count_digit:
add x5, x5, #1
udiv x0, x0, x1 /* quotient */
cbnz x0, .count_digit

mov x0, x4 /* number */

.extract_digit:
udiv x2, x0, x1 /* quotient */
msub x3, x2, x1, x0 /* remainder becomes base */
mov x0, x2
mov x9, #1 /* multiplier */
mov x10, x5 /* exponent */

.raise:
mul x7, x9, x3
tst x10, #1
csel x9, x7, x9, ne /* multiplier *= base, provided exponent is odd */

mul x3, x3, x3 /* square base */
lsr x10, x10, #1 /* halve exponent */
cbnz x10, .raise

add x6, x6, x9 /* update sum of digit powers */
cbnz x2, .extract_digit

cmp x6, x4
cset x0, eq /* 1 if sum of digit powers == number, otherwise 0 */
ret
45 changes: 45 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 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.

[c1ed103c-258d-45b2-be73-d8c6d9580c7b]
description = "Zero is an Armstrong number"

[579e8f03-9659-4b85-a1a2-d64350f6b17a]
description = "Single-digit numbers are Armstrong numbers"

[2d6db9dc-5bf8-4976-a90b-b2c2b9feba60]
description = "There are no two-digit Armstrong numbers"

[509c087f-e327-4113-a7d2-26a4e9d18283]
description = "Three-digit number that is an Armstrong number"

[7154547d-c2ce-468d-b214-4cb953b870cf]
description = "Three-digit number that is not an Armstrong number"

[6bac5b7b-42e9-4ecb-a8b0-4832229aa103]
description = "Four-digit number that is an Armstrong number"

[eed4b331-af80-45b5-a80b-19c9ea444b2e]
description = "Four-digit number that is not an Armstrong number"

[f971ced7-8d68-4758-aea1-d4194900b864]
description = "Seven-digit number that is an Armstrong number"

[7ee45d52-5d35-4fbd-b6f1-5c8cd8a67f18]
description = "Seven-digit number that is not an Armstrong number"

[5ee2fdf8-334e-4a46-bb8d-e5c19c02c148]
description = "Armstrong number containing seven zeroes"
include = false

[12ffbf10-307a-434e-b4ad-c925680e1dd4]
description = "The largest and last Armstrong number"
include = false
36 changes: 36 additions & 0 deletions exercises/practice/armstrong-numbers/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/armstrong-numbers/armstrong_numbers.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.text
.globl is_armstrong_number

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

extern int is_armstrong_number(unsigned number);

void setUp(void) {
}

void tearDown(void) {
}

void test_zero_is_an_armstrong_number(void) {
TEST_ASSERT_TRUE(is_armstrong_number(0));
}

void test_singledigit_numbers_are_armstrong_numbers(void) {
TEST_IGNORE();
TEST_ASSERT_TRUE(is_armstrong_number(5));
}

void test_there_are_no_twodigit_armstrong_numbers(void) {
TEST_IGNORE();
TEST_ASSERT_FALSE(is_armstrong_number(10));
}

void test_threedigit_number_that_is_an_armstrong_number(void) {
TEST_IGNORE();
TEST_ASSERT_TRUE(is_armstrong_number(153));
}

void test_threedigit_number_that_is_not_an_armstrong_number(void) {
TEST_IGNORE();
TEST_ASSERT_FALSE(is_armstrong_number(100));
}

void test_fourdigit_number_that_is_an_armstrong_number(void) {
TEST_IGNORE();
TEST_ASSERT_TRUE(is_armstrong_number(9474));
}

void test_fourdigit_number_that_is_not_an_armstrong_number(void) {
TEST_IGNORE();
TEST_ASSERT_FALSE(is_armstrong_number(9475));
}

void test_sevendigit_number_that_is_an_armstrong_number(void) {
TEST_IGNORE();
TEST_ASSERT_TRUE(is_armstrong_number(9926315));
}

void test_sevendigit_number_that_is_not_an_armstrong_number(void) {
TEST_IGNORE();
TEST_ASSERT_FALSE(is_armstrong_number(9926314));
}

int main(void) {
UNITY_BEGIN();
RUN_TEST(test_zero_is_an_armstrong_number);
RUN_TEST(test_singledigit_numbers_are_armstrong_numbers);
RUN_TEST(test_there_are_no_twodigit_armstrong_numbers);
RUN_TEST(test_threedigit_number_that_is_an_armstrong_number);
RUN_TEST(test_threedigit_number_that_is_not_an_armstrong_number);
RUN_TEST(test_fourdigit_number_that_is_an_armstrong_number);
RUN_TEST(test_fourdigit_number_that_is_not_an_armstrong_number);
RUN_TEST(test_sevendigit_number_that_is_an_armstrong_number);
RUN_TEST(test_sevendigit_number_that_is_not_an_armstrong_number);
return UNITY_END();
}
Loading

0 comments on commit e5085d8

Please sign in to comment.