Problem:
Problem B: Polygonal Line Search

Multiple polygonal lines are given on the xy-plane.
Given a list of polygonal lines and a template,
you must find out polygonal lines
which have the same shape as the template.

A polygonal line consists of several line segments parallel to x-axis or
y-axis. It is defined by a list of xy-coordinates of vertices from the start-point to the end-point in order,
and always turns 90 degrees at each vertex.
A single polygonal line does not pass the same point twice.

Two polygonal lines have the same shape when they
fully overlap each other only with rotation and translation
within xy-plane (i.e. without magnification or a flip).
The vertices given in reverse order from the start-point to the end-point is the
same as that given in order.

Figure 1 shows examples of polygonal lines.
In this figure, polygonal lines A and B have the same shape.

Write a program that answers polygonal lines which have the same shape as
the template.

Figure 1: Polygonal lines

Input

The input consists of multiple datasets.
The end of the input is indicated by a line which contains a zero.

A dataset is given as follows.

n

Polygonal line0

Polygonal line1

Polygonal line2

...

Polygonal linen

n is the number of polygonal lines for the object of search on
xy-plane.
n is an integer, and 1 <= n <= 50.
Polygonal line0 indicates the template.

A polygonal line is given as follows.

m

x1 y1

x2 y2

...

xm ym

m is the number of the vertices of a polygonal line (3 <= m <= 10).

xi and yi, separated by a space,
are the x- and y-coordinates
of a vertex, respectively (-10000 < xi < 10000, -10000 <yi < 10000).

Output

For each dataset in the input, your program should report numbers assigned to the polygonal lines that have the same shape as the template, in ascending order.
Each number must be written in a separate line without any other characters such as leading or trailing spaces.

Five continuous "+"s must be placed in a line at the end of each dataset.

Sample Input

5
5
0 0
2 0
2 1
4 1
4 0
5
0 0
0 2
-1 2
-1 4
0 4
5
0 0
0 1
-2 1
-2 2
0 2
5
0 0
0 -1
2 -1
2 0
4 0
5
0 0
2 0
2 -1
4 -1
4 0
5
0 0
2 0
2 1
4 1
4 0
4
4
-60 -75
-60 -78
-42 -78
-42 -6
4
10 3
10 7
-4 7
-4 40
4
-74 66
-74 63
-92 63
-92 135
4
-12 22
-12 25
-30 25
-30 -47
4
12 -22
12 -25
30 -25
30 47
3
5
-8 5
-8 2
0 2
0 4
8 4
5
-3 -1
0 -1
0 7
-2 7
-2 16
5
-1 6
-1 3
7 3
7 5
16 5
5
0 1
0 -2
8 -2
8 0
17 0
0

Output for the Sample Input

1
3
5
+++++
3
4
+++++
+++++

Solution in Ruby (judge verdict: Accepted)

module Direction
  TURN_LEFT = 0
  TURN_RIGHT = 1
  BASE = TURN_RIGHT
end

class Edge
  def initialize length
    @length = length
    @next_edge = nil
    @next_direction = nil
    @prev_edge = nil
    @prev_direction = nil
  end

  def eql? edge
    return false unless @length == edge.length
    return true if @next_edge.nil? and edge.next_edge.nil?
    return false if @next_edge.nil? or edge.next_edge.nil?
    return false unless @next_direction == edge.next_direction
    return @next_edge.eql?(edge.next_edge)
  end

  def reverse_eql? edge
    return false unless @length == edge.length
    return true if @next_edge.nil? and edge.prev_edge.nil?
    return false if @next_edge.nil? or edge.prev_edge.nil?
    return false unless @next_direction == edge.prev_direction
    return @next_edge.reverse_eql?(edge.prev_edge)
  end

  attr_accessor :length, :next_edge, :next_direction, :prev_edge, :prev_direction
end

def main
  loop do
    n = gets.chomp.to_i
    break if n == 0

    polygonal_lines = []
    (n+1).times do
      line = []
      m = gets.chomp.to_i
      prev_x,prev_y = gets.chomp.split(' ').map(&:to_i)
      prev_prev_x = nil
      prev_prev_y = nil
      prev_edge = nil
      (m-1).times do
        x,y = gets.chomp.split(' ').map(&:to_i)

        length = get_length(prev_x, prev_y, x, y)
        edge = Edge.new(length)

        unless line.empty?
          prev_edge.next_direction = get_direction(x, y, prev_x, prev_y, prev_prev_x, prev_prev_y)
          edge.prev_direction = prev_edge.next_direction ^ Direction::BASE
          prev_edge.next_edge = edge
          edge.prev_edge = prev_edge
        end
        line << edge

        prev_edge = edge
        prev_prev_x = prev_x
        prev_prev_y = prev_y
        prev_x = x
        prev_y = y
      end
      polygonal_lines << line
    end

    target = polygonal_lines.shift
    polygonal_lines.each_with_index do |p_line, i|
      puts i + 1 if target[0].eql?(p_line[0]) or target[0].reverse_eql?(p_line[-1])
    end
    puts '+++++'
  end
end

def get_direction x, y, prev_x, prev_y, prev_prev_x, prev_prev_y
  case
  when x > prev_x
    case
    when prev_y > prev_prev_y; Direction::TURN_RIGHT
    when prev_y < prev_prev_y; Direction::TURN_LEFT
    end
  when x < prev_x
    case
    when prev_y > prev_prev_y; Direction::TURN_LEFT
    when prev_y < prev_prev_y; Direction::TURN_RIGHT
    end
  when y > prev_y
    case
    when prev_x > prev_prev_x; Direction::TURN_LEFT
    when prev_x < prev_prev_x; Direction::TURN_RIGHT
    end
  when y < prev_y
    case
    when prev_x > prev_prev_x; Direction::TURN_RIGHT
    when prev_x < prev_prev_x; Direction::TURN_LEFT
    end
  end
end

def get_length prev_x, prev_y, next_x, next_y
  unless next_x == prev_x
    if (next_x <=> prev_x) > 0
      return (next_x - prev_x).abs + 1
    else
      return (prev_x - next_x).abs + 1
    end
  else
    if (next_y <=> prev_y) > 0
      return (next_y - prev_y).abs + 1
    else
      return (prev_y - next_y).abs + 1
    end
  end
end

main