問題
左右どちらから読んでも同じ値になる数を回文数という. 2桁の数の積で表される回文数のうち, 最大のものは 9009 = 91 × 99 である.
では, 3桁の数の積で表される回文数の最大値を求めよ.
素直に
3 |
% {
# i ≦ j となるような3桁の数 i, j の積のうち
foreach ($i in [Math]::Pow(10, $_ - 1)..([Math]::Pow(10, $_) - 1))
{foreach ($j in $i..([Math]::Pow(10, $_) - 1))
{($i * $j).ToString()}}
} |
? {
# 回文数になっているもので
foreach ($k in 0..([Math]::Floor(($_.Length - 1) / 2)))
{if ($_[$k] -ne $_[$_.Length - 1 - $k])
{return $false}}
$true
} |
% {$max = 0} {$max = [Math]::Max($max, [int]$_)} {$max} # 最大のもの
回文数を大きい方から生成して、3桁の積か確認する
1桁の場合も正確に回答できるようにするとやや面倒。
3 |
% {
$n = $_
([Math]::Pow(10, $n) - 1)..[Math]::Pow(10, $n - 1) |
%{"$_" + -join "$_"[("$_".Length - 1)..0]}
if ($n -eq 1)
{
9..0 | %{$_.ToString()}
}
else
{
([Math]::Pow(10, $n - 1) - 1)..[Math]::Pow(10, $n - 2) |
% {
$i = $_.ToString()
9..0 | %{"${i}${_}" + -join $i[($i.Length - 1)..0]}
}
}
} |
? {
foreach ($k in ([Math]::Pow(10, $n) - 1)..[Math]::Pow(10, $n - 1))
{if (([int]$_) % $k -eq 0 -and "$(([int]$_) / $k)".Length -eq $n)
{return $true}}
$false
} |
select -first 1
見つけた回文数によってループの範囲を狭める
3 |
% {
$max = $max_j = [Math]::Pow(10, $_ - 1)
for ($i = ([Math]::Pow(10, $_) - 1); $i -ge $max_j; $i--)
{
:j for ($j = $i; $i * $j -ge $max ;$j--)
{
$n = ($i * $j).ToString()
foreach ($k in 0..([Math]::Floor(($n.Length - 1) / 2)))
{
if ($n[$k] -ne $n[$n.Length - 1 - $k])
{continue j}
}
$max, $max_j = ($i * $j) , $j
}
}
$max
}
以上
おわり。