第29回オフラインリアルタイムどう書く「サイコロの展開図」の ruby による実装
問題 : http://nabetani.sakura.ne.jp/hena/ord29devdice/
解答リンク集 : http://qiita.com/Nabetani/items/4c21127f07bfa68fa1f8
イベント : https://yhpg.doorkeeper.jp/events/20844
で。
当日お見せした実装。
PATTERNS = %w(
12S/453 1T6/D45 146/53D 15S/3D4
215/T64 6T1/54D 2S5/41T 3D4/15S
512/46T 41T/2S5 453/12S 53D/146
).flat_map{ |x| [x,x.reverse] }
def solve( src )
re=/#{src.tr("xyzw", "....")}/
m=PATTERNS.select{ |x| re===x }
case m.size
when 0;
"none"
when 1
src.chars.zip( m[0].chars )
.select{ |a,b| a!=b }
.map{ |c| c.join("=") }
.join(",")
else
"many"
end
end
DATA.map{ |line|
id, src, expected = line.split(/\s+/)
actual = solve(src)
(actual == expected).tap do |ok|
puts '***NG*** : %s %s->%s ( %s )' % [id, src, actual, expected] unless ok
end
}.tap{ |x| puts( "ok:%d / NG:%d" % [ x.count(true), x.count(false) ] ) }
__END__
0 Tx4/5yz x=1,y=S,z=2
1 14S/xyz none
2 1w6/xyz many
で。
展開図は
- 上段左端に来る目は6通り( 2 と D を同一視して )
- その隣に来る目は4通り( 2 と D を同一視して )
ということで、全部で 6×4=24 通りしかない。
しかも。
展開図の文字列は reverse しても有効な展開図なので、実際には 12 通り列挙すれば足りてしまう。
というわけで、12通りまたは24通りの展開図をソースコード上に書ききれば勝ったも同然。
1個書くのに1分要しても30分以上余る。
全部の展開図が手に入れば、あとは正規表現で調べれば答えがわかる。
簡単でしょ?
まあ列挙するのはかっこ悪い感じではあるけれども、かっこ悪くても計算が正しければ良いのである。
で。
続いて、列挙した結果をソースに書きたくない場合。
DATA.map{
以下は同じなので、それより前の部分を:
# 目の図形を90度回す
def rot_face(f)
key="D2T3S6114455"
key[ key.index(f)^1 ]
end
# サイコロを90度回す
def rot_dice(s)
[rot_face(s[5]), s[0], (s[1]),
"/",
rot_face(s[4]), rot_face(s[2]), rot_face(s[6])
].join
end
# 展開図の可能なパターンをすべて列挙する
def enum_patterns( pats={}, c="146/53D", &block)
return if pats[c]
pats[c]=true
block.(c)
enum_patterns(pats, c.reverse, &block)
enum_patterns(pats, rot_dice(c), &block)
end
#解く
def solve( src )
re=/#{src.tr("xyzw", "....")}/
m = enum_for(:enum_patterns).select{ |x| re===x }
case m.size
when 0
"none"
when 1
src.chars.zip( m[0].chars )
.select{ |a,b| a!=b }
.map{ |c| c.join("=") }
.join(",")
else
"many"
end
end
というわけで、まじめに回すとだいぶ長くなる。
簡単に説明すると:
- サイコロの二種類の方法で回しつつ、メモ化再帰で探索。(
enum_patterns
) - サイコロの回し方は二種類。
rot_dice
と、reverse
。
という感じ。
rot_face
では、排他的論理和( ^
)を使ってみた。ビット演算が明らかに要求されている文脈以外ではなかなか出番のない排他的論理和だけど、たぶん、ここは使いどころだと思う。
enum_patterns
はデフォルト引数の悪用っぽい感じがする。どうかなぁ。
Author And Source
この問題について(第29回オフラインリアルタイムどう書く「サイコロの展開図」の ruby による実装), 我々は、より多くの情報をここで見つけました https://qiita.com/Nabetani/items/a08282cd8e03f41a4348著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .