Решение на Шеста задача от Анджелин Неделчев

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

Към профила на Анджелин Неделчев

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 13 успешни тест(а)
  • 1 неуспешни тест(а)

Код

module TurtleGraphics
class Point
attr_accessor :x
attr_accessor :y
def initialize(x, y)
@x = x
@y = y
end
def next(direction)
case direction
when :up then Point.new(@x - 1, @y)
when :right then Point.new(@x, @y + 1)
when :down then Point.new(@x + 1, @y)
when :left then Point.new(@x, @y - 1)
end
end
end
class Turtle
DIRECTIONS = [:up, :right, :down, :left]
attr_reader :canvas
def initialize(rows, columns)
@rows = rows
@columns = columns
@spawned = false
init_canvas
look(:right)
end
def init_canvas
@canvas = []
@rows.times { @canvas << Array.new(@columns, 0) }
end
def draw(drawer = nil, &block)
instance_eval &block
return @canvas unless drawer
drawer.to_canvas(@canvas)
end
def move
spawn_at(0, 0) unless @spawned
next_position = @position.next(@looks_at)
next_position.x %= @rows
next_position.y %= @columns
spawn_at(next_position.x, next_position.y)
end
def turn_left
look(DIRECTIONS[DIRECTIONS.index(@looks_at) - 1])
end
def turn_right
look(DIRECTIONS[(DIRECTIONS.index(@looks_at) + 1) % DIRECTIONS.size])
end
def spawn_at(row, column)
@spawned = true
@position = Point.new(row, column)
@canvas[row][column] += 1
end
def look(orientation)
unless (DIRECTIONS.include? orientation)
raise ArgumentError, "'#{orientation}' is not a valid direction."
end
@looks_at = orientation
end
end
module Canvas
class ASCII
def initialize(symbols)
@symbols = symbols
@step = 1.0 / (symbols.size - 1)
end
def to_canvas(canvas)
asci = ""
max = canvas.flatten.max
canvas.each do |row|
row.each { |cell| asci += pick_symbol(cell, max) }
asci += "\n"
end
asci
end
def pick_symbol(cell, max)
intensity = max == 0 ? max : cell.to_f / max
@symbols[(intensity / @step).floor]
end
end
class HTML
HEADER = '<!DOCTYPE html><html><head>' \
'<title>Turtle graphics</title>%s</head>'
CSS = '<style>table {border-spacing: 0;} tr{padding: 0;}' \
'td {width: %spx;height: %spx;background-color: black;' \
'padding: 0;}</style>'
ENTRY = '<td style="opacity: %s"></td>'
def initialize(td_size)
@document = HEADER % (CSS % [td_size, td_size])
end
def to_canvas(canvas)
@document += '<body><table>'
max = canvas.flatten.max
canvas.each do |row|
@document += '<tr>'
row.each do |cell|
opacity = calculate_opacity(cell, max)
@document += ENTRY % format('%.2f', opacity)
end
@document += '</tr>'
end
@document += '</table></body></html>'
end
def calculate_opacity(cell, max)
max == 0 ? max : cell.to_f / max
end
end
end
end

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

..........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: "toz\nzzz\nzzz"
       
       (compared using ==)
       
       Diff:
       @@ -1,4 +1,4 @@
       -ttz
       -ooz
       +toz
       +zzz
        zzz
     # /tmp/d20151203-5272-1hsodbn/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)>'

Finished in 0.01249 seconds
14 examples, 1 failure

Failed examples:

rspec /tmp/d20151203-5272-1hsodbn/spec.rb:135 # TurtleGraphics Canvas::ASCII can render with a different number of symbols

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

Анджелин обнови решението на 28.11.2015 18:47 (преди над 8 години)

