「数学100の問題」 数学セミナー編集部[編]に載っていた
郵便切手の問題について考えてみた。
n = 12のとき 12196と載っているが、12198の間違いである。
また、オンライン整数列大辞典の
A000682のCOMMENTSにあるように
number of ways a semi-infinite directed curve can cross a straight line n times は
number of ways to fold a strip of n+1 labeled stamps with leaf 1 on top に等しいので、
番号はずれるが、求めた数値の正しさは
https://oeis.org/A000682/list
で確かめればよい。
なお、コード中のtest_intersect(ary) は
http://ja.stackoverflow.com/questions/20208/%E5%90%8C%E3%81%98%E6%95%B0%E5%90%8C%E5%A3%AB%E7%B7%9A%E3%81%A7%E7%B5%90%E3%82%93%E3%81%A0%E3%81%A8%E3%81%8D-%E4%BA%A4%E7%82%B9%E3%81%8C%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%8B%E5%90%A6%E3%81%8B%E3%81%AE%E5%88%A4%E5%AE%9A%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
のunarist さんの回答が元です。
# 切手が貫通していないか
def test_intersect(ary)
ary.inject([]){|stack, i| stack.last == i ? stack[0..-2] : stack << i} == []
end
def up_check(ary)
ary1 = ary.map{|i| (i + 1) / 2}
ary1.delete((ary.size + 1) / 2) if ary.size % 2 == 1
test_intersect(ary1)
end
def down_check(ary)
ary2 = ary[1..-1].map{|i| i / 2}
ary2.delete(ary.size / 2) if ary.size % 2 == 0
test_intersect(ary2)
end
def f(n)
cnt = 0
(2..n).to_a.permutation(n - 1){|c|
# 左が一番上
c = [1] + c
if up_check(c)
cnt += 1 if down_check(c)
end
}
cnt
end
(1..12).each{|i| p f(i)}
出力結果
1
1
2
4
10
24
66
174
504
1406
4210
12198
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。