Решение на Осма задача от Георги Киряков

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

Към профила на Георги Киряков

Резултати

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

Код

class Spreadsheet
private
def parse(text)
lines = text.strip.split(/\n/)
lines.map { |line| line.strip.split(/\t+| {2,}/).map(&:strip) }
end
def get_cell_index(cell_index)
return nil unless cell_index = Expression.index?(cell_index)
column = cell_index[1].each_byte.reverse_each.map { |byte| byte - 64 }
column.map!.with_index { |byte, index| byte * (26 ** index) }
row = cell_index[2].to_i - 1
column = column.reduce(:+) - 1
[row, column]
end
def validate_cell_index(cell_index)
row, column = get_cell_index cell_index
if row.nil?
raise Error, "Invalid cell index '#{cell_index}'"
elsif @table[row].nil? || @table[row][column].nil?
raise Error, "Cell '#{cell_index}' does not exist"
end
end
public
def initialize(table = "")
@table = parse table
end
def empty?
@table.empty?
end
def cell_at(cell_index)
validate_cell_index cell_index
row, column = get_cell_index cell_index
@table[row][column]
end
def [](cell_index)
cell = cell_at cell_index
Expression.evaluate(cell, self).to_s
end
def to_s
@table.map do |row|
row.map do |cell|
Expression.evaluate(cell, self).to_s
end.join("\t")
end.join("\n")
end
class Error < RuntimeError
end
module Expression
def self.match?(string)
not string.match(/^=/).nil?
end
def self.number?(string)
string.match(/^\d+(\.\d+)?$/)
end
def self.index?(cell_index)
cell_index.match(/^([A-Z]+)(\d+)$/)
end
def self.normalize(result)
result = result.to_f
if result == result.floor then ("%d" % result) else ("%.2f" % result) end
end
def self.evaluate(string, sheet)
string = evaluate_string(string, sheet) if match? string
string
end
private
def self.evaluate_string(string, sheet)
expression = string.match(/[\w.]+/)[0]
return normalize(expression) if number? expression
return sheet[expression] if index? expression
normalize evaluate_formula(string, sheet)
end
def self.evaluate_formula(formula, sheet)
Formula.verify formula
formula, *args = formula.scan(/[\w.]+/)
formula = formula.sub(/=/, "").downcase
args.map! { |argument| Expression.evaluate_string(argument, sheet).to_f }
Formula.send(formula, *args)
end
end
module Formula
def self.add(first, second, *more)
first + second + more.reduce(0, :+)
end
def self.multiply(first, second, *more)
first * second * more.reduce(1, :*)
end
def self.subtract(first, second)
first - second
end
def self.divide(first, second)
first / second
end
def self.mod(first, second)
first % second
end
def self.verify(string)
unless string.match(/^= ?[A-Z]+\([\w\s,.=]+\)$/) &&
string.count(",") == string.scan(/[\w.]+/).size - 2
raise Error, "Invalid expression '#{string.sub(/^=/, "")}'"
end
end
def self.verify_arguments(formula, args)
real_args = method(formula).arity
message = "Wrong number of arguments for '#{formula.upcase}': expected "
if real_args > 0 && real_args != args
raise Error, message + "#{real_args}, got #{args}"
elsif real_args < 0 && real_args.abs - 1 > args
raise Error, message + "at least #{real_args.abs - 1}, got #{args}"
end
end
def self.send(name, *args, &block)
if methods.include?(name.to_sym)
verify_arguments(name, args.size)
super
elsif
raise Error, "Unknown function '#{name.upcase}'"
end
end
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-dr4t1w/solution.rb:132:in `verify'
         # /tmp/d20160121-5693-dr4t1w/solution.rb:97:in `evaluate_formula'
         # /tmp/d20160121-5693-dr4t1w/solution.rb:93:in `evaluate_string'
         # /tmp/d20160121-5693-dr4t1w/solution.rb:82:in `evaluate'
         # /tmp/d20160121-5693-dr4t1w/solution.rb:49:in `[]'
         # /tmp/d20160121-5693-dr4t1w/spec.rb:123:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-dr4t1w/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-dr4t1w/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-dr4t1w/solution.rb:132:in `verify'
         # /tmp/d20160121-5693-dr4t1w/solution.rb:97:in `evaluate_formula'
         # /tmp/d20160121-5693-dr4t1w/solution.rb:93:in `evaluate_string'
         # /tmp/d20160121-5693-dr4t1w/solution.rb:82:in `evaluate'
         # /tmp/d20160121-5693-dr4t1w/solution.rb:49:in `[]'
         # /tmp/d20160121-5693-dr4t1w/spec.rb:153:in `block (4 levels) in <top (required)>'
         # /tmp/d20160121-5693-dr4t1w/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-dr4t1w/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.03796 seconds