+module TurtleGraphics
+ class Point
+ attr_accessor :x
+ attr_accessor :y
+
+ def initialize(x, y)
+ @x = x
+ @y = y
+ end
+
+ def next(direction)
+ case direction
+ when :up then Point.new(@x - 1, @y)
+ when :right then Point.new(@x, @y + 1)
+ when :down then Point.new(@x + 1, @y)
+ when :left then Point.new(@x, @y - 1)
+ end
+ end
+ end
+
+
+ class Turtle
+ DIRECTIONS = [:up, :right, :down, :left]
+
+ attr_reader :canvas
+
+ def initialize(rows, columns)
+ @rows = rows
+ @columns = columns
+ @spawned = false
+
+ init_canvas()
+ look(:right)
+ end
+
+ def init_canvas()
+ @canvas = []
+ @rows.times { @canvas << Array.new(@columns, 0) }
+ end
+
+ def draw(drawer = nil, &block)
+ instance_eval &block
+
+ return @canvas unless drawer
+ drawer.to_canvas(@canvas)
+ end
+
+ def move()
+ unless @spawned
+ spawn_at(0, 0)
+ end
+
+ next_position = @position.next(@looks_at)
+ next_position.x %= @rows
+ next_position.y %= @columns
+
+ spawn_at(next_position.x, next_position.y)
+ end
+
+ def turn_left()
+ look(DIRECTIONS[DIRECTIONS.index(@looks_at) - 1])
+ end
+
+ def turn_right()
+ look(DIRECTIONS[(DIRECTIONS.index(@looks_at) + 1) % DIRECTIONS.size])
+ end
+
+ def spawn_at(row, column)
+ @spawned = true
+ @position = Point.new(row, column)
+ @canvas[row][column] += 1
+ end
+
+ def look(orientation)
+ unless (DIRECTIONS.include? orientation)
+ raise ArgumentError, "'#{orientation}' is not a valid direction."
+ end
+
+ @looks_at = orientation
+ end
+ end
+
+ module Canvas
+ class ASCII
+ def initialize(symbols)
+ @symbols = symbols
+ end
+
+ def to_canvas(canvas)
+ asci = ""
+ canvas.each do |row|
+ row.each { |cell| asci += drawer.symbols[cell] }
+ asci += "\n"
+ end
+
+ asci
+ end
+ end
+
+ class HTML
+ HEADER = '<!DOCTYPE html><html><head>' \
+ '<title>Turtle graphics</title>%s</head>'
+
+ CSS = '<style>table {border-spacing: 0;} tr{padding: 0;}' \
+ 'td {width: %spx;height: %spx;background-color: black;' \
+ 'padding: 0;}</style>'
+
+ ENTRY = '<td style="opacity: %s"></td>'
+
+
+ def initialize(td_size)
+ @document = HEADER % (CSS % [td_size, td_size])
+ end
+
+ def to_canvas(canvas)
+ @document += '<body><table>'
+
+ canvas.each do |row|
+ @document += '<tr>'
+
+ row.each do |cell|
+ @document += ENTRY % format('%.2f', (cell / row.max rescue 0))
+ end
+ @document += '</tr>'
+ end
+
+ @document += '</table></body></html>'
+ end
+ end
+ end
+end

Анджелин обнови решението на 28.11.2015 21:24 (преди над 8 години)

module TurtleGraphics
class Point
attr_accessor :x
attr_accessor :y
def initialize(x, y)
@x = x
@y = y
end
def next(direction)
case direction
when :up then Point.new(@x - 1, @y)
when :right then Point.new(@x, @y + 1)
when :down then Point.new(@x + 1, @y)
when :left then Point.new(@x, @y - 1)
end
end
end
class Turtle
DIRECTIONS = [:up, :right, :down, :left]
attr_reader :canvas
def initialize(rows, columns)
@rows = rows
@columns = columns
@spawned = false
init_canvas()
look(:right)
end
def init_canvas()
@canvas = []
@rows.times { @canvas << Array.new(@columns, 0) }
end
def draw(drawer = nil, &block)
instance_eval &block
return @canvas unless drawer
drawer.to_canvas(@canvas)
end
def move()
unless @spawned
spawn_at(0, 0)
end
next_position = @position.next(@looks_at)
next_position.x %= @rows
next_position.y %= @columns
spawn_at(next_position.x, next_position.y)
end
def turn_left()
look(DIRECTIONS[DIRECTIONS.index(@looks_at) - 1])
end
def turn_right()
look(DIRECTIONS[(DIRECTIONS.index(@looks_at) + 1) % DIRECTIONS.size])
end
def spawn_at(row, column)
@spawned = true
@position = Point.new(row, column)
@canvas[row][column] += 1
end
def look(orientation)
unless (DIRECTIONS.include? orientation)
raise ArgumentError, "'#{orientation}' is not a valid direction."
end
@looks_at = orientation
end
end
module Canvas
class ASCII
def initialize(symbols)
@symbols = symbols
end
def to_canvas(canvas)
asci = ""
canvas.each do |row|
row.each { |cell| asci += drawer.symbols[cell] }
asci += "\n"
end
asci
end
end
class HTML
HEADER = '<!DOCTYPE html><html><head>' \
'<title>Turtle graphics</title>%s</head>'
CSS = '<style>table {border-spacing: 0;} tr{padding: 0;}' \
'td {width: %spx;height: %spx;background-color: black;' \
'padding: 0;}</style>'
ENTRY = '<td style="opacity: %s"></td>'
def initialize(td_size)
@document = HEADER % (CSS % [td_size, td_size])
end
def to_canvas(canvas)
@document += '<body><table>'
canvas.each do |row|
@document += '<tr>'
row.each do |cell|
- @document += ENTRY % format('%.2f', (cell / row.max rescue 0))
+ opacity = calculate_opacity(cell, row.max)
+ @document += ENTRY % format('%.2f', opacity)
end
@document += '</tr>'
end
@document += '</table></body></html>'
+ end
+
+ def calculate_opacity(cell, max)
+ max == 0 ? max : cell.to_f / max
end
end
end
end

