Programozás 2/2007/Ruby megoldások

A MathWikiből
A lap korábbi változatát látod, amilyen SisakAron (vitalap | szerkesztései) 2007. november 29., 11:35-kor történt szerkesztése után volt.

fill.rb

A 12. feladat (fill) megoldására egy javaslat (még bővítendő az alakzat konvexitását ellenőrző kóddal)

class AngleException < Exception; end
class NonConvexException < Exception; end
class Vertex
  attr_accessor :x, :y
  def initialize(x=0, y=0)
    self.x = x
    self.y = y
  end
  def +(v2)
    Vertex.new(self.x + v2.x, self.y + v2.y)
  end
  def -(v2)
    Vertex.new(self.x - v2.x, self.y - v2.y)
  end
  def ==(v2)
    self.x == v2.x && self.y == v2.y
  end
  def to_s()
    "(" + self.x.to_s + ", " + self.y.to_s + ")"
  end
end
class Polygon
  attr_accessor :width, :height, :vertices, :canvas
  def initialize(dim, vertices)
    self.width = dim[0].to_i
    self.height = dim[1].to_i
    self.vertices = vertices.map! {|v| Vertex.new(v[0].to_i, v[1].to_i)}
    self.canvas = Array.new(self.height).map!{ Array.new(self.width) }
    # check 45 degrees
    vertices.each_index do |i|
      v1 = vertices[i]
      v2 = vertices[(i + 1) % vertices.length]
      if(v1.x != v2.x && v1.y != v2.y && v1.x - v2.x != v1.y - v2.y && v1.x - v2.x != v2.y - v1.y) then
        raise AngleException
      end
    end
    # TODO: check if polygon is convex
  end
  # emit (already rendered) picture in PBM format
  def emit()
    print "P1 " + self.width.to_s + " " + self.height.to_s + "\n"
    self.canvas.reverse_each {|row|
      row.each {|pixel|
        print pixel.to_s + " "
      }
      print "\n"
    }
  end    
  # render picture to canvas buffer
  def render()
    # clear canvas
    canvas.map! {|row| row.fill(0)}
    # draw polygon
    vertices.each_index do |i|
      v1 = vertices[i]
      v2 = vertices[(i + 1) % vertices.length]
      e = Vertex.new((v2.x-v1.x)!=0 ? (v2.x-v1.x)/(v2.x-v1.x).abs : 0, (v2.y-v1.y)!=0 ? (v2.y-v1.y)/(v2.y-v1.y).abs : 0)
      v = v1 - e
      # print "v1=" + v1.to_s + ", v2=" + v2.to_s + ", e=" + e.to_s + ", v=" + v.to_s + "\n"
      while (v != v2) do
        v += e
        # print "\tv=" + v.to_s + "\n"
        self.canvas[v.y][v.x] = 1
      end
    end
    # fill polygon
    self.canvas.each {|row|
      min = row.index(1)
      max = row.rindex(1)
      if(min && max) then
        for x in min..max do row[x] = 1 end
      end
    }
  end
end
dim=[]
vertices=[]
STDIN.each_line { |s|
  begin
  if(dim.empty?)
    dim=s.split(/\s+/)
  else
    vertex = s.split(/\s+/)
    if(vertex[0].to_i == -1 and vertex[1].to_i == -1)
      poly = Polygon.new(dim, vertices)
      poly.render()
      poly.emit()
      dim=[]
      vertices=[]
    else
      v=[]
      v[0] = vertex[0].to_i
      v[1] = vertex[1].to_i
      vertices.push(v)
    end
  end
  rescue AngleException
    print "ANGLE\n"
  rescue NonConvexException
    print "NOT_CONVEX\n"
  end
}
Személyes eszközök