Skip to content

Commit

Permalink
Implement exercise 'prime-factors'
Browse files Browse the repository at this point in the history
  • Loading branch information
ingydotnet committed Oct 25, 2024
1 parent 6fa6d4f commit f08fd5d
Show file tree
Hide file tree
Showing 13 changed files with 523 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@
"prerequisites": [],
"difficulty": 1
},
{
"slug": "prime-factors",
"name": "Prime Factors",
"uuid": "9cc8f9a8-66c4-44e2-ad9d-c9ca4efa9dfc",
"practices": [],
"prerequisites": [],
"difficulty": 1
},
{
"slug": "resistor-color",
"name": "Resistor Color",
Expand Down
7 changes: 7 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ exercises:
prerequisites: []
difficulty: 1

- slug: prime-factors
name: Prime Factors
uuid: 9cc8f9a8-66c4-44e2-ad9d-c9ca4efa9dfc
practices: []
prerequisites: []
difficulty: 1

- slug: resistor-color
name: Resistor Color
uuid: edb17966-2a6c-47c8-ac65-d66b00deb97b
Expand Down
36 changes: 36 additions & 0 deletions exercises/practice/prime-factors/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Instructions

Compute the prime factors of a given natural number.

A prime number is only evenly divisible by itself and 1.

Note that 1 is not a prime number.

## Example

What are the prime factors of 60?

- Our first divisor is 2.
2 goes into 60, leaving 30.
- 2 goes into 30, leaving 15.
- 2 doesn't go cleanly into 15.
So let's move on to our next divisor, 3.
- 3 goes cleanly into 15, leaving 5.
- 3 does not go cleanly into 5.
The next possible factor is 4.
- 4 does not go cleanly into 5.
The next possible factor is 5.
- 5 does go cleanly into 5.
- We're left only with 1, so now, we're done.

Our successful divisors in that computation represent the list of prime factors of 60: 2, 2, 3, and 5.

You can check this yourself:

```text
2 * 2 * 3 * 5
= 4 * 15
= 60
```

Success!
28 changes: 28 additions & 0 deletions exercises/practice/prime-factors/.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.80

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
22 changes: 22 additions & 0 deletions exercises/practice/prime-factors/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"authors": [
"ingydotnet"
],
"files": {
"solution": [
"prime-factors.ys"
],
"test": [
"prime-factors-test.ys",
"GNUmakefile",
"Makefile",
".yamlscript/exercism-ys-installer"
],
"example": [
".meta/prime-factors.ys"
]
},
"blurb": "Compute the prime factors of a given natural number.",
"source": "The Prime Factors Kata by Uncle Bob",
"source_url": "https://web.archive.org/web/20221026171801/http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata"
}
96 changes: 96 additions & 0 deletions exercises/practice/prime-factors/.meta/prime-factors-test.ys
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env ys-0

require ys::taptest: :all

use: prime-factors

test::
- name: No factors
code: factors(1)
want: []
uuid: 924fc966-a8f5-4288-82f2-6b9224819ccd

- name: Prime number
code: factors(2)
want:
- 2
uuid: 17e30670-b105-4305-af53-ddde182cb6ad

- name: Another prime number
code: factors(3)
want:
- 3
uuid: 238d57c8-4c12-42ef-af34-ae4929f94789

- name: Square of a prime
code: factors(9)
want:
- 3
- 3
uuid: f59b8350-a180-495a-8fb1-1712fbee1158

- name: Product of first prime
code: factors(4)
want:
- 2
- 2
uuid: 756949d3-3158-4e3d-91f2-c4f9f043ee70

- name: Cube of a prime
code: factors(8)
want:
- 2
- 2
- 2
uuid: bc8c113f-9580-4516-8669-c5fc29512ceb

- name: Product of second prime
code: factors(27)
want:
- 3
- 3
- 3
uuid: 7d6a3300-a4cb-4065-bd33-0ced1de6cb44

- name: Product of third prime
code: factors(625)
want:
- 5
- 5
- 5
- 5
uuid: 073ac0b2-c915-4362-929d-fc45f7b9a9e4

- name: Product of first and second prime
code: factors(6)
want:
- 2
- 3
uuid: 6e0e4912-7fb6-47f3-a9ad-dbcd79340c75

- name: Product of primes and non-primes
code: factors(12)
want:
- 2
- 2
- 3
uuid: 00485cd3-a3fe-4fbe-a64a-a4308fc1f870

- name: Product of primes
code: factors(901255)
want:
- 5
- 17
- 23
- 461
uuid: 02251d54-3ca1-4a9b-85e1-b38f4b0ccb91

- name: Factors include a large prime
code: factors(93819012551)
want:
- 11
- 9539
- 894119
uuid: 070cf8dc-e202-4285-aa37-8d775c9cd473

done: 12
8 changes: 8 additions & 0 deletions exercises/practice/prime-factors/.meta/prime-factors.ys
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
!yamlscript/v0

defn factors(value):
or _ []:
when value >= 2:
divisor =: range(2 (value / 2).++)
.filter(\((value % _) == 0)):first || value
into [divisor]: factors(quot(value divisor))
46 changes: 46 additions & 0 deletions exercises/practice/prime-factors/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 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.

[924fc966-a8f5-4288-82f2-6b9224819ccd]
description = "no factors"

[17e30670-b105-4305-af53-ddde182cb6ad]
description = "prime number"

[238d57c8-4c12-42ef-af34-ae4929f94789]
description = "another prime number"

[f59b8350-a180-495a-8fb1-1712fbee1158]
description = "square of a prime"

[756949d3-3158-4e3d-91f2-c4f9f043ee70]
description = "product of first prime"

[bc8c113f-9580-4516-8669-c5fc29512ceb]
description = "cube of a prime"

[7d6a3300-a4cb-4065-bd33-0ced1de6cb44]
description = "product of second prime"

[073ac0b2-c915-4362-929d-fc45f7b9a9e4]
description = "product of third prime"

[6e0e4912-7fb6-47f3-a9ad-dbcd79340c75]
description = "product of first and second prime"

[00485cd3-a3fe-4fbe-a64a-a4308fc1f870]
description = "product of primes and non-primes"

[02251d54-3ca1-4a9b-85e1-b38f4b0ccb91]
description = "product of primes"

[070cf8dc-e202-4285-aa37-8d775c9cd473]
description = "factors include a large prime"
127 changes: 127 additions & 0 deletions exercises/practice/prime-factors/.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 "$@"
Loading

0 comments on commit f08fd5d

Please sign in to comment.