Problem:
Problem E: Kuru-Kuru Robot

ロボット工学の研究者であるアシモフ博士は、新しいロボットの開発に成功した。このロボットは、床に張り巡らせた特殊なワイヤーに沿って自由に動くことができる。ロボットは常に現在いるワイヤーに平行な方向を向いて前進する。

すばらしいことに、このロボットはワイヤー上を移動するためにその距離にかかわらずエネルギーを消費しない。しかし、ワイヤーの端点やワイヤーの交点で向きを変えるためにはその点を中心に回転する必要があり、その回転角度だけエネルギーを消費する。

このロボットをスタート地点からゴール地点まで動かしたい。例えば、下図においてロボットを start に東向き（下図 x軸の正の向き）で配置し goal まで動かしてみよう。start から交点 A 交点 B を経由して goal にたどり着く経路と、交点 A 交点 C を経由する経路があるが、前者の方が移動距離が長いものの回転角度が少ないためエネルギー消費量は少ない。

あなたの仕事は、床にあるワイヤーの位置、スタート地点、ゴール地点を読み込み、スタート地点からゴール地点へ移動するために必要な回転角度の合計の最小値を報告するプログラムを作成することである。

ロボットはスタート地点においてどのような向きに配置してもよく、ゴール地点ではどの方向を向いていてもよい。

Input

入力は複数のデータセットからなる。各データセットの形式は以下のとおり：

n
x11 y11 x21 y21
x12 y12 x22 y22
.
.
.
x1n y1n x2n y2n
sx sy gx gy

n はワイヤーの数を示す整数である。x1i y1i は i 番目のワイヤーの一方の端点の座標、x2i y2i は i 番目のワイヤーのもう一方の端点の座標を示す。

sx sy、gx gy はそれぞれスタート地点とゴール地点の座標を示す。

与えられる座標はすべて整数値であり、x軸 y軸の値は -1000　以上 1000 以下である。また、スタート地点とゴール地点は与えられるワイヤーの端点上にあると仮定してよい。

n ≤ 50 であると仮定してよい。

n が 0 のとき入力の終了を示す。

Output

各データセットに対して、回転角度の合計の最小値を１行に出力せよ。ロボットがゴール地点にたどり着けない場合は "-1" と出力せよ。出力は 0.00001 以下の誤差を含んでもよい。

Sample Input

8
1 3 11 3
5 3 13 11
10 10 17 10
11 2 11 6
10 5 14 5
13 6 13 2
17 10 17 3
13 3 19 3
1 3 19 3
6
1 3 11 3
5 3 13 11
10 10 17 10
11 2 11 6
10 5 14 5
13 3 19 3
1 3 19 3
2
0 0 7 0
3 0 7 3
0 0 7 3
0

Output for the Sample Input

270.0000
-1
36.86989765

Solution in Ruby (judge verdict: Wrong Answer)

#!/usr/bin/ruby
#
# 1033-1.rb: Kuru-Kuru Robot
#

### subroutines

# w0 := s*v0+p0, w1 := t*v1+p1
# s*v0+p0 = t*v1+p1 -> s*v0-t*v1=p1-p0
# |s*v0x - t*v1x| = |v0x -v1x| |s| = |p1x-p0x|
# |s*v0y - t*v1y|   |v0y -v1y| |t|   |p1y-p0y|
# |s| = 1/(v0x*(-v1y)-(-v1x)*v0y) |-v1y v1x||p1x-p0x|
# |t|                             |-v0y v0x||p1y-p0y|
# 

def cross_st(w0, w1)
  x00, y00, x01, y01 = w0
  x10, y10, x11, y11 = w1

  v0x, v0y = x01 - x00, y01 - y00
  v1x, v1y = x11 - x10, y11 - y10

  d = v0x * v1y - v0y * v1x
  return nil if d == 0

  px = x10 - x00
  py = y10 - y00

  s = (v1y * px - v1x * py).to_f / d
  t = (v0y * px - v0x * py).to_f / d

  return nil if s < 0.0 || s > 1.0 || t < 0.0 || t > 1.0

  [s * v0x + x00, s * v0y + y00, s, t]
end

def rev_deg(deg)
  deg <= 0 ? deg + 180 : deg - 180
end

def deg_change(deg0, deg1)
  d = deg1 - deg0
  while d < 0
    d += 360
  end
  while d > 360
    d -= 360
  end
  [d, 360 - d].min
end

### main

loop do
  n = gets.to_i
  break if n == 0

  wires = []
  n.times do
    x0, y0, x1, y1 = gets.split.map(&:to_i)
    deg = Math.atan2(y1 - y0, x1 - x0) * 180 / Math::PI
    wires << [x0, y0, x1, y1, deg, rev_deg(deg)]
  end
  #p wires

  sx, sy, gx, gy = gets.split.map(&:to_i)
  #p [sx, sy, gx, gy]

  nodes = [[], []]

  for i in (0...n)
    wi = wires[i]
    if sx == wi[0] && sy == wi[1]
      nodes[0] << [i, 0.0]
    elsif sx == wi[2] && sy == wi[3]
      nodes[0] << [i, 1.0]
    end
    if gx == wi[0] && gy == wi[1]
      nodes[1] << [i, 0.0]
    elsif gx == wi[2] && gy == wi[3]
      nodes[1] << [i, 1.0]
    end
  end
  
  for i in (0...(n - 1))
    wi = wires[i]
    for j in ((i + 1)...n)
      wj = wires[j]

      st = cross_st(wi, wj)
      if ! st.nil?
        x, y, s, t = st
        nodes << [[i, s], [j, t]]
      end
    end
  end
  #p nodes

  nnd = nodes.length

  edges = nnd.times.map{nnd.times.map{nil}}
  nbrs = nnd.times.map{[]}

  for k in (0...n)
    wins = []
    for i in (0...nnd)
      s = nodes[i].assoc(k)
      if ! s.nil?
        wins << [i, s[1]]
      end
    end

    nwins = wins.length
    deg0, deg1 = wires[k][4..5]

    for i in (0...(nwins - 1))
      i0, s0 = wins[i]
      for j in ((i + 1)...nwins)
        i1, s1 = wins[j]

        if s0 < s1
          edges[i0][i1] = deg0
          edges[i1][i0] = deg1
        else
          edges[i0][i1] = deg1
          edges[i1][i0] = deg0
        end

        nbrs[i0] << i1
        nbrs[i1] << i0
      end
    end
  end
  #p edges
  #p nbrs

  dists = nnd.times.map{nnd.times.map{Float::INFINITY}}
  q = []
  min_deg = Float::INFINITY
  
  for n1 in nbrs[0]
    dists[0][n1] = 0.0
    q << [0, n1]
  end

  while ! q.empty?
    u = q.min{|a, b| dists[a[0]][a[1]] <=> dists[b[0]][b[1]]}
    q.delete(u)

    u0, u1 = u
    du = dists[u0][u1]

    if u1 == 1
      min_deg = du if min_deg > du
      next
    end

    degu = edges[u0][u1]

    for v in nbrs[u1]
      degv = edges[u1][v]
      degc = deg_change(degu, degv)
      dv = dists[u1][v]
      if dv > du + degc
        dists[u1][v] = du + degc
        if dv == Float::INFINITY
          q << [u1, v]
        end
      end
    end
  end

  if min_deg == Float::INFINITY
    puts -1
  else
    puts "%.9f" % min_deg
  end
end