Решение на Осма задача от Никола Терзиев

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

Към профила на Никола Терзиев

Резултати

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

Код

module SpreadSheetHelper
FORMULAS = ['ADD', 'MULTIPLY', 'SUBTRACT', 'DIVIDE', 'MOD']
INFORMATION = {'ADD': [2, 'ge', :+], 'MULTIPLY': [2, 'ge', :*],
'SUBTRACT': [2, 'eq', :-], 'DIVIDE': [2, 'eq', :/],
'MOD': [2, 'eq', :%]}
ERRORS = {'eq': ""}
def is_cell_reference? (index)
true if parse_index index rescue false
end
def is_number?(item)
true if Float(item) rescue false
end
def parse_sheet(sheet)
rows = sheet.split("\n").select { |item| ! (item =~ /^\s*$/) }.map(&:strip)
rows.map { |row| row.split(/\t|(?:\ {2,})/) }
end
def parse_formula(item)
formula = /^\ *([A-Z]+)\((.+)\)$/.match(item)
raise self.class::Error, "Invalid expression '#{item}'" if formula.nil?
formula_name, parameters = formula.captures
parameters = evaluate_formula_parameters parameters.split(',').map(&:strip)
validate_formula INFORMATION[formula_name.to_sym], formula_name, parameters
evaluate_formula INFORMATION[formula_name.to_sym], formula_name, parameters
end
def validate_formula(info, formula_name, parameters)
if ! FORMULAS.include? formula_name
raise self.class::Error, "Unknown function '#{formula_name}'"
else
validate_formula_helper info, formula_name, parameters
end
end
def validate_formula_helper(info, formula_name, parameters)
if parameters.length != info[0] && info[1] == 'eq'
raise self.class::Error, "Wrong number of arguments for '#{formula_name}'\
: expected #{info[0]}, got #{parameters.length}"
elsif parameters.length < info[0] && info[1] == 'ge'
raise self.class::Error, "Wrong number of arguments for '#{formula_name}'\
: expected at least #{info[0]}, got #{parameters.length}"
end
end
def evaluate_formula (info, formula_name, parameters)
if info[1] == 'ge'
result = parameters.reduce(&info[2])
else
result = parameters[0].public_send info[2], parameters[1]
end
if result == result.floor
result.to_i.to_s
else
'%.2f' % result
end
end
def parse_index(index)
parsed_index = /^([A-Z]+)([0-9]+)$/.match(index)
raise self.class::Error, "Invalid cell index '#{index}'"if parsed_index.nil?
col = parsed_index[1].split("").reverse.map.with_index do |char, power|
(char.ord - 64) * (26 ** power)
end.reduce(&:+)
[Integer(parsed_index[2]) - 1, col - 1]
end
end
class Spreadsheet
include SpreadSheetHelper
def initialize(sheet = '')
@sheet = parse_sheet sheet
end
def empty?
@sheet.empty?
end
def cell_at(cell_index)
index_vector = parse_index cell_index
if @sheet.length <= index_vector[0] ||
@sheet[index_vector[0]].length <= index_vector[1]
raise Error, "Cell '#{cell_index}' does not exist"
end
@sheet[index_vector[0]][index_vector[1]]
end
def [](cell_index)
evaluate_cell cell_at(cell_index)
end
def to_s
@sheet.map do |row|
row.map { |cell| evaluate_cell cell }.join("\t")
end.join("\n")
end
def evaluate_cell(cell)
return cell if cell[0] != '='
if is_number? cell[1..-1]
cell[1..-1]
elsif is_cell_reference? cell[1..-1]
self. [] cell[1..-1]
else
parse_formula cell[1..-1]
end
end
def evaluate_formula_parameters parameters
parameters.map do |item|
is_cell_reference?(item) ? (self. [] (item)).to_f : item.to_f
end
end
class Error < StandardError
end
end

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

..................F...F.................

Failures:

  1) Spreadsheet#[] raises an exception for less than two arguments passed to ADD
     Failure/Error: expect { Spreadsheet.new('=ADD()')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'ADD': expected at least 2, got 0/, got #<Spreadsheet::Error: Invalid expression 'ADD()'> with backtrace:
         # /tmp/d20160121-5693-cmx67r/solution.rb:23:in `parse_formula'
         # /tmp/d20160121-5693-cmx67r/solution.rb:111:in `evaluate_cell'
         # /tmp/d20160121-5693-cmx67r/solution.rb:95:in `[]'
         # /tmp/d20160121-5693-cmx67r/spec.rb:123:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-cmx67r/spec.rb:123: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-cmx67r/spec.rb:123: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#[] raises an exception for less than two arguments to MULTIPLY
     Failure/Error: expect { Spreadsheet.new('=MULTIPLY()')['A1'] }.to raise_error(
       expected Spreadsheet::Error with message matching /Wrong number of arguments for 'MULTIPLY': expected at least 2, got 0/, got #<Spreadsheet::Error: Invalid expression 'MULTIPLY()'> with backtrace:
         # /tmp/d20160121-5693-cmx67r/solution.rb:23:in `parse_formula'
         # /tmp/d20160121-5693-cmx67r/solution.rb:111:in `evaluate_cell'
         # /tmp/d20160121-5693-cmx67r/solution.rb:95:in `[]'
         # /tmp/d20160121-5693-cmx67r/spec.rb:153:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-cmx67r/spec.rb:153: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-cmx67r/spec.rb:153: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.0329 seconds
40 examples, 2 failures

Failed examples:

rspec /tmp/d20160121-5693-cmx67r/spec.rb:118 # Spreadsheet#[] raises an exception for less than two arguments passed to ADD
rspec /tmp/d20160121-5693-cmx67r/spec.rb:148 # Spreadsheet#[] raises an exception for less than two arguments to MULTIPLY

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

Никола обнови решението на 11.01.2016 15:34 (преди над 8 години)

+module SpreadSheetHelper
+ FORMULAS = ['ADD', 'MULTIPLY', 'SUBTRACT', 'DIVIDE', 'MOD']
+ INFORMATION = {'ADD': [2, 'ge', :+], 'MULTIPLY': [2, 'ge', :*],
+ 'SUBTRACT': [2, 'eq', :-], 'DIVIDE': [2, 'eq', :/],
+ 'MOD': [2, 'eq', :%]}
+ ERRORS = {'eq': ""}
+
+ def is_cell_reference? (index)
+ true if parse_index index rescue false
+ end
+
+ def is_number?(item)
+ true if Float(item) rescue false
+ end
+
+ def parse_sheet(sheet)
+ rows = sheet.split("\n").select { |item| ! (item =~ /^\s*$/) }.map(&:strip)
+ rows.map { |row| row.split(/\t|(?:\ {2,})/) }
+ end
+
+ def parse_formula(item)
+ formula = /^\ *([A-Z]+)\((.+)\)$/.match(item)
+ raise self.class::Error, "Invalid expression '#{item}'" if formula.nil?
+ formula_name, parameters = formula.captures
+ parameters = evaluate_formula_parameters parameters.split(',').map(&:strip)
+ validate_formula INFORMATION[formula_name.to_sym], formula_name, parameters
+ evaluate_formula INFORMATION[formula_name.to_sym], formula_name, parameters
+ end
+
+ def validate_formula(info, formula_name, parameters)
+ if ! FORMULAS.include? formula_name
+ raise self.class::Error, "Unknown function '#{formula_name}'"
+ else
+ validate_formula_helper info, formula_name, parameters
+ end
+ end
+
+ def validate_formula_helper(info, formula_name, parameters)
+ if parameters.length != info[0] && info[1] == 'eq'
+ raise self.class::Error, "Wrong number of arguments for '#{formula_name}'\
+: expected #{info[0]}, got #{parameters.length}"
+ elsif parameters.length < info[0] && info[1] == 'ge'
+ raise self.class::Error, "Wrong number of arguments for '#{formula_name}'\
+: expected at least #{info[0]}, got #{parameters.length}"
+ end
+ end
+
+ def evaluate_formula (info, formula_name, parameters)
+ if info[1] == 'ge'
+ result = parameters.reduce(&info[2])
+ else
+ result = parameters[0].public_send info[2], parameters[1]
+ end
+ if result == result.floor
+ result.to_i.to_s
+ else
+ '%.2f' % result
+ end
+ end
+
+ def parse_index(index)
+ parsed_index = /^([A-Z]+)([0-9]+)$/.match(index)
+ raise self.class::Error, "Invalid cell index '#{index}'"if parsed_index.nil?
+ col = parsed_index[1].split("").reverse.map.with_index do |char, power|
+ (char.ord - 64) * (26 ** power)
+ end.reduce(&:+)
+ [Integer(parsed_index[2]) - 1, col - 1]
+ end
+
+end
+
+
+class Spreadsheet
+ include SpreadSheetHelper
+
+ def initialize(sheet = '')
+ @sheet = parse_sheet sheet
+ end
+
+ def empty?
+ @sheet.empty?
+ end
+
+ def cell_at(cell_index)
+ index_vector = parse_index cell_index
+
+ if @sheet.length <= index_vector[0] ||
+ @sheet[index_vector[0]].length <= index_vector[1]
+ raise Error, "Cell '#{cell_index}' does not exist"
+ end
+ @sheet[index_vector[0]][index_vector[1]]
+ end
+
+ def [](cell_index)
+ evaluate_cell cell_at(cell_index)
+ end
+
+ def to_s
+ @sheet.map do |row|
+ row.map { |cell| evaluate_cell cell }.join("\t")
+ end.join("\n")
+ end
+
+ def evaluate_cell(cell)
+ return cell if cell[0] != '='
+ if is_number? cell[1..-1]
+ cell[1..-1]
+ elsif is_cell_reference? cell[1..-1]
+ self. [] cell[1..-1]
+ else
+ parse_formula cell[1..-1]
+ end
+ end
+
+ def evaluate_formula_parameters parameters
+ parameters.map do |item|
+ is_cell_reference?(item) ? (self. [] (item)).to_f : item.to_f
+ end
+ end
+
+
+ class Error < StandardError
+ end
+
+end