Решение на Шеста задача от Станимира Влаева

Обратно към всички решения

Към профила на Станимира Влаева

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 11 успешни тест(а)
  • 3 неуспешни тест(а)

Код

module TurtleGraphics
class Matrix
attr_reader :rows, :column_count, :row_count
def initialize(row_count, column_count = row_count)
@rows = Array.new(row_count) { Array.new(column_count) { 0 } }
@column_count = column_count
@row_count = row_count
end
end
class Turtle
DIRECTIONS = [:left, :up, :right, :down].freeze
def initialize(row_count, column_count)
@matrix = Matrix.new(row_count, column_count)
look(:right)
end
def draw(canvas = nil)
self.instance_eval(&Proc.new) if block_given?
canvas != nil ? canvas.build(@matrix) : @matrix.rows
end
private
def move
if @x.nil? and @y.nil?
spawn_at(0, 0)
end
case @direction
when 0 then @y -= 1
when 1 then @x -= 1
when 2 then @y += 1
when 3 then @x += 1
end
@x = @x < 0 ? @matrix.row_count - 1 : @x % @matrix.row_count
@y = @y < 0 ? @matrix.column_count - 1 : @y % @matrix.column_count
@matrix.rows[@x][@y] += 1
end
def turn_left
@direction = @direction == 0 ? DIRECTIONS.length - 1 : @direction - 1
end
def turn_right
@direction = @direction == DIRECTIONS.length - 1 ? 0 : @direction + 1
end
def spawn_at(row, column)
@x = row
@y = column
@matrix.rows[@x][@y] += 1
end
def look(direction)
@direction = DIRECTIONS.index(direction)
end
end
module Canvas
def calculate_max_frequency(matrix)
matrix.rows.collect { |row| row.max }.max
end
class ASCII
include Canvas
def initialize(symbols)
@symbols = symbols
end
def build(matrix)
max_frequency = calculate_max_frequency(matrix)
interval = (1.0 / max_frequency).to_f
canvas = []
matrix.rows.each do |row|
row.each { |cell| canvas << @symbols[cell / (max_frequency * interval)] }
canvas << "\n"
end
canvas.join
end
end
class HTML
include Canvas
def initialize(pixel_size)
@pixel_size = pixel_size
end
def build(matrix)
%{
<!DOCTYPE html>
<html>
#{head}
#{body(matrix)}
</html>
}
end
private
def head
%{
<head>
<title>Turtle graphics</title>
<style>
table {
border-spacing: 0;
}
tr {
padding: 0;
}
td {
width: #{@pixel_size}px;
height: #{@pixel_size}px;
background-color: black;
padding: 0;
}
</style>
</head>
}
end
def body(matrix)
%{
<body>
#{generate_table(matrix)}
</body>
}
end
def generate_table(matrix)
max_frequency = calculate_max_frequency(matrix)
table = ["<table>"]
matrix.rows.each do |row|
table << "<tr>"
row.each do |cell|
cell_intensity = cell.to_f / max_frequency
table << "<td style='opacity: #{cell_intensity}'></td>"
end
table << "</tr>"
end
table << "</table>"
table.join
end
end
end
end

Лог от изпълнението

..........FF.F

