Решение на Осма задача от Пепа Симеонова

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

Към профила на Пепа Симеонова

Резултати

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

Код

module Functions
def calculate_formula(formula, sheet)
formula = formula.gsub('=', '')
if sheet.sheet[formula]
sheet[formula]
elsif formula == '0' or formula.to_i != 0
formula.to_i
else
run_formula(formula)
end
end
def run_formula(formula)
formula = formula.gsub('=', '')
formula = formula.split(/(\(|\))/)
formula.delete_if {|item| item == '(' or item == ')' }
function_name = formula.shift
begin
method(function_name.downcase).call(formula[0])
rescue
raise Spreadsheet::Error.new "Unknown function '#{function_name}'"
end
end
def add(args)
args = args.split(',')
args.map {|argument| argument.to_i }.reduce(:+)
end
def multiply(args)
args = args.split(',')
args.map {|argument| argument.to_i }.reduce(:*)
end
def subtract(args)
args = args.split(',')
args[0].to_i - args[1].to_i
end
def divide(args)
args = args.split(',')
args[0].to_i / args[1].to_i
end
def mod(args)
args = args.split(',')
args[0].to_i % args[1].to_i
end
end
class Spreadsheet
extend Functions
include Functions
attr_reader :sheet
def initialize(content = nil)
@sheet = {}
if content
add_content(content)
end
@sheet
end
def empty?
@sheet.empty?
end
def cell_at(cell_index)
unless @sheet[cell_index]
raise Spreadsheet::Error.new "Cell #{cell_index} does not exist"
end
@sheet[cell_index]
end
def [](cell_index)
unless @sheet[cell_index]
raise Spreadsheet::Error.new "Cell '#{cell_index}' does not exist"
end
if @sheet[cell_index][0] == '='
Spreadsheet.calculate_formula(@sheet[cell_index], self).to_s
else
@sheet[cell_index]
end
end
def to_s
get_string_representation(1, '')
end
def get_string_representation(row, string)
@sheet.keys.each do |key|
if key[1] == "#{row + 1}"
row, string = row + 1, string[0, string.length - 1]
string << "\n" << method("[]").call(key) << "\t"
else
string << method("[]").call(key) << "\t"
end
end
string = string[0, string.length - 1]
end
private
def add_content(content)
content, column, row = content.split(/\n/), nil, 0
content.each do |line|
row, first_column = row += 1, true unless line == ''
line.split(/\s/).delete_if {|cell| cell == ''}.each do |cell|
column, first_column = next_column(column, first_column), false
@sheet["#{column}#{row}"] = cell
end
end
end
def next_column(column, first_column)
if ! column || first_column
column = 'A'
else
column.next!
end
end
class Error < StandardError
end
end

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

....F....F.F...FFFFFFFFFFFFFFFFFFFFFF.FF

