5
\$\begingroup\$

A word is balanced at the index if the sum of the alphabet positions of all the chars multiplied by the distance to the index is zero.

This description is equivalent to the one given by DailyProgrammer in the challenge info.

I did not code Input/Output as I found them not as interesting as the logic.

The code works for the given testcase.

def balanced_at?(string, index, alphabet=("a".."z").to_a)
 string
 .chars
 .each_with_index
 .map { |char, char_index| (alphabet.index(char) + 1) * (char_index - index)}
 .inject(:+)
 .zero?
end
def balanced_where(string)
 (0..string.length)
 .detect {|index| balanced_at?(string, index)}
end
puts balanced_where("stead")
Snowhawk
6,7701 gold badge19 silver badges37 bronze badges
asked Jul 7, 2015 at 18:29
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$
  1. You may use splat operator instead of .to_a
  2. You may use .map.with_index instead of .each_with_index.map
  3. You should (bug?) use ... instead of ..
def balanced_at? string, index, alphabet = [*"a".."z"]
 string.chars.map.with_index do |char, char_index|
 (alphabet.index(char) + 1) * (char_index - index)
 end.inject(:+).zero?
end
def balanced_where string
 (0...string.length).detect do |index|
 balanced_at? string, index
 end
end
puts balanced_where "stead"

But note, that your function is monotone, so you may get a perfomance profit by using find-any mode of .bsearch instead of .detect:

def balance string, index, alphabet = [*"a".."z"]
 string.chars.map.with_index do |char, char_index|
 (alphabet.index(char) + 1) * (char_index - index)
 end.inject(:+)
end
def balanced_where string
 (0...string.length).bsearch do |index|
 balance string, index
 end
end

Read Array#bsearch docs for explanation.

answered Jul 8, 2015 at 23:37
\$\endgroup\$
3
  • \$\begingroup\$ 1. The same, not an improvement 2. ditto as 1 3. "z" is a letter of the alphabet (in Ruby .. is inclusive): irb(main):006:0> ("a".."z").to_a => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"] 4. your function is monotone wrong, my function returns something like [false, true, false, false] that is not ok according to, citing the docs: the block returns false for any element whose index is less than i, and the block returns true for any element whose index is greater than or equal to i. \$\endgroup\$ Commented Jul 9, 2015 at 7:05
  • \$\begingroup\$ 3. I mean 0..string.length 4. your function is monotone, until you wrap it in .zero? -- do not do it. \$\endgroup\$ Commented Jul 9, 2015 at 10:03
  • \$\begingroup\$ Yes I think including the ending length is a bug considering that ruby will return nil at array[array.length], not wrapping it in zero is good and leads to refactoring: def balancement_value(string, index, alphabet=("a".."z").to_a) string .chars .each_with_index .map { |char, char_index| (alphabet.index(char) + 1) * (char_index - index)} .inject(:+) end and then def balanced_at?(string, index, alphabet=("a".."z").to_a) balancement_value(string, index, alphabet=("a".."z").to_a).zero? end I will call balancement_value from balanced_where (Ps: why this formatting?) \$\endgroup\$ Commented Jul 9, 2015 at 10:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.