Решение на Четвърта задача от Кристиян Азманов

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

Към профила на Кристиян Азманов

Резултати

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

Код

module Asm
module Commands
def mov destination_register, source
receiver = destination_register
if source == :ax then send("#{receiver.to_s}_assign",@ax_real) end
if source == :bx then send("#{receiver.to_s}_assign",@bx_real) end
if source == :cx then send("#{receiver.to_s}_assign",@cx_real) end
if source == :dx then send("#{receiver.to_s}_assign",@dx_real) end
if source.class != Symbol then send("#{receiver.to_s}_assign",source) end
end
def inc destination_register, source = 1
receiver = destination_register
if source == :ax then send("#{receiver.to_s}_increment",@ax_real) end
if source == :bx then send("#{receiver.to_s}_increment",@bx_real) end
if source == :cx then send("#{receiver.to_s}_increment",@cx_real) end
if source == :dx then send("#{receiver.to_s}_increment",@dx_real) end
if source.class != Symbol then send("#{receiver.to_s}_increment",source) end
end
def dec destination_register, source = 1
receiver = destination_register
if source == :ax then send("#{receiver.to_s}_decrement",@ax_real) end
if source == :bx then send("#{receiver.to_s}_decrement",@bx_real) end
if source == :cx then send("#{receiver.to_s}_decrement",@cx_real) end
if source == :dx then send("#{receiver.to_s}_decrement",@dx_real) end
if source.class != Symbol then send("#{receiver.to_s}_decrement",source) end
end
def cmp register, source
receiver = register
if source == :ax then send("#{receiver.to_s}_compare",@ax_real) end
if source == :bx then send("#{receiver.to_s}_compare",@bx_real) end
if source == :cx then send("#{receiver.to_s}_compare",@cx_real) end
if source == :dx then send("#{receiver.to_s}_compare",@dx_real) end
if source.class != Symbol then send("#{receiver.to_s}_compare",source) end
end
module AsignOperations
def ax_assign value
@ax_real = value
end
def bx_assign value
@bx_real = value
end
def cx_assign value
@cx_real = value
end
def dx_assign value
@dx_real = value
end
end
module IncrementOperations
def ax_increment value
@ax_real += value
end
def bx_increment value
@bx_real += value
end
def cx_increment value
@cx_real += value
end
def dx_increment value
@dx_real += value
end
end
module DecrementOperations
def ax_decrement value
@ax_real -= value
end
def bx_decrement value
@bx_real -= value
end
def cx_decrement value
@cx_real -= value
end
def dx_decrement value
@dx_real -= value
end
end
module CompareOperations
def ax_compare value
@last_comparison = (@ax_real <=> value)
end
def bx_compare value
@last_comparison = (@bx_real <=> value)
end
def cx_compare value
@last_comparison = (@cx_real <=> value)
end
def dx_compare value
@last_comparison = (@dx_real <=> value)
end
end
end
class Evaluator
def initialize
@ax, @bx, @cx, @dx = :ax, :bx, :cx, :dx
@ax_real, @bx_real, @cx_real, @dx_real = 0, 0, 0, 0
end
#def show
# p [@ax_real,@bx_real,@cx_real,@dx_real,@last_comparison]
#end
end
def self.asm(&block)
(Evaluator.new).instance_eval &block
end
end

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

FFFFFFFF

