LoginSignup
0
1

More than 5 years have passed since last update.

オフラインリアルタイムどう書くE15の問題の実装例です。

Posted at

問題 : 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_numnil を返したら、nil にする。
という具合。

Integer#digits が便利。
でも、Integer#digits の逆もほしい。ないのが残念。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1