Решение на Шеста задача от Бойко Караджов

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

Към профила на Бойко Караджов

Резултати

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

Код

module TurtleGraphics
class Turtle
def initialize(height, width)
@width, @height = width, height
@board = Array.new(height) { Array.new(width, 0) }
@position = @orientation = nil
@directions = {
left: Complex(-1, 0),
up: Complex(0, -1),
right: Complex(1, 0),
down: Complex(0, 1)
}
end
def draw(canvas = nil, &block)
self.instance_eval &block
if canvas.nil?
@board
else
canvas.print(@board)
end
end
private
def ensure_spawn
spawn_at(0, 0) if @position.nil?
@orientation = @directions[:right] if @orientation.nil?
end
def move
ensure_spawn
delta_x, delta_y = @orientation.real, @orientation.imag
@position = [(@position[0] + delta_y) % @height,
(@position[1] + delta_x) % @width]
@board[@position[0]][@position[1]] += 1
end
def spawn_at(row, column)
@position = [row, column]
y, x = @position
@board[y][x] = 1
end
def turn_right
ensure_spawn
@orientation *= @directions[:down]
end
def turn_left
ensure_spawn
@orientation *= @directions[:up]
end
def look(orientation)
@orientation = @directions[orientation]
end
end
module Canvas
def self.normalize(board)
max = board.flatten.max
max = 1 if max == 0
board.map { |row| row.map { |x| x / max.to_f } }
end
class ASCII
def initialize(characters)
@characters = characters
@range_size = 1 / @characters.size.to_f
end
def print(board)
normalized_board = TurtleGraphics::Canvas::normalize board
output = ""
normalized_board.each do |row|
output << row.map { |x| correspondig_character x }.join << "\n"
end
output
end
private
def correspondig_character(intensity)
@characters[(intensity / @range_size).ceil - 1]
end
end
class HTML
def initialize(size)
@size = size
end
def print(board)
normalized_board = TurtleGraphics::Canvas::normalize board
rows = normalized_board.map { |row| html_row row }.join("\n")
%Q(<!DOCTYPE html>
<html>
<head>
<title>Turtle graphics</title>
<style>
table {
border-spacing: 0;
}
tr {
padding: 0;
}
td {
width: #{@size}px;
height: #{@size}px;
background-color: black;
padding: 0;
}
</style>
</head>
<body>
<table>
#{rows}
</table>
</body>
</html>)
end
private
def html_row(row)
pixels = row.map { |intensity| html_pixel intensity }.join("\n")
"<tr>\n#{pixels}\n</tr>"
end
def html_pixel(intensity)
"<td style=\"opacity: #{format('%.2f', intensity)}\"></td>\n"
end
end
end
end

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

.........FF...

Failures:

  1) TurtleGraphics Canvas::ASCII renders the proper symbols depending on the intensity
     Failure/Error: expect(ascii.sub(/\n\z/, '')).to eq [
       
       expected: "320\n110\n000"
            got: "323\n113\n333"
       
       (compared using ==)
       
       Diff:
       @@ -1,4 +1,4 @@
       -320
       -110
       -000
       +323
       +113
       +333
     # /tmp/d20151203-5272-ey5mgh/spec.rb:128: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::ASCII can render with a different number of symbols
     Failure/Error: expect(ascii.sub(/\n\z/, '')).to eq [
       
       expected: "ttz\nooz\nzzz"
            got: "tot\nzzt\nttt"
       
       (compared using ==)
       
       Diff:
       @@ -1,4 +1,4 @@
       -ttz
       -ooz
       -zzz
       +tot
       +zzt
       +ttt
     # /tmp/d20151203-5272-ey5mgh/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.01286 seconds
14 examples, 2 failures

Failed examples:

rspec /tmp/d20151203-5272-ey5mgh/spec.rb:112 # TurtleGraphics Canvas::ASCII renders the proper symbols depending on the intensity
rspec /tmp/d20151203-5272-ey5mgh/spec.rb:135 # TurtleGraphics Canvas::ASCII can render with a different number of symbols

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

Бойко обнови решението на 28.11.2015 20:45 (преди над 8 години)

+module TurtleGraphics
+ class Turtle
+ def initialize(height, width)
+ @width, @height = width, height
+ @board = Array.new(height) { Array.new(width, 0) }
+ @position = nil
+ @orientation = nil
+ end
+
+ def draw(canvas = nil, &block)
+ self.instance_eval &block
+
+ if canvas.nil?
+ @board
+ else
+ canvas.print(@board)
+ end
+ end
+
+ private
+
+ def ensure_spawn
+ spawn_at(0, 0) if @position.nil?
+ @orientation = Complex(0, 1) if @orientation.nil?
+ end
+
+ def move
+ ensure_spawn
+ delta_y, delta_x = @orientation.real, @orientation.imag
+ @position = [@position[0] + delta_y, @position[1] + delta_x]
+ @board[@position[0]][@position[1]] += 1
+ end
+
+ def spawn_at(row, column)
+ @position = [row, column]
+ y, x = @position
+ @board[y][x] = 1
+ end
+
+ def turn_right
+ ensure_spawn
+ @orientation *= Complex(0, -1)
+ end
+
+ def turn_left
+ ensure_spawn
+ @orientation *= Complex(0, 1)
+ end
+
+ def look(orientation)
+ @orientation = case orientation
+ when :left
+ Complex(0, 1)
+ when :up
+ Complex(-1, 0)
+ when :right
+ Complex(0, -1)
+ when :down
+ Complex(1, 0)
+ end
+ end
+ end
+
+ module Canvas
+ def self.normalize(board)
+ max = board.flatten.max
+ max = 1 if max == 0
+ board.map { |row| row.map { |x| x / max.to_f } }
+ end
+
+ class ASCII
+ def initialize(characters)
+ @characters = characters
+ range_size = 1 / (characters.length - 1).to_f
+ @ranges = Array.new(characters.length) { |i|
+ (((i - 1) * range_size).next_float.. i * range_size)
+ }
+
+ @ranges[0] = (0.. 0) if characters.length > 0
+ end
+
+ def print(board)
+ normalized_board = TurtleGraphics::Canvas::normalize board
+ output = ""
+
+ normalized_board.each { |row|
+ output << row.map { |x| correspondig_character x }.join << "\n"
+ }
+
+ output
+ end
+
+ private
+
+ def correspondig_character(intensity)
+ @characters[@ranges.find_index { |r| r.cover? intensity }]
+ end
+ end
+
+ class HTML
+ def initialize(size)
+ @size = size
+ end
+
+ def print(board)
+ normalized_board = TurtleGraphics::Canvas::normalize board
+ rows = normalized_board.map { |row| html_row row }.join("\n")
+ %Q(<!DOCTYPE html>
+<html>
+<head>
+ <title>Turtle graphics</title>
+
+ <style>
+ table {
+ border-spacing: 0;
+ }
+
+ tr {
+ padding: 0;
+ }
+
+ td {
+ width: #{@size}px;
+ height: #{@size}px;
+
+ background-color: black;
+ padding: 0;
+ }
+ </style>
+</head>
+<body>
+ <table>
+ #{rows}
+ </table>
+</body>
+</html>)
+ end
+
+ private
+
+ def html_row(row)
+ pixels = row.map { |intensity| html_pixel intensity }.join("\n")
+ "<tr>\n#{pixels}\n</tr>"
+ end
+
+ def html_pixel(intensity)
+ "<td style=\"opacity: #{format('%.2f', intensity)}\"></td>\n"
+ end
+ end
+ end
+end

Бойко обнови решението на 28.11.2015 21:07 (преди над 8 години)

module TurtleGraphics
class Turtle
def initialize(height, width)
@width, @height = width, height
@board = Array.new(height) { Array.new(width, 0) }
@position = nil
@orientation = nil
end
def draw(canvas = nil, &block)
self.instance_eval &block
if canvas.nil?
@board
else
canvas.print(@board)
end
end
private
def ensure_spawn
spawn_at(0, 0) if @position.nil?
@orientation = Complex(0, 1) if @orientation.nil?
end
def move
ensure_spawn
delta_y, delta_x = @orientation.real, @orientation.imag
- @position = [@position[0] + delta_y, @position[1] + delta_x]
+ @position = [(@position[0] + delta_y) % @height,
+ (@position[1] + delta_x) % @width]
@board[@position[0]][@position[1]] += 1
end
def spawn_at(row, column)
@position = [row, column]
y, x = @position
@board[y][x] = 1
end
def turn_right
ensure_spawn
@orientation *= Complex(0, -1)
end
def turn_left
ensure_spawn
@orientation *= Complex(0, 1)
end
def look(orientation)
@orientation = case orientation
when :left
- Complex(0, 1)
+ Complex(0, -1)
when :up
Complex(-1, 0)
when :right
- Complex(0, -1)
+ Complex(0, 1)
when :down
Complex(1, 0)
end
end
end
module Canvas
def self.normalize(board)
max = board.flatten.max
max = 1 if max == 0
board.map { |row| row.map { |x| x / max.to_f } }
end
class ASCII
def initialize(characters)
@characters = characters
range_size = 1 / (characters.length - 1).to_f
@ranges = Array.new(characters.length) { |i|
(((i - 1) * range_size).next_float.. i * range_size)
}
@ranges[0] = (0.. 0) if characters.length > 0
end
def print(board)
normalized_board = TurtleGraphics::Canvas::normalize board
output = ""
normalized_board.each { |row|
output << row.map { |x| correspondig_character x }.join << "\n"
}
output
end
private
def correspondig_character(intensity)
@characters[@ranges.find_index { |r| r.cover? intensity }]
end
end
class HTML
def initialize(size)
@size = size
end
def print(board)
normalized_board = TurtleGraphics::Canvas::normalize board
rows = normalized_board.map { |row| html_row row }.join("\n")
%Q(<!DOCTYPE html>
<html>
<head>
<title>Turtle graphics</title>
<style>
table {
border-spacing: 0;
}
tr {
padding: 0;
}
td {
width: #{@size}px;
height: #{@size}px;
background-color: black;
padding: 0;
}
</style>
</head>
<body>
<table>
#{rows}
</table>
</body>
</html>)
end
private
def html_row(row)
pixels = row.map { |intensity| html_pixel intensity }.join("\n")
"<tr>\n#{pixels}\n</tr>"
end
def html_pixel(intensity)
"<td style=\"opacity: #{format('%.2f', intensity)}\"></td>\n"
end
end
end
end

Здравей!

  • Имаш стилови проблеми - многоредовите блокове не се пишат с този синтаксис.
  • Това е лошо използване на Complex. Ако ти трябва подобен клас си напиши собствен. :) Complex не е създаден за тази цел.
  • Избирането на подходящ символ в ASCII може да стане доста по-чисто с използване на малко математика. Помисли как да превърнеш интензитет в индекс от масива със символите. :)

Бойко обнови решението на 30.11.2015 21:46 (преди над 8 години)

module TurtleGraphics
class Turtle
def initialize(height, width)
@width, @height = width, height
@board = Array.new(height) { Array.new(width, 0) }
@position = nil
@orientation = nil
end
def draw(canvas = nil, &block)
self.instance_eval &block
if canvas.nil?
@board
else
canvas.print(@board)
end
end
private
def ensure_spawn
spawn_at(0, 0) if @position.nil?
@orientation = Complex(0, 1) if @orientation.nil?
end
def move
ensure_spawn
delta_y, delta_x = @orientation.real, @orientation.imag
@position = [(@position[0] + delta_y) % @height,
(@position[1] + delta_x) % @width]
@board[@position[0]][@position[1]] += 1
end
def spawn_at(row, column)
@position = [row, column]
y, x = @position
@board[y][x] = 1
end
def turn_right
ensure_spawn
@orientation *= Complex(0, -1)
end
def turn_left
ensure_spawn
@orientation *= Complex(0, 1)
end
def look(orientation)
@orientation = case orientation
when :left
Complex(0, -1)
when :up
Complex(-1, 0)
when :right
Complex(0, 1)
when :down
Complex(1, 0)
end
end
end
module Canvas
def self.normalize(board)
max = board.flatten.max
max = 1 if max == 0
board.map { |row| row.map { |x| x / max.to_f } }
end
class ASCII
def initialize(characters)
@characters = characters
- range_size = 1 / (characters.length - 1).to_f
- @ranges = Array.new(characters.length) { |i|
- (((i - 1) * range_size).next_float.. i * range_size)
- }
-
- @ranges[0] = (0.. 0) if characters.length > 0
+ @range_size = 1 / @characters.size.to_f
end
def print(board)
normalized_board = TurtleGraphics::Canvas::normalize board
output = ""
- normalized_board.each { |row|
+ normalized_board.each do |row|
output << row.map { |x| correspondig_character x }.join << "\n"
- }
+ end
output
end
private
def correspondig_character(intensity)
- @characters[@ranges.find_index { |r| r.cover? intensity }]
+ @characters[(intensity / @range_size).ceil - 1]
end
end
class HTML
def initialize(size)
@size = size
end
def print(board)
normalized_board = TurtleGraphics::Canvas::normalize board
rows = normalized_board.map { |row| html_row row }.join("\n")
%Q(<!DOCTYPE html>
<html>
<head>
<title>Turtle graphics</title>
<style>
table {
border-spacing: 0;
}
tr {
padding: 0;
}
td {
width: #{@size}px;
height: #{@size}px;
background-color: black;
padding: 0;
}
</style>
</head>
<body>
<table>
#{rows}
</table>
</body>
</html>)
end
private
def html_row(row)
pixels = row.map { |intensity| html_pixel intensity }.join("\n")
"<tr>\n#{pixels}\n</tr>"
end
def html_pixel(intensity)
"<td style=\"opacity: #{format('%.2f', intensity)}\"></td>\n"
end
end
end
end

Здравей,

Благодаря за коментарите! Мисля че оправих многоредовите блокове и намирането на правилен индекс за ASCII.

За Complex, така го харесвам. Според мен комплексните числа много добре изразяват посока и ротацията се получава естествено с умножение. Може би би било семантично подобрение ако го заменя с 2-мерен вектор, но Complex ми се вижда по-интуитивно.

Поздрави,

Бойко

Не разбирам как би било по-интуитивно. :) Може ли да опишеш защо ти се струва по-интуитивно от двумерен вектор?

Ето моите доводи:

  • Complex прави кода по-трудно четим, защото предполага познаване на особеностите на комплексните числа.
  • Никак не е очевидно, че @orientation *= Complex(0, -1) ще завърти нещото в правилната посока. Освен ако не си учил комплексни числа миналата седмица.
  • Не използваш класа по предназначение. Стандартното представяне на точка в равнина е чрез вектор, не чрез комплексно число. Това качва коефициента на WTF-та в минута. :) В този случай почти използваш Complex като вектор.

Като цяло, идеята не е да измислим най-хитрия начин да направим нещо с възможно най-малко символи, а да го направим лесно четим и ясен.

Съгласен съм, че семантично "вектор" е геометричния термин, а комплексното число може да се разглежда като вектор. Не мога да намеря дефиниция на комплексно число без да има геометричен смисъл описан редом до аритметичния и те всички имат картинка на вектор. Ето няколко причини поради които предпочитам да използвам точно комплексни числа, а не вектор:

  • Комплексното число си е точно двумерен вектор с числа, а "вектор" само по себе си е по-широкото понятие от линейната алгебра.

  • Разгледах вградения Vector в Ruby и идва доста по-мощен от комплексно число, идва от модул Matrix и в крайна сметка се гледа като ред или колона от матрица. Не ми дава да умножа 2 вектора без да транспонирам единия.

  • Да си напиша мой вектор, който просто дублира комплексните числа ми се вижда странно. Един такъв потенциален клас ако трябва да скрие алгебрата то ще има вътре двата метода, които ни трябват - rotate_right и rotate_left и пак ще трябва да се напише това умножение вътре. В костенурката това същото е точно по един ред в метод със сответното име. От името е очевидно какво се очаква да прави.

Tова качва коефициента на WTF-та в минута. този смисъл на умножението не ми е познат, но пак - защо да дискриминираме геометричния смисъл в полза на този или който и да е? Числата са абстрактни понятия. Все едно да спрем да ползваме реалните числа за дължина, защото вече ги ползваме за скорост.

Можеш да ми проследиш мисълта: тръгнах от case с 4 случая. Като си го прочетох се засрамих. Това с умножението на комплексно число е първото, което ми дойде на ум в контекста на аналитична геометрия. За това смятам, че е интуитивно, но разбира се, съдя само по себе си. Разбирам, че така се добавя тежестта на линейната алгебра върху читателя, но в контекста на геометрията е човешко да се очаква, че ако на някой не му е ясно какво прави умножението ще си провери в wikipedia. Не съм учил тези неща миналата седмица и не уцелих от първия път точно по кой вектор трябва да умножа за правилната посока, но не ми беше зле да си припомня.

Съжалявам, че излезе толкова дълго, но ме провокира да се аргументирам :) . Правя го в името на добрата дискусия. Ако кажеш - спирам да се обяснявам и го сменям на... нещо. Не знам наистина какво се очаква да смени това умножение. Сигурно ще е някакъв малък вектор, който вместо да се умножава ще се ротира.

Няма за какво да съжаляваш. Точно това исках - да стане дискусия :) Не искам да го смениш против волята си, без да си съгласен с промяната - това би било безсмислено и излишно.

Продължавам дискусията:

Един такъв потенциален клас ако трябва да скрие алгебрата то ще има вътре 
двата метода, които ни трябват - rotate_right и rotate_left и пак ще трябва да се 
напише това умножение вътре. В костенурката това същото е точно по един ред в 
метод със сответното име. От името е очевидно какво се очаква да прави.

Именно :) Защо изобщо ти трябва клас тогава?

Разбирам, че в някакъв математически смисъл, комплексните числа представят точка в двумерно пространство. Твърдя, че използването му в този смисъл не е добра идея в този код. Ако не можеше да използваш този трик със завъртането би ли използвал пак Complex?

За да бъде един софтуер лесен за промяна, разширяемост и поддръжка, той на първо място трябва да е лесен за разбиране. Не мисля, че един код, използващ Complex, за да замести две променливи е постигнал максимална яснота:

Разбирам, че така се добавя тежестта на линейната алгебра върху читателя, 
но в контекста на геометрията е човешко да се очаква, че ако на някой не му 
е ясно какво прави умножението ще си провери в wikipedia.
Не съм учил тези неща миналата седмица и не уцелих от първия път точно 
по кой вектор трябва да умножа за правилната посока

Ето го проблема. Значи, за да разбера едно парче код в потенциално огромен проект, аз трябва да използвам Wikipedia. Вместо да прочета още два реда и да разбера веднага какво прави. :)
Сега си представи проект с десетки файлове и за да разбереш всеки трябва за всеки да потърсиш различно нещо в Wikipedia. Ако ти беше четящият щеше ли да си доволен от използването на Complex, или щеше да предпочиташ по-простата имплементация? :) Разбира се, не говоря за проект, който се занимава конкретно с математика и комплексни числа - тогава Complex е очаквано нещо и читателят се очаква да знае или да научи това. За всеки друг проект, Complex е далече от контекста.

тръгнах от case с 4 случая. Като си го прочетох се засрамих.

Първо, един прост case не е толкова лош. Аз лично бих го предпочел, ако избора беше само case или Complex. Отново, заради яснотата на четене. В случая, обаче, има вариант просто да си създадеш един масив [:left, :up, :right, :down] и да се местиш наляво или надясно в него. Елиминираш и другия case.

@orientation = case orientation
  when :left
    Complex(0, -1)
  when :up
    Complex(-1, 0)
  when :right
    Complex(0, 1)
  when :down
    Complex(1, 0)
end

Този case е по-голям повод за засрамване :) Най-малкото защото поражда въпроси от рода на "Защо се използва реалната част за y, а не за x координатата?".
Не се засрамвай от простите неща. Ако си успял да постигнеш необходимата функционалност с максимално очевидни и интуитивни средства, значи си си свършил страхотно работата. :)
По-скоро обърни нещата - стреми се да го правиш по-просто, не по-сложно. Яснотата е най-важният признак за качеството на един код. Дори не винаги по-простото решение е по-дълго като редове. Нашето решение е точно толкова реда, колкото и твоето, и не използва Complex. Като свърши срока може да разгледаш и него :)

Много е полезно да се поставиш на мястото на човек, който няма никаква представа от кода и трябва да го разбере, за да оправи бъг. Колко време ще му отнеме? Трябва ли да се допитва до Wikipedia? Все въпроси, които са важни.

Бойко обнови решението на 02.12.2015 00:37 (преди над 8 години)

module TurtleGraphics
class Turtle
def initialize(height, width)
@width, @height = width, height
@board = Array.new(height) { Array.new(width, 0) }
- @position = nil
- @orientation = nil
+ @position = @orientation = nil
+ @directions = {
+ left: Complex(-1, 0),
+ up: Complex(0, -1),
+ right: Complex(1, 0),
+ down: Complex(0, 1)
+ }
end
def draw(canvas = nil, &block)
self.instance_eval &block
if canvas.nil?
@board
else
canvas.print(@board)
end
end
private
def ensure_spawn
spawn_at(0, 0) if @position.nil?
- @orientation = Complex(0, 1) if @orientation.nil?
+ @orientation = @directions[:right] if @orientation.nil?
end
def move
ensure_spawn
- delta_y, delta_x = @orientation.real, @orientation.imag
+ delta_x, delta_y = @orientation.real, @orientation.imag
@position = [(@position[0] + delta_y) % @height,
(@position[1] + delta_x) % @width]
@board[@position[0]][@position[1]] += 1
end
def spawn_at(row, column)
@position = [row, column]
y, x = @position
@board[y][x] = 1
end
def turn_right
ensure_spawn
- @orientation *= Complex(0, -1)
+ @orientation *= @directions[:down]
end
def turn_left
ensure_spawn
- @orientation *= Complex(0, 1)
+ @orientation *= @directions[:up]
end
def look(orientation)
- @orientation = case orientation
- when :left
- Complex(0, -1)
- when :up
- Complex(-1, 0)
- when :right
- Complex(0, 1)
- when :down
- Complex(1, 0)
- end
+ @orientation = @directions[orientation]
end
end
module Canvas
def self.normalize(board)
max = board.flatten.max
max = 1 if max == 0
board.map { |row| row.map { |x| x / max.to_f } }
end
class ASCII
def initialize(characters)
@characters = characters
@range_size = 1 / @characters.size.to_f
end
def print(board)
normalized_board = TurtleGraphics::Canvas::normalize board
output = ""
normalized_board.each do |row|
output << row.map { |x| correspondig_character x }.join << "\n"
end
output
end
private
def correspondig_character(intensity)
@characters[(intensity / @range_size).ceil - 1]
end
end
class HTML
def initialize(size)
@size = size
end
def print(board)
normalized_board = TurtleGraphics::Canvas::normalize board
rows = normalized_board.map { |row| html_row row }.join("\n")
%Q(<!DOCTYPE html>
<html>
<head>
<title>Turtle graphics</title>
<style>
table {
border-spacing: 0;
}
tr {
padding: 0;
}
td {
width: #{@size}px;
height: #{@size}px;
background-color: black;
padding: 0;
}
</style>
</head>
<body>
<table>
#{rows}
</table>
</body>
</html>)
end
private
def html_row(row)
pixels = row.map { |intensity| html_pixel intensity }.join("\n")
"<tr>\n#{pixels}\n</tr>"
end
def html_pixel(intensity)
"<td style=\"opacity: #{format('%.2f', intensity)}\"></td>\n"
end
end
end
end

Последен аргумент за Complex: "Утре" ако някой каже, че стъпката, ще е с по 10 градуса примерно от тази имплементация ще стане по-лесна промяната.

Пооправих нещата като кръстих комплексните числа със символи и ползвам реалната част за X, а имагинерната за Y. Искаше ми се да ги инициализирам с ъгъл за да е по-ясно какво става: Complex.polar(1, Math::PI/2), но така се получават неточни числа: не е точно [0, 1], примерно, а е някакво много близко число... сигурно заради загубите от floating point operations. Това не може да се ползва като работим с цели числа, а излиза някакво излишно да ги round-вам в последствие.

След това упражнение (.с polar) стана ясно, че за задачата масивче от посоките с да бягане по индексите си е доста прилично решение на задачата, но вече ми е късно да променям. Ще разглеждам поне вашето решение после.