Failures:

  1) Asm.asm works with empty programs
     Failure/Error: Asm.asm {}.should eq [0, 0, 0, 0]
       
       expected: [0, 0, 0, 0]
            got: nil
       
       (compared using ==)
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:3:in `block (2 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) Asm.asm implements MOV
     Failure/Error: mov ax, 3
     NameError:
       undefined local variable or method `ax' for #<Asm::Evaluator:0xba199b40>
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:8:in `block (3 levels) in <top (required)>'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `instance_eval'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `asm'
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:7:in `block (2 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) Asm.asm implements INC
     Failure/Error: inc ax
     NameError:
       undefined local variable or method `ax' for #<Asm::Evaluator:0xba199924>
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:16:in `block (3 levels) in <top (required)>'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `instance_eval'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `asm'
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:15:in `block (2 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) Asm.asm implements DEC
     Failure/Error: mov ax, 3
     NameError:
       undefined local variable or method `ax' for #<Asm::Evaluator:0xba196a6c>
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:24:in `block (3 levels) in <top (required)>'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `instance_eval'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `asm'
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:23:in `block (2 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) Asm.asm implements CMP
     Failure/Error: mov ax, 2
     NameError:
       undefined local variable or method `ax' for #<Asm::Evaluator:0xba195040>
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:35:in `block (3 levels) in <top (required)>'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `instance_eval'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `asm'
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:34:in `block (2 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) Asm.asm implements JMP
     Failure/Error: mov cx, 1
     NameError:
       undefined local variable or method `cx' for #<Asm::Evaluator:0xba192ed0>
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:69:in `block (3 levels) in <top (required)>'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `instance_eval'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `asm'
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:68:in `block (2 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) Asm.asm implements LABEL
     Failure/Error: mov ax, 1
     NameError:
       undefined local variable or method `ax' for #<Asm::Evaluator:0xba190b44>
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:79:in `block (3 levels) in <top (required)>'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `instance_eval'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `asm'
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:78:in `block (2 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) Asm.asm can be used to find GCD of two numbers
     Failure/Error: mov ax, 40
     NameError:
       undefined local variable or method `ax' for #<Asm::Evaluator:0xba18b860>
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:90:in `block (3 levels) in <top (required)>'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `instance_eval'
     # /tmp/d20140115-8451-1j1ayzr/solution.rb:123:in `asm'
     # /tmp/d20140115-8451-1j1ayzr/spec.rb:89:in `block (2 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.00728 seconds
8 examples, 8 failures

Failed examples:

rspec /tmp/d20140115-8451-1j1ayzr/spec.rb:2 # Asm.asm works with empty programs
rspec /tmp/d20140115-8451-1j1ayzr/spec.rb:6 # Asm.asm implements MOV
rspec /tmp/d20140115-8451-1j1ayzr/spec.rb:14 # Asm.asm implements INC
rspec /tmp/d20140115-8451-1j1ayzr/spec.rb:22 # Asm.asm implements DEC
rspec /tmp/d20140115-8451-1j1ayzr/spec.rb:33 # Asm.asm implements CMP
rspec /tmp/d20140115-8451-1j1ayzr/spec.rb:67 # Asm.asm implements JMP
rspec /tmp/d20140115-8451-1j1ayzr/spec.rb:77 # Asm.asm implements LABEL
rspec /tmp/d20140115-8451-1j1ayzr/spec.rb:88 # Asm.asm can be used to find GCD of two numbers

История (2 версии и 8 коментара)

Кристиян обнови решението на 12.01.2014 12:13 (преди почти 11 години)

+module Asm
+ module Commands
+ def mov destination_register, source
+ receiver = destination_register
+ if source == :ax then send("#{receiver.to_s}_real=",@ax_real) end
+ if source == :bx then send("#{receiver.to_s}_real=",@bx_real) end
+ if source == :cx then send("#{receiver.to_s}_real=",@cx_real) end
+ if source == :dx then send("#{receiver.to_s}_real=",@dx_real) end
+ if source.class != Symbol then send("#{receiver.to_s}_real=",source) end
+ end
+ end
+
+ class Evaluator
+ include Commands
+ def initialize
+ @ax, @bx, @cx, @dx = :ax, :bx, :cx, :dx
+ @ax_real, @bx_real, @cx_real, @dx_real = 0, 0, 0, 0
+ end
+
+ def ax_real= (value)
+ @ax_real = value
+ end
+
+ def bx_real= (value)
+ @bx_real = value
+ end
+
+ def cx_real= (value)
+ @cx_real = value
+ end
+
+ def dx_real= (value)
+ @dx_real = value
+ end
+ end
+ def self.asm(&block)
+ (Evaluator.new).instance_eval &block
+ end
+end

Кристиян обнови решението на 12.01.2014 15:45 (преди почти 11 години)

