Решение на Шеста задача от Милена Дренска

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

Към профила на Милена Дренска

Резултати

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

Код

module TurtleGraphics
class Turtle
ORIENTATIONS = {up: 0, down: 180, right: 90, left:270}
def initialize(rows, cols)
@rows = rows
@cols = cols
@orientation = 90
@position = {}
@grid = Array.new(@rows) { Array.new(@cols){0} }
end
def move
spawn_at(0, 0) unless @position.length > 0
direction = @orientation == 180 || @orientation == 90 ? 1 : -1
updated_index = @orientation == 180 || @orientation == 0 ? :row : :col
@position[updated_index] = (@position[updated_index] + direction) % @rows
@grid[@position[:row]][@position[:col]] += 1
end
def turn_right
@orientation = (@orientation + 90) % 360
end
def turn_left
@orientation = (@orientation - 90) % 360
end
def spawn_at(row, col)
@position = {row: row % @rows , col: col % @cols}
@grid[@position[:row]][@position[:col]] += 1
end
def look(orientation)
@orientation = ORIENTATIONS[orientation]
end
def draw(canvas = nil)
self.instance_eval(&Proc.new) if block_given?
return @grid if canvas == nil
canvas.render(@grid)
end
end
module Canvas
class ASCII
def initialize(symbols)
@symbols = symbols
@range_step = 1.to_f / (@symbols.length - 1)
end
def render(grid)
max_visits = grid.max_by { |array| array.max }.max
output = grid.collect do |row|
render_line(row, max_visits)
end
output.join.chomp("\n")
end
private
def render_line(row, max_visits)
output = row.collect do |value|
symbol_index = ((value.to_f / max_visits) / @range_step).ceil
@symbols[symbol_index]
end
"%s\n" % output.join
end
end
class HTML
LAYOUT = "<!DOCTYPE html>
<html>
<head>
<title>Turtle graphics</title>
<style>
table {
border-spacing: 0;
}
tr {
padding: 0;
}
td {
width: %spx;
height: %spx;
background-color: black;
padding: 0;
}
</style>
</head>
<body>
<table>
%s
</table>
</body>
</html>"
def initialize(pixel_size)
@pixel_size = pixel_size
end
def render(grid)
max_visits = grid.max_by { |array| array.max }.max
output = grid.collect do |row|
render_line(row, max_visits)
end
LAYOUT % [@pixel_size, @pixel_size, output.join]
end
private
def render_line(row, max_visits)
output = row.collect do |value|
opacity = format('%.2f', value.to_f / max_visits)
%Q[<td style="opacity: #{opacity}"></td>]
end
"<tr>%s</tr>" % output.join
end
end
end
end

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

..............

Finished in 0.01217 seconds
14 examples, 0 failures

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

Милена обнови решението на 29.11.2015 15:14 (преди над 8 години)

+module TurtleGraphics
+ class Turtle
+ ORIENTATIONS = {up: 0, down: 180, right: 90, left:270}
+
+ attr_reader :position, :steps
+
+ def initialize(rows, cols)
+ @rows = rows
+ @cols = cols
+ @orientation = 90
+ @position = {}
+ @steps = []
+ end
+
+ def move
+ spawn_at(0, 0) unless @position.length > 0
+ @position[:row] = (@position[:row] + 1) % @rows if @orientation == 180
+ @position[:row] = (@position[:row] - 1) % @rows if @orientation == 0
+ @position[:col] = (@position[:col] + 1) % @rows if @orientation == 90
+ @position[:col] = (@position[:col] - 1) % @rows if @orientation == 270
+ @steps << @position.dup
+ end
+
+ def turn_right
+ @orientation = (@orientation + 90) % 360
+ end
+
+ def turn_left
+ @orientation = (@orientation - 90) % 360
+ end
+
+ def spawn_at(row, col)
+ new_row, new_col = row % @rows, col % @cols
+ @position = {row: new_row , col: new_col}
+ @steps << @position.dup
+ end
+
+ def look(orientation)
+ @orientation = ORIENTATIONS[orientation]
+ end
+
+ def draw(canvas = nil)
+ self.instance_eval(&Proc.new) if block_given?
+ grid = Array.new(@rows) { Array.new(@cols){0} }
+ @steps.each { |p| grid[p[:row]][p[:col]] += 1}
+ return grid if canvas == nil
+ canvas.render(grid)
+ end
+ end
+
+ module Canvas
+ class ASCII
+ def initialize(symbols)
+ @symbols = symbols
+ @range_step = 1.to_f / (@symbols.length - 1)
+ end
+
+ def render(grid)
+ max_visits, output = grid.max_by { |array| array.max }.max, ''
+ grid.each do |row|
+ output += render_line(row, max_visits)
+ end
+ output.chomp("\n")
+ end
+
+ private
+
+ def render_line(row, max_visits)
+ output = ''
+ row.each_with_index do |value, index|
+ symbol_index = ((value.to_f / max_visits) / @range_step).ceil
+ output += @symbols[symbol_index]
+ end
+ output + "\n"
+ end
+ end
+
+ class HTML
+ LAYOUT = "<!DOCTYPE html>
+ <html>
+ <head>
+ <title>Turtle graphics</title>
+
+ <style>
+ table {
+ border-spacing: 0;
+ }
+
+ tr {
+ padding: 0;
+ }
+
+ td {
+ width: %spx;
+ height: %spx;
+
+ background-color: black;
+ padding: 0;
+ }
+ </style>
+ </head>
+ <body>
+ %s
+ </body>
+ </html>"
+ def initialize(pixel_size)
+ @pixel_size = pixel_size
+ end
+
+ def render(grid)
+ max_visits, table = grid.max_by { |array| array.max }.max, '<table>'
+ grid.each do |row|
+ table += render_line(row, max_visits)
+ end
+ table += '</table>'
+ LAYOUT % [@pixel_size, @pixel_size, table]
+ end
+
+ private
+
+ def render_line(row, max_visits)
+ output = '<tr>'
+ row.each do |value|
+ opacity = format('%.2f', value.to_f / max_visits)
+ output += "<td style='opacity: #{opacity}'></td>"
+ end
+
+ output += '</tr>'
+ end
+ end
+ end
+end

Здравей :)

Ето малко коментари:

  • Интересно представяне с градуси :) В move има доста повторение. Защо не го замениш с case?
  • Защо пазиш стъпките отделно от матрицата и я обновяваш само накрая? Можеш да обновяваш директно нея.
  • Паралелното присвояване не се използва толкова често на практика. Няма ползи от него в този му вид new_row, new_col = row % @rows, col % @cols. Много по-чисто би било на два отделни реда.
  • Конкатенирането на низове, особено in-place не е добра практика в Ruby. Опитай да го направиш без += на низове.
  • Харесва ми, че си изнесла HTML-а в константа :)
  • Не-whitespace символите в HTML-а трябва да са същите като използваните в условието. HTML кода, който създаваш в момента ще работи в браузър, но не е както в условието и ще ти се счупят тестовете.

Милена обнови решението на 01.12.2015 21:00 (преди над 8 години)

module TurtleGraphics
class Turtle
ORIENTATIONS = {up: 0, down: 180, right: 90, left:270}
- attr_reader :position, :steps
-
def initialize(rows, cols)
@rows = rows
@cols = cols
@orientation = 90
@position = {}
- @steps = []
+ @grid = Array.new(@rows) { Array.new(@cols){0} }
end
def move
spawn_at(0, 0) unless @position.length > 0
- @position[:row] = (@position[:row] + 1) % @rows if @orientation == 180
- @position[:row] = (@position[:row] - 1) % @rows if @orientation == 0
- @position[:col] = (@position[:col] + 1) % @rows if @orientation == 90
- @position[:col] = (@position[:col] - 1) % @rows if @orientation == 270
- @steps << @position.dup
+
+ direction = @orientation == 180 || @orientation == 90 ? 1 : -1
+ updated_index = @orientation == 180 || @orientation == 0 ? :row : :col
+ @position[updated_index] = (@position[updated_index] + direction) % @rows
+ @grid[@position[:row]][@position[:col]] += 1
end
def turn_right
@orientation = (@orientation + 90) % 360
end
def turn_left
@orientation = (@orientation - 90) % 360
end
def spawn_at(row, col)
- new_row, new_col = row % @rows, col % @cols
- @position = {row: new_row , col: new_col}
- @steps << @position.dup
+ @position = {row: row % @rows , col: col % @cols}
+ @grid[@position[:row]][@position[:col]] += 1
end
def look(orientation)
@orientation = ORIENTATIONS[orientation]
end
def draw(canvas = nil)
self.instance_eval(&Proc.new) if block_given?
- grid = Array.new(@rows) { Array.new(@cols){0} }
- @steps.each { |p| grid[p[:row]][p[:col]] += 1}
- return grid if canvas == nil
- canvas.render(grid)
+
+ return @grid if canvas == nil
+ canvas.render(@grid)
end
end
module Canvas
class ASCII
def initialize(symbols)
@symbols = symbols
@range_step = 1.to_f / (@symbols.length - 1)
end
def render(grid)
- max_visits, output = grid.max_by { |array| array.max }.max, ''
- grid.each do |row|
- output += render_line(row, max_visits)
+ max_visits = grid.max_by { |array| array.max }.max
+
+ output = grid.collect do |row|
+ render_line(row, max_visits)
end
- output.chomp("\n")
+
+ output.join.chomp("\n")
end
private
def render_line(row, max_visits)
- output = ''
- row.each_with_index do |value, index|
- symbol_index = ((value.to_f / max_visits) / @range_step).ceil
- output += @symbols[symbol_index]
+ output = row.collect do |value|
+ symbol_index = ((value.to_f / max_visits) / @range_step).ceil
+ @symbols[symbol_index]
end
- output + "\n"
+ "%s\n" % output.join
end
end
class HTML
LAYOUT = "<!DOCTYPE html>
<html>
<head>
<title>Turtle graphics</title>
<style>
table {
border-spacing: 0;
}
tr {
padding: 0;
}
td {
width: %spx;
height: %spx;
background-color: black;
padding: 0;
}
</style>
</head>
<body>
+ <table>
%s
+ </table>
</body>
</html>"
+
def initialize(pixel_size)
@pixel_size = pixel_size
end
def render(grid)
- max_visits, table = grid.max_by { |array| array.max }.max, '<table>'
- grid.each do |row|
- table += render_line(row, max_visits)
+ max_visits = grid.max_by { |array| array.max }.max
+
+ output = grid.collect do |row|
+ render_line(row, max_visits)
end
- table += '</table>'
- LAYOUT % [@pixel_size, @pixel_size, table]
+
+ LAYOUT % [@pixel_size, @pixel_size, output.join]
end
private
def render_line(row, max_visits)
- output = '<tr>'
- row.each do |value|
- opacity = format('%.2f', value.to_f / max_visits)
- output += "<td style='opacity: #{opacity}'></td>"
+ output = row.collect do |value|
+ opacity = format('%.2f', value.to_f / max_visits)
+ %Q[<td style="opacity: #{opacity}"></td>]
end
- output += '</tr>'
+ "<tr>%s</tr>" % output.join
end
end
end
end