Skip to content

Commit 808a38d

Browse files
authored
Merge pull request #171 from atk/palindrome-products
new exercise: palindrome-products
2 parents 5f1bb80 + c81d7f6 commit 808a38d

File tree

13 files changed

+540
-0
lines changed

13 files changed

+540
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,14 @@
439439
"prerequisites": [],
440440
"difficulty": 6
441441
},
442+
{
443+
"slug": "palindrome-products",
444+
"name": "Palindrome Products",
445+
"uuid": "96a3edc8-2421-4fb0-b3d1-fb65f48f8230",
446+
"practices": [],
447+
"prerequisites": [],
448+
"difficulty": 7
449+
},
442450
{
443451
"slug": "pig-latin",
444452
"name": "Pig Latin",
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
## Return values
2+
3+
The functions are supposed to return the product and the offset and length of the factors array. The factors are just written as pairs of i32 into memory:
4+
5+
6+
```
7+
Return value:
8+
[u32 $product] [u32 $factorsOffset] [u32 $factorsLength]
9+
10+
Memory at $factorsOffset
11+
[u32 firstFactor] [u32 firstCofactor] [u32 secondFactor] [u32 secondCofactor] ...
12+
```
13+
14+
For the largest one-digit palindrome product, it would look like this:
15+
16+
```
17+
Return value
18+
0009 0000 0004
19+
20+
Memory at offset 0
21+
0001 0009 0003 0003
22+
```
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Instructions
2+
3+
Detect palindrome products in a given range.
4+
5+
A palindromic number is a number that remains the same when its digits are reversed.
6+
For example, `121` is a palindromic number but `112` is not.
7+
8+
Given a range of numbers, find the largest and smallest palindromes which
9+
are products of two numbers within that range.
10+
11+
Your solution should return the largest and smallest palindromes, along with the factors of each within the range.
12+
If the largest or smallest palindrome has more than one pair of factors within the range, then return all the pairs.
13+
14+
## Example 1
15+
16+
Given the range `[1, 9]` (both inclusive)...
17+
18+
And given the list of all possible products within this range:
19+
`[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 15, 21, 24, 27, 20, 28, 32, 36, 25, 30, 35, 40, 45, 42, 48, 54, 49, 56, 63, 64, 72, 81]`
20+
21+
The palindrome products are all single digit numbers (in this case):
22+
`[1, 2, 3, 4, 5, 6, 7, 8, 9]`
23+
24+
The smallest palindrome product is `1`.
25+
Its factors are `(1, 1)`.
26+
The largest palindrome product is `9`.
27+
Its factors are `(1, 9)` and `(3, 3)`.
28+
29+
## Example 2
30+
31+
Given the range `[10, 99]` (both inclusive)...
32+
33+
The smallest palindrome product is `121`.
34+
Its factors are `(11, 11)`.
35+
The largest palindrome product is `9009`.
36+
Its factors are `(91, 99)`.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"root": true,
3+
"extends": "@exercism/eslint-config-javascript",
4+
"env": {
5+
"jest": true
6+
},
7+
"overrides": [
8+
{
9+
"files": [
10+
"*.spec.js"
11+
],
12+
"excludedFiles": [
13+
"custom.spec.js"
14+
],
15+
"extends": "@exercism/eslint-config-javascript/maintainers"
16+
}
17+
]
18+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"authors": [
3+
"atk"
4+
],
5+
"files": {
6+
"solution": [
7+
"palindrome-products.wat"
8+
],
9+
"test": [
10+
"palindrome-products.spec.js"
11+
],
12+
"example": [
13+
".meta/proof.ci.wat"
14+
],
15+
"invalidator": [
16+
"package.json"
17+
]
18+
},
19+
"blurb": "Detect palindrome products in a given range.",
20+
"source": "Problem 4 at Project Euler",
21+
"source_url": "https://projecteuler.net/problem=4",
22+
"custom": {
23+
"version.tests.compatibility": "jest-27",
24+
"flag.tests.task-per-describe": false,
25+
"flag.tests.may-run-long": false,
26+
"flag.tests.includes-optional": false
27+
}
28+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
(module
2+
(import "console" "log_i32_s" (func $log_i32_s (param i32)))
3+
(memory (export "mem") 1)
4+
5+
(global $minMaxError i32 (i32.const -1))
6+
7+
;;
8+
;; Find the first palindrome product based on factors inclusively between minFactor and maxFactor, iterating by step
9+
;;
10+
;; @param {i32} $minFactor - smallest factor of the product
11+
;; @param {i32} $maxFactor - largest factor of the product
12+
;; @param {i32} $step - step
13+
;;
14+
;; @returns {(i32,i32,i32)} - product (0 = not found, -1 = error), offset and length of an array of pairwise factors
15+
;;
16+
(func $find (param $minFactor i32) (param $maxFactor i32) (param $step i32) (result i32 i32 i32)
17+
(local $prod i32)
18+
(local $last i32)
19+
(local $factor i32)
20+
(local $cofactor i32)
21+
(local $num i32)
22+
(local $rev i32)
23+
(local $factorsCount i32)
24+
(if (i32.gt_u (local.get $minFactor) (local.get $maxFactor)) (then
25+
(return (global.get $minMaxError) (i32.const 0) (i32.const 0))))
26+
(if (i32.eq (local.get $step) (i32.const 1)) (then
27+
(local.set $prod (i32.sub (i32.mul (local.get $minFactor) (local.get $minFactor)) (i32.const 1)))
28+
(local.set $last (i32.mul (local.get $maxFactor) (local.get $maxFactor))))
29+
(else
30+
(local.set $prod (i32.sub (i32.mul (local.get $maxFactor) (local.get $maxFactor)) (i32.const -1)))
31+
(local.set $last (i32.mul (local.get $minFactor) (local.get $minFactor)))))
32+
(loop $products
33+
(local.set $prod (i32.add (local.get $prod) (local.get $step)))
34+
(local.set $num (local.get $prod))
35+
(local.set $rev (i32.const 0))
36+
(loop $reverse
37+
(local.set $rev (i32.add (i32.mul (local.get $rev) (i32.const 10))
38+
(i32.rem_s (local.get $num) (i32.const 10))))
39+
(local.set $num (i32.div_u (local.get $num) (i32.const 10)))
40+
(br_if $reverse (local.get $num)))
41+
(if (i32.eq (local.get $rev) (local.get $prod)) (then
42+
(local.set $factor (local.get $minFactor))
43+
(loop $factorize
44+
(if (i32.eqz (i32.rem_u (local.get $prod) (local.get $factor))) (then
45+
(local.set $cofactor (i32.div_u (local.get $prod) (local.get $factor)))
46+
(if (i32.lt_u (local.get $cofactor) (local.get $factor))
47+
(then (local.set $factor (local.get $maxFactor)))
48+
(else (if (i32.and (i32.ge_u (local.get $cofactor) (local.get $minFactor))
49+
(i32.le_u (local.get $cofactor) (local.get $maxFactor))) (then
50+
(i32.store (i32.shl (local.get $factorsCount) (i32.const 2)) (local.get $factor))
51+
(i32.store (i32.shl (i32.add (local.get $factorsCount) (i32.const 1)) (i32.const 2))
52+
(local.get $cofactor))
53+
(local.set $factorsCount (i32.add (local.get $factorsCount) (i32.const 2)))))))))
54+
(local.set $factor (i32.add (local.get $factor) (i32.const 1)))
55+
(br_if $factorize (i32.le_u (local.get $factor) (local.get $maxFactor))))
56+
(if (local.get $factorsCount) (then
57+
(return (local.get $prod) (i32.const 0) (local.get $factorsCount))))
58+
))
59+
(br_if $products (i32.ne (local.get $prod) (local.get $last))))
60+
(i32.const 0) (i32.const 0) (i32.const 0)
61+
)
62+
63+
;;
64+
;; Find the smallest palindrome product based on factors inclusively between minFactor and maxFactor
65+
;;
66+
;; @param {i32} $minFactor - smallest factor of the product
67+
;; @param {i32} $maxFactor - largest factor of the product
68+
;;
69+
;; @returns {(i32,i32,i32)} - product (0 = not found, -1 = error), offset and length of an array of pairwise factors
70+
;;
71+
(func (export "smallest") (param $minFactor i32) (param $maxFactor i32) (result i32 i32 i32)
72+
(call $find (local.get $minFactor) (local.get $maxFactor) (i32.const 1))
73+
)
74+
75+
;;
76+
;; Find the largest palindrome product based on factors inclusively between minFactor and maxFactor
77+
;;
78+
;; @param {i32} $minFactor - smallest factor of the product
79+
;; @param {i32} $maxFactor - largest factor of the product
80+
;;
81+
;; @returns {(i32,i32,i32)} - product (0 = not found, -1 = error), offset and length of an array of pairwise factors
82+
;;
83+
(func (export "largest") (param $minFactor i32) (param $maxFactor i32) (result i32 i32 i32)
84+
(call $find (local.get $minFactor) (local.get $maxFactor) (i32.const -1))
85+
)
86+
)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[5cff78fe-cf02-459d-85c2-ce584679f887]
13+
description = "find the smallest palindrome from single digit factors"
14+
15+
[0853f82c-5fc4-44ae-be38-fadb2cced92d]
16+
description = "find the largest palindrome from single digit factors"
17+
18+
[66c3b496-bdec-4103-9129-3fcb5a9063e1]
19+
description = "find the smallest palindrome from double digit factors"
20+
21+
[a10682ae-530a-4e56-b89d-69664feafe53]
22+
description = "find the largest palindrome from double digit factors"
23+
24+
[cecb5a35-46d1-4666-9719-fa2c3af7499d]
25+
description = "find the smallest palindrome from triple digit factors"
26+
27+
[edab43e1-c35f-4ea3-8c55-2f31dddd92e5]
28+
description = "find the largest palindrome from triple digit factors"
29+
30+
[4f802b5a-9d74-4026-a70f-b53ff9234e4e]
31+
description = "find the smallest palindrome from four digit factors"
32+
33+
[787525e0-a5f9-40f3-8cb2-23b52cf5d0be]
34+
description = "find the largest palindrome from four digit factors"
35+
36+
[58fb1d63-fddb-4409-ab84-a7a8e58d9ea0]
37+
description = "empty result for smallest if no palindrome in the range"
38+
39+
[9de9e9da-f1d9-49a5-8bfc-3d322efbdd02]
40+
description = "empty result for largest if no palindrome in the range"
41+
42+
[12e73aac-d7ee-4877-b8aa-2aa3dcdb9f8a]
43+
description = "error result for smallest if min is more than max"
44+
45+
[eeeb5bff-3f47-4b1e-892f-05829277bd74]
46+
description = "error result for largest if min is more than max"
47+
48+
[16481711-26c4-42e0-9180-e2e4e8b29c23]
49+
description = "smallest product does not use the smallest factor"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
audit=false
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Exercism
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export default {
2+
presets: ["@exercism/babel-preset-javascript"],
3+
plugins: [],
4+
};

0 commit comments

Comments
 (0)