40 examples, 2 failures

Failed examples:

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

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

Георги обнови решението на 08.01.2016 16:50 (преди над 8 години)

+class Spreadsheet
+private
+ def parse(text)
+ lines = text.strip.split(/\n/)
+ lines.map { |line| line.strip.split(/\t| {2,}/) }
+ end
+
+ def get_cell_index(cell_index)
+ return nil unless cell_index = Expression.index?(cell_index)
+
+ column = cell_index[1].each_byte.reverse_each.map { |byte| byte - 64 }
+ column.map!.with_index { |byte, index| byte * (26 ** index) }
+
+ row = cell_index[2].to_i - 1
+ column = column.reduce(:+) - 1
+
+ [row, column]
+ end
+
+ def validate_cell_index(cell_index)
+ row, column = get_cell_index cell_index
+ if row.nil?
+ raise Error, "Invalid cell index '#{cell_index}'"
+ elsif @table[row].nil? || @table[row][column].nil?
+ raise Error, "Cell '#{cell_index}' does not exist"
+ end
+ end
+
+public
+ def initialize(table = "")
+ @table = parse table
+ end
+
+ def empty?
+ @table.empty?
+ end
+
+ def cell_at(cell_index)
+ validate_cell_index cell_index
+
+ row, column = get_cell_index cell_index
+
+ @table[row][column]
+ end
+
+ def [](cell_index)
+ cell = cell_at cell_index
+
+ Expression.evaluate(cell, self).to_s
+ end
+
+ def to_s
+ @table.map do |row|
+ row.map{ |cell| Expression.evaluate(cell, self).to_s }.join("\t")
+ end.join("\n")
+ end
+
+ class Error < RuntimeError
+
+ end
+
+ module Expression
+ def self.match?(string)
+ not string.match(/^=/).nil?
+ end
+
+ def self.number?(string)
+ string.match(/^\d+(\.\d+)?$/)
+ end
+
+ def self.index?(cell_index)
+ cell_index.match(/^([A-Z]+)(\d+)$/)
+ end
+
+ def self.normalize(result)
+ result = ("%.2f" % result).to_f
+
+ result = result.floor if result == result.floor
+ result.to_s
+ end
+
+ def self.evaluate(string, sheet)
+ return string unless match? string
+
+ expression = string.match(/^=([\w.]+)/)[1]
+
+ return normalize(expression) if number? expression
+
+ return sheet[expression] if index? expression
+
+ normalize evaluate_formula(string, sheet)
+ end
+
+ def self.evaluate_formula(formula, sheet)
+ Formula.verify formula
+
+ formula, *args = formula.scan(/[\w.=]+/)
+ formula.sub!(/^=/, "").downcase!
+
+ args.map! { |argument| Expression.evaluate(argument, sheet).to_f }
+
+ Formula.send(formula, *args)
+ end
+ end
+
+ module Formula
+ def self.add(first, second, *more)
+ first + second + more.reduce(0, :+)
+ end
+
+ def self.multiply(first, second, *more)
+ first * second * more.reduce(1, :*)
+ end
+
+ def self.subtract(first, second)
+ first - second
+ end
+
+ def self.divide(first, second)
+ first / second
+ end
+
+ def self.mod(first, second)
+ first % second
+ end
+
+ def self.verify(string)
+ unless string.match(/^=([A-Z]+\([\w\s,.=]+\))$/) &&
+ string.count(",") == string.scan(/[\w.=]+/).size - 2
+ raise Error, "Invalid expression '#{string}'"
+ end
+ end
+
+ def self.verify_arguments(formula, args)
+ real_args = method(formula).arity
+ message = "Wrong number of arguments for '#{formula.upcase}': expected "
+ if real_args > 0 && real_args != args
+ raise Error, message + "#{real_args}, got #{args}"
+ elsif real_args < 0 && real_args.abs - 1 > args
+ raise Error, message + "at least #{real_args.abs - 1}, got #{args}"
+ end
+ end
+
+ # def self.method_missing(name, *args, &block)
+ # raise Error, "Unknown function '#{name.upcase}'"
+ # end
+
+ def self.send(name, *args, &block)
+ if methods.include?(name.to_sym)
+ verify_arguments(name, args.size)
+ super
+ elsif
+ raise Error, "Unknown function '#{name.upcase}'"
+ end
+ end
+ end
+end

Георги обнови решението на 11.01.2016 16:10 (преди над 8 години)

class Spreadsheet
private
def parse(text)
lines = text.strip.split(/\n/)
lines.map { |line| line.strip.split(/\t| {2,}/) }
end
def get_cell_index(cell_index)
return nil unless cell_index = Expression.index?(cell_index)
column = cell_index[1].each_byte.reverse_each.map { |byte| byte - 64 }
column.map!.with_index { |byte, index| byte * (26 ** index) }
row = cell_index[2].to_i - 1
column = column.reduce(:+) - 1
[row, column]
end
def validate_cell_index(cell_index)
row, column = get_cell_index cell_index
if row.nil?
raise Error, "Invalid cell index '#{cell_index}'"
elsif @table[row].nil? || @table[row][column].nil?
raise Error, "Cell '#{cell_index}' does not exist"
end
end
public
def initialize(table = "")
@table = parse table
end
def empty?
@table.empty?
end
def cell_at(cell_index)
validate_cell_index cell_index
row, column = get_cell_index cell_index
@table[row][column]
end
def [](cell_index)
cell = cell_at cell_index
Expression.evaluate(cell, self).to_s
end
def to_s
@table.map do |row|
- row.map{ |cell| Expression.evaluate(cell, self).to_s }.join("\t")
+ row.map do |cell|
+ Expression.evaluate(cell, self).to_s
+ end.join("\t")
end.join("\n")
end
class Error < RuntimeError
-
end
module Expression
def self.match?(string)
not string.match(/^=/).nil?
end
def self.number?(string)
string.match(/^\d+(\.\d+)?$/)
end
def self.index?(cell_index)
cell_index.match(/^([A-Z]+)(\d+)$/)
end
def self.normalize(result)
- result = ("%.2f" % result).to_f
-
- result = result.floor if result == result.floor
- result.to_s
+ result = result.to_f
+ if result == result.floor then ("%d" % result) else ("%.2f" % result) end
end
def self.evaluate(string, sheet)
- return string unless match? string
+ string = evaluate_string(string, sheet) if match? string
+ string
+ end
+private
+ def self.evaluate_string(string, sheet)
+ expression = string.match(/[\w.]+/)[0]
- expression = string.match(/^=([\w.]+)/)[1]
-
return normalize(expression) if number? expression
return sheet[expression] if index? expression
normalize evaluate_formula(string, sheet)
end
def self.evaluate_formula(formula, sheet)
Formula.verify formula
- formula, *args = formula.scan(/[\w.=]+/)
- formula.sub!(/^=/, "").downcase!
+ formula, *args = formula.scan(/[\w.]+/)
+ formula = formula.sub(/=/, "").downcase
- args.map! { |argument| Expression.evaluate(argument, sheet).to_f }
+ args.map! { |argument| Expression.evaluate_string(argument, sheet).to_f }
Formula.send(formula, *args)
end
end
module Formula
def self.add(first, second, *more)
first + second + more.reduce(0, :+)
end
def self.multiply(first, second, *more)
first * second * more.reduce(1, :*)
end
def self.subtract(first, second)
first - second
end
def self.divide(first, second)
first / second
end
def self.mod(first, second)
first % second
end
def self.verify(string)
- unless string.match(/^=([A-Z]+\([\w\s,.=]+\))$/) &&
- string.count(",") == string.scan(/[\w.=]+/).size - 2
- raise Error, "Invalid expression '#{string}'"
+ unless string.match(/^= ?[A-Z]+\([\w\s,.=]+\)$/) &&
+ string.count(",") == string.scan(/[\w.]+/).size - 2
+ raise Error, "Invalid expression '#{string.sub(/^=/, "")}'"
end
end
def self.verify_arguments(formula, args)
real_args = method(formula).arity
message = "Wrong number of arguments for '#{formula.upcase}': expected "
if real_args > 0 && real_args != args
raise Error, message + "#{real_args}, got #{args}"
elsif real_args < 0 && real_args.abs - 1 > args
raise Error, message + "at least #{real_args.abs - 1}, got #{args}"
end
end
- # def self.method_missing(name, *args, &block)
- # raise Error, "Unknown function '#{name.upcase}'"
- # end
-
def self.send(name, *args, &block)
if methods.include?(name.to_sym)
verify_arguments(name, args.size)
super
elsif
raise Error, "Unknown function '#{name.upcase}'"
end
end
end
-end
+end

Георги обнови решението на 11.01.2016 17:17 (преди над 8 години)

class Spreadsheet
private
def parse(text)
lines = text.strip.split(/\n/)
- lines.map { |line| line.strip.split(/\t| {2,}/) }
+ lines.map { |line| line.strip.split(/\t+| {2,}/).map(&:strip) }
end
def get_cell_index(cell_index)
return nil unless cell_index = Expression.index?(cell_index)
column = cell_index[1].each_byte.reverse_each.map { |byte| byte - 64 }
column.map!.with_index { |byte, index| byte * (26 ** index) }
row = cell_index[2].to_i - 1
column = column.reduce(:+) - 1
[row, column]
end
def validate_cell_index(cell_index)
row, column = get_cell_index cell_index
if row.nil?
raise Error, "Invalid cell index '#{cell_index}'"
elsif @table[row].nil? || @table[row][column].nil?
raise Error, "Cell '#{cell_index}' does not exist"
end
end
public
def initialize(table = "")
@table = parse table
end
def empty?
@table.empty?
end
def cell_at(cell_index)
validate_cell_index cell_index
row, column = get_cell_index cell_index
@table[row][column]
end
def [](cell_index)
cell = cell_at cell_index
Expression.evaluate(cell, self).to_s
end
def to_s
@table.map do |row|
row.map do |cell|
Expression.evaluate(cell, self).to_s
end.join("\t")
end.join("\n")
end
class Error < RuntimeError
end
module Expression
def self.match?(string)
not string.match(/^=/).nil?
end
def self.number?(string)
string.match(/^\d+(\.\d+)?$/)
end
def self.index?(cell_index)
cell_index.match(/^([A-Z]+)(\d+)$/)
end
def self.normalize(result)
result = result.to_f
if result == result.floor then ("%d" % result) else ("%.2f" % result) end
end
def self.evaluate(string, sheet)
string = evaluate_string(string, sheet) if match? string
string
end
private
def self.evaluate_string(string, sheet)
expression = string.match(/[\w.]+/)[0]
return normalize(expression) if number? expression
return sheet[expression] if index? expression
normalize evaluate_formula(string, sheet)
end
def self.evaluate_formula(formula, sheet)
Formula.verify formula
formula, *args = formula.scan(/[\w.]+/)
formula = formula.sub(/=/, "").downcase
args.map! { |argument| Expression.evaluate_string(argument, sheet).to_f }
Formula.send(formula, *args)
end
end
module Formula
def self.add(first, second, *more)
first + second + more.reduce(0, :+)
end
def self.multiply(first, second, *more)
first * second * more.reduce(1, :*)
end
def self.subtract(first, second)
first - second
end
def self.divide(first, second)
first / second
end
def self.mod(first, second)
first % second
end
def self.verify(string)
unless string.match(/^= ?[A-Z]+\([\w\s,.=]+\)$/) &&
string.count(",") == string.scan(/[\w.]+/).size - 2
raise Error, "Invalid expression '#{string.sub(/^=/, "")}'"
end
end
def self.verify_arguments(formula, args)
real_args = method(formula).arity
message = "Wrong number of arguments for '#{formula.upcase}': expected "
if real_args > 0 && real_args != args
raise Error, message + "#{real_args}, got #{args}"
elsif real_args < 0 && real_args.abs - 1 > args
raise Error, message + "at least #{real_args.abs - 1}, got #{args}"
end
end
def self.send(name, *args, &block)
if methods.include?(name.to_sym)
verify_arguments(name, args.size)
super
elsif
raise Error, "Unknown function '#{name.upcase}'"
end
end
end
end