- Коректно
- 8 успешни тест(а)
- 0 неуспешни тест(а)
........ Finished in 0.0099 seconds 8 examples, 0 failures
Срокът за предаване на решения е отминал
Изберете си число между 1 и 10. Умножете това число по 2. Умножете полученото по 5. Разделете новия резултат на числото, което бяхте избрали първоначално. Извадете 7 от новия резултат.
Абракадабра!
Получихте 3, нали?
Всички сме чували/представяли такива трикове, дори сме бивали дълбоко впечатлявани от тях, когато сме били невръстни. Разбира се, тестването на достоверността на тези трикове би било по-лесно, ако се напише малко код. Един изключително полезен съвет от книгата "The Pragmatic Programmer: From Journeyman to Master" e:
Да опитаме.
Искаме да създадем мини-език, a.k.a. DSL в който „операторите“ са манипулациите с числа, близки до естествения език, с който бихме описали трика. Например, трикът, който представихме в началото, може да бъде записан и проверен по следния начин:
Charlatan.trick do
pick_from 1..10
multiply_by 2
multiply_by 5
divide_by :your_number
subtract 7
you_should_get 3
end
За целите на това предизвикателство, ще приемем, че горният код е по-четим заради близостта си до "проблемната област" (domain), от този:
(1..10).all? do |number|
((number * 2 * 5) / number) - 7 == 3
end
Затова, създайте модул Charlatan
, в който има метод Charlatan.trick
, приемащ
блок, който дефинира „проверяваща програма“ от следния вид:
pick_from <range>
– задава интервал от цели числа, за които ще тестваме
дали трикът работи. Приема само области от числа.add <number>
– добавя число към текущия резултат.subtract <number>
– изважда число от текущия резултат.multiply_by <number>
– умножава текущия резултат по число.divide_by <number>
– Разделя (целочислено) текущия резултат на число.you_should_get <number>
– последният ред на програмата указва числото,
което трябва да бъде „разпознато“ от шарлатана в края на трика.Вместо число, на всички операции без pick_from
, може да се подаде символът
:your_number
, който трябва да представлява стойността на първоначално
избраното число.
Изпълнението на Charlatan.trick
трябва да връща true
, или false
, в
зависимост от това дали манипулациите върху всяко число от областта са довели
до числото, подадено като аргумент на you_should_get
.
Примери:
Charlatan.trick do
pick_from 1..1
add 1
you_should_get 2
end # => true
Charlatan.trick do
pick_from 1..2
add 2
subtract 2
you_should_get :your_number
end # => true
Charlatan.trick do
pick_from 10..100
multiply_by 3
you_should_get 1000
end # => false
Забележка: Подадените на Charlatan.trick
програми ще бъдат коректни,
всички ще започват с pick_from
и ще завършват с you_should_get
. Също така,
няма да се подават некоректни данни, както сме казвали много пъти досега.
Ако изпитвате затруднения да измислите как да реализирате този DSL, питайте във форума или ни пишете.
........ Finished in 0.0099 seconds 8 examples, 0 failures
........ Finished in 0.00994 seconds 8 examples, 0 failures
........ Finished in 0.01418 seconds 8 examples, 0 failures
........ Finished in 0.01136 seconds 8 examples, 0 failures
true .true .true .true .true .true .true .true false . Finished in 0.01011 seconds 8 examples, 0 failures
........ Finished in 0.01128 seconds 8 examples, 0 failures
........ Finished in 0.0101 seconds 8 examples, 0 failures
........ Finished in 0.0097 seconds 8 examples, 0 failures
........ Finished in 0.00983 seconds 8 examples, 0 failures
........ Finished in 0.01819 seconds 8 examples, 0 failures
true .true .true .true .true .Ftrue .F Failures: 1) Charlatan allows :your_number as an argument to arithmetic methods Failure/Error: you_should_get 0 TypeError: :your_number can't be coerced into Fixnum # /tmp/d20140105-32545-2su3w4/solution.rb:46:in `-' # /tmp/d20140105-32545-2su3w4/solution.rb:46:in `execute_action' # /tmp/d20140105-32545-2su3w4/solution.rb:56:in `block (2 levels) in you_should_get' # /tmp/d20140105-32545-2su3w4/solution.rb:56:in `each' # /tmp/d20140105-32545-2su3w4/solution.rb:56:in `block in you_should_get' # /tmp/d20140105-32545-2su3w4/solution.rb:54:in `each' # /tmp/d20140105-32545-2su3w4/solution.rb:54:in `you_should_get' # /tmp/d20140105-32545-2su3w4/spec.rb:45:in `block (3 levels) in <top (required)>' # /tmp/d20140105-32545-2su3w4/solution.rb:4:in `instance_eval' # /tmp/d20140105-32545-2su3w4/solution.rb:4:in `trick' # /tmp/d20140105-32545-2su3w4/spec.rb:42: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) Charlatan actually performs calculations Failure/Error: you_should_get 3 TypeError: :your_number can't be coerced into Fixnum # /tmp/d20140105-32545-2su3w4/solution.rb:50:in `/' # /tmp/d20140105-32545-2su3w4/solution.rb:50:in `execute_action' # /tmp/d20140105-32545-2su3w4/solution.rb:56:in `block (2 levels) in you_should_get' # /tmp/d20140105-32545-2su3w4/solution.rb:56:in `each' # /tmp/d20140105-32545-2su3w4/solution.rb:56:in `block in you_should_get' # /tmp/d20140105-32545-2su3w4/solution.rb:54:in `each' # /tmp/d20140105-32545-2su3w4/solution.rb:54:in `you_should_get' # /tmp/d20140105-32545-2su3w4/spec.rb:63:in `block (3 levels) in <top (required)>' # /tmp/d20140105-32545-2su3w4/solution.rb:4:in `instance_eval' # /tmp/d20140105-32545-2su3w4/solution.rb:4:in `trick' # /tmp/d20140105-32545-2su3w4/spec.rb:57: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.01031 seconds 8 examples, 2 failures Failed examples: rspec /tmp/d20140105-32545-2su3w4/spec.rb:41 # Charlatan allows :your_number as an argument to arithmetic methods rspec /tmp/d20140105-32545-2su3w4/spec.rb:56 # Charlatan actually performs calculations
........ Finished in 0.0096 seconds 8 examples, 0 failures
........ Finished in 0.01239 seconds 8 examples, 0 failures
........ Finished in 0.01115 seconds 8 examples, 0 failures
........ Finished in 0.00961 seconds 8 examples, 0 failures
........ Finished in 0.00983 seconds 8 examples, 0 failures
........ Finished in 0.01043 seconds 8 examples, 0 failures
........ Finished in 0.01014 seconds 8 examples, 0 failures
........ Finished in 0.00972 seconds 8 examples, 0 failures
....F..F Failures: 1) Charlatan performs division Failure/Error: divide_by 2 NoMethodError: undefined method `divide_by' for Charlatan:Module # /tmp/d20140105-32545-qao338/spec.rb:36:in `block (3 levels) in <top (required)>' # /tmp/d20140105-32545-qao338/solution.rb:5:in `instance_eval' # /tmp/d20140105-32545-qao338/solution.rb:5:in `trick' # /tmp/d20140105-32545-qao338/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)>' 2) Charlatan actually performs calculations Failure/Error: divide_by :your_number NoMethodError: undefined method `divide_by' for Charlatan:Module # /tmp/d20140105-32545-qao338/spec.rb:61:in `block (3 levels) in <top (required)>' # /tmp/d20140105-32545-qao338/solution.rb:5:in `instance_eval' # /tmp/d20140105-32545-qao338/solution.rb:5:in `trick' # /tmp/d20140105-32545-qao338/spec.rb:57: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.00986 seconds 8 examples, 2 failures Failed examples: rspec /tmp/d20140105-32545-qao338/spec.rb:33 # Charlatan performs division rspec /tmp/d20140105-32545-qao338/spec.rb:56 # Charlatan actually performs calculations
........ Finished in 0.00973 seconds 8 examples, 0 failures
........ Finished in 0.00969 seconds 8 examples, 0 failures
........ Finished in 0.01017 seconds 8 examples, 0 failures
........ Finished in 0.0105 seconds 8 examples, 0 failures
F.....F. Failures: 1) Charlatan works without operations Failure/Error: you_should_get 1 NoMethodError: undefined method `all?' for nil:NilClass # /tmp/d20140105-32545-1j4yxtb/solution.rb:37:in `you_should_get' # /tmp/d20140105-32545-1j4yxtb/spec.rb:5:in `block (3 levels) in <top (required)>' # /tmp/d20140105-32545-1j4yxtb/solution.rb:9:in `instance_eval' # /tmp/d20140105-32545-1j4yxtb/solution.rb:9:in `execute' # /tmp/d20140105-32545-1j4yxtb/solution.rb:55:in `trick' # /tmp/d20140105-32545-1j4yxtb/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) Charlatan accepts :your_number as an argument to you_should_get Failure/Error: you_should_get :your_number NoMethodError: undefined method `first' for nil:NilClass # /tmp/d20140105-32545-1j4yxtb/solution.rb:35:in `you_should_get' # /tmp/d20140105-32545-1j4yxtb/spec.rb:52:in `block (3 levels) in <top (required)>' # /tmp/d20140105-32545-1j4yxtb/solution.rb:9:in `instance_eval' # /tmp/d20140105-32545-1j4yxtb/solution.rb:9:in `execute' # /tmp/d20140105-32545-1j4yxtb/solution.rb:55:in `trick' # /tmp/d20140105-32545-1j4yxtb/spec.rb:50: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.00997 seconds 8 examples, 2 failures Failed examples: rspec /tmp/d20140105-32545-1j4yxtb/spec.rb:2 # Charlatan works without operations rspec /tmp/d20140105-32545-1j4yxtb/spec.rb:49 # Charlatan accepts :your_number as an argument to you_should_get
........ Finished in 0.00962 seconds 8 examples, 0 failures
FFFFF... Failures: 1) Charlatan works without operations Failure/Error: Charlatan.trick do expected: true value got: false # /tmp/d20140105-32545-158er48/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) Charlatan performs addition Failure/Error: Charlatan.trick do expected: true value got: false # /tmp/d20140105-32545-158er48/spec.rb:10: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) Charlatan performs substraction Failure/Error: Charlatan.trick do expected: true value got: false # /tmp/d20140105-32545-158er48/spec.rb:18: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) Charlatan performs multiplication Failure/Error: Charlatan.trick do expected: true value got: false # /tmp/d20140105-32545-158er48/spec.rb:26: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) Charlatan performs division Failure/Error: Charlatan.trick do expected: true value got: false # /tmp/d20140105-32545-158er48/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)>' Finished in 0.01026 seconds 8 examples, 5 failures Failed examples: rspec /tmp/d20140105-32545-158er48/spec.rb:2 # Charlatan works without operations rspec /tmp/d20140105-32545-158er48/spec.rb:9 # Charlatan performs addition rspec /tmp/d20140105-32545-158er48/spec.rb:17 # Charlatan performs substraction rspec /tmp/d20140105-32545-158er48/spec.rb:25 # Charlatan performs multiplication rspec /tmp/d20140105-32545-158er48/spec.rb:33 # Charlatan performs division
........ Finished in 0.01245 seconds 8 examples, 0 failures
........ Finished in 0.00964 seconds 8 examples, 0 failures
.......F Failures: 1) Charlatan actually performs calculations Failure/Error: Charlatan.trick do expected: true value got: false # /tmp/d20140105-32545-1y39hg6/spec.rb:57: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.00985 seconds 8 examples, 1 failure Failed examples: rspec /tmp/d20140105-32545-1y39hg6/spec.rb:56 # Charlatan actually performs calculations