Браво, изглежда доста добре :)

Обаче, винаги може да стане по-добре :)

  • Не слагай празни скоби при извикване (и дефиниране) на методи без аргументи init_canvas() => init_canvas.
  • Използвай едноредовия вариант на if и unless за едноредов код: spawn_at(0, 0) unless @spawned
  • Имплементацията ти на ASCII е грешна - погледни пак условието.
  • При едно от завъртанията може да се получи грешка.

Анджелин обнови решението на 29.11.2015 21:35 (преди над 8 години)

module TurtleGraphics
class Point
attr_accessor :x
attr_accessor :y
def initialize(x, y)
@x = x
@y = y
end
def next(direction)
case direction
when :up then Point.new(@x - 1, @y)
when :right then Point.new(@x, @y + 1)
when :down then Point.new(@x + 1, @y)
when :left then Point.new(@x, @y - 1)
end
end
end
class Turtle
DIRECTIONS = [:up, :right, :down, :left]
attr_reader :canvas
def initialize(rows, columns)
@rows = rows
@columns = columns
@spawned = false
- init_canvas()
+ init_canvas
look(:right)
end
- def init_canvas()
+ def init_canvas
@canvas = []
@rows.times { @canvas << Array.new(@columns, 0) }
end
def draw(drawer = nil, &block)
instance_eval &block
return @canvas unless drawer
drawer.to_canvas(@canvas)
end
- def move()
- unless @spawned
- spawn_at(0, 0)
- end
+ def move
+ spawn_at(0, 0) unless @spawned
next_position = @position.next(@looks_at)
next_position.x %= @rows
next_position.y %= @columns
spawn_at(next_position.x, next_position.y)
end
- def turn_left()
+ def turn_left
look(DIRECTIONS[DIRECTIONS.index(@looks_at) - 1])
end
- def turn_right()
+ def turn_right
look(DIRECTIONS[(DIRECTIONS.index(@looks_at) + 1) % DIRECTIONS.size])
end
def spawn_at(row, column)
@spawned = true
@position = Point.new(row, column)
@canvas[row][column] += 1
end
def look(orientation)
unless (DIRECTIONS.include? orientation)
raise ArgumentError, "'#{orientation}' is not a valid direction."
end
@looks_at = orientation
end
end
module Canvas
class ASCII
def initialize(symbols)
@symbols = symbols
+ @step = 1.0 / (symbols.size - 1)
end
def to_canvas(canvas)
asci = ""
canvas.each do |row|
- row.each { |cell| asci += drawer.symbols[cell] }
+ row.each { |cell| asci += pick_symbol(cell, row.max) }
asci += "\n"
end
asci
end
+
+ def pick_symbol(cell, max)
+ intensity = max == 0 ? max : cell.to_f / max
+ @symbols[(intensity / @step).floor]
+ end
end
class HTML
HEADER = '<!DOCTYPE html><html><head>' \
'<title>Turtle graphics</title>%s</head>'
CSS = '<style>table {border-spacing: 0;} tr{padding: 0;}' \
'td {width: %spx;height: %spx;background-color: black;' \
'padding: 0;}</style>'
ENTRY = '<td style="opacity: %s"></td>'
def initialize(td_size)
@document = HEADER % (CSS % [td_size, td_size])
end
def to_canvas(canvas)
@document += '<body><table>'
canvas.each do |row|
@document += '<tr>'
row.each do |cell|
opacity = calculate_opacity(cell, row.max)
@document += ENTRY % format('%.2f', opacity)
end
@document += '</tr>'
end
@document += '</table></body></html>'
end
def calculate_opacity(cell, max)
max == 0 ? max : cell.to_f / max
end
end
end
-end
+end

