Skip to content

Instantly share code, notes, and snippets.

@pocari
Created July 13, 2013 06:18
Show Gist options
  • Save pocari/5989632 to your computer and use it in GitHub Desktop.
Save pocari/5989632 to your computer and use it in GitHub Desktop.
#coding: Windows-31J
# 3行5列のマスを塗っていくパターンは
# ある列がそれより左の列の1行目が塗られている場合のみ塗れるので、
# ・1列目だけ塗るパターン
# ■
# □
# □
#
# ・2列めまで塗るパターン
# ■■
# □□
# □□
#
# ...
#
# ・5列目まで塗るパターン
# ■■■■■
# □□□□□
# □□□□□
#
# の5パターンある。
#
#
# また、各列を塗るパターンは「何行目まで塗るか?」なので、
# ■
# □
# □
#
# ■
# ■
# □
#
# ■
# ■
# ■
# の3通りある。
# すると、最初の5パターンそれぞれについて
#  (1列を塗るパターン) ^ (使用する列数)
# = 3 ^ (使用する列数)
# が各パターン毎の塗り方になるので、
# ・1列目だけ・・・3^1 = 3
# ・2列目まで・・・3^2 = 9
# ・3列目まで・・・3^3 = 27
# ・4列目まで・・・3^4 = 81
# ・5列目まで・・・3^5 = 243
# となって、全体のパターン数はこれらの和になるので、
# 初項3、公比3の等比数列の和がパターン数になる。
# よって、
#  パターン数 = (初項 * (1 - 公比^5))/(1 - 公比)
# = (3 * (1 - 3^5))/(1 - 3)
# = 363通り
# になる。
#
# 一般化すると、n行m列の場合
#  パターン数 = (n * (1 - n^m)) / (1 - n)
# になる。
#
# n個塗るパターン単位で考える場合は、
# 総数の求め方のように
# 「左から詰めて各列何行目まで塗るか?」
# を考えるだけでいいので、
# 1~3(行数)までの数を最大5(列数)回足してnになる組み合わせを求める。
#
ROW = 3
COL = 5
#パターンを元に絵にする。
def pattern_to_s(pattern)
(0 ... COL).map{|c|
if c < pattern.size
(['■'] * pattern[c]) + (['□'] * (ROW - pattern[c]))
else
Array.new(ROW, '□')
end
}.transpose.map(&:join).join("\n")
end
#n個塗るパターンをすべて表示
def get_pattern(cols, n)
if n == 0
puts "pattern:" + cols.join(" ")
puts pattern_to_s(cols)
puts ""
else
(1 .. ROW).each do |i|
if (cols.size < COL) && (n - i >= 0)
get_pattern(cols + [i], n - i)
end
end
end
end
#1~全マス数までそれぞれ求める
(1 .. (ROW * COL)).each do |n|
puts "#{n}---------------------------------"
get_pattern([], n)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment