Skip to content

Commit

Permalink
Implement exercise 'armstrong-numbers'
Browse files Browse the repository at this point in the history
  • Loading branch information
ingydotnet committed Sep 16, 2024
1 parent 41fa41a commit ad55803
Show file tree
Hide file tree
Showing 15 changed files with 414 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@
"prerequisites": [],
"difficulty": 2
},
{
"slug": "armstrong-numbers",
"name": "Armstrong Numbers",
"uuid": "d9beb726-00fe-4b2c-9a58-1cadcaa4f4b5",
"practices": [],
"prerequisites": [],
"difficulty": 2
},
{
"slug": "binary-search",
"name": "Binary Search",
Expand Down
7 changes: 7 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ exercises:
prerequisites: []
difficulty: 2

- slug: armstrong-numbers
name: Armstrong Numbers
uuid: d9beb726-00fe-4b2c-9a58-1cadcaa4f4b5
practices: []
prerequisites: []
difficulty: 2

- slug: binary-search
name: Binary Search
uuid: db284b8d-a06d-4a34-9f8a-6c78ef56ce26
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
YS_VERSION := 0.1.75
28 changes: 28 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
SHELL := bash

BASE := $(shell pwd)

export YS_VERSION := 0.1.76

YS_LOCAL_PREFIX := ../../../../.local/v$(YS_VERSION)

YS_LOCAL_BIN := $(YS_LOCAL_PREFIX)/bin

YS_BIN := $(YS_LOCAL_BIN)/ys-$(YS_VERSION)

TEST_FILE ?= $(wildcard *-test.ys)


export PATH := $(YS_LOCAL_BIN):$(PATH)

export YSPATH := $(BASE)


default:

test: $(YS_BIN)
prove -v $(TEST_FILE)

$(YS_BIN):
curl -s https://yamlscript.org/install | \
BIN=1 VERSION=$(YS_VERSION) PREFIX=$(YS_LOCAL_PREFIX) bash >/dev/null
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env ys-0

require ys::taptest: :all

use: armstrong-numbers

test::
- name: Zero is an armstrong number
code: is-armstrong-number(0)
want: true
uuid: c1ed103c-258d-45b2-be73-d8c6d9580c7b

- name: Single-digit numbers are armstrong numbers
code: is-armstrong-number(5)
want: true
uuid: 579e8f03-9659-4b85-a1a2-d64350f6b17a

- name: There are no two-digit armstrong numbers
code: is-armstrong-number(10)
want: false
uuid: 2d6db9dc-5bf8-4976-a90b-b2c2b9feba60

- name: Three-digit number that is an armstrong number
code: is-armstrong-number(153)
want: true
uuid: 509c087f-e327-4113-a7d2-26a4e9d18283

- name: Three-digit number that is not an armstrong number
code: is-armstrong-number(100)
want: false
uuid: 7154547d-c2ce-468d-b214-4cb953b870cf

- name: Four-digit number that is an armstrong number
code: is-armstrong-number(9474)
want: true
uuid: 6bac5b7b-42e9-4ecb-a8b0-4832229aa103

- name: Four-digit number that is not an armstrong number
code: is-armstrong-number(9475)
want: false
uuid: eed4b331-af80-45b5-a80b-19c9ea444b2e

- name: Seven-digit number that is an armstrong number
code: is-armstrong-number(9926315)
want: true
uuid: f971ced7-8d68-4758-aea1-d4194900b864

- name: Seven-digit number that is not an armstrong number
code: is-armstrong-number(9926314)
want: false
uuid: 7ee45d52-5d35-4fbd-b6f1-5c8cd8a67f18

done: 9
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
!yamlscript/v0

defn is-armstrong-number(number):
number ==: map(\(_ ** str(number).#) digits(number)).sum()
23 changes: 23 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"authors": [
"ingydotnet"
],
"files": {
"solution": [
"armstrong-numbers.ys"
],
"test": [
"armstrong-numbers-test.ys",
"GNUmakefile",
"Makefile",
".yamlscript/exercise.mk",
".yamlscript/exercism-ys-installer"
],
"example": [
".meta/armstrong-numbers.ys"
]
},
"blurb": "Determine if a number is an Armstrong number.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Narcissistic_number"
}
43 changes: 43 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# 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"

[12ffbf10-307a-434e-b4ad-c925680e1dd4]
description = "The largest and last Armstrong number"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
YS_VERSION := 0.1.75
127 changes: 127 additions & 0 deletions exercises/practice/armstrong-numbers/.yamlscript/exercism-ys-installer
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/env/bin/env bash

set -euo pipefail

intro-prompt() (
cat <<...
--------------------------------------------------------------------------------
This YAMLScript Exercism exercise requires the YAMLScript version $version
interpreter command file to be installed here:
$prefix/bin/ys
You can install it by pressing Enter now, or by running this command:
$make install-ys
This should only take a few seconds and you only need to do this once.
Other exercises will use the same file.
See https://yamlscript.org/doc/install/ for more YAMLScript installation info.
--------------------------------------------------------------------------------
Would you like to install the 'ys' file now?
...

printf "Press Enter to install. Ctl-C to Quit."; read -r
)

main() {
setup "$@"

install-from-local

$auto && intro-prompt

installed || install-from-release || true
installed || install-from-build || true
installed ||
die "Installing '$installed' failed. Giving up." \
"Consider filing an issue at: $gh_issue_url"

echo
echo 'Success!'
echo "$installed is now installed."
echo
}

installed() {
[[ -f $installed ]]
}

install-from-local() {
local path
path=$(command -v "$ysfq") || true
if [[ -f $path ]]; then
mkdir -p "$bin"
cp "$path" "$bin"/
ln -fs "$ysfq" "$bin/ys-0"
ln -fs "$ysfq" "$bin/ys"
(installed && $auto) && exit
true
fi
}

install-from-release() (
set -x
curl -s https://yamlscript.org/install |
BIN=1 VERSION="$version" PREFIX="$prefix" bash
)

install-from-build() (
cat <<...
The binary release installation failed.
We can attempt to build and install $ysfq now.
This can take from 1 to 5 minutes to complete.
...

printf "Press Enter to install. Ctl-C to Quit."; read -r

[[ -d /tmp && -w /tmp ]] ||
die "Can't write to /tmp" \
'Giving up.'

set -x

rm -fr "$yamlscript_clone"

git clone --branch="$version" "$yamlscript_repo" "$yamlscript_clone"

"$make" -C "$yamlscript_clone/ys" install PREFIX="$prefix"
)

setup() {
version=$1
prefix=$2
make=$3
auto=false
[[ ${4-} ]] && auto=true

[[ $version =~ ^0\.1\.[0-9]+$ ]] ||
die "Invalid YS_VERSION '$version'"

bin=$prefix/bin
ysfq=ys-$version
installed=$bin/$ysfq

if installed; then
echo "'$installed' is already installed."
exit
fi

yamlscript_repo=https://github.com/yaml/yamlscript
yamlscript_clone=/tmp/yamlscript-exercism
gh_issue_url=https://github.com/exercism/yamlscript/issues
}

die() {
printf '%s\n' "$@" >&2
exit 1
}

main "$@"
49 changes: 49 additions & 0 deletions exercises/practice/armstrong-numbers/GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
SHELL := bash

BASE := $(shell pwd)

include .yamlscript/exercise.mk

YS_LOCAL_PREFIX := ../../../.local/v$(YS_VERSION)
ifeq (,$(shell [[ -d "$(YS_LOCAL_PREFIX)" ]] && echo ok))
YS_LOCAL_PREFIX := $(shell cd .. && pwd -P)/.local/v$(YS_VERSION)
endif

YS_LOCAL_BIN := $(YS_LOCAL_PREFIX)/bin
YS_BIN := $(YS_LOCAL_BIN)/ys-$(YS_VERSION)

YS_INSTALLER := .yamlscript/exercism-ys-installer
YS_INSTALLER_CMD := \
bash $(YS_INSTALLER) $(YS_VERSION) $(YS_LOCAL_PREFIX) $(MAKE)

TEST_FILE ?= $(wildcard *-test.ys)

export PATH := $(YS_LOCAL_BIN):$(PATH)
export YSPATH := $(BASE)


#-------------------------------------------------------------------------------
default:
@echo " No default make rule. Try 'make test'."

test: $(YS_BIN)
prove -v $(TEST_FILE)

install-ys:
@$(YS_INSTALLER_CMD)

uninstall-ys:
rm -fr $(YS_LOCAL_PREFIX)


#-------------------------------------------------------------------------------
ifdef EXERCISM_YAMLSCRIPT_GHA
$(YS_BIN):

else ifeq (/mnt/,$(dir $(BASE)))
$(YS_BIN):

else
$(YS_BIN):
@$(YS_INSTALLER_CMD) auto
endif
8 changes: 8 additions & 0 deletions exercises/practice/armstrong-numbers/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This Makefile is a decoy to attempt to detect when a non-GNU make is being
# used and alert the user.

test:
@echo "You appear to be using a non-GNU version of the 'make' program."
@echo "The YAMLScript Exercism track requires you to use GNU make."
@echo "Please try 'make $@' again using GNU make."
@exit 1
Loading

0 comments on commit ad55803

Please sign in to comment.