格子点の列挙(Ruby)
格子点の列挙 - みずぴー日記
ここの問題で遊んでみました。
問題を再掲しておきます。
二次元平面上の格子点(X,Y座標がともに整数の点)を、原点から近い順に列挙してください。
http://d.hatena.ne.jp/mzp/20071006/lattice
同じ距離の点はどういう順番でも構いませんが、可能であればX軸に一番近い第一象限の点から原点を中心として反時計回りの順に列挙してください。 列挙の方法は、1行に一つの点の、X,Y座標を出力することとします。
結果の例(括弧をつけた出力にしました)。
( 3, -2) (-6, 1) (-5, 4) ( 4, -5) ( 5, -7) (-9, -2) (-2, -9) ( 7, 7) (-8, 8) ( 8, -9)
コード。
class Complex include Comparable def <=>(a) f = ->(θ) {(θ < 0) ? 2 * Math::PI + θ : θ} l1, l2 = abs2, a.abs2 θ1, θ2 = f.(angle), f.(a.angle) if l1 > l2 then 1 elsif l1 < l2 then -1 elsif θ1 > θ2 then 1 elsif θ1 < θ2 then -1 else 0 end end def to_s sprintf "(% 2d, % 2d)", real, imaginary end end ar = 10.times.map {Complex(rand(-9..9), rand(-9..9))} puts ar.sort
いわゆる「宇宙船演算子」(<=>というやつ)を Complex クラスに定義して解いてみました。並べ替えはふつうに Array#sort でやっています。
ちょっとトリッキーですかね。