Problem:
投石おみくじ

「自分の道は自分で切り開く」をモットーに、ある神社が自分自身の手で運勢を決めるおみくじを作りました。そのおみくじを引く人にはまず6つの石を投げてもらい、その投げた石の一つ目と二つ目を結ぶ 線分、三つ目と四つ目を結ぶ 線分、五つ目と六つ目を結ぶ 線分の3本の線分の交点を頂点とする 三角形の面積から運勢を決めるというものです。各運勢と三角形の面積との関係は以下のとおりです。

線分の交点を頂点とする三角形の面積

運勢

1,900,000以上

大吉 (dai-kichi)

1,000,000以上1,900,000未満

中吉 (chu-kichi)

100,000以上1,000,000未満

吉 (kichi)

0より大きく 100,000未満

小吉 (syo-kichi)

三角形なし

凶 (kyo)

しかし、三角形の面積の大きさの判定は神主さんが手計算でやっているので正確とはいえず、時間もかかってしまいます。そこで近所に住む優秀なプログラマであるあなたは、一刻でも早くプログラムを書いて神主さんを助けてあげることにしました。

3 本の線分の情報を入力とし、線分の交点を頂点とする 三角形の面積から運勢を出力するプログラムを作成してください。線分の情報は始点の座標 (x1, y1) と、終点の座標 (x2, y2) が与えられ、始点と終点の座標は必ず異なることとします。また、2 つ以上の線分が同一直線上にある場合、交点を持たない 2 つの線分がある場合、3 つの線分が 1 点で交わる場合は、「三角形なし」となります。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロ4つの行で示されます。
各データセットは以下の形式で与えられます。

line1
line2
line3

i 行目に i 番目の線分の情報が与えられます。各線分の情報は以下の形式で与えられます。

x1 y1 x2 y2

線分の端点の座標を表す整数 (x1, y1), (x2, y2) (-1000 ≤ x1, y1, x2, y2 ≤ 1000 ) が空白区切りで与えられます。

Output

データセット毎に、おみくじの結果を１行に出力します。

Sample Input

-3 -2 9 6
3 -2 7 6
-1 0 5 0
2 2 -1 -1
0 1 2 1
-3 -1 3 1
0 0 0 0

Output for the Sample Input

syo-kichi
kyo

Solution in Ruby (judge verdict: Wrong Answer)

class Class
  def ===(other)
    self==other
  end
end

class Point
  include Comparable
  attr_accessor :x, :y
  def initialize(x=0.0, y=0.0)
    @x, @y = x.to_f, y.to_f
  end

  def <=>(p)
    @x != p.x ? @x <=> p.x : @y <=> p.y
  end
  def +(p)
    Point.new(@x+p.x, @y+p.y)
  end
  def -(p)
    Point.new(@x-p.x, @y-p.y)
  end
  def -@
    Point.new(-@x, -@y)
  end

  def times(f)
    Point.new(@x*f, @y*f)
  end
  def dot(p)
    @x*p.x + @y*p.y
  end
  def cross(p)
    @x*p.y - @y*p.x
  end
  def abs
    Math::hypot(@x, @y)
  end
  def norm
    @x**2 + @y**2
  end
  # 直線abと点pの位置関係を調べる
  # 0: 線分上, -1: 時計回り, 1: 反時計回り, -2: a-b-p, 2: p-a-b
  def ccw(b, p)
    a = self
    v1, v2 = b-a, p-a
    return 1 if v1.cross(v2) > 0
    return -1 if v1.cross(v2) < 0
    return 2 if v1.dot(v2) < 0
    return -2 if v1.norm < v2.norm
    0
  end
end

class Line
  EPS = 1e-12
  attr_accessor :a, :b
  def initialize(p1=Point.new, p2=Point.new)
    @a, @b = p1, p2
  end

  # 直線abと点pの位置関係を調べる
  # 0: 線分上, -1: 時計回り, 1: 反時計回り, -2: a-b-p, 2: p-a-b
  def ccw(p)
    v1, v2 = @b - @a, p - @a
    return 1 if v1.cross(v2) > EPS
    return -1 if v1.cross(v2) < -EPS
    return 2 if v1.dot(v2) < -EPS
    return -2 if v2.norm - v1.norm > EPS
    0
  end
  # 交差判定
  def intersect?(target)
    case target.class
      when Point
        v1, v2 = @a-target, @b-target
        return (v2.cross(v1)).abs == 0.0
      when Segment
        v1, v2, v3 = @b-@a, target.a-@a, target.b-@a
        return v1.cross(v2) * v1.cross(v3) <= 0.0
      when Line
        v1, v2, v3 = @b-@a, target.b-target.a, target.a-@a
        return v1.cross(v2).abs > 0.0 || v1.cross(v3).abs == 0.0
    end
  end
  # 直線上に射影した点
  def projection(p)
    v1, v2 = p-a, a-b
    a + v2.times(v1.dot(v2)/v2.norm)
  end
  # 直線に関して対象な点
  def reflection(p)
    p + (projection(p) - p).times(2.0)
  end
  # 距離
  def distance(target)
    case target.class
      when Point
        return (target - projection(target)).abs
      when Segment
        return intersect?(target) ? 0.0 : [distance(target.a), distance(target.b)].min
      when Line
        return intersect?(target) ? 0.0 : distance(target.a)
    end
  end
  # 交点
  def crosspoint(l)
    v1, v2, v3 = @b-@a, l.b-l.a, @b-l.a
    a, b = v1.cross(v2), v1.cross(v3)
    return l.a if a.abs <= EPS && b.abs <= EPS
    l.a + v2.times(b/a)
  end
end

class Segment < Line
  # 交差判定
  def intersect?(target)
    case target.class
      when Point
        return (@a-target).abs + (@b-target).abs == (@b-@a).abs
      when Segment
        return target.ccw(@a) * target.ccw(@b) <= 0 && ccw(target.a) * ccw(target.b) <= 0
      when Line
        return target.intersect?(self)
    end
  end
  # 距離
  def distance(target)
    case target.class
      when Point
        p = projection(target)
        return intersect?(p) ? (p-target).abs : [(@a-target).abs, (@b-target).abs].min
      when Segment
        return intersect?(target) ? 0.0 : [distance(target.a), distance(target.b), target.distance(@a), target.distance(@b)].min
      when Line
        return target.distance(self)
    end
  end
end

#交点、同一直線上、一点で交わる　→　凶
edge = Array.new
until (x1,y1,x2,y2=gets.split.map(&:to_i)).all?(&:zero?) do
  edge.push(Segment.new(Point.new(x1,y1), Point.new(x2,y2)))
  next if edge.size < 3
  point = Array.new
  for i in 0...3 do
    break unless edge[i].intersect?(edge[(i+1)%3])
    break if edge[i].intersect?(edge[(i+1)%3].a) && edge[i].intersect?(edge[(i+1)%3].b)
    point.push(edge[i].crosspoint(edge[(i+1)%3]))
  end
  s = 0
  unless point.size<3 || point[0]==point[1] || point[1]==point[2] || point[2]==point[0]
    x1 = point[1].x - point[0].x
    y1 = point[1].y - point[0].y
    x2 = point[2].x - point[0].x
    y2 = point[2].y - point[0].y
    s = (x1*y2 - x2*y1).abs/2.0
  end
  if s==0
    puts "kyo"
  elsif s<100000
    puts "sho-kichi"
  elsif s<1000000
    puts "kichi"
  elsif s<1900000
    puts "chu-kichi"
  else
    puts "dai-kichi"
  end
  edge.clear
end