module Asm
module Commands
def mov destination_register, source
receiver = destination_register
- if source == :ax then send("#{receiver.to_s}_real=",@ax_real) end
- if source == :bx then send("#{receiver.to_s}_real=",@bx_real) end
- if source == :cx then send("#{receiver.to_s}_real=",@cx_real) end
- if source == :dx then send("#{receiver.to_s}_real=",@dx_real) end
- if source.class != Symbol then send("#{receiver.to_s}_real=",source) end
+ if source == :ax then send("#{receiver.to_s}_assign",@ax_real) end
+ if source == :bx then send("#{receiver.to_s}_assign",@bx_real) end
+ if source == :cx then send("#{receiver.to_s}_assign",@cx_real) end
+ if source == :dx then send("#{receiver.to_s}_assign",@dx_real) end
+ if source.class != Symbol then send("#{receiver.to_s}_assign",source) end
end
- end
- class Evaluator
- include Commands
- def initialize
- @ax, @bx, @cx, @dx = :ax, :bx, :cx, :dx
- @ax_real, @bx_real, @cx_real, @dx_real = 0, 0, 0, 0
+ def inc destination_register, source = 1
+ receiver = destination_register
+ if source == :ax then send("#{receiver.to_s}_increment",@ax_real) end
+ if source == :bx then send("#{receiver.to_s}_increment",@bx_real) end
+ if source == :cx then send("#{receiver.to_s}_increment",@cx_real) end
+ if source == :dx then send("#{receiver.to_s}_increment",@dx_real) end
+ if source.class != Symbol then send("#{receiver.to_s}_increment",source) end
end
- def ax_real= (value)
+ def dec destination_register, source = 1
+ receiver = destination_register
+ if source == :ax then send("#{receiver.to_s}_decrement",@ax_real) end
+ if source == :bx then send("#{receiver.to_s}_decrement",@bx_real) end
+ if source == :cx then send("#{receiver.to_s}_decrement",@cx_real) end
+ if source == :dx then send("#{receiver.to_s}_decrement",@dx_real) end
+ if source.class != Symbol then send("#{receiver.to_s}_decrement",source) end
+ end
+
+ def cmp register, source
+ receiver = register
+ if source == :ax then send("#{receiver.to_s}_compare",@ax_real) end
+ if source == :bx then send("#{receiver.to_s}_compare",@bx_real) end
+ if source == :cx then send("#{receiver.to_s}_compare",@cx_real) end
+ if source == :dx then send("#{receiver.to_s}_compare",@dx_real) end
+ if source.class != Symbol then send("#{receiver.to_s}_compare",source) end
+ end
+
+ module AsignOperations
+ def ax_assign value
@ax_real = value
end
- def bx_real= (value)
+ def bx_assign value
@bx_real = value
end
- def cx_real= (value)
+ def cx_assign value
@cx_real = value
end
- def dx_real= (value)
+ def dx_assign value
@dx_real = value
end
+ end
+
+ module IncrementOperations
+ def ax_increment value
+ @ax_real += value
+ end
+
+ def bx_increment value
+ @bx_real += value
+ end
+
+ def cx_increment value
+ @cx_real += value
+ end
+
+ def dx_increment value
+ @dx_real += value
+ end
+ end
+
+ module DecrementOperations
+ def ax_decrement value
+ @ax_real -= value
+ end
+
+ def bx_decrement value
+ @bx_real -= value
+ end
+
+ def cx_decrement value
+ @cx_real -= value
+ end
+
+ def dx_decrement value
+ @dx_real -= value
+ end
+ end
+
+ module CompareOperations
+ def ax_compare value
+ @last_comparison = (@ax_real <=> value)
+ end
+
+ def bx_compare value
+ @last_comparison = (@bx_real <=> value)
+ end
+
+ def cx_compare value
+ @last_comparison = (@cx_real <=> value)
+ end
+
+ def dx_compare value
+ @last_comparison = (@dx_real <=> value)
+ end
+ end
+
+ end
+ class Evaluator
+ def initialize
+ @ax, @bx, @cx, @dx = :ax, :bx, :cx, :dx
+ @ax_real, @bx_real, @cx_real, @dx_real = 0, 0, 0, 0
+ end
+
+ #def show
+ # p [@ax_real,@bx_real,@cx_real,@dx_real,@last_comparison]
+ #end
end
def self.asm(&block)
(Evaluator.new).instance_eval &block
end
end

Дотук имаш доста повторения (лошо е, виж DRY принципа). Какво ще стане, ако утре scope-а на задачата се промени и някой каже „Трябват ни още 4 регистъра - ex, fx, gx и hx“? Опитай се да абстрахираш операциите върху регистър и не hardcode-вай имената на регистрите при имплементацията на операциите.

Да, осъзнавам го, но просто нямам достатъчно знания, които да ми помогнат да избегна това. В момента дори съм се отказал да решавам задачата понеже стгнах до момента с "label" командата, при която няма как да хардкодна идващите аргументи. Вероятно и подхпдът ми като цяло е грешен. Просто следвах принципа на решаване на предизвикателството " Шарлатан", но явно тук няма да ми се получат нещата.

Опитах да направя 'label' с method_missing, но когато имам 'label cycle' тук и двете се възприемат като методи и реално с правят 2 извиквания на method_missing. Като цяло смятам, че подходът ми е грешен, затова ще я зарежа тази задача и ще видя решенията на колегите после. Иначе, мерси за Hint-a!