0 から 1000 までのカプレカ数を求めよとのことだ...
カプレカ数とは馴染みのないものであるが,定義は 2 通りあるそうだ。
1. 2 乗して前の部分と後ろの部分に分けて(偶数桁 2n 桁である場合は先頭 n 桁と末尾 n 桁に分け,奇数桁 2n + 1 桁である場合は先頭 n 桁と末尾 n + 1 桁に分けて)和を取ったとき,元の値に等しくなるもの。
2. 桁を並べ替えて最大にしたものから最小にしたものの差を取ったとき,元の値に等しくなるもの。
今回は,前者のことをいっているようだ。
Wikipedia で調べると
カプレカ数
1, 9, 45, 55, 99, 297, 703, 999, 2223, 2728, 4879, 4950, 5050, 5292, …(オンライン整数列大辞典の数列 A006886 http://oeis.org/A006886)が簡単に見つかる。
プログラムを書いて,0 ~ 5300 の範囲を探索すると,得られる出力と違うところがある。
a1 = 0:5300
a2 = a1^2
old = options(scipen=10)
a3 = strsplit(as.character(a2), "")
options(old)
a4 = sapply(a3, function(x) {
y = unlist(x)
n = length(y)
if (n == 1) {
as.numeric(paste(y, collapse=""))
} else {
m = n %/% 2
as.numeric(paste(y[1:m], collapse="")) + as.numeric(paste(y[(m+1):n], collapse=""))
}
})
a1[a1 == a4]
> a1[a1 == a4]
[1] 0 1 9 45 55 99 297 703 999 2223 2728 4950 5050
0 は明白な カプレカ数だと思うがそれはさておき,プログラムによる出力には 4879 はない。4879^2 = 2380 と 4641 なので,2380 + 4641 = 7021 になるので,カプレカ数ではないはず。2380 の最後の 0 を無視するというルールならば,238 + 4641 = 4879 になるのでカプレカ数ということになるのだが。同様に,5292^2 = 2800 と 5264 なので,28 + 5264 = 5292 ではあるが?と根拠を求めてネットサーフィンすると,
Karekar numbers
http://www.numbersaplenty.com/set/Kaprekar_number/
に,
Note that the second part can start with zero: 5292^2 = {28} {005264} and 28+5264=5292.
と書いてあった。後ろ半分の数字の前に 0 があってもよいということは,前の部分の後ろの 0 は無視してもよいということである(無視しない場合も考えよということ)。このルールも加えてプログラムを修正する。
プログラムに for を使うことになったがやむを得ない。
N = 5300
a1 = 0:N
a2 = a1^2
old = options(scipen=10)
a3 = strsplit(as.character(a2), "")
options(old)
a4 = a5 = integer(N+1)
for (i in seq_along(a1)) {
y = unlist(a3[[i]])
n = length(y)
if (n == 1) {
a4[i] = a5[i] = as.numeric(paste(y, collapse=""))
} else {
m = n %/% 2
a4[i] = as.numeric(paste(y[1:m], collapse="")) + # 前半分の後ろの 0 を無視しない
as.numeric(paste(y[(m+1):n], collapse=""))
a5[i] = as.numeric(paste(gsub("0*$", "", y[1:m]), collapse="")) + # 前半分の後ろの 0 を無視する
as.numeric(paste(y[(m+1):n], collapse=""))
}
}
a1[a1 == a4 | a1 == a5] # 前半分の後ろの 0 を無視しない場合と無視する場合のどちらか一方でも可ということで
> a1[a1 == a4 | a1 == a5]
[1] 0 1 9 45 55 99 297 703 999 2223 2728 4879 4950 5050 5292
Wikipedia などの例示と一致した。
10 万までで 5 秒弱かかって,以下の結果を得る。
> print(a1[a1 == a4 | a1 == a5])})
[1] 0 1 9 45 55 99 297 703 999 2223 2728 4879 4950 5050 5292 7272
[17] 7777 9999 17344 22222 38962 77778 82656 95121 99999
最新の画像[もっと見る]
- 算額(その2135) 9時間前
- 算額(その2134) 16時間前
- 算額(その2133) 1日前
- 算額(その2132) 3日前
- 算額(その2131) 4日前
- 算額(その2130) 4日前
- 算額(その2129) 5日前
- 算額(その2128) 5日前
- 算額(その2127) 6日前
- 算額(その2126) 6日前
※コメント投稿者のブログIDはブログ作成者のみに通知されます