2

Been working on this Kata for quite some time now and still can't figure out what I'm missing. The question is given two integers a and b, which can be positive or negative, find the sum of all the numbers between including them too and return it. If the two numbers are equal return a or b.

So far this is what my solution looks like:

def get_sum(a,b)
  sum = [a+=b].sum      
  if sum == a or b 
    return a
  end 
end

and this is the output result:

Test Passed: Value == 1
Test Passed: Value == 3
Expected: 14, instead got: 4
Expected: 127759, instead got: 509
Expected: 44178, instead got: 444

I believe the keyword is all the numbers between but I'm not sure how to write that syntactically. I've included some examples below for further clarification.

get_sum(1, 0) == 1   # 1 + 0 = 1
get_sum(1, 2) == 3   # 1 + 2 = 3
get_sum(0, 1) == 1   # 0 + 1 = 1
get_sum(1, 1) == 1   # 1 Since both are same
get_sum(-1, 0) == -1 # -1 + 0 = -1
get_sum(-1, 2) == 2  # -1 + 0 + 1 + 2 = 2

https://www.codewars.com/kata/55f2b110f61eb01779000053/train/ruby

KobbyAdarkwa
  • 181
  • 2
  • 16
  • Could you give a link to the original question? – Aetherus Sep 17 '20 at 08:35
  • where is `return sum` ? – MBo Sep 17 '20 at 08:37
  • 2
    I am not familiar with ruby, but I see at least three very suspicious things in your code. 1) Why is there an `a+=b`? "all the numbers between a and b including them" means `a + a+1 + a+2 + a+3 + ... + b`. There is no `a+b` in that list. For instance if `a=100, b=120`, then `a+b=220` is not helpful. 2) `if sum == a or b`. Judging from https://ruby-doc.org/core-2.6.2/doc/syntax/precedence_rdoc.html this means "if sum == a, or if b is true". What did you intend with this test? I think in ruby, everything is true except `false` and `nil`, so `b` is always true. – Stef Sep 17 '20 at 08:45
  • 3) in some cases you return `a`. In other cases you don't return anything. It looks like you never return a sum. – Stef Sep 17 '20 at 08:45
  • Finally, knowing that for any nonnegative `n`, `1+2+...+n = n*(n+1)/2`, we get: `a + a+1 + a+2 + ... + b = a + a+1 + a+2 + ... + a+(b-a) = (b-a+1)*a + 1+2+...+(b-a) = (b-a+1)*a + (b-a)*(b-a+1)/2 = (b-a+1)*(a+(b-a)/2) = (b-a+1)*(a+b)/2` so you could just write `def get_sum(a,b) return (b-a+1)*(a+b)/2` – Stef Sep 17 '20 at 08:50
  • just added @Aetherus – KobbyAdarkwa Sep 17 '20 at 08:58

4 Answers4

2

Your code does not return result except for a=b case. Also - what [a+=b] generates? Array with a single element a+b, so it's sum is just a+b

Make a range and get it's sum.

Added: parameter ordering

def get_sum(a,b)
    a, b = b, a if a > b
    return (a..b).sum      
end

print get_sum(1,3)
print get_sum(2,2)
print get_sum(-1,2)
print get_sum(3,-1)

>> 6 2 2 5
MBo
  • 77,366
  • 5
  • 53
  • 86
  • I wasn't the downvoter but I assume a justification for the downvote would be that this answer doesn't provide any explanation whatsoever and doesn't help the OP understand what is wrong with their code. – Stef Sep 17 '20 at 08:54
  • unbelievable it really is that simple? definitely going to have to remember this for future. – KobbyAdarkwa Sep 17 '20 at 09:08
  • 1
    It's fails when "Test.assert_equals(get_sum(5,-1),14)" – Vikram Jain Sep 17 '20 at 09:10
  • Test in "https://www.codewars.com/kata/55f2b110f61eb01779000053/train/ruby" where two test case was fail – Vikram Jain Sep 17 '20 at 09:11
2

You can use formula for Arithmetic progression:

def get_sum(a, b)
  a, b = b, a if a > b

  (b - a + 1) * (a + b) / 2
end

Active Support(Rails) extension for Range class OR modern(>= 2.4) Ruby do the same.

So, you can use @MBo answer if your Kata site uses either Rails or modern Ruby. Usually such sites specify the environment and the interpreter version.

def get_sum(a, b)
  a, b = b, a if a > b

  (a..b).sum
end
Pavel Mikhailyuk
  • 2,757
  • 9
  • 17
  • Yes, it seems to work. Note that it's already implemented this way by Range#sum (https://stackoverflow.com/questions/41449617/why-is-sum-so-much-faster-than-inject), so it's just like MBo's answer. – Eric Duminil Sep 17 '20 at 08:53
  • I know, edited the post. My current project uses older Ruby version, but ActiveSupport does anyway: `sum + (actual_last - first + 1) * (actual_last + first) / 2` – Pavel Mikhailyuk Sep 17 '20 at 08:56
0

Please, try with below and ref enter link description here:

def get_sum(a,b)
  return a if a == b  
  return (a..b).sum if b > a
  return (b..a).sum if a > b
end

Test:

describe "Example Tests" do
  Test.assert_equals(get_sum(1,1),1)
  Test.assert_equals(get_sum(0,1),1)
  Test.assert_equals(get_sum(0,-1),-1)
  Test.assert_equals(get_sum(1,2),3)
  Test.assert_equals(get_sum(5,-1),14)
end

Outout:

Test Results:
 Example Tests
Test Passed: Value == 1
Test Passed: Value == -1
Test Passed: Value == 3
Test Passed: Value == 14
You have passed all of the tests! :)
Vikram Jain
  • 5,498
  • 1
  • 19
  • 31
0
def get_sum(a,b)
  sum = [a+=b].sum      
  if sum == a or b 
    return a
  end 
end

Other answers explain what you could write instead, so let's check your code:

  • a+=b is called first. It's basically a = a + b, so it calculates the sum of both inputs, saves it in a, and returns a.
  • sum = [a].sum creates an array with one element, and calculates its sum (which is just this one element). So sum = a
  • a or b is just a when a is truthy (that is, neither false nor nil).

So here's what your code actually does:

def get_sum(a,b)
  a = a + b
  sum = a
  if sum == a
    return a
  end 
end

Which is just:

def get_sum(a,b)
  a = a + b
  return a
end

Or :

def get_sum(a,b)
  a = a + b
end

or :

def get_sum(a,b)
  a + b
end
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124