Skip to content

Commit d45740f

Browse files
authored
Sync palindrome products (#1722)
* [palindrome-products] Add missing tests * [palindrome-products] Update example solution * [palindrome-products] Update config.json * [palindrome-products] Fix formatting (example.rb)
1 parent fa35ccc commit d45740f

File tree

5 files changed

+125
-74
lines changed

5 files changed

+125
-74
lines changed

exercises/practice/palindrome-products/.meta/config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"Insti",
1313
"kotp",
1414
"markijbema",
15-
"tryantwit"
15+
"tryantwit",
16+
"themetar"
1617
],
1718
"files": {
1819
"solution": [
Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,42 @@
11
Palindrome = Struct.new(:value, :factors)
22

33
class Palindromes
4-
attr_reader :range
5-
def initialize(options)
6-
max = options.fetch(:max_factor)
7-
min = options.fetch(:min_factor) { 1 }
8-
@range = (min..max)
9-
end
4+
private
105

11-
def generate
12-
@palindromes = {}
13-
range.each do |i|
14-
range.each do |j|
15-
product = i * j
16-
if palindrome?(product)
17-
palindrome = @palindromes[product] || Palindrome.new(product, [])
18-
palindrome.factors << [i, j].sort
19-
palindrome.factors.uniq!
20-
@palindromes[product] = palindrome
21-
end
22-
end
23-
end
6+
attr_reader :min, :max
7+
8+
def initialize(max_factor:, min_factor: 1)
9+
raise ArgumentError, "min must be <= max" unless min_factor <= max_factor
10+
11+
@min = min_factor
12+
@max = max_factor
2413
end
2514

2615
def palindrome?(number)
2716
number.to_s == number.to_s.reverse
2817
end
2918

30-
def sort
31-
@palindromes.sort_by do |key, _palindrome|
32-
key
19+
def factors(palindrome)
20+
(min..Math.sqrt(palindrome)).each_with_object([]) do |number, factors|
21+
div, mod = palindrome.divmod(number)
22+
factors << [number, div] if div.between?(min, max) && mod.zero?
3323
end
3424
end
3525

36-
def largest
37-
sort.last[1]
26+
def find_palindrome(enum)
27+
enum.lazy.
28+
filter { |number| palindrome? number }.
29+
map { |number| Palindrome.new number, factors(number) }.
30+
find { |palindrome| !palindrome.factors.empty? }
3831
end
3932

40-
def smallest
41-
sort.first[1]
33+
public
34+
35+
attr_reader :smallest, :largest
36+
37+
def generate
38+
@smallest = find_palindrome(min**2..max**2) || Palindrome.new(nil, [])
39+
40+
@largest = find_palindrome((max**2..min**2).step(-1)) || Palindrome.new(nil, [])
4241
end
4342
end

exercises/practice/palindrome-products/.meta/example_2.rb

Lines changed: 0 additions & 47 deletions
This file was deleted.

exercises/practice/palindrome-products/.meta/tests.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
# As user-added comments (using the # character) will be removed when this file
1010
# is regenerated, comments can be added via a `comment` key.
1111

12+
[5cff78fe-cf02-459d-85c2-ce584679f887]
13+
description = "find the smallest palindrome from single digit factors"
14+
1215
[0853f82c-5fc4-44ae-be38-fadb2cced92d]
1316
description = "find the largest palindrome from single digit factors"
1417

@@ -23,3 +26,24 @@ description = "find the smallest palindrome from triple digit factors"
2326

2427
[edab43e1-c35f-4ea3-8c55-2f31dddd92e5]
2528
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"

exercises/practice/palindrome-products/palindrome_products_test.rb

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22
require_relative 'palindrome_products'
33

44
class PalindromesTest < Minitest::Test
5+
def test_smallest_palindrome_from_single_digit_factors
6+
palindromes = Palindromes.new(max_factor: 9)
7+
palindromes.generate
8+
smallest = palindromes.smallest
9+
assert_equal 1, smallest.value
10+
assert_equal [[1, 1]], smallest.factors
11+
end
12+
513
def test_largest_palindrome_from_single_digit_factors
14+
skip
615
palindromes = Palindromes.new(max_factor: 9)
716
palindromes.generate
817
largest = palindromes.largest
@@ -45,4 +54,69 @@ def test_smallest_palindrome_from_triple_digit_factors
4554
assert_equal 10_201, smallest.value
4655
assert_equal [[101, 101]], smallest.factors
4756
end
57+
58+
def test_smallest_palindrome_from_four_digit_factors
59+
skip
60+
palindromes = Palindromes.new(min_factor: 1000, max_factor: 9999)
61+
palindromes.generate
62+
smallest = palindromes.smallest
63+
assert_equal 1_002_001, smallest.value
64+
assert_equal [[1001, 1001]], smallest.factors
65+
end
66+
67+
def test_largest_palindrome_from_four_digit_factors
68+
skip
69+
palindromes = Palindromes.new(min_factor: 1000, max_factor: 9999)
70+
palindromes.generate
71+
largest = palindromes.largest
72+
assert_equal 99_000_099, largest.value
73+
assert_equal [[9901, 9999]], largest.factors
74+
end
75+
76+
def test_empty_for_smallest_if_no_palindrome_in_range
77+
skip
78+
palindromes = Palindromes.new(min_factor: 1002, max_factor: 1003)
79+
palindromes.generate
80+
smallest = palindromes.smallest
81+
assert_nil smallest.value
82+
assert_empty smallest.factors
83+
end
84+
85+
def test_empty_for_largest_if_no_palindrome_in_range
86+
skip
87+
palindromes = Palindromes.new(min_factor: 15, max_factor: 15)
88+
palindromes.generate
89+
largest = palindromes.largest
90+
assert_nil largest.value
91+
assert_empty largest.factors
92+
end
93+
94+
def test_error_for_smallest_if_min_more_than_max
95+
skip
96+
error = assert_raises(ArgumentError) do
97+
palindromes = Palindromes.new(min_factor: 10_000, max_factor: 1)
98+
palindromes.generate
99+
palindromes.smallest
100+
end
101+
assert_equal "min must be <= max", error.message
102+
end
103+
104+
def test_error_for_largest_if_min_more_than_max
105+
skip
106+
error = assert_raises(ArgumentError) do
107+
palindromes = Palindromes.new(min_factor: 2, max_factor: 1)
108+
palindromes.generate
109+
palindromes.smallest
110+
end
111+
assert_equal "min must be <= max", error.message
112+
end
113+
114+
def test_smallest_palindrome_does_not_use_smallest_factors
115+
skip
116+
palindromes = Palindromes.new(min_factor: 3215, max_factor: 4000)
117+
palindromes.generate
118+
smallest = palindromes.smallest
119+
assert_equal 10_988_901, smallest.value
120+
assert_equal [[3297, 3333]], smallest.factors
121+
end
48122
end

0 commit comments

Comments
 (0)