Skip to content

Commit 1ef7775

Browse files
Add palindrome-products (#507)
1 parent fe6d853 commit 1ef7775

File tree

8 files changed

+432
-0
lines changed

8 files changed

+432
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,14 @@
10831083
"prerequisites": [],
10841084
"difficulty": 7
10851085
},
1086+
{
1087+
"slug": "palindrome-products",
1088+
"name": "Palindrome Products",
1089+
"uuid": "4f4d859e-18c2-4a80-ad95-5f2427dafc9d",
1090+
"practices": [],
1091+
"prerequisites": [],
1092+
"difficulty": 8
1093+
},
10861094
{
10871095
"slug": "word-count",
10881096
"name": "Word Count",
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Instructions append
2+
3+
## Zig-specific Notes
4+
5+
You may assume the range `[min, max]` is valid: `min <= max`.
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: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"keiravillekode"
4+
],
5+
"files": {
6+
"solution": [
7+
"palindrome_products.zig"
8+
],
9+
"test": [
10+
"test_palindrome_products.zig"
11+
],
12+
"example": [
13+
".meta/example.zig"
14+
]
15+
},
16+
"blurb": "Detect palindrome products in a given range.",
17+
"source": "Problem 4 at Project Euler",
18+
"source_url": "https://projecteuler.net/problem=4"
19+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
const std = @import("std");
2+
const math = std.math;
3+
const mem = std.mem;
4+
5+
pub const Pair = struct {
6+
first: u64,
7+
second: u64,
8+
};
9+
10+
pub const Palindrome = struct {
11+
value: u64,
12+
factors: []Pair,
13+
};
14+
15+
fn palindrome(number: u64) bool {
16+
var buffer: [20]u64 = undefined;
17+
buffer[0] = number % 10;
18+
var end: usize = 1;
19+
var n: u64 = number / 10;
20+
while (n != 0) {
21+
buffer[end] = n % 10;
22+
end += 1;
23+
n = n / 10;
24+
}
25+
26+
var begin: usize = 0;
27+
while (begin + 1 < end) {
28+
end -= 1;
29+
if (buffer[begin] != buffer[end]) {
30+
return false;
31+
}
32+
begin += 1;
33+
}
34+
return true;
35+
}
36+
37+
pub fn smallest(allocator: mem.Allocator, min: u64, max: u64) mem.Allocator.Error!?Palindrome {
38+
std.debug.assert(min <= max);
39+
var value: u64 = math.maxInt(u64);
40+
var factors = std.array_list.Managed(Pair).init(allocator);
41+
errdefer factors.deinit();
42+
43+
for (min..max) |i| {
44+
const first = @as(u64, @intCast(i));
45+
for (first..max) |j| {
46+
const second = @as(u64, @intCast(j));
47+
const product = first * second;
48+
if (product > value) {
49+
break;
50+
}
51+
52+
if (!palindrome(product)) {
53+
continue;
54+
}
55+
56+
if (product < value) {
57+
factors.clearRetainingCapacity();
58+
value = product;
59+
}
60+
61+
try factors.append(.{ .first = first, .second = second });
62+
}
63+
}
64+
if (factors.items.len == 0) {
65+
return null;
66+
}
67+
68+
return .{
69+
.value = value,
70+
.factors = try factors.toOwnedSlice(),
71+
};
72+
}
73+
74+
pub fn largest(allocator: mem.Allocator, min: u64, max: u64) mem.Allocator.Error!?Palindrome {
75+
std.debug.assert(min <= max);
76+
var value: u64 = 0;
77+
78+
var factors = std.array_list.Managed(Pair).init(allocator);
79+
errdefer factors.deinit();
80+
81+
for (0..(max - min + 1)) |i| {
82+
const second = @as(u64, @intCast(max - i));
83+
for (0..(second - min + 1)) |j| {
84+
const first = @as(u64, @intCast(second - j));
85+
const product = first * second;
86+
if (product < value) {
87+
break;
88+
}
89+
90+
if (!palindrome(product)) {
91+
continue;
92+
}
93+
94+
if (product > value) {
95+
factors.clearRetainingCapacity();
96+
value = product;
97+
}
98+
99+
try factors.append(.{ .first = first, .second = second });
100+
}
101+
}
102+
if (factors.items.len == 0) {
103+
return null;
104+
}
105+
106+
return .{
107+
.value = value,
108+
.factors = try factors.toOwnedSlice(),
109+
};
110+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
include = false
45+
46+
[eeeb5bff-3f47-4b1e-892f-05829277bd74]
47+
description = "error result for largest if min is more than max"
48+
include = false
49+
50+
[16481711-26c4-42e0-9180-e2e4e8b29c23]
51+
description = "smallest product does not use the smallest factor"
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const std = @import("std");
2+
const mem = std.mem;
3+
4+
pub const Pair = struct {
5+
first: u64,
6+
second: u64,
7+
};
8+
9+
pub const Palindrome = struct {
10+
value: u64,
11+
factors: []Pair,
12+
};
13+
14+
pub fn smallest(allocator: mem.Allocator, min: u64, max: u64) mem.Allocator.Error!?Palindrome {
15+
_ = allocator;
16+
_ = min;
17+
_ = max;
18+
@compileError("please implement the smallest function");
19+
}
20+
21+
pub fn largest(allocator: mem.Allocator, min: u64, max: u64) mem.Allocator.Error!?Palindrome {
22+
_ = allocator;
23+
_ = min;
24+
_ = max;
25+
@compileError("please implement the largest function");
26+
}

0 commit comments

Comments
 (0)