Failures:

  1) TurtleGraphics Canvas::ASCII can render with a different number of symbols
     Failure/Error: expect(ascii.sub(/\n\z/, '')).to eq [
       
       expected: "ttz\nooz\nzzz"
            got: "tz\nooz\nzzz"
       
       (compared using ==)
       
       Diff:
       @@ -1,4 +1,4 @@
       -ttz
       +tz
        ooz
        zzz
     # /tmp/d20151203-5272-1ld0d08/spec.rb:151:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) TurtleGraphics Canvas::HTML renders the proper template
     Failure/Error: expect(canvas.gsub(/\s+/, '')).to eq <<-HTML.gsub(/\s+/, '')
       
       expected: "<!DOCTYPEhtml><html><head><title>Turtlegraphics</title><style>table{border-spacing:0;}tr{padding:0;}td{width:5px;height:5px;background-color:black;padding:0;}</style></head><body><table><tr><tdstyle=\"opacity:1.00\"></td><tdstyle=\"opacity:1.00\"></td><tdstyle=\"opacity:1.00\"></td></tr><tr><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td></tr><tr><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td></tr></table></body></html>"
            got: "<!DOCTYPEhtml><html><head><title>Turtlegraphics</title><style>table{border-spacing:0;}tr{padding:0;}td{width:5px;height:5px;background-color:black;padding:0;}</style></head><body><table><tr><tdstyle='opacity:1.0'></td><tdstyle='opacity:1.0'></td><tdstyle='opacity:1.0'></td></tr><tr><tdstyle='opacity:0.0'></td><tdstyle='opacity:0.0'></td><tdstyle='opacity:0.0'></td></tr><tr><tdstyle='opacity:0.0'></td><tdstyle='opacity:0.0'></td><tdstyle='opacity:0.0'></td></tr></table></body></html>"
       
       (compared using ==)
     # /tmp/d20151203-5272-1ld0d08/spec.rb:171:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) TurtleGraphics Canvas::HTML changes the opacity of a cell based on the times we have passed
     Failure/Error: expect(canvas.gsub(/\s+/, '')).to include <<-HTML.gsub(/\s+/, '')
       expected "<!DOCTYPEhtml><html><head><title>Turtlegraphics</title><style>table{border-spacing:0;}tr{padding:0;}td{width:5px;height:5px;background-color:black;padding:0;}</style></head><body><table><tr><tdstyle='opacity:1.0'></td><tdstyle='opacity:0.6666666666666666'></td><tdstyle='opacity:0.0'></td></tr><tr><tdstyle='opacity:0.3333333333333333'></td><tdstyle='opacity:0.3333333333333333'></td><tdstyle='opacity:0.0'></td></tr><tr><tdstyle='opacity:0.0'></td><tdstyle='opacity:0.0'></td><tdstyle='opacity:0.0'></td></tr></table></body></html>" to include "<table><tr><tdstyle=\"opacity:1.00\"></td><tdstyle=\"opacity:0.67\"></td><tdstyle=\"opacity:0.00\"></td></tr><tr><tdstyle=\"opacity:0.33\"></td><tdstyle=\"opacity:0.33\"></td><tdstyle=\"opacity:0.00\"></td></tr><tr><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td><tdstyle=\"opacity:0.00\"></td></tr></table>"
     # /tmp/d20151203-5272-1ld0d08/spec.rb:242:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.01258 seconds
14 examples, 3 failures

Failed examples:

rspec /tmp/d20151203-5272-1ld0d08/spec.rb:135 # TurtleGraphics Canvas::ASCII can render with a different number of symbols
rspec /tmp/d20151203-5272-1ld0d08/spec.rb:165 # TurtleGraphics Canvas::HTML renders the proper template
rspec /tmp/d20151203-5272-1ld0d08/spec.rb:227 # TurtleGraphics Canvas::HTML changes the opacity of a cell based on the times we have passed

История (4 версии и 4 коментара)

Станимира обнови решението на 27.11.2015 14:14 (преди над 8 години)

+module TurtleGraphics
+end
+
+class TurtleGraphics::Matrix
+ attr_reader :rows, :column_count, :row_count
+
+ def initialize(row_count, column_count = row_count)
+ @rows = Array.new(row_count) do |i|
+ Array.new(column_count) do |j|
+ i = j = 0
+ end
+ end
+ @column_count = column_count
+ @row_count = row_count
+ end
+end
+
+class TurtleGraphics::Turtle
+ DIRECTIONS = [:left, :up, :right, :down].freeze
+
+ def initialize(row_count, column_count)
+ @matrix = TurtleGraphics::Matrix.new(row_count, column_count)
+ look(:right)
+ end
+
+ def draw(canvas = nil)
+ self.instance_eval(&Proc.new) if block_given?
+ canvas != nil ? canvas.build(@matrix) : @matrix.rows
+ end
+
+ private
+ def move
+ unless defined? @position
+ spawn_at(0, 0)
+ incerement_canvas(0, 0)
+ end
+
+ case @direction
+ when 0 then change_position(-1, :column)
+ when 1 then change_position(-1, :row)
+ when 2 then change_position(1, :column)
+ when 3 then change_position(1, :row)
+ end
+
+ incerement_canvas(@position[:row], @position[:column])
+ end
+
+ def change_position(step, axis)
+ new_position = @position[axis] + step
+ canvas_size = @matrix.send(axis.to_s + "_count")
+
+ if new_position < 0
+ @position[axis] = canvas_size
+ elsif new_position >= canvas_size
+ @position[axis] = 0
+ else
+ @position[axis] = new_position
+ end
+ end
+
+ def incerement_canvas(row, column)
+ @matrix.rows[row][column] += 1
+ end
+
+ def turn_left
+ @direction = @direction == 0 ? DIRECTIONS.length - 1 : @direction - 1
+ end
+
+ def turn_right
+ @direction = @direction == DIRECTIONS.length - 1 ? 0 : @direction + 1
+ end
+
+ def spawn_at(row, column)
+ @position = {row: row, column: column}
+ end
+
+ def look(direction)
+ @direction = DIRECTIONS.index(direction)
+ end
+end
+
+module TurtleGraphics::Canvas
+ def max_frequency(matrix)
+ matrix.rows.collect { |row| row.max }.max
+ end
+end
+
+class TurtleGraphics::Canvas::ASCII
+ include TurtleGraphics::Canvas
+
+ def initialize(symbols)
+ @symbols = symbols
+ end
+
+ def build(matrix)
+ calculate_intensities(matrix)
+
+ canvas = ""
+ matrix.rows.each do |row|
+ row.each { |cell| canvas << to_symbol(cell) }
+ canvas << "\n"
+ end
+
+ canvas
+ end
+
+ private
+ def calculate_intensities(matrix)
+ @max_frequency = max_frequency(matrix)
+ interval = (1.0 / @max_frequency).to_f
+
+ @intensities = { 0 => @symbols[0] }
+ @symbols.each_with_index do |sym, index|
+ next if index == 0
+
+ range_start = (index - 1) * interval
+ range_end = (index == @symbols.length - 1) ? 1 : index * interval
+ @intensities[range_start..range_end] = sym
+ end
+ end
+
+ def to_symbol(cell)
+ cell_intensity = cell.to_f / @max_frequency
+ @intensities.select { |range| range === cell_intensity }.values.first
+ end
+end
+
+class TurtleGraphics::Canvas::HTML
+ include TurtleGraphics::Canvas
+
+ def initialize(pixel_size)
+ @pixel_size = pixel_size
+ end
+
+ def build(matrix)
+ html = %{
+ <!DOCTYPE html>
+ <html>
+ #{head}
+ #{body(matrix)}
+ </html>
+ }
+
+ html.delete!("\n")
+ end
+
+ private
+ def head
+ %{
+ <head>
+ <title>Turtle graphics</title>
+
+ <style>
+ table {
+ border-spacing: 0;
+ }
+
+ tr {
+ padding: 0;
+ }
+
+ td {
+ width: #{@pixel_size}px;
+ height: #{@pixel_size}px;
+
+ background-color: black;
+ padding: 0;
+ }
+ </style>
+ </head>
+ }
+ end
+
+ def body(matrix)
+ %{
+ <body>
+ #{generate_table(matrix)}
+ </body>
+ }
+ end
+
+ def generate_table(matrix)
+ max = max_frequency(matrix)
+
+ table = "<table>"
+ matrix.rows.each do |row|
+ table << "<tr>"
+ row.each do |cell|
+ cell_intensity = cell.to_f / max
+ table << "<td style='opacity: #{cell_intensity}'></td>"
+ end
+ table << "</tr>"
+ end
+ table << "</table>"
+ end
+end

Здравей :) Като по-рано предала - печелиш коментари :)

  • Хубаво е да дефинираш класове в други класове/модули като ги нестваш:
module TurtleGraphics
  class Turtle
    ...
  end
end

вместо

module TurtleGraphics
end

class TurtleGraphics::Turtle
  ...
end

Разликата е в начина, по който се търсят константи от кода на мястото на многоточието. При първия вариант се търси първо в Turtle, после в TurtleGraphics и накрая в Object. Във втория случай се търси само в Turtle и Object. - Това присвояване е излишно - i = j = 0. Можеш просто да напишеш 0 и ще има същият ефект. И е хубаво да е едноредов блок, вместо да има един ред само с 0. - Оставяй празен ред след private :) - Това:

if new_position < 0
  @position[axis] = canvas_size
elsif new_position >= canvas_size
  @position[axis] = 0
else
  @position[axis] = new_position
end

може да се направи на един ред с един математически оператор :)

  • Прекалено "мета" ми идва change_position. Затова ще подскажа малко :)
case @direction
  when 0 then change_position(-1, :column)
  when 1 then change_position(-1, :row)
  when 2 then change_position(1, :column)
  when 3 then change_position(1, :row)
end

=>

case @direction
  when 0 then @x -= 1
  when 1 then @y -= 1
  when 2 then @x += 1
  when 3 then @y += 1
end

И след това може да ги "вкараш в граници". change_position стана излишен. Помисли къде другаде можеш да приложиш подобно опростяване.

  • unless defined? @position => unless @position или unless @position.nil?. Инстанционните променливи съдържат nil по подразбиране.
  • Повечето от нещата в calculate_intensities могат да станат с мааалко количество математика. Помисли как да превърнеш интензитет в цяло число - индекс от масива със символите.
  • В ASCII#build използвай join. Конкатенирането на низове не е особено красиво и по принцип се избягва. Същото важи и за generate_table.

Като подобриш тези неща ще се получи супер :)

Станимира обнови решението на 29.11.2015 15:48 (преди над 8 години)

module TurtleGraphics
-end
+ class Matrix
+ attr_reader :rows, :column_count, :row_count
-class TurtleGraphics::Matrix
- attr_reader :rows, :column_count, :row_count
-
- def initialize(row_count, column_count = row_count)
- @rows = Array.new(row_count) do |i|
- Array.new(column_count) do |j|
- i = j = 0
- end
+ def initialize(row_count, column_count = row_count)
+ @rows = Array.new(row_count) { Array.new(column_count) { 0 } }
+ @column_count = column_count
+ @row_count = row_count
end
- @column_count = column_count
- @row_count = row_count
end
-end
-class TurtleGraphics::Turtle
- DIRECTIONS = [:left, :up, :right, :down].freeze
+ class Turtle
+ DIRECTIONS = [:left, :up, :right, :down].freeze
- def initialize(row_count, column_count)
- @matrix = TurtleGraphics::Matrix.new(row_count, column_count)
- look(:right)
- end
-
- def draw(canvas = nil)
- self.instance_eval(&Proc.new) if block_given?
- canvas != nil ? canvas.build(@matrix) : @matrix.rows
- end
-
- private
- def move
- unless defined? @position
- spawn_at(0, 0)
- incerement_canvas(0, 0)
+ def initialize(row_count, column_count)
+ @matrix = Matrix.new(row_count, column_count)
+ look(:right)
end
- case @direction
- when 0 then change_position(-1, :column)
- when 1 then change_position(-1, :row)
- when 2 then change_position(1, :column)
- when 3 then change_position(1, :row)
+ def draw(canvas = nil)
+ self.instance_eval(&Proc.new) if block_given?
+ canvas != nil ? canvas.build(@matrix) : @matrix.rows
end
- incerement_canvas(@position[:row], @position[:column])
- end
+ private
- def change_position(step, axis)
- new_position = @position[axis] + step
- canvas_size = @matrix.send(axis.to_s + "_count")
+ def move
+ if @x.nil? and @y.nil?
+ spawn_at(0, 0)
+ @matrix.rows[0][0] += 1
+ end
- if new_position < 0
- @position[axis] = canvas_size
- elsif new_position >= canvas_size
- @position[axis] = 0
- else
- @position[axis] = new_position
+ case @direction
+ when 0 then @y -= 1
+ when 1 then @x -= 1
+ when 2 then @y += 1
+ when 3 then @x += 1
+ end
+
+ put_in_borders
+ @matrix.rows[@x][@y] += 1
end
- end
- def incerement_canvas(row, column)
- @matrix.rows[row][column] += 1
- end
+ def put_in_borders
+ @x = @matrix.row_count if @x < 0
+ @x = 0 if @x >= @matrix.row_count
- def turn_left
- @direction = @direction == 0 ? DIRECTIONS.length - 1 : @direction - 1
- end
+ @y = @matrix.column_count if @y < 0
+ @y = 0 if @y >= @matrix.column_count
+ end
- def turn_right
- @direction = @direction == DIRECTIONS.length - 1 ? 0 : @direction + 1
- end
+ def turn_left
+ @direction = @direction == 0 ? DIRECTIONS.length - 1 : @direction - 1
+ end
- def spawn_at(row, column)
- @position = {row: row, column: column}
- end
+ def turn_right
+ @direction = @direction == DIRECTIONS.length - 1 ? 0 : @direction + 1
+ end
- def look(direction)
- @direction = DIRECTIONS.index(direction)
- end
-end
+ def spawn_at(row, column)
+ @x = row
+ @y = column
+ end
-module TurtleGraphics::Canvas
- def max_frequency(matrix)
- matrix.rows.collect { |row| row.max }.max
+ def look(direction)
+ @direction = DIRECTIONS.index(direction)
+ end
end
-end
-class TurtleGraphics::Canvas::ASCII
- include TurtleGraphics::Canvas
+ module Canvas
+ def calculate_max_frequency(matrix)
+ matrix.rows.collect { |row| row.max }.max
+ end
- def initialize(symbols)
- @symbols = symbols
- end
+ class ASCII
+ include Canvas
- def build(matrix)
- calculate_intensities(matrix)
+ def initialize(symbols)
+ @symbols = symbols
+ end
- canvas = ""
- matrix.rows.each do |row|
- row.each { |cell| canvas << to_symbol(cell) }
- canvas << "\n"
- end
+ def build(matrix)
+ max_frequency = calculate_max_frequency(matrix)
+ interval = (1.0 / max_frequency).to_f
- canvas
- end
+ canvas = []
+ matrix.rows.each do |row|
+ row.each { |cell| canvas << @symbols[cell / (max_frequency * interval)] }
+ canvas << "\n"
+ end
- private
- def calculate_intensities(matrix)
- @max_frequency = max_frequency(matrix)
- interval = (1.0 / @max_frequency).to_f
+ canvas.join
+ end
+ end
- @intensities = { 0 => @symbols[0] }
- @symbols.each_with_index do |sym, index|
- next if index == 0
+ class HTML
+ include Canvas
- range_start = (index - 1) * interval
- range_end = (index == @symbols.length - 1) ? 1 : index * interval
- @intensities[range_start..range_end] = sym
- end
- end
+ def initialize(pixel_size)
+ @pixel_size = pixel_size
+ end
- def to_symbol(cell)
- cell_intensity = cell.to_f / @max_frequency
- @intensities.select { |range| range === cell_intensity }.values.first
- end
-end
+ def build(matrix)
+ html = %{
+ <!DOCTYPE html>
+ <html>
+ #{head}
+ #{body(matrix)}
+ </html>
+ }
-class TurtleGraphics::Canvas::HTML
- include TurtleGraphics::Canvas
+ html.delete!("\n")
+ end
- def initialize(pixel_size)
- @pixel_size = pixel_size
- end
+ private
- def build(matrix)
- html = %{
- <!DOCTYPE html>
- <html>
- #{head}
- #{body(matrix)}
- </html>
- }
+ def head
+ %{
+ <head>
+ <title>Turtle graphics</title>
- html.delete!("\n")
- end
+ <style>
+ table {
+ border-spacing: 0;
+ }
- private
- def head
- %{
- <head>
- <title>Turtle graphics</title>
+ tr {
+ padding: 0;
+ }
- <style>
- table {
- border-spacing: 0;
- }
+ td {
+ width: #{@pixel_size}px;
+ height: #{@pixel_size}px;
- tr {
- padding: 0;
+ background-color: black;
+ padding: 0;
+ }
+ </style>
+ </head>
}
+ end
- td {
- width: #{@pixel_size}px;
- height: #{@pixel_size}px;
-
- background-color: black;
- padding: 0;
+ def body(matrix)
+ %{
+ <body>
+ #{generate_table(matrix)}
+ </body>
}
- </style>
- </head>
- }
- end
+ end
- def body(matrix)
- %{
- <body>
- #{generate_table(matrix)}
- </body>
- }
- end
+ def generate_table(matrix)
+ max_frequency = calculate_max_frequency(matrix)
- def generate_table(matrix)
- max = max_frequency(matrix)
-
- table = "<table>"
- matrix.rows.each do |row|
- table << "<tr>"
- row.each do |cell|
- cell_intensity = cell.to_f / max
- table << "<td style='opacity: #{cell_intensity}'></td>"
+ table = ["<table>"]
+ matrix.rows.each do |row|
+ table << "<tr>"
+ row.each do |cell|
+ cell_intensity = cell.to_f / max_frequency
+ table << "<td style='opacity: #{cell_intensity}'></td>"
+ end
+ table << "</tr>"
+ end
+ table << "</table>"
+ table.join
end
- table << "</tr>"
end
- table << "</table>"
end
end

Благодаря за коментарите! Мисля, че направих нужните промени :)
Единствено не успях да измисля как да вкарам @x и @y в граници с 1 мат. оператор. Предполагах, че ще стане с изваждане (matrix_size - current_position , ако current_position е извън границите), но все ми се губи единица в един от граничните случаи (в зависимост дали почвам индексите от 0 или 1).

Станимира обнови решението на 29.11.2015 16:11 (преди над 8 години)

module TurtleGraphics
class Matrix
attr_reader :rows, :column_count, :row_count
def initialize(row_count, column_count = row_count)
@rows = Array.new(row_count) { Array.new(column_count) { 0 } }
@column_count = column_count
@row_count = row_count
end
end
class Turtle
DIRECTIONS = [:left, :up, :right, :down].freeze
def initialize(row_count, column_count)
@matrix = Matrix.new(row_count, column_count)
look(:right)
end
def draw(canvas = nil)
self.instance_eval(&Proc.new) if block_given?
canvas != nil ? canvas.build(@matrix) : @matrix.rows
end
private
def move
if @x.nil? and @y.nil?
spawn_at(0, 0)
- @matrix.rows[0][0] += 1
end
case @direction
when 0 then @y -= 1
when 1 then @x -= 1
when 2 then @y += 1
when 3 then @x += 1
end
put_in_borders
@matrix.rows[@x][@y] += 1
end
def put_in_borders
- @x = @matrix.row_count if @x < 0
+ @x = @matrix.row_count - 1 if @x < 0
@x = 0 if @x >= @matrix.row_count
- @y = @matrix.column_count if @y < 0
+ @y = @matrix.column_count - 1 if @y < 0
@y = 0 if @y >= @matrix.column_count
end
def turn_left
@direction = @direction == 0 ? DIRECTIONS.length - 1 : @direction - 1
end
def turn_right
@direction = @direction == DIRECTIONS.length - 1 ? 0 : @direction + 1
end
def spawn_at(row, column)
@x = row
@y = column
+ @matrix.rows[@x][@y] += 1
end
def look(direction)
@direction = DIRECTIONS.index(direction)
end
end
module Canvas
def calculate_max_frequency(matrix)
matrix.rows.collect { |row| row.max }.max
end
class ASCII
include Canvas
def initialize(symbols)
@symbols = symbols
end
def build(matrix)
max_frequency = calculate_max_frequency(matrix)
interval = (1.0 / max_frequency).to_f
canvas = []
matrix.rows.each do |row|
row.each { |cell| canvas << @symbols[cell / (max_frequency * interval)] }
canvas << "\n"
end
canvas.join
end
end
class HTML
include Canvas
def initialize(pixel_size)
@pixel_size = pixel_size
end
def build(matrix)
html = %{
<!DOCTYPE html>
<html>
#{head}
#{body(matrix)}
</html>
}
html.delete!("\n")
end
private
def head
%{
<head>
<title>Turtle graphics</title>
<style>
table {
border-spacing: 0;
}
tr {
padding: 0;
}
td {
width: #{@pixel_size}px;
height: #{@pixel_size}px;
background-color: black;
padding: 0;
}
</style>
</head>
}
end
def body(matrix)
%{
<body>
#{generate_table(matrix)}
</body>
}
end
def generate_table(matrix)
max_frequency = calculate_max_frequency(matrix)
table = ["<table>"]
matrix.rows.each do |row|
table << "<tr>"
row.each do |cell|
cell_intensity = cell.to_f / max_frequency
table << "<td style='opacity: #{cell_intensity}'></td>"
end
table << "</tr>"
end
table << "</table>"
table.join
end
end
end
end

Станимира обнови решението на 30.11.2015 00:01 (преди над 8 години)

module TurtleGraphics
class Matrix
attr_reader :rows, :column_count, :row_count
def initialize(row_count, column_count = row_count)
@rows = Array.new(row_count) { Array.new(column_count) { 0 } }
@column_count = column_count
@row_count = row_count
end
end
class Turtle
DIRECTIONS = [:left, :up, :right, :down].freeze
def initialize(row_count, column_count)
@matrix = Matrix.new(row_count, column_count)
look(:right)
end
def draw(canvas = nil)
self.instance_eval(&Proc.new) if block_given?
canvas != nil ? canvas.build(@matrix) : @matrix.rows
end
private
def move
if @x.nil? and @y.nil?
spawn_at(0, 0)
end
case @direction
when 0 then @y -= 1
when 1 then @x -= 1
when 2 then @y += 1
when 3 then @x += 1
end
- put_in_borders
+ @x = @x < 0 ? @matrix.row_count - 1 : @x % @matrix.row_count
+ @y = @y < 0 ? @matrix.column_count - 1 : @y % @matrix.column_count
@matrix.rows[@x][@y] += 1
end
- def put_in_borders
- @x = @matrix.row_count - 1 if @x < 0
- @x = 0 if @x >= @matrix.row_count
-
- @y = @matrix.column_count - 1 if @y < 0
- @y = 0 if @y >= @matrix.column_count
- end
-
def turn_left
@direction = @direction == 0 ? DIRECTIONS.length - 1 : @direction - 1
end
def turn_right
@direction = @direction == DIRECTIONS.length - 1 ? 0 : @direction + 1
end
def spawn_at(row, column)
@x = row
@y = column
@matrix.rows[@x][@y] += 1
end
def look(direction)
@direction = DIRECTIONS.index(direction)
end
end
module Canvas
def calculate_max_frequency(matrix)
matrix.rows.collect { |row| row.max }.max
end
class ASCII
include Canvas
def initialize(symbols)
@symbols = symbols
end
def build(matrix)
max_frequency = calculate_max_frequency(matrix)
interval = (1.0 / max_frequency).to_f
canvas = []
matrix.rows.each do |row|
row.each { |cell| canvas << @symbols[cell / (max_frequency * interval)] }
canvas << "\n"
end
canvas.join
end
end
class HTML
include Canvas
def initialize(pixel_size)
@pixel_size = pixel_size
end
def build(matrix)
- html = %{
+ %{
<!DOCTYPE html>
<html>
#{head}
#{body(matrix)}
</html>
}
-
- html.delete!("\n")
end
private
def head
%{
<head>
<title>Turtle graphics</title>
<style>
table {
border-spacing: 0;
}
tr {
padding: 0;
}
td {
width: #{@pixel_size}px;
height: #{@pixel_size}px;
background-color: black;
padding: 0;
}
</style>
</head>
}
end
def body(matrix)
%{
<body>
#{generate_table(matrix)}
</body>
}
end
def generate_table(matrix)
max_frequency = calculate_max_frequency(matrix)
table = ["<table>"]
matrix.rows.each do |row|
table << "<tr>"
row.each do |cell|
cell_intensity = cell.to_f / max_frequency
table << "<td style='opacity: #{cell_intensity}'></td>"
end
table << "</tr>"
end
table << "</table>"
table.join
end
end
end
end