I am working on a string incrementer project on codewars. Basicly, Writing a function which increments a string, to create a new string.
If the string already ends with a number, the number should be incremented by 1. If the string does not end with a number. the number 1 should be appended to the new string. If the number has leading zeros the amount of digits should be considered. foo -> foo1
foo001 ->foo002
foobar23 -> foobar24
foo099 -> foo100
My code is : input.gsub(/\d/,"")+input.split().map {|x| x[/\d+/].next!}.join(" ")
https://repl.it/@tanilserbes/ViolentNoteworthyDowngrade . It works on this playground
However it doesnt work on codewars. I get this error:
main.rb:5:in block in increment_string': undefined method
next!' for nil:NilClass (NoMethodError)`
Any idea?
thanks in advance!.
Here are some points to consider in developing your solution.
If your string were:
str = "ca9t00456"
the desired return value would be:
"ca9t00457"
(Note that the OP's solution would return an incorrect result ("cat10"
) for this string. The Codewars question does not say that the only digits in the string are those at the end; it only mentions the "number" at the end of the string".)
A reasonable first step would be to divide the string into two parts:
n = str.index(/\d+\z/)
#=> 4
prefix = str[0, n]
#=> "ca9t"
suffix = str[n..-1]
#=> "00456"
See String#index. The regular expression, /\d+\z/
, reads, "match one or more (+
) digits (\d
) followed by the end of the string (\z
). The digit '9'
is skipped over because it is neither followed by a digit nor is at the end of the string. See also See String#[].
The string we return will begin with (the value held by) prefix
, so we can set that aside for now and concentrate on modifying suffix
.
One approach would be:
((suffix.to_i) + 1).to_s
#=> "457"
but then we would have to add the correct number of leading zeroes. Here that would be the same as the number of leading zeroes in suffix
(2), but if suffix
were, for example, 00999
, it would be only one (01000
). That could be done, but it's messy.
An easier way would be to use the method String#succ, as @steenslag suggested in the comments.
new_suffix = suffix.succ
#=> "00457"
"00999".succ
#=> "01000"
Now we need only combine prefix
and new_suffix
.
Note what happens if we execute succ
on the entire string:
"ca9t0456".succ
#=> "ca9t0457" correct
"ca9t0999".succ
#=> "ca9t1000" correct
"ca9t9999".succ
#=> "ca9u0000" incorrect
As you see, there's a problem with the third example. That's why I chose to divide the string into two parts as a first step.
You need to investigate three other cases. The first is when the prefix is an empty string:
str = "00456"
the second is when the suffix is an empty string:
str = "ca9t"
and the third is when the string is empty:
str = ""
You can check if the previous calculations still work in the first case.
In the second case we would find:
n = str.index(/\d+\z/)
#=> "cat9t".index(/\d+\z/) => nil
The nil
value for n
tells us that the desired return value is:
str + "1"
#=> "ca9t" + "1" => "ca9t1"
Would that work?