Не си се натрапил :)

Наистина има проблем. Прочети хубаво частта от условието, свързана с интензитетите.

Ще ти е полезно да си напишеш няколко теста с малки примерни "рисунки". Така ще забележиш проблема по-лесно.

Анджелин обнови решението на 01.12.2015 22:31 (преди над 8 години)

module TurtleGraphics
class Point
attr_accessor :x
attr_accessor :y
def initialize(x, y)
@x = x
@y = y
end
def next(direction)
case direction
when :up then Point.new(@x - 1, @y)
when :right then Point.new(@x, @y + 1)
when :down then Point.new(@x + 1, @y)
when :left then Point.new(@x, @y - 1)
end
end
end
class Turtle
DIRECTIONS = [:up, :right, :down, :left]
attr_reader :canvas
def initialize(rows, columns)
@rows = rows
@columns = columns
@spawned = false
init_canvas
look(:right)
end
def init_canvas
@canvas = []
@rows.times { @canvas << Array.new(@columns, 0) }
end
def draw(drawer = nil, &block)
instance_eval &block
return @canvas unless drawer
drawer.to_canvas(@canvas)
end
def move
spawn_at(0, 0) unless @spawned
next_position = @position.next(@looks_at)
next_position.x %= @rows
next_position.y %= @columns
spawn_at(next_position.x, next_position.y)
end
def turn_left
look(DIRECTIONS[DIRECTIONS.index(@looks_at) - 1])
end
def turn_right
look(DIRECTIONS[(DIRECTIONS.index(@looks_at) + 1) % DIRECTIONS.size])
end
def spawn_at(row, column)
@spawned = true
@position = Point.new(row, column)
@canvas[row][column] += 1
end
def look(orientation)
unless (DIRECTIONS.include? orientation)
raise ArgumentError, "'#{orientation}' is not a valid direction."
end
@looks_at = orientation
end
end
module Canvas
class ASCII
def initialize(symbols)
@symbols = symbols
@step = 1.0 / (symbols.size - 1)
end
def to_canvas(canvas)
asci = ""
+ max = canvas.flatten.max
+
canvas.each do |row|
- row.each { |cell| asci += pick_symbol(cell, row.max) }
+ row.each { |cell| asci += pick_symbol(cell, max) }
asci += "\n"
end
asci
end
def pick_symbol(cell, max)
intensity = max == 0 ? max : cell.to_f / max
@symbols[(intensity / @step).floor]
end
end
class HTML
HEADER = '<!DOCTYPE html><html><head>' \
'<title>Turtle graphics</title>%s</head>'
CSS = '<style>table {border-spacing: 0;} tr{padding: 0;}' \
'td {width: %spx;height: %spx;background-color: black;' \
'padding: 0;}</style>'
ENTRY = '<td style="opacity: %s"></td>'
def initialize(td_size)
@document = HEADER % (CSS % [td_size, td_size])
end
def to_canvas(canvas)
@document += '<body><table>'
+ max = canvas.flatten.max
canvas.each do |row|
@document += '<tr>'
row.each do |cell|
- opacity = calculate_opacity(cell, row.max)
+ opacity = calculate_opacity(cell, max)
@document += ENTRY % format('%.2f', opacity)
end
@document += '</tr>'
end
@document += '</table></body></html>'
end
def calculate_opacity(cell, max)
max == 0 ? max : cell.to_f / max
end
end
end
end