Решение на Шеста задача от Йоан Динков

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

Към профила на Йоан Динков

Резултати

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

Код

module TurtleGraphics
class Turtle
DIRECTIONS = [:up, :right, :down, :left]
def initialize(rows = 0, columns = 0)
@matrix = create_matrix(rows, columns)
@row = 0
@column = 0
@rows = rows
@columns = columns
@direction = :right
@spawned = false
end
def draw(canvas = Canvas::Default.new, &block)
instance_eval(&block)
canvas.process(@matrix)
end
def move
spawn_at(0, 0) unless @spawned
case @direction
when :up then @row -= 1
when :right then @column += 1
when :down then @row += 1
when :left then @column -= 1
end
@row %= @rows
@column %= @columns
step_at(@row, @column)
end
def turn_left
change_direction(:to_left)
end
def turn_right
change_direction(:to_right)
end
def look(direction)
@direction = direction
end
def spawn_at(row, column)
@spawned = true
@row = row
@column = column
step_at(@row, @column)
end
private
def create_matrix(rows, columns)
Array.new(rows) { Array.new(columns, 0) }
end
def step_at(row, column)
@matrix[row][column] += 1
end
def change_direction(direction)
current_direction_index = DIRECTIONS.index(@direction)
if direction == :to_right
current_direction_index += 1
else
current_direction_index -= 1
end
current_direction_index %= DIRECTIONS.length
@direction = DIRECTIONS[current_direction_index]
end
end
module Canvas
class Base
def process(matrix)
matrix
end
private
def to_proportions(matrix)
max_item = matrix.flatten.max
matrix_proportions = matrix.map do |row|
row.map { |element| element / max_item.to_f }
end
matrix_proportions
end
end
class ASCII < Base
def initialize(symbols)
@symbols = symbols
end
def process(matrix)
proportions = to_proportions(matrix)
to_ascii(proportions)
end
private
def to_ascii(matrix)
symbols_matrix = matrix.map do |row|
row_symbols = row.map { |element| ascii_element element }
row_symbols.join
end
symbols_matrix.join("\n")
end
def ascii_element(percent)
steps = @symbols.length
interval = 1.0 / (steps - 1)
percent = percent.round(2)
steps.times do |step|
return @symbols[step] if percent <= (interval * step).round(2)
end
end
end
class HTML < Base
def initialize(pixel_size)
@pixel_size = pixel_size
end
def process(matrix)
proportions = to_proportions(matrix)
to_html(proportions)
end
private
def to_html(matrix)
"<!DOCTYPE html><html><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><body><table>#{generate_table_html(matrix)}</table></body>
</html>"
end
def generate_table_html(matrix)
rows_html = matrix.map do |row|
"<tr>#{generate_table_data_html(row)}</tr>"
end
rows_html.join
end
def generate_table_data_html(proportions)
proportions_html = proportions.map do |proportion|
"<td style=\"opacity: #{format('%.2f', proportion)}\"></td>"
end
proportions_html.join
end
end
class Default < Base
end
end
end

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

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

Finished in 0.01191 seconds
14 examples, 0 failures

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

Йоан обнови решението на 24.11.2015 15:18 (преди около 9 години)

+module TurtleGraphics
+ class Turtle
+ DIRECTIONS = [:up, :right, :down, :left]
+
+ def initialize(rows = 0, columns = 0)
+ @matrix = create_matrix(rows, columns)
+ @row = 0
+ @column = 0
+ @rows = rows
+ @columns = columns
+ @direction = :right
+ @spawned = false
+ end
+
+ def draw(canvas = Canvas::Default.new, &block)
+ instance_eval(&block)
+
+ canvas.process(@matrix)
+ end
+
+ def move
+ spawn_at(0, 0) unless @spawned
+
+ case @direction
+ when :up then @row -= 1
+ when :right then @column += 1
+ when :down then @row += 1
+ when :left then @column -= 1
+ end
+
+ @row %= @rows
+ @column %= @columns
+
+ step_at(@row, @column)
+ end
+
+ def turn_left
+ change_direction(:to_left)
+ end
+
+ def turn_right
+ change_direction(:to_right)
+ end
+
+ def look(direction)
+ @direction = direction
+ end
+
+ def spawn_at(row, column)
+ @spawned = true
+
+ @row = row
+ @column = column
+
+ step_at(@row, @column)
+ end
+
+ private
+
+ def create_matrix(rows, columns)
+ Array.new(rows) { Array.new(columns, 0) }
+ end
+
+ def step_at(row, column)
+ @matrix[row][column] += 1
+ end
+
+ def change_direction(direction)
+ current_direction_index = DIRECTIONS.index(@direction)
+
+ if direction == :to_right
+ current_direction_index += 1
+ else
+ current_direction_index -= 1
+ end
+
+ current_direction_index %= DIRECTIONS.length
+
+ @direction = DIRECTIONS[current_direction_index]
+ end
+ end
+
+ module Canvas
+ class Base
+ def process(matrix)
+ matrix
+ end
+
+ private
+
+ def to_proportions(matrix)
+ max_item = matrix.flatten.max
+
+ matrix_proportions = matrix.map do |row|
+ row.map { |element| element / max_item.to_f }
+ end
+
+ matrix_proportions
+ end
+ end
+
+ class ASCII < Base
+ def initialize(symbols)
+ @lowest_symbol = symbols[0]
+ @low_symbol = symbols[1]
+ @high_symbol = symbols[2]
+ @highest_symbol = symbols[3]
+ end
+
+ def process(matrix)
+ proportions = to_proportions(matrix)
+
+ to_ascii(proportions)
+ end
+
+ private
+
+ def to_ascii(matrix)
+ symbols_matrix = matrix.map do |row|
+ row_symbols = row.map { |element| ascii_element element }
+ row_symbols.join
+ end
+
+ symbols_matrix.join("\n")
+ end
+
+ def ascii_element(percent)
+ percent = percent.round(2)
+
+ case
+ when percent == 0 then @lowest_symbol
+ when percent <= 0.34 then @low_symbol
+ when percent <= 0.67 then @high_symbol
+ when percent <= 1 then @highest_symbol
+ end
+ end
+ end
+
+ class HTML < Base
+ def initialize(pixel_size)
+ @pixel_size = pixel_size
+ end
+
+ def process(matrix)
+ proportions = to_proportions(matrix)
+
+ to_html(proportions)
+ end
+
+ private
+
+ def to_html(matrix)
+ "<!DOCTYPE html><html><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><body><table>#{generate_table_html(matrix)}</table></body>
+ </html>"
+ end
+
+ def generate_table_html(matrix)
+ rows_html = matrix.map do |row|
+ "<tr>#{generate_table_data_html(row)}</tr>"
+ end
+
+ rows_html.join
+ end
+
+ def generate_table_data_html(proportions)
+ proportions_html = proportions.map do |proportion|
+ "<td style=\"opacity: #{format('%.2f', proportion)}\"></td>"
+ end
+
+ proportions_html.join
+ end
+ end
+
+ class Default < Base
+ end
+ end
+end

Изглежда доста добре :)

ASCII, обаче, може да приема произволен брой символи. Както си го направил в момента, не поддържаш брой, различен от четири.

Също, не съм сигурен, че правилното място за to_proportions е в базовия клас. Не всеки наследник го интересува.

Йоан обнови решението на 26.11.2015 11:50 (преди около 9 години)

module TurtleGraphics
class Turtle
DIRECTIONS = [:up, :right, :down, :left]
def initialize(rows = 0, columns = 0)
@matrix = create_matrix(rows, columns)
@row = 0
@column = 0
@rows = rows
@columns = columns
@direction = :right
@spawned = false
end
def draw(canvas = Canvas::Default.new, &block)
instance_eval(&block)
canvas.process(@matrix)
end
def move
spawn_at(0, 0) unless @spawned
case @direction
when :up then @row -= 1
when :right then @column += 1
when :down then @row += 1
when :left then @column -= 1
end
@row %= @rows
@column %= @columns
step_at(@row, @column)
end
def turn_left
change_direction(:to_left)
end
def turn_right
change_direction(:to_right)
end
def look(direction)
@direction = direction
end
def spawn_at(row, column)
@spawned = true
@row = row
@column = column
step_at(@row, @column)
end
private
def create_matrix(rows, columns)
Array.new(rows) { Array.new(columns, 0) }
end
def step_at(row, column)
@matrix[row][column] += 1
end
def change_direction(direction)
current_direction_index = DIRECTIONS.index(@direction)
if direction == :to_right
current_direction_index += 1
else
current_direction_index -= 1
end
current_direction_index %= DIRECTIONS.length
@direction = DIRECTIONS[current_direction_index]
end
end
module Canvas
class Base
def process(matrix)
matrix
end
private
def to_proportions(matrix)
max_item = matrix.flatten.max
matrix_proportions = matrix.map do |row|
row.map { |element| element / max_item.to_f }
end
matrix_proportions
end
end
class ASCII < Base
def initialize(symbols)
- @lowest_symbol = symbols[0]
- @low_symbol = symbols[1]
- @high_symbol = symbols[2]
- @highest_symbol = symbols[3]
+ @symbols = symbols
end
def process(matrix)
proportions = to_proportions(matrix)
to_ascii(proportions)
end
private
def to_ascii(matrix)
symbols_matrix = matrix.map do |row|
row_symbols = row.map { |element| ascii_element element }
row_symbols.join
end
symbols_matrix.join("\n")
end
def ascii_element(percent)
+ steps = @symbols.length
+
+ interval = 1.0 / (steps - 1)
+
percent = percent.round(2)
- case
- when percent == 0 then @lowest_symbol
- when percent <= 0.34 then @low_symbol
- when percent <= 0.67 then @high_symbol
- when percent <= 1 then @highest_symbol
+ steps.times do |step|
+ return @symbols[step] if percent <= (interval * step).round(2)
end
end
end
class HTML < Base
def initialize(pixel_size)
@pixel_size = pixel_size
end
def process(matrix)
proportions = to_proportions(matrix)
to_html(proportions)
end
private
def to_html(matrix)
"<!DOCTYPE html><html><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>
+ table{border-spacing:0;}tr{padding:0;}td{width:#{@pixel_size}px;
+ height:#{@pixel_size}px;background-color:black;padding:0;}</style>
</head><body><table>#{generate_table_html(matrix)}</table></body>
</html>"
end
def generate_table_html(matrix)
rows_html = matrix.map do |row|
"<tr>#{generate_table_data_html(row)}</tr>"
end
rows_html.join
end
def generate_table_data_html(proportions)
proportions_html = proportions.map do |proportion|
"<td style=\"opacity: #{format('%.2f', proportion)}\"></td>"
end
proportions_html.join
end
end
class Default < Base
end
end
end

Здравей, исках да попитам за "минифицираната" версия на html-a, във примера, който е даден всеки таг е на отделен ред, а аз съм го минифицирал да не заема място, обаче ако ги сравняваме като текст са два напълно различни варианта? Трябва ли да се съобразявам с това?