読者です 読者をやめる 読者になる 読者になる

RACING CHARS(CodeEval)

CHALLENGE DESCRIPTION:

In this challenge you will be given a file where each line is a section of a race track with obstructions, gates and checkpoints. The goal is to find a way of passing this track, using the following rules: Each section contains only a single gate or a gate with a checkpoint. The race car can ride only through gates or checkpoints. You should prefer driving through checkpoint rather then a gate. The obstructions are represented by "#" (hash). The gates are represented by "_" (underscore). The checkpoints are represented by "C" .

INPUT SAMPLE:

Your program should accept as its first argument a path to a filename. Each line in this file is a new segment of a race track. E.g.

#########_##
########C_##
#######_####
######_#C###
#######_C###
#######_####
######C#_###
######C_####
#######_####
#######_####

OUTPUT SAMPLE:

Print out the way of passing this race track starting from the first line of the file. Use a "|" (pipe) for the straight, use a "/" (forward slash) for the left turn and use a "\" (back slash) for the right turn. E.g.

#########|##
########/_##
#######/####
######_#\###
#######_|###
#######/####
######/#_###
######|_####
#######\####
#######|####

Constraints: The number of lines in a file is 50. The width of a section is 12 chars.

My Code

#!/usr/bin/env ruby -w

class RacingChars
  GATE = '_'
  CHECKPOINT = 'C'
  RIGHT = '\\'
  LEFT  = '/'
  STRAIGHT = '|'
  OBSTRUCTION = '#'

  def initialize
    @bef_gate_point = 0
  end

  def race(line)
    gate_point = line.index(GATE)
    check_point = line.index(CHECKPOINT)
    if check_point
      direction = turn_direction(check_point)
      print_with_checkpoint(line.size, check_point, gate_point, direction)
      @bef_gate_point = check_point
    else
      direction = turn_direction(gate_point)
      print_without_checkpoint(line.size, gate_point, direction)
      @bef_gate_point = gate_point
    end
  end

  private

  def turn_direction(point)
    if @bef_gate_point == 0 ||
       @bef_gate_point == point
      STRAIGHT
    elsif @bef_gate_point > point
      LEFT
    else
      RIGHT
    end
  end

  def print_result(line_size)
    line_size.times { |n| print yield(n) }
    print "\n"
  end

  def print_with_checkpoint(line_size, check_point, gate_point, direction)
    print_result(line_size) do |n|
      if n == check_point
        direction
      elsif n == gate_point
        GATE
      else
        OBSTRUCTION
      end
    end
  end

  def print_without_checkpoint(line_size, gate_point, direction)
    print_result(line_size) do |n|
      (n == gate_point) ? direction : OBSTRUCTION
    end
  end
end

rc = RacingChars.new
ARGF.each_line do |line|
  rc.race(line.chomp)
end