Решение на Осма задача от Кузман Белев

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

Към профила на Кузман Белев

Резултати

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

Код

module Excel
NUMBER = /\A[0-9]+\z/
CELL = "[A-Z]+[0-9]+"
ROWS = ("A"..."ZZZ").to_a
OPERATIONS = {
:ADD => "+",
:SUBTRACT => "-",
:MULTIPLY => "*",
# :DIVIDE => "/",
:MOD => "%"
} # беше със символи, но Skeptic реве, че няма шпация след *
PARENTHESIS = /\((\w|\W)+\)/
def delete_empty_cells(spreadsheet)
spreadsheet.select { |cell| cell.value != ""}
end
def get_cell(cell_index)
data.find { |cell| cell.cell_id == cell_index }
end
def return_parameters(cell_index)
cell_at(cell_index).match(PARENTHESIS).to_s[1..-2].split(",").map do |item|
item.strip
end
end
def is_equation?(value)
value.start_with?("=")
end
def return_cell(cell_index)
self[cell_at(cell_index).match(/#{CELL}\z/).to_s]
end
def return_number(cell_index)
cell_at(cell_index).match(/[0-9]+/).to_s
end
def cell_array(result, array, column)
array.strip.split(/\t| /).each_with_index do |value, row|
result << Cell.new(value, column + 1, ROWS[row])
end
end
end
class Spreadsheet
include Excel
attr_reader :data
def initialize(tabbed_values = "")
@data = create_cells(tabbed_values)
end
def empty?
data.empty?
end
def cell_at(cell_index)
exception_thrower(cell_index)
get_cell(cell_index).value
end
def [](cell_index)
return cell_index if cell_index.match(NUMBER)
exception_thrower(cell_index)
return cell_at(cell_index) if ! cell_at(cell_index).start_with?("=")
return return_number(cell_index) if get_cell(cell_index).equals_number?
return return_cell(cell_index) if get_cell(cell_index).equals_cell?
calculate(get_cell(cell_index).operation, return_parameters(cell_index))
end
def to_s #някакъв map може би ще е по-смислен
result = self[data.first.cell_id].to_s
data.each_cons(2) do |first_cell, second_cell|
if first_cell.column == second_cell.column
result += "\t" + self[second_cell.cell_id].to_s
else
result += "\n" + self[second_cell.cell_id].to_s
end
end
result
end
private
def create_cells(tabbed_values)
result = []
tabbed_values.strip.split(/\n/).each_slice(1).with_index do |item, column|
cell_array(result, item[0], column)
end #da razkaram slice?
delete_empty_cells(result)
end
def calculate(operation, parameters)
if operation.to_s == "DIVIDE" # Skeptic again :)
result = self[parameters[0]].to_f / self[parameters[1]].to_f
else
result = (parameters.map do |item|
self[item].to_f
end.reduce(OPERATIONS[operation].to_sym))
end
result.to_i == result ? result.to_i.to_s : result.to_f.round(2).to_s
end
def exception_thrower(cell_index)
if ! cell_index.match(/\A#{CELL}\z/)
raise Error.new("Invalid cell index \'#{cell_index}\'")
elsif get_cell(cell_index) == nil
raise Error.new("Cell \'#{cell_index}\' does not exist")
end
end
end
class Spreadsheet::Error < StandardError
end
class Cell
attr_reader :value, :column, :row, :operation
include Excel
def initialize(value, column, row)
@value = value
@column = column
@row = row
@operation = check_operation
end
def cell_id
row + column.to_s
end
def equals_cell?
value.match(/\A=#{CELL}\z/) != nil
end
def equals_number?
value.match(/\A=[0-9]+\z/) != nil
end
private
def check_operation
is_equation?(value) ? value[1..-1].match(/\w+/).to_s.to_sym : nil
end
end

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

....F...FF........F...F..F..F..FFFFF.F.F

Failures:

  1) Spreadsheet#to_s returns blank tables as blank strings
     Failure/Error: expect(Spreadsheet.new.to_s).to eq ''
     NoMethodError:
       undefined method `cell_id' for nil:NilClass
     # /tmp/d20160121-5693-90hdk8/solution.rb:74:in `to_s'
     # /tmp/d20160121-5693-90hdk8/spec.rb:24: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) Spreadsheet#to_s splits cells by two or more spaces
     Failure/Error: expect(Spreadsheet.new("foo  bar   42\nbaz    larodi  100").to_s).to eq "foo\tbar\t42\nbaz\tlarodi\t100"
       
       expected: "foo\tbar\t42\nbaz\tlarodi\t100"
            got: "foo\tbar\t 42\nbaz\tlarodi\t100"
       
       (compared using ==)
       
       Diff:
       @@ -1,3 +1,3 @@
       -foo	bar	42
       +foo	bar	 42
        baz	larodi	100
     # /tmp/d20160121-5693-90hdk8/spec.rb:40: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) Spreadsheet#to_s returns the evaluated spreadsheet as a table
     Failure/Error: expect(sheet.to_s).to eq \
       
       expected: "foo\t10\t2.1\t15\nbar\t11\t2.2\t5\nbaz\t12\t2.3\t27.60"
            got: "foo\t 10\t2.1\t =ADD(B1, C1, 2.9)\nbar\t 11\t2.2\t =DIVIDE(B2, C2)\nbaz\t 12\t2.3\t =MULTIPLY(C3, B3)"
       
       (compared using ==)
       
       Diff:
       @@ -1,4 +1,4 @@
       -foo	10	2.1	15
       -bar	11	2.2	5
       -baz	12	2.3	27.60
       +foo	 10	2.1	 =ADD(B1, C1, 2.9)
       +bar	 11	2.2	 =DIVIDE(B2, C2)
       +baz	 12	2.3	 =MULTIPLY(C3, B3)
     # /tmp/d20160121-5693-90hdk8/spec.rb:50: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)>'

  4) Spreadsheet#[] raises an exception for less than two arguments passed to ADD
     Failure/Error: expect { Spreadsheet.new('=ADD(1)')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'ADD': expected at least 2, got 1/ but nothing was raised
     # /tmp/d20160121-5693-90hdk8/spec.rb:119: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)>'

  5) Spreadsheet#[] raises an exception for less than two arguments to MULTIPLY
     Failure/Error: expect { Spreadsheet.new('=MULTIPLY(1)')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'MULTIPLY': expected at least 2, got 1/ but nothing was raised
     # /tmp/d20160121-5693-90hdk8/spec.rb:149: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)>'

  6) Spreadsheet#[] raises an exception when SUBTRACT is called with a wrong number of arguments
     Failure/Error: expect { Spreadsheet.new('=SUBTRACT(1)')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'SUBTRACT': expected 2, got 1/ but nothing was raised
     # /tmp/d20160121-5693-90hdk8/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)>'

  7) Spreadsheet#[] raises an exception when DIVIDE is called with a wrong number of arguments
     Failure/Error: expect { Spreadsheet.new('=DIVIDE(1)')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'DIVIDE': expected 2, got 1/, got #<NoMethodError: undefined method `match' for nil:NilClass> with backtrace:
         # /tmp/d20160121-5693-90hdk8/solution.rb:65:in `[]'
         # /tmp/d20160121-5693-90hdk8/solution.rb:97:in `calculate'
         # /tmp/d20160121-5693-90hdk8/solution.rb:70:in `[]'
         # /tmp/d20160121-5693-90hdk8/spec.rb:195:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-90hdk8/spec.rb:195: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)>'
     # /tmp/d20160121-5693-90hdk8/spec.rb:195: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)>'

  8) Spreadsheet#[] raises an exception when MOD is called with a wrong number of arguments
     Failure/Error: expect { Spreadsheet.new('=MOD(1)')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'MOD': expected 2, got 1/ but nothing was raised
     # /tmp/d20160121-5693-90hdk8/spec.rb:219: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)>'

  9) Spreadsheet#[] adds floating point numbers with ADD
     Failure/Error: expect(Spreadsheet.new('10  =ADD(A1, 1.1)')['B1']).to eq '11.10'
     Spreadsheet::Error:
       Invalid cell index '1.1'
     # /tmp/d20160121-5693-90hdk8/solution.rb:108:in `exception_thrower'
     # /tmp/d20160121-5693-90hdk8/solution.rb:66:in `[]'
     # /tmp/d20160121-5693-90hdk8/solution.rb:100:in `block in calculate'
     # /tmp/d20160121-5693-90hdk8/solution.rb:99:in `map'
     # /tmp/d20160121-5693-90hdk8/solution.rb:99:in `calculate'
     # /tmp/d20160121-5693-90hdk8/solution.rb:70:in `[]'
     # /tmp/d20160121-5693-90hdk8/spec.rb:229: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)>'

  10) Spreadsheet#[] subtracts floating point numbers with SUBTRACT
     Failure/Error: expect(Spreadsheet.new('10  =SUBTRACT(A1, 1.1)')['B1']).to eq '8.90'
     Spreadsheet::Error:
       Invalid cell index '1.1'
     # /tmp/d20160121-5693-90hdk8/solution.rb:108:in `exception_thrower'
     # /tmp/d20160121-5693-90hdk8/solution.rb:66:in `[]'
     # /tmp/d20160121-5693-90hdk8/solution.rb:100:in `block in calculate'
     # /tmp/d20160121-5693-90hdk8/solution.rb:99:in `map'
     # /tmp/d20160121-5693-90hdk8/solution.rb:99:in `calculate'
     # /tmp/d20160121-5693-90hdk8/solution.rb:70:in `[]'
     # /tmp/d20160121-5693-90hdk8/spec.rb:234: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)>'

  11) Spreadsheet#[] multiplies floating point numbers with MULTIPLY
     Failure/Error: expect(Spreadsheet.new('10  =MULTIPLY(A1, 1.1)')['B1']).to eq '11'
     Spreadsheet::Error:
       Invalid cell index '1.1'
     # /tmp/d20160121-5693-90hdk8/solution.rb:108:in `exception_thrower'
     # /tmp/d20160121-5693-90hdk8/solution.rb:66:in `[]'
     # /tmp/d20160121-5693-90hdk8/solution.rb:100:in `block in calculate'
     # /tmp/d20160121-5693-90hdk8/solution.rb:99:in `map'
     # /tmp/d20160121-5693-90hdk8/solution.rb:99:in `calculate'
     # /tmp/d20160121-5693-90hdk8/solution.rb:70:in `[]'
     # /tmp/d20160121-5693-90hdk8/spec.rb:239: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)>'

  12) Spreadsheet#[] divides floating point numbers with DIVIDE
     Failure/Error: expect(Spreadsheet.new('10  =DIVIDE(A1, 4)')['B1']).to eq '2.50'
       
       expected: "2.50"
            got: "2.5"
       
       (compared using ==)
     # /tmp/d20160121-5693-90hdk8/spec.rb:244: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)>'

  13) Spreadsheet#[] raises an exception for unknown functions
     Failure/Error: expect { Spreadsheet.new('=FOO(42)  100')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Unknown function 'FOO'/, got #<NoMethodError: undefined method `to_sym' for nil:NilClass> with backtrace:
         # /tmp/d20160121-5693-90hdk8/solution.rb:101:in `calculate'
         # /tmp/d20160121-5693-90hdk8/solution.rb:70:in `[]'
         # /tmp/d20160121-5693-90hdk8/spec.rb:254:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-90hdk8/spec.rb:254: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)>'
     # /tmp/d20160121-5693-90hdk8/spec.rb:254: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)>'

  14) Spreadsheet#[] raises an exception for invalid expressions
     Failure/Error: expect { Spreadsheet.new('=FOO  100')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Invalid expression 'FOO'/, got #<NoMethodError: undefined method `split' for nil:NilClass> with backtrace:
         # /tmp/d20160121-5693-90hdk8/solution.rb:23:in `return_parameters'
         # /tmp/d20160121-5693-90hdk8/solution.rb:70:in `[]'
         # /tmp/d20160121-5693-90hdk8/spec.rb:266:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-90hdk8/spec.rb:266: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)>'
     # /tmp/d20160121-5693-90hdk8/spec.rb:266: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.04167 seconds
40 examples, 14 failures

Failed examples:

rspec /tmp/d20160121-5693-90hdk8/spec.rb:23 # Spreadsheet#to_s returns blank tables as blank strings
rspec /tmp/d20160121-5693-90hdk8/spec.rb:39 # Spreadsheet#to_s splits cells by two or more spaces
rspec /tmp/d20160121-5693-90hdk8/spec.rb:43 # Spreadsheet#to_s returns the evaluated spreadsheet as a table
rspec /tmp/d20160121-5693-90hdk8/spec.rb:118 # Spreadsheet#[] raises an exception for less than two arguments passed to ADD
rspec /tmp/d20160121-5693-90hdk8/spec.rb:148 # Spreadsheet#[] raises an exception for less than two arguments to MULTIPLY
rspec /tmp/d20160121-5693-90hdk8/spec.rb:170 # Spreadsheet#[] raises an exception when SUBTRACT is called with a wrong number of arguments
rspec /tmp/d20160121-5693-90hdk8/spec.rb:194 # Spreadsheet#[] raises an exception when DIVIDE is called with a wrong number of arguments
rspec /tmp/d20160121-5693-90hdk8/spec.rb:218 # Spreadsheet#[] raises an exception when MOD is called with a wrong number of arguments
rspec /tmp/d20160121-5693-90hdk8/spec.rb:228 # Spreadsheet#[] adds floating point numbers with ADD
rspec /tmp/d20160121-5693-90hdk8/spec.rb:233 # Spreadsheet#[] subtracts floating point numbers with SUBTRACT
rspec /tmp/d20160121-5693-90hdk8/spec.rb:238 # Spreadsheet#[] multiplies floating point numbers with MULTIPLY
rspec /tmp/d20160121-5693-90hdk8/spec.rb:243 # Spreadsheet#[] divides floating point numbers with DIVIDE
rspec /tmp/d20160121-5693-90hdk8/spec.rb:253 # Spreadsheet#[] raises an exception for unknown functions
rspec /tmp/d20160121-5693-90hdk8/spec.rb:265 # Spreadsheet#[] raises an exception for invalid expressions

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

Кузман обнови решението на 09.01.2016 23:04 (преди над 8 години)

+module Excel
+ NUMBER = /\A[0-9]+\z/
+ CELL = "[A-Z]+[0-9]+"
+ ROWS = ("A"..."ZZZ").to_a
+ OPS = { "AD" => "+", "SU" => "-", "MU" => "*", "DI" => "/", "MO" => "%" }
+ PARENTHESIS = /\((\w|\W)+\)/
+
+ def delete_empty_cells(spreadsheet)
+ spreadsheet.select { |cell| cell.value != ""}
+ end
+
+ def get_cell(cell_index)
+ data.find { |cell| cell.cell_id == cell_index }
+ end
+
+ def return_parameters(cell_index)
+ cell_at(cell_index).match(PARENTHESIS).to_s[1..-2].split(",").map do |item|
+ item.strip
+ end
+ end
+
+ def is_equation(value)
+ value.start_with?("=") ? true : false
+ end
+
+ def return_cell(cell_index)
+ self[cell_at(cell_index).match(/#{CELL}\z/).to_s]
+ end
+
+ def return_number(cell_index)
+ cell_at(cell_index).match(/[0-9]+/).to_s
+ end
+
+ def decouple_values(result, array, column)
+ array.strip.split(/\t| /).each_with_index do |value, row|
+ result << Cell.new(value, column + 1, ROWS[row])
+ end
+ end
+end
+
+class Spreadsheet
+ include Excel
+ attr_reader :data
+
+ def initialize(tabbed_values = "")
+ @data = create_cells(tabbed_values)
+ end
+
+ def empty?
+ data.empty?
+ end
+
+ def cell_at(cell_index)
+ exception_thrower(cell_index)
+ get_cell(cell_index).value
+ end
+
+ def [](cell_index)
+ return cell_index if cell_index.match(NUMBER)
+ exception_thrower(cell_index)
+ return cell_at(cell_index) if ! cell_at(cell_index).start_with?("=")
+ return return_number(cell_index) if get_cell(cell_index).equals_number?
+ return return_cell(cell_index) if get_cell(cell_index).equals_cell?
+ calculate(get_cell(cell_index).operation, return_parameters(cell_index))
+ end
+
+ def to_s #някакъв map може би ще е по-смислен
+ result = self[data.first.cell_id].to_s
+ data.each_cons(2) do |first_cell, second_cell|
+ if first_cell.column == second_cell.column
+ result += "\t" + self[second_cell.cell_id].to_s
+ else
+ result += "\n" + self[second_cell.cell_id].to_s
+ end
+ end
+ result
+ end
+
+ private
+ def create_cells(tabbed_values)
+ result = []
+ tabbed_values.strip.split(/\n/).each_slice(1).with_index do |item, column|
+ decouple_values(result, item[0], column)
+ end #da razkaram slice?
+ delete_empty_cells(result)
+ end
+
+ def calculate(operation, parameters) # :/ ne e okay!!!
+ parameters.map do |item|
+ self[item].to_i
+ end.reduce(OPS[operation].to_sym).to_s
+ end
+
+ def exception_thrower(cell_index)
+ if ! cell_index.match(/\A#{CELL}\z/)
+ raise Error.new("Invalid cell index \'#{cell_index}\'")
+ elsif get_cell(cell_index) == nil
+ raise Error.new("Cell \'#{cell_index}\' does not exist")
+ end
+ end
+end
+
+class Spreadsheet::Error < StandardError
+attr_reader :message
+
+ def initialize(message)
+ @message = message
+ end
+end
+
+class Cell
+ attr_reader :value, :column, :row, :operation
+ include Excel
+
+ def initialize(value, column, row)
+ @value = value
+ @column = column
+ @row = row
+ @operation = check_operation
+ end
+
+ def cell_id
+ row + column.to_s
+ end
+
+ def equals_cell?
+ value.match(/\A=#{CELL}\z/) != nil ? true : false
+ end
+
+ def equals_number?
+ value.match(/\A=[0-9]+\z/) != nil ? true : false
+ end
+
+ private
+ def check_operation
+ is_equation(value) ? value[1..-1].match(/\w+/).to_s.byteslice(0, 2) : nil
+ end
+end

Малко бележки:

  • Мисля, че може да направиш така, че CELL да е регулярен израз, а не просто низ.
  • ROWS ми изглежда ограничено до ZZZ, но по условие няма такова ограничение. Въпреки това, признавам, че е хитро наблюдение, че range-овете в Ruby поддържат и такава подредба.
  • Аз не бих избрал такъв начин за маркиране на команди - OPS. Моят избор ще е по-експлицитно изреждане, с пълни имена.
  • is_equasion не е Ruby конвенция. Ruby конвенцията трябва да е equasion?.
  • Това е тавтология: foo ? true : false, особено когато foo вече е boolean.
  • decouple_values е странно име. Може да е много по-добро, според мен.
  • Excel можеше да е клас, а не модул, който да изсипеш в друг клас и да раздуеш този друг клас с още отговорности.
  • Имаш проблеми с идентацията на няколко места.
  • Оставяй по един празен ред след private.
  • Не оставяй интервал след унарния !: !foo, а не ! foo.
  • Изключението ти Error няма нужда да дефинира нищо. Всичко си идва наготов от родителя.

Има интересни моменти в решението ти, но има и много неща, които могат да се подобрят. След крайния срок на задачата, прегледай решенията на колегите, както и нашето решение. Скоро ще имаш шанс да направиш подобрение. :)

Кузман обнови решението на 11.01.2016 15:56 (преди над 8 години)

module Excel
NUMBER = /\A[0-9]+\z/
CELL = "[A-Z]+[0-9]+"
ROWS = ("A"..."ZZZ").to_a
- OPS = { "AD" => "+", "SU" => "-", "MU" => "*", "DI" => "/", "MO" => "%" }
+ OPERATIONS = {
+ :ADD => "+",
+ :SUBTRACT => "-",
+ :MULTIPLY => "*",
+# :DIVIDE => :/,
+ :MOD => "%"
+ } # беше със символи, но Skeptic реве, че няма шпация след *
PARENTHESIS = /\((\w|\W)+\)/
def delete_empty_cells(spreadsheet)
spreadsheet.select { |cell| cell.value != ""}
end
def get_cell(cell_index)
data.find { |cell| cell.cell_id == cell_index }
end
def return_parameters(cell_index)
cell_at(cell_index).match(PARENTHESIS).to_s[1..-2].split(",").map do |item|
- item.strip
+ item.strip
end
end
- def is_equation(value)
- value.start_with?("=") ? true : false
+ def is_equation?(value)
+ value.start_with?("=")
end
def return_cell(cell_index)
self[cell_at(cell_index).match(/#{CELL}\z/).to_s]
end
def return_number(cell_index)
cell_at(cell_index).match(/[0-9]+/).to_s
end
- def decouple_values(result, array, column)
+ def cell_array(result, array, column)
array.strip.split(/\t| /).each_with_index do |value, row|
result << Cell.new(value, column + 1, ROWS[row])
end
end
end
class Spreadsheet
include Excel
attr_reader :data
def initialize(tabbed_values = "")
@data = create_cells(tabbed_values)
end
def empty?
data.empty?
end
def cell_at(cell_index)
exception_thrower(cell_index)
get_cell(cell_index).value
end
def [](cell_index)
return cell_index if cell_index.match(NUMBER)
exception_thrower(cell_index)
return cell_at(cell_index) if ! cell_at(cell_index).start_with?("=")
return return_number(cell_index) if get_cell(cell_index).equals_number?
return return_cell(cell_index) if get_cell(cell_index).equals_cell?
calculate(get_cell(cell_index).operation, return_parameters(cell_index))
end
def to_s #някакъв map може би ще е по-смислен
result = self[data.first.cell_id].to_s
data.each_cons(2) do |first_cell, second_cell|
if first_cell.column == second_cell.column
result += "\t" + self[second_cell.cell_id].to_s
else
result += "\n" + self[second_cell.cell_id].to_s
end
end
result
end
private
+
def create_cells(tabbed_values)
result = []
tabbed_values.strip.split(/\n/).each_slice(1).with_index do |item, column|
- decouple_values(result, item[0], column)
+ cell_array(result, item[0], column)
end #da razkaram slice?
delete_empty_cells(result)
end
- def calculate(operation, parameters) # :/ ne e okay!!!
- parameters.map do |item|
- self[item].to_i
- end.reduce(OPS[operation].to_sym).to_s
+ def calculate(operation, parameters)
+ if operation.to_s == "DIVIDE" # Skeptic again :)
+ "%g" % (self[parameters[0]].to_f / self[parameters[1]].to_f.round(2))
+ else
+ parameters.map do |item|
+ self[item].to_i
+ end.reduce(OPERATIONS[operation].to_sym).to_s
+ end
end
def exception_thrower(cell_index)
if ! cell_index.match(/\A#{CELL}\z/)
raise Error.new("Invalid cell index \'#{cell_index}\'")
elsif get_cell(cell_index) == nil
raise Error.new("Cell \'#{cell_index}\' does not exist")
end
end
end
class Spreadsheet::Error < StandardError
-attr_reader :message
-
- def initialize(message)
- @message = message
- end
end
class Cell
attr_reader :value, :column, :row, :operation
include Excel
def initialize(value, column, row)
@value = value
@column = column
@row = row
@operation = check_operation
end
def cell_id
row + column.to_s
end
def equals_cell?
- value.match(/\A=#{CELL}\z/) != nil ? true : false
+ value.match(/\A=#{CELL}\z/) != nil
end
def equals_number?
- value.match(/\A=[0-9]+\z/) != nil ? true : false
+ value.match(/\A=[0-9]+\z/) != nil
end
private
+
def check_operation
- is_equation(value) ? value[1..-1].match(/\w+/).to_s.byteslice(0, 2) : nil
+ is_equation?(value) ? value[1..-1].match(/\w+/).to_s.to_sym : nil
end
end

Кузман обнови решението на 11.01.2016 16:31 (преди над 8 години)

module Excel
NUMBER = /\A[0-9]+\z/
CELL = "[A-Z]+[0-9]+"
ROWS = ("A"..."ZZZ").to_a
OPERATIONS = {
:ADD => "+",
:SUBTRACT => "-",
:MULTIPLY => "*",
# :DIVIDE => :/,
:MOD => "%"
} # беше със символи, но Skeptic реве, че няма шпация след *
PARENTHESIS = /\((\w|\W)+\)/
def delete_empty_cells(spreadsheet)
spreadsheet.select { |cell| cell.value != ""}
end
def get_cell(cell_index)
data.find { |cell| cell.cell_id == cell_index }
end
def return_parameters(cell_index)
cell_at(cell_index).match(PARENTHESIS).to_s[1..-2].split(",").map do |item|
item.strip
end
end
def is_equation?(value)
value.start_with?("=")
end
def return_cell(cell_index)
self[cell_at(cell_index).match(/#{CELL}\z/).to_s]
end
def return_number(cell_index)
cell_at(cell_index).match(/[0-9]+/).to_s
end
def cell_array(result, array, column)
array.strip.split(/\t| /).each_with_index do |value, row|
result << Cell.new(value, column + 1, ROWS[row])
end
end
end
class Spreadsheet
include Excel
attr_reader :data
def initialize(tabbed_values = "")
@data = create_cells(tabbed_values)
end
def empty?
data.empty?
end
def cell_at(cell_index)
exception_thrower(cell_index)
get_cell(cell_index).value
end
def [](cell_index)
return cell_index if cell_index.match(NUMBER)
exception_thrower(cell_index)
return cell_at(cell_index) if ! cell_at(cell_index).start_with?("=")
return return_number(cell_index) if get_cell(cell_index).equals_number?
return return_cell(cell_index) if get_cell(cell_index).equals_cell?
calculate(get_cell(cell_index).operation, return_parameters(cell_index))
end
def to_s #някакъв map може би ще е по-смислен
result = self[data.first.cell_id].to_s
data.each_cons(2) do |first_cell, second_cell|
if first_cell.column == second_cell.column
result += "\t" + self[second_cell.cell_id].to_s
else
result += "\n" + self[second_cell.cell_id].to_s
end
end
result
end
private
def create_cells(tabbed_values)
result = []
tabbed_values.strip.split(/\n/).each_slice(1).with_index do |item, column|
cell_array(result, item[0], column)
end #da razkaram slice?
delete_empty_cells(result)
end
def calculate(operation, parameters)
if operation.to_s == "DIVIDE" # Skeptic again :)
- "%g" % (self[parameters[0]].to_f / self[parameters[1]].to_f.round(2))
+ result = self[parameters[0]].to_f / self[parameters[1]].to_f
+ result.to_i == result ? result.to_i.to_s : result.round(2).to_s
else
parameters.map do |item|
self[item].to_i
end.reduce(OPERATIONS[operation].to_sym).to_s
end
end
def exception_thrower(cell_index)
if ! cell_index.match(/\A#{CELL}\z/)
raise Error.new("Invalid cell index \'#{cell_index}\'")
elsif get_cell(cell_index) == nil
raise Error.new("Cell \'#{cell_index}\' does not exist")
end
end
end
class Spreadsheet::Error < StandardError
end
class Cell
attr_reader :value, :column, :row, :operation
include Excel
def initialize(value, column, row)
@value = value
@column = column
@row = row
@operation = check_operation
end
def cell_id
row + column.to_s
end
def equals_cell?
value.match(/\A=#{CELL}\z/) != nil
end
def equals_number?
value.match(/\A=[0-9]+\z/) != nil
end
private
def check_operation
is_equation?(value) ? value[1..-1].match(/\w+/).to_s.to_sym : nil
end
end

Кузман обнови решението на 11.01.2016 16:43 (преди над 8 години)

module Excel
NUMBER = /\A[0-9]+\z/
CELL = "[A-Z]+[0-9]+"
ROWS = ("A"..."ZZZ").to_a
OPERATIONS = {
:ADD => "+",
:SUBTRACT => "-",
:MULTIPLY => "*",
-# :DIVIDE => :/,
+# :DIVIDE => "/",
:MOD => "%"
} # беше със символи, но Skeptic реве, че няма шпация след *
PARENTHESIS = /\((\w|\W)+\)/
def delete_empty_cells(spreadsheet)
spreadsheet.select { |cell| cell.value != ""}
end
def get_cell(cell_index)
data.find { |cell| cell.cell_id == cell_index }
end
def return_parameters(cell_index)
cell_at(cell_index).match(PARENTHESIS).to_s[1..-2].split(",").map do |item|
item.strip
end
end
def is_equation?(value)
value.start_with?("=")
end
def return_cell(cell_index)
self[cell_at(cell_index).match(/#{CELL}\z/).to_s]
end
def return_number(cell_index)
cell_at(cell_index).match(/[0-9]+/).to_s
end
def cell_array(result, array, column)
array.strip.split(/\t| /).each_with_index do |value, row|
result << Cell.new(value, column + 1, ROWS[row])
end
end
end
class Spreadsheet
include Excel
attr_reader :data
def initialize(tabbed_values = "")
@data = create_cells(tabbed_values)
end
def empty?
data.empty?
end
def cell_at(cell_index)
exception_thrower(cell_index)
get_cell(cell_index).value
end
def [](cell_index)
return cell_index if cell_index.match(NUMBER)
exception_thrower(cell_index)
return cell_at(cell_index) if ! cell_at(cell_index).start_with?("=")
return return_number(cell_index) if get_cell(cell_index).equals_number?
return return_cell(cell_index) if get_cell(cell_index).equals_cell?
calculate(get_cell(cell_index).operation, return_parameters(cell_index))
end
def to_s #някакъв map може би ще е по-смислен
result = self[data.first.cell_id].to_s
data.each_cons(2) do |first_cell, second_cell|
if first_cell.column == second_cell.column
result += "\t" + self[second_cell.cell_id].to_s
else
result += "\n" + self[second_cell.cell_id].to_s
end
end
result
end
private
def create_cells(tabbed_values)
result = []
tabbed_values.strip.split(/\n/).each_slice(1).with_index do |item, column|
cell_array(result, item[0], column)
end #da razkaram slice?
delete_empty_cells(result)
end
def calculate(operation, parameters)
if operation.to_s == "DIVIDE" # Skeptic again :)
result = self[parameters[0]].to_f / self[parameters[1]].to_f
result.to_i == result ? result.to_i.to_s : result.round(2).to_s
else
parameters.map do |item|
- self[item].to_i
+ self[item].to_f
end.reduce(OPERATIONS[operation].to_sym).to_s
end
end
def exception_thrower(cell_index)
if ! cell_index.match(/\A#{CELL}\z/)
raise Error.new("Invalid cell index \'#{cell_index}\'")
elsif get_cell(cell_index) == nil
raise Error.new("Cell \'#{cell_index}\' does not exist")
end
end
end
class Spreadsheet::Error < StandardError
end
class Cell
attr_reader :value, :column, :row, :operation
include Excel
def initialize(value, column, row)
@value = value
@column = column
@row = row
@operation = check_operation
end
def cell_id
row + column.to_s
end
def equals_cell?
value.match(/\A=#{CELL}\z/) != nil
end
def equals_number?
value.match(/\A=[0-9]+\z/) != nil
end
private
def check_operation
is_equation?(value) ? value[1..-1].match(/\w+/).to_s.to_sym : nil
end
end

Кузман обнови решението на 11.01.2016 17:09 (преди над 8 години)

module Excel
NUMBER = /\A[0-9]+\z/
CELL = "[A-Z]+[0-9]+"
ROWS = ("A"..."ZZZ").to_a
OPERATIONS = {
:ADD => "+",
:SUBTRACT => "-",
:MULTIPLY => "*",
# :DIVIDE => "/",
:MOD => "%"
} # беше със символи, но Skeptic реве, че няма шпация след *
PARENTHESIS = /\((\w|\W)+\)/
def delete_empty_cells(spreadsheet)
spreadsheet.select { |cell| cell.value != ""}
end
def get_cell(cell_index)
data.find { |cell| cell.cell_id == cell_index }
end
def return_parameters(cell_index)
cell_at(cell_index).match(PARENTHESIS).to_s[1..-2].split(",").map do |item|
item.strip
end
end
def is_equation?(value)
value.start_with?("=")
end
def return_cell(cell_index)
self[cell_at(cell_index).match(/#{CELL}\z/).to_s]
end
def return_number(cell_index)
cell_at(cell_index).match(/[0-9]+/).to_s
end
def cell_array(result, array, column)
array.strip.split(/\t| /).each_with_index do |value, row|
result << Cell.new(value, column + 1, ROWS[row])
end
end
end
class Spreadsheet
include Excel
attr_reader :data
def initialize(tabbed_values = "")
@data = create_cells(tabbed_values)
end
def empty?
data.empty?
end
def cell_at(cell_index)
exception_thrower(cell_index)
get_cell(cell_index).value
end
def [](cell_index)
return cell_index if cell_index.match(NUMBER)
exception_thrower(cell_index)
return cell_at(cell_index) if ! cell_at(cell_index).start_with?("=")
return return_number(cell_index) if get_cell(cell_index).equals_number?
return return_cell(cell_index) if get_cell(cell_index).equals_cell?
calculate(get_cell(cell_index).operation, return_parameters(cell_index))
end
def to_s #някакъв map може би ще е по-смислен
result = self[data.first.cell_id].to_s
data.each_cons(2) do |first_cell, second_cell|
if first_cell.column == second_cell.column
result += "\t" + self[second_cell.cell_id].to_s
else
result += "\n" + self[second_cell.cell_id].to_s
end
end
result
end
private
def create_cells(tabbed_values)
result = []
tabbed_values.strip.split(/\n/).each_slice(1).with_index do |item, column|
cell_array(result, item[0], column)
end #da razkaram slice?
delete_empty_cells(result)
end
- def calculate(operation, parameters)
- if operation.to_s == "DIVIDE" # Skeptic again :)
- result = self[parameters[0]].to_f / self[parameters[1]].to_f
- result.to_i == result ? result.to_i.to_s : result.round(2).to_s
- else
- parameters.map do |item|
- self[item].to_f
- end.reduce(OPERATIONS[operation].to_sym).to_s
- end
- end
+ def calculate(operation, parameters)
+ if operation.to_s == "DIVIDE" # Skeptic again :)
+ result = self[parameters[0]].to_f / self[parameters[1]].to_f
+ else
+ result = (parameters.map do |item|
+ self[item].to_f
+ end.reduce(OPERATIONS[operation].to_sym))
+ end
+ result.to_i == result ? result.to_i.to_s : result.to_f.round(2).to_s
+ end
def exception_thrower(cell_index)
if ! cell_index.match(/\A#{CELL}\z/)
raise Error.new("Invalid cell index \'#{cell_index}\'")
elsif get_cell(cell_index) == nil
raise Error.new("Cell \'#{cell_index}\' does not exist")
end
end
end
class Spreadsheet::Error < StandardError
end
class Cell
attr_reader :value, :column, :row, :operation
include Excel
def initialize(value, column, row)
@value = value
@column = column
@row = row
@operation = check_operation
end
def cell_id
row + column.to_s
end
def equals_cell?
value.match(/\A=#{CELL}\z/) != nil
end
def equals_number?
value.match(/\A=[0-9]+\z/) != nil
end
private
def check_operation
is_equation?(value) ? value[1..-1].match(/\w+/).to_s.to_sym : nil
end
end

Кузман обнови решението на 11.01.2016 17:09 (преди над 8 години)

module Excel
NUMBER = /\A[0-9]+\z/
CELL = "[A-Z]+[0-9]+"
ROWS = ("A"..."ZZZ").to_a
OPERATIONS = {
:ADD => "+",
:SUBTRACT => "-",
:MULTIPLY => "*",
# :DIVIDE => "/",
:MOD => "%"
} # беше със символи, но Skeptic реве, че няма шпация след *
PARENTHESIS = /\((\w|\W)+\)/
def delete_empty_cells(spreadsheet)
spreadsheet.select { |cell| cell.value != ""}
end
def get_cell(cell_index)
data.find { |cell| cell.cell_id == cell_index }
end
def return_parameters(cell_index)
cell_at(cell_index).match(PARENTHESIS).to_s[1..-2].split(",").map do |item|
item.strip
end
end
def is_equation?(value)
value.start_with?("=")
end
def return_cell(cell_index)
self[cell_at(cell_index).match(/#{CELL}\z/).to_s]
end
def return_number(cell_index)
cell_at(cell_index).match(/[0-9]+/).to_s
end
def cell_array(result, array, column)
array.strip.split(/\t| /).each_with_index do |value, row|
result << Cell.new(value, column + 1, ROWS[row])
end
end
end
class Spreadsheet
include Excel
attr_reader :data
def initialize(tabbed_values = "")
@data = create_cells(tabbed_values)
end
def empty?
data.empty?
end
def cell_at(cell_index)
exception_thrower(cell_index)
get_cell(cell_index).value
end
def [](cell_index)
return cell_index if cell_index.match(NUMBER)
exception_thrower(cell_index)
return cell_at(cell_index) if ! cell_at(cell_index).start_with?("=")
return return_number(cell_index) if get_cell(cell_index).equals_number?
return return_cell(cell_index) if get_cell(cell_index).equals_cell?
calculate(get_cell(cell_index).operation, return_parameters(cell_index))
end
def to_s #някакъв map може би ще е по-смислен
result = self[data.first.cell_id].to_s
data.each_cons(2) do |first_cell, second_cell|
if first_cell.column == second_cell.column
result += "\t" + self[second_cell.cell_id].to_s
else
result += "\n" + self[second_cell.cell_id].to_s
end
end
result
end
private
def create_cells(tabbed_values)
result = []
tabbed_values.strip.split(/\n/).each_slice(1).with_index do |item, column|
cell_array(result, item[0], column)
end #da razkaram slice?
delete_empty_cells(result)
end
- def calculate(operation, parameters)
- if operation.to_s == "DIVIDE" # Skeptic again :)
- result = self[parameters[0]].to_f / self[parameters[1]].to_f
- else
- result = (parameters.map do |item|
- self[item].to_f
- end.reduce(OPERATIONS[operation].to_sym))
- end
- result.to_i == result ? result.to_i.to_s : result.to_f.round(2).to_s
- end
+ def calculate(operation, parameters)
+ if operation.to_s == "DIVIDE" # Skeptic again :)
+ result = self[parameters[0]].to_f / self[parameters[1]].to_f
+ else
+ result = (parameters.map do |item|
+ self[item].to_f
+ end.reduce(OPERATIONS[operation].to_sym))
+ end
+ result.to_i == result ? result.to_i.to_s : result.to_f.round(2).to_s
+ end
def exception_thrower(cell_index)
if ! cell_index.match(/\A#{CELL}\z/)
raise Error.new("Invalid cell index \'#{cell_index}\'")
elsif get_cell(cell_index) == nil
raise Error.new("Cell \'#{cell_index}\' does not exist")
end
end
end
class Spreadsheet::Error < StandardError
end
class Cell
attr_reader :value, :column, :row, :operation
include Excel
def initialize(value, column, row)
@value = value
@column = column
@row = row
@operation = check_operation
end
def cell_id
row + column.to_s
end
def equals_cell?
value.match(/\A=#{CELL}\z/) != nil
end
def equals_number?
value.match(/\A=[0-9]+\z/) != nil
end
private
def check_operation
is_equation?(value) ? value[1..-1].match(/\w+/).to_s.to_sym : nil
end
end