DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #110 - Love VS. Friendship

If a = 1, b = 2, c = 3 ... z = 26

Then l + o + v + e = 54

and f + r + i + e + n + d + s + h + i + p = 108

So friendship is twice as strong as love :-)

Write a function to find the "strength" of each of these values.

Test cases:
wordsToMarks(attitude)
wordsToMarks(friends)
wordsToMarks(family)
wordsToMarks(selflessness)
wordsToMarks(knowledge)

Good luck!


This challenge comes from J or nor J on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Top comments (20)

Collapse
 
ynndvn profile image
La blatte

A bit like @nicolas Hervé, using the reduce method:

f=a=>[...a].reduce((t,l)=>t+l.charCodeAt``-96,0)
  • [...a] transforms the string to an array with every character (["l", "o", "v", "e"])
  • The reduce methods will loop through every character, get its charCode, subtract 96 to it (the charCode associated with "a" + 1), and sum everything
Collapse
 
dak425 profile image
Donald Feury • Edited

I started picking up ruby for rails, so here is my shining gem.

Try it out here

word.rb

class Word
  @@alphabet = ('a'..'z').to_a

  def self.to_mark(word)
    word.chars.sum { |char| @@alphabet.index(char.downcase) + 1 }
  end
end

word_test.rb

require 'minitest/autorun'
require_relative 'word'

class TestWord < Minitest::Test
  def setup
    @cases = [
      { input: 'love', expected: 54 },
      { input: 'friendship', expected: 108 },
      { input: 'attitude', expected: 100 },
      { input: 'friends', expected: 75 },
      { input: 'family', expected: 66 },
      { input: 'selflessness', expected: 154 },
      { input: 'knowledge', expected: 96 }
    ]
  end

  def test_to_mark
    @cases.each { |test| assert_equal test[:expected], Word.to_mark(test[:input]) }
  end
end
Collapse
 
kesprit profile image
kesprit

Thanks to @ynndvn for showing me reduce method, it exist too in Swift language and it's awesome !!!

This is my solution in Swift :

func wordsToMarks(word: String) -> Int {
    return word.compactMap { $0 }.reduce(0) {
       $0 + Int($1.asciiValue ?? 0) - 96
    }
}

wordsToMarks(word:"attitude")
wordsToMarks(word:"friends")
wordsToMarks(word:"family")
wordsToMarks(word:"selflessness")
wordsToMarks(word:"knowledge")
Collapse
 
yechielk profile image
Yechiel Kalmenson
def wordsToMarks(word)
  alphabet = ("a".."z").to_a
  mark = 0
  word.each_char do |char|
    mark += alphabet.index(char.downcase) + 1
  end
  mark
end
Collapse
 
scrabill profile image
Shannon Crabill

("a".."z").to_a is nifty!

Collapse
 
yechielk profile image
Yechiel Kalmenson

Well, my first attempt had me iterating calling .index on ("a".."z") only to find out that you can't call index on a range, so in trying to work around that I realized I could just convert the range into an array... :)

Collapse
 
jbristow profile image
Jon Bristow
words_to_marks("",0).
words_to_marks(S,Mark) :-
    string_codes(S,SC),
    length(SC, SCL),
    sum_list(SC,SCS),
    Mark is SCS - SCL * 96.
?- words_to_marks(“love”, V).
% V = 54

?- words_to_marks(“declarative”, V).
% V = 100
Collapse
 
peter279k profile image
peter279k

Here is the simple solution with Python:

def words_to_marks(s):
    alphabet = {
        'a': 1,
        'b': 2,
        'c': 3,
        'd': 4,
        'e': 5,
        'f': 6,
        'g': 7,
        'h': 8,
        'i': 9,
        'j': 10,
        'k': 11,
        'l': 12,
        'm': 13,
        'n': 14,
        'o': 15,
        'p': 16,
        'q': 17,
        'r': 18,
        's': 19,
        't': 20,
        'u': 21,
        'v': 22,
        'w': 23,
        'x': 24,
        'y': 25,
        'z': 26,
    }

    sum_length = 0
    for char in s:
        sum_length += alphabet[char]

    return sum_length
Collapse
 
hnicolas profile image
Nicolas Hervé
const wordsToMarks = (word) => word.split("").reduce((acc, curr) => acc + curr.charCodeAt(0) - "a".charCodeAt(0) + 1, 0);
Collapse
 
khenhey profile image
Karin

A little solution for Ruby :) this was fun!

def wordsToMarks(word)
  strength = 0
  alphabet = ('a'..'z').to_a
  word.split('').each do |i|
    strength = strength + (alphabet.index(i) + 1)
  end
  return strength
end
Collapse
 
edreeseg profile image
Ed Reeseg • Edited
#include <stdio.h>

int main(int argc, char *argv[]) 
{
    if (argc != 2)
    {
        printf("Usage: ./strength string\n");
        return 1;
    }
    int sum = 0;
    char *c = argv[1];
    while(*c != '\0')
    {
        if (*c < 'a' || *c > 'z')
        {
            printf("Invalid argument\n");
            return 1;
        }
        sum += *c - 'a' + 1;
        c++;
    }
    printf("%i\n", sum);
    return 0;
}
Collapse
 
kesprit profile image
kesprit

Oh nice! That's better !

I forgot String are a table of Character so you right compactMap is useless.
I have totally ignored emojis because the challenger treat only letter a to z

So thank you for your feedback, your optimisation is truly better 👌