Failures:

  1) Spreadsheet#to_s returns blank tables as blank strings
     Failure/Error: expect(Spreadsheet.new.to_s).to eq ''
       
       expected: ""
            got: nil
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/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 returns the evaluated spreadsheet as a table
     Failure/Error: expect(sheet.to_s).to eq \
     Spreadsheet::Error:
       Unknown function 'DIVIDE'
     # /tmp/d20160121-5693-114gm49/solution.rb:21:in `rescue in run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:18:in `run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:9:in `calculate_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:82:in `[]'
     # /tmp/d20160121-5693-114gm49/solution.rb:98:in `call'
     # /tmp/d20160121-5693-114gm49/solution.rb:98:in `block in get_string_representation'
     # /tmp/d20160121-5693-114gm49/solution.rb:93:in `each'
     # /tmp/d20160121-5693-114gm49/solution.rb:93:in `get_string_representation'
     # /tmp/d20160121-5693-114gm49/solution.rb:89:in `to_s'
     # /tmp/d20160121-5693-114gm49/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)>'

  3) Spreadsheet#cell_at returns the raw value of existing cells
     Failure/Error: expect(sheet.cell_at('B1')).to eq '=ADD(2, 2)'
       
       expected: "=ADD(2, 2)"
            got: "=ADD(2,"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/spec.rb:69: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#[] returns the calculated value of formulae cells
     Failure/Error: expect(sheet['B1']).to eq 'ADD(2, 2)'
       
       expected: "ADD(2, 2)"
            got: "ADD(2,"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/spec.rb:102: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#[] adds two numbers with ADD
     Failure/Error: expect(sheet['A1']).to eq('4')
       
       expected: "4"
            got: "2"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/spec.rb:109: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#[] adds five numbers with ADD
     Failure/Error: expect(sheet['A1']).to eq('15')
       
       expected: "15"
            got: "1"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/spec.rb:115: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 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-114gm49/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)>'

  8) Spreadsheet#[] adds numbers from cell references and as immediate arguments with ADD
     Failure/Error: expect(sheet['B1']).to eq('55')
       
       expected: "55"
            got: "1"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/spec.rb:131: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 numbers only from cell references with ADD
     Failure/Error: expect(sheet['D1']).to eq('10')
       
       expected: "10"
            got: "0"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/spec.rb:137: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#[] multiplies numbers with MULTIPLY
     Failure/Error: expect(sheet1['A1']).to eq('120')
       
       expected: "120"
            got: "1"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/spec.rb:144: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#[] 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-114gm49/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)>'

  12) Spreadsheet#[] subtracts two numbers with SUBTRACT
     Failure/Error: expect(sheet['A1']).to eq('2')
       
       expected: "2"
            got: "5"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/spec.rb:161: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#[] subtracts numbers via cell references
     Failure/Error: expect(sheet['D1']).to eq('4')
       
       expected: "4"
            got: "0"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/spec.rb:167: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 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-114gm49/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)>'

  15) Spreadsheet#[] divides two numbers with DIVIDE
     Failure/Error: expect(sheet['A1']).to eq('42')
     Spreadsheet::Error:
       Unknown function 'DIVIDE'
     # /tmp/d20160121-5693-114gm49/solution.rb:21:in `rescue in run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:18:in `run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:9:in `calculate_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:82:in `[]'
     # /tmp/d20160121-5693-114gm49/spec.rb:183: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)>'

  16) Spreadsheet#[] divides numbers via cell references
     Failure/Error: expect(sheet1['C1']).to eq('42')
     Spreadsheet::Error:
       Unknown function 'DIVIDE'
     # /tmp/d20160121-5693-114gm49/solution.rb:21:in `rescue in run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:18:in `run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:9:in `calculate_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:82:in `[]'
     # /tmp/d20160121-5693-114gm49/spec.rb:190: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)>'

  17) 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 #<Spreadsheet::Error: Unknown function 'DIVIDE'> with backtrace:
         # /tmp/d20160121-5693-114gm49/solution.rb:21:in `rescue in run_formula'
         # /tmp/d20160121-5693-114gm49/solution.rb:18:in `run_formula'
         # /tmp/d20160121-5693-114gm49/solution.rb:9:in `calculate_formula'
         # /tmp/d20160121-5693-114gm49/solution.rb:82:in `[]'
         # /tmp/d20160121-5693-114gm49/spec.rb:195:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-114gm49/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-114gm49/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)>'

  18) Spreadsheet#[] calculates the modulo of two numbers with MOD
     Failure/Error: expect(Spreadsheet.new('=MOD(42, 5)')['A1']).to eq('2')
     Spreadsheet::Error:
       Unknown function 'MOD'
     # /tmp/d20160121-5693-114gm49/solution.rb:21:in `rescue in run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:18:in `run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:9:in `calculate_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:82:in `[]'
     # /tmp/d20160121-5693-114gm49/spec.rb:205: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)>'

  19) Spreadsheet#[] calculates the modulo of two numbers with MOD via cell references
     Failure/Error: expect(sheet1['C1']).to eq('4')
     Spreadsheet::Error:
       Unknown function 'MOD'
     # /tmp/d20160121-5693-114gm49/solution.rb:21:in `rescue in run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:18:in `run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:9:in `calculate_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:82:in `[]'
     # /tmp/d20160121-5693-114gm49/spec.rb:214: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)>'

  20) 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/, got #<Spreadsheet::Error: Unknown function 'MOD'> with backtrace:
         # /tmp/d20160121-5693-114gm49/solution.rb:21:in `rescue in run_formula'
         # /tmp/d20160121-5693-114gm49/solution.rb:18:in `run_formula'
         # /tmp/d20160121-5693-114gm49/solution.rb:9:in `calculate_formula'
         # /tmp/d20160121-5693-114gm49/solution.rb:82:in `[]'
         # /tmp/d20160121-5693-114gm49/spec.rb:219:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-114gm49/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)>'
     # /tmp/d20160121-5693-114gm49/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)>'

  21) Spreadsheet#[] adds floating point numbers with ADD
     Failure/Error: expect(Spreadsheet.new('10  =ADD(A1, 1.1)')['B1']).to eq '11.10'
       
       expected: "11.10"
            got: "0"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/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)>'

  22) Spreadsheet#[] subtracts floating point numbers with SUBTRACT
     Failure/Error: expect(Spreadsheet.new('10  =SUBTRACT(A1, 1.1)')['B1']).to eq '8.90'
       
       expected: "8.90"
            got: "0"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/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)>'

  23) Spreadsheet#[] multiplies floating point numbers with MULTIPLY
     Failure/Error: expect(Spreadsheet.new('10  =MULTIPLY(A1, 1.1)')['B1']).to eq '11'
       
       expected: "11"
            got: "0"
       
       (compared using ==)
     # /tmp/d20160121-5693-114gm49/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)>'

  24) Spreadsheet#[] divides floating point numbers with DIVIDE
     Failure/Error: expect(Spreadsheet.new('10  =DIVIDE(A1, 4)')['B1']).to eq '2.50'
     Spreadsheet::Error:
       Unknown function 'DIVIDE'
     # /tmp/d20160121-5693-114gm49/solution.rb:21:in `rescue in run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:18:in `run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:9:in `calculate_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:82:in `[]'
     # /tmp/d20160121-5693-114gm49/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)>'

  25) Spreadsheet#[] evaluates deeply-nested cell references
     Failure/Error: expect(Spreadsheet.new('10  =ADD(5, A1)  3  =DIVIDE(B1, C1)  =MOD(D1, 4)')['E1']).to eq '1'
     Spreadsheet::Error:
       Unknown function 'DIVIDE'
     # /tmp/d20160121-5693-114gm49/solution.rb:21:in `rescue in run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:18:in `run_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:9:in `calculate_formula'
     # /tmp/d20160121-5693-114gm49/solution.rb:82:in `[]'
     # /tmp/d20160121-5693-114gm49/spec.rb:250: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)>'

  26) Spreadsheet#[] raises an exception for missing cells passed as function arguments
     Failure/Error: expect { Spreadsheet.new('=ADD(1, B4)  100')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Cell 'B4' does not exist/ but nothing was raised
     # /tmp/d20160121-5693-114gm49/spec.rb:260: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)>'

  27) 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 #<Spreadsheet::Error: Unknown function 'FOO'> with backtrace:
         # /tmp/d20160121-5693-114gm49/solution.rb:21:in `rescue in run_formula'
         # /tmp/d20160121-5693-114gm49/solution.rb:18:in `run_formula'
         # /tmp/d20160121-5693-114gm49/solution.rb:9:in `calculate_formula'
         # /tmp/d20160121-5693-114gm49/solution.rb:82:in `[]'
         # /tmp/d20160121-5693-114gm49/spec.rb:266:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-114gm49/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-114gm49/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.02967 seconds
40 examples, 27 failures

Failed examples:

rspec /tmp/d20160121-5693-114gm49/spec.rb:23 # Spreadsheet#to_s returns blank tables as blank strings
rspec /tmp/d20160121-5693-114gm49/spec.rb:43 # Spreadsheet#to_s returns the evaluated spreadsheet as a table
rspec /tmp/d20160121-5693-114gm49/spec.rb:62 # Spreadsheet#cell_at returns the raw value of existing cells
rspec /tmp/d20160121-5693-114gm49/spec.rb:98 # Spreadsheet#[] returns the calculated value of formulae cells
rspec /tmp/d20160121-5693-114gm49/spec.rb:106 # Spreadsheet#[] adds two numbers with ADD
rspec /tmp/d20160121-5693-114gm49/spec.rb:112 # Spreadsheet#[] adds five numbers with ADD
rspec /tmp/d20160121-5693-114gm49/spec.rb:118 # Spreadsheet#[] raises an exception for less than two arguments passed to ADD
rspec /tmp/d20160121-5693-114gm49/spec.rb:128 # Spreadsheet#[] adds numbers from cell references and as immediate arguments with ADD
rspec /tmp/d20160121-5693-114gm49/spec.rb:134 # Spreadsheet#[] adds numbers only from cell references with ADD
rspec /tmp/d20160121-5693-114gm49/spec.rb:140 # Spreadsheet#[] multiplies numbers with MULTIPLY
rspec /tmp/d20160121-5693-114gm49/spec.rb:148 # Spreadsheet#[] raises an exception for less than two arguments to MULTIPLY
rspec /tmp/d20160121-5693-114gm49/spec.rb:158 # Spreadsheet#[] subtracts two numbers with SUBTRACT
rspec /tmp/d20160121-5693-114gm49/spec.rb:164 # Spreadsheet#[] subtracts numbers via cell references
rspec /tmp/d20160121-5693-114gm49/spec.rb:170 # Spreadsheet#[] raises an exception when SUBTRACT is called with a wrong number of arguments
rspec /tmp/d20160121-5693-114gm49/spec.rb:180 # Spreadsheet#[] divides two numbers with DIVIDE
rspec /tmp/d20160121-5693-114gm49/spec.rb:186 # Spreadsheet#[] divides numbers via cell references
rspec /tmp/d20160121-5693-114gm49/spec.rb:194 # Spreadsheet#[] raises an exception when DIVIDE is called with a wrong number of arguments
rspec /tmp/d20160121-5693-114gm49/spec.rb:204 # Spreadsheet#[] calculates the modulo of two numbers with MOD
rspec /tmp/d20160121-5693-114gm49/spec.rb:210 # Spreadsheet#[] calculates the modulo of two numbers with MOD via cell references
rspec /tmp/d20160121-5693-114gm49/spec.rb:218 # Spreadsheet#[] raises an exception when MOD is called with a wrong number of arguments
rspec /tmp/d20160121-5693-114gm49/spec.rb:228 # Spreadsheet#[] adds floating point numbers with ADD
rspec /tmp/d20160121-5693-114gm49/spec.rb:233 # Spreadsheet#[] subtracts floating point numbers with SUBTRACT
rspec /tmp/d20160121-5693-114gm49/spec.rb:238 # Spreadsheet#[] multiplies floating point numbers with MULTIPLY
rspec /tmp/d20160121-5693-114gm49/spec.rb:243 # Spreadsheet#[] divides floating point numbers with DIVIDE
rspec /tmp/d20160121-5693-114gm49/spec.rb:249 # Spreadsheet#[] evaluates deeply-nested cell references
rspec /tmp/d20160121-5693-114gm49/spec.rb:259 # Spreadsheet#[] raises an exception for missing cells passed as function arguments
rspec /tmp/d20160121-5693-114gm49/spec.rb:265 # Spreadsheet#[] raises an exception for invalid expressions

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

Пепа обнови решението на 10.01.2016 19:50 (преди над 8 години)

+module Functions
+ def calculate_formula(formula, sheet)
+ formula = formula.gsub('=', '')
+ if sheet.sheet[formula]
+ sheet[formula]
+ elsif formula == '0' or formula.to_i != 0
+ formula.to_i
+ else
+ run_formula(formula)
+ end
+ end
+
+ def run_formula(formula)
+ formula = formula.gsub('=', '')
+ formula = formula.split(/(\(|\))/)
+ formula.delete_if {|item| item == '(' or item == ')' }
+ function_name = formula.shift
+ begin
+ method(function_name.downcase).call(formula[0])
+ rescue
+ raise Spreadsheet::Error.new "Unknown function '#{function_name}'"
+ end
+ end
+
+ def add(args)
+ args = args.split(',')
+ args.map {|argument| argument.to_i }.reduce(:+)
+ end
+
+ def multiply(args)
+ args = args.split(',')
+ args.map {|argument| argument.to_i }.reduce(:*)
+ end
+
+ def subtract(args)
+ args = args.split(',')
+ args[0].to_i - args[1].to_i
+ end
+
+ def divide(args)
+ args = args.split(',')
+ args[0].to_i / args[1].to_i
+ end
+
+ def mod(args)
+ args = args.split(',')
+ args[0].to_i % args[1].to_i
+ end
+end
+
+class Spreadsheet
+
+ extend Functions
+ include Functions
+
+ attr_reader :sheet
+
+ def initialize(content = nil)
+ @sheet = {}
+ if content
+ add_content(content)
+ end
+ @sheet
+ end
+
+ def empty?
+ @sheet.empty?
+ end
+
+ def cell_at(cell_index)
+ unless @sheet[cell_index]
+ raise Spreadsheet::Error.new "Cell #{cell_index} does not exist"
+ end
+ @sheet[cell_index]
+ end
+
+ def [](cell_index)
+ unless @sheet[cell_index]
+ raise Spreadsheet::Error.new "Cell '#{cell_index}' does not exist"
+ end
+ if @sheet[cell_index][0] == '='
+ Spreadsheet.calculate_formula(@sheet[cell_index], self).to_s
+ else
+ @sheet[cell_index]
+ end
+ end
+
+ def to_s
+ get_string_representation(1, '')
+ end
+
+ def get_string_representation(row, string)
+ @sheet.keys.each do |key|
+ if key[1] == "#{row + 1}"
+ row, string = row + 1, string[0, string.length - 1]
+ string << "\n" << method("[]").call(key) << "\t"
+ else
+ string << method("[]").call(key) << "\t"
+ end
+ end
+ string = string[0, string.length - 1]
+ end
+
+ private
+
+ def add_content(content)
+ content, column, row = content.split(/\n/), nil, 0
+ content.each do |line|
+ row, first_column = row += 1, true unless line == ''
+ line.split(/\s/).delete_if {|cell| cell == ''}.each do |cell|
+ column, first_column = next_column(column, first_column), false
+ @sheet["#{column}#{row}"] = cell
+ end
+ end
+ end
+
+ def next_column(column, first_column)
+ if ! column || first_column
+ column = 'A'
+ else
+ column.next!
+ end
+ end
+
+ class Error < StandardError
+ end
+end