In this question, would dig be 2 inputs, such as 91 and 99? And lim can be any number the user calls?

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99. Write a function that is called this way:
>> n = palin_product(dig,lim);
The function returns the largest palindrome smaller than lim that is the product of two dig digit numbers. If no such number exists, the function returns 0. (Inspired by Project Euler.)

 Accepted Answer

I know that this is homework, but someone needed to demonstrate how this can be done quite simply, without using slow and unnecessary third-party functions: I believe that champions2015 and future readers deserve to be shown that MATLAB code can be neat, efficient, and straightforward. Note that this code actually does exactly what the question asks for!
function n = palin_product(dig,lim)
n = 0;
V = 10.^dig-1:-1:10.^(dig-1);
for k1 = V
for k2 = V
p = k1*k2;
if p>n && p<lim
s = sprintf('%d',p);
if all(s==s(end:-1:1))
n = p;
end
end
end
end
end
And tested:
>> palin_product(2,10000)
ans = 9009
>> palin_product(2,9009)
ans = 8448
>> palin_product(2,8448)
ans = 8118
>> palin_product(2,8118)
ans = 8008
>> palin_product(2,8008)
ans = 7227

6 Comments

Thanks Stephen, this really helped! Just a few quick questions about your code: Is 's' a string/cell of numbers, which keeps having continuous values of 'p' added onto it? Could you also create a cell named 's' instead of using 'sprintf' function? Why do you have to check if p is greater than n? What are you checking with 'all(s==s(end:-1:1))'? Is it to check if s/p is symetrical?
"Is 's' a string/cell of numbers"
No, s is a 1xN character array, as the sprintf documentation clearly describes. The char array s contains a representation of the product p.
"which keeps having continuous values of 'p' added onto it?"
No, nothing gets "added onto it": s gets totally reassigned each time that line is run. Whatever data s contained on the last iteration is totally irrelevant to the current iteration.
"Could you also create a cell named 's' instead of using 'sprintf' function?"
I have no idea what you mean, or why you would want to do this.
"Why do you have to check if p is greater than n?"
To identify "the largest palindrome" as your question requests. Only if the current product p is larger than the last identified palindromic number n does the code then check if the current product is also palindromic. There is no point in checking if p is smaller than n, because we already have a larger value stored in n. Thus as well as giving you the right answer it also makes the code much more efficient.
"What are you checking with 'all(s==s(end:-1:1))'?"
If the 1xN character array s is a palindrome.
"Is it to check if s/p is symetrical?"
If you mean checking if s is a palindrome, then yes.
hi Champion and Cobeldick
The Champions League 2015 was won by Barcelona FC, wasn't it?
to Champions2015, may I call you culé?
I caught an error in Coberdick's loops, look:
lim=121 with dig=2 should give the solution 11 11, right?
however,
clear all;clc
dig=2;lim=121
n = 0;
V = 10.^(dig-1):10.^dig-1;
for k1 = V
for k2 = V
p = k1*k2;
if p>n && p<lim
s = sprintf('%d',p);
if all(s==s(end:-1:1))
n = p;
end
end
end
end
n
=
0
error, ain't null yet Stephen's loops return n=0.
.
my function
clear all;clc
lim2=121
dig=2
% function [lim r1 r2]=palin_product(dig,lim)
r1=0;r2=0;
ispal=0;
decom=1;
lim=lim2 % keep start value in lim2, modify lim
while decom
ispal=0;
while ~ispal % find next symmetric integer below input lim2
L1=num2str(lim);
n1=1;n2=length(L1);
while L1(n1)==L1(n2) && n1<=floor(length(L1)/2)
n1=n1+1;n2=n2-1;
end
if L1(n1)==L1(n2) ispal=1; end
if ~ispal lim=lim-1; end
end
s1=10^(dig-1);s2=str2num(repmat('9',1,dig)); % find whether found lim can be decomposed
S=[s1:1:s2];
L=combinator(numel(S),dig,'p','r');
p=1;
s1=S(L(p,1));s2=S(L(p,2));
while ~(s1*s2==lim) && p<length(L)
s1=S(L(p,1));s2=S(L(p,2));
p=p+1;
end
if p<=length(L) && s1*s2==lim
r1=s1;r2=s2
end
if r1==0 && r2==0 && lim>1
lim=lim-1;
end
if lim==1
return
end
if r1*r2>0
decom=0;
end
end
% end % function
r1
r2
r1 =
11
r2 =
11
.
and you get the right answer plus the 2 figures of dig digits decomposition, if exists.
@John BG: you might like to actually read the question. It states "The function returns the largest palindrome smaller than lim that is the product of two dig digit numbers", and that is what my function does. There is no product of two two-digit numbers smaller than the limit 121 that is a palindrome, therefor the correct output should be zero, as the question requests.
If the question had asked for the largest palindrome less than or equal to the limit then this would a be a trivial change in my code of the p<lim to p<=lim, which most people would agree is a simple and intuitive change.
+1. This is a clean, compact and efficient solution.
Alternative to if all(s==s(end:-1:1)):
if isequal(s, s(end:-1:1))

Sign in to comment.

More Answers (3)

I would interpret it as follows.
You are trying to find p1 * p2 = n.
  • lim is any number the user chooses (just as you guessed). The output, n, must be smaller than lim.
  • dig is the number of digits that p1 and p2 each have. For example, if p1=91, and p2=99, then dig=2, because they are 2-digit numbers.
hi champions2015
the following is a slight variation of what's been asked, this function
  • returns the nearest palindrome to the input
  • also calculates the 2 numbers of digit length dig that multiplied are lim
  • if the input is already a palindrome, it decomposes as requested lim, not seeking any smaller palindrome.
clear all;clc
lim2=8448
dig=2
function [lim r1 r2]=palin_product(dig,lim2)
r1=0;r2=0;
ispal=0;
decom=1;
lim=lim2 % keep start value in lim2, modify lim
while decom
ispal=0;
while ~ispal % find next symmetric integer below input lim2
L1=num2str(lim);
n1=1;n2=length(L1);
while L1(n1)==L1(n2) && n1<=floor(length(L1)/2)
n1=n1+1;n2=n2-1;
end
if L1(n1)==L1(n2) ispal=1; end
if ~ispal lim=lim-1; end
end
s1=10^(dig-1);s2=str2num(repmat('9',1,dig)); % find whether found lim can be decomposed
S=[s1:1:s2];
L=combinator(numel(S),dig,'p','r');
p=1;
s1=S(L(p,1));s2=S(L(p,2));
while ~(s1*s2==lim) && p<length(L)
s1=S(L(p,1));s2=S(L(p,2));
p=p+1;
end
if p<=length(L) && s1*s2==lim
r1=s1;r2=s2
end
if r1==0 && r2==0
lim=lim-1;
end
if r1*r2>0
decom=0;
end
end
end % function
.
the most recent version of the function combinator and its support functions are all packed and freely available from
combinator_update.zip and palin_product.m are both attached to this answer.
.
If you find this answer useful would you please be so kind to consider marking my answer as Accepted Answer?
To any other reader, if you find this answer useful please consider clicking on the thumbs-up vote link
thanks in advance
John BG
[EDITED: Copyrighted code removed]

2 Comments

Hi John! Thanks for you answer! I'm not entirely sure if I understand how your code works, and it doesn't seem to work either when I run the function... Why are there 2 outputs? Wouldn't the output be simply somthing like 9009?
Hi Champions2015
When the input is already is such palindrome that can be decomposed as requested, why would you want to seek a smaller palindrome that can be decomposed into 2 figures of digit length dig?
My function also calculates the requested digit dig length decomposition.

Sign in to comment.

Categories

Find more on Communications Toolbox in Help Center and File Exchange

Asked:

on 6 Sep 2017

Edited:

Jan
on 25 Feb 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!