問題 : http://nabetani.sakura.ne.jp/hena/orde15nohil/
解答リンク集 : http://qiita.com/Nabetani/items/705fa83cfbf20377b92f
イベント : https://yhpg.doorkeeper.jp/events/61418
いつも通り ruby で。テストケースの大半は省略。
ruby2.4
def to_xy( src )
d=src.digits(3)
d.zip([*0..d.size]).inject(0) do |acc,(n,ix)|
acc+case n
when 0; 0
when 1; 1*2**ix
when 2; 1i*2**ix
end
end
end
def to_num(pos)
return nil if pos.real<0 || pos.imag<0
x=pos.real.digits(2)
y=pos.imag.digits(2)
return [0,1,1i].index(pos) if 1==[x.size, y.size].max
a=to_num( (pos.real/2).floor + (pos.imag/2).floor * 1i )
b=to_num( x[0]+y[0]*1i )
a && b && a*3+b
end
def neibours(src)
pos = to_xy(src)
[pos+1, pos-1, pos+1i, pos-1i ].map{ |x| to_num(x) }
end
def solve( src )
neibours(src.to_i).compact.sort.join(",")
end
DATA.map{ |line|
num, src, expected = line.split( /\s+/ )
actual = solve( src )
ok = actual==expected
puts [ ok ? "ok" : "***NG***", src, actual, expected ].join(" ")
ok
}.all?.tap{ |x| puts( x ? "okay!" : "something wrong" ) }
__END__
0 21 19,22,23
1 0 1,2
2 1 0,3
51 1000000 999999,1000002
順当な実装のつもり。
数値→座標→隣の座標→数値 という流れ。
数値を座標に変換する関数と、座標を数値に変換する関数を書く必要がある。
数値を座標に変換するのは、to_xy
。二次元座標なので複素数で。
入力を 3進数に変換して、
* 1 があったら $2^{桁数}$ マス、右へ。
* 2 があったら $2^{桁数}$ マス、下へ。
という具合。
座標を数値に変換するのは、to_num
。
入力を 3進数に変換して、一桁なら決め打ちで。
二桁以上なら、右端の一桁とそれ以外に分割。以下の二件の合計が求める値。
* 「右端の一桁」を to_num
* 「それ以外」を to_num
して三倍
ただし、to_num
が nil
を返したら、nil
にする。
という具合。
Integer#digits
が便利。
でも、Integer#digits
の逆もほしい。ないのが残念。