Daily Challenge #110 - Love VS. Friendship

twitter logo ・1 min read

Daily Challenge (122 Part Series)

1) Daily Challenge #1 - String Peeler 2) Daily Challenge #2 - String Diamond 3 ... 120 3) Daily Challenge #3 - Vowel Counter 4) Daily Challenge #4 - Checkbook Balancing 5) Daily Challenge #5 - Ten Minute Walk 6) Daily Challenge #6 - Grandma and her friends 7) Daily Challenge #7 - Factorial Decomposition 8) Daily Challenge #8 - Scrabble Word Calculator 9) Daily Challenge #9 - What's Your Number? 10) Daily Challenge #10 - Calculator 11) Daily Challenge #11 - Cubic Numbers 12) Daily Challenge #12 - Next Larger Number 13) Daily Challenge #13 - Twice Linear 14) Daily Challenge #14 - Square into Squares 15) Daily Challenge #15 - Stop gninnipS My sdroW! 16) Daily Challenge #16 - Number of People on the Bus 17) Daily Challenge #17 - Double Trouble 18) Daily Challenge #18 - Triple Trouble 19) Daily Challenge #19 - Turn numbers into words 20) Daily Challenge Post #20 - Number Check 21) Daily Challenge #21 - Human Readable Time 22) Daily Challenge #22 - Simple Pig Latin 23) Daily Challenge #23 - Morse Code Decoder 24) Daily Challenge #24 - Shortest Step 25) Daily Challenge #25 - Double Cola 26) Daily Challenge #26 - Ranking Position 27) Daily Challenge #27 - Unlucky Days 28) Daily Challenge #28 - Kill the Monster! 29) Daily Challenge #29 - Xs and Os 30) Daily Challenge #30 - What is the price? 31) Daily Challenge #31 - Count IPv4 Addresses 32) Daily Challenge #32 - Hide Phone Numbers 33) Daily Challenge #33 - Did you mean...? 34) Daily Challenge #34 - WeIrD StRiNg CaSe 35) Daily Challenge #35 - Find the Outlier 36) Daily Challenge #36 - Let's go for a run! 37) Daily Challenge #37 - Name Swap 38) Daily Challenge #38 - Middle Name 39) Daily Challenge #39 - Virus 40) Daily Challenge #40 - Counting Sheep 41) Daily Challenge #41 - Greed is Good 42) Daily Challenge #42 - Caesar Cipher 43) Daily Challenge #43 - Boardgame Fight Resolver 44) Daily Challenge #44 - Mexican Wave 45) Daily Challenge #45 - Change Machine 46) Daily Challenge #46 - ??? 47) Daily Challenge #47 - Alphabets 48) Daily Challenge #48 - Facebook Likes 49) Daily Challenge #49 - Dollars and Cents 50) Daily Challenge #50 - Number Neighbor 51) Daily Challenge #51 - Valid Curly Braces 52) Daily Challenge #52 - Building a Pyramid 53) Daily Challenge #53 - Faro Shuffle 54) Daily Challenge #54 - What century is it? 55) Daily Challenge #55 - Building a Pile of Cubes 56) Daily Challenge #56 - Coffee Shop 57) Daily Challenge #57 - BMI Calculator 58) Daily Challenge #58 - Smelting Iron Ingots 59) Daily Challenge #59 - Snail Sort 60) Daily Challenge #60 - Find the Missing Letter 61) Daily Challenge #61 - Evolution Rate 62) Daily Challenge #62 - Josephus Survivor 63) Daily Challenge #63- Two Sum 64) Daily Challenge #64- Drying Potatoes 65) Daily Challenge #65- A Disguised Sequence 66) Daily Challenge #66- Friend List 67) Daily Challenge #67- Phone Directory 68) Daily Challenge #68 - Grade Book 69) Daily Challenge #69 - Going to the Cinema 70) Daily Challenge #70 - Pole Vault Competition Results 71) Daily Challenge #71 - See you next Happy Year 72) Daily Challenge #72 - Matrix Shift 73) Daily Challenge #73 - ATM Heist 74) Daily Challenge #74 - Free Pizza 75) Daily Challenge #75 - Set Alarm 76) Daily Challenge #76 - Bingo! (or not...) 77) Daily Challenge #77 - Bird Mountain 78) Daily Challenge #78 - Number of Proper Fractions with Denominator d 79) Daily Challenge #79 - Connect Four 80) Daily Challenge #80 - Longest Vowel Change 81) Daily Challenge #81 - Even or Odd 82) Daily Challenge #82 - English Beggars 83) Daily Challenge #83 - Deodorant Evaporator 84) Daily Challenge #84 - Third Angle of a Triangle 85) Daily Challenge #85 - Unwanted Dollars 86) Daily Challenge #86 - Wouldn't, not Would. 87) Daily Challenge #87 - Pony Express 88) Daily Challenge #88 - Recursive Ninjas 89) Daily Challenge #89 - Extract domain name from URL 90) Daily Challenge #90 - One Step at a Time 91) Daily Challenge #91 - Bananas 92) Daily Challenge #92 - Boggle Board 93) Daily Challenge #93 - Range Extraction 94) Daily Challenge #94 - Last Digit 95) Daily Challenge #95 - CamelCase Method 96) Daily Challenge #96 - Easter Egg Crush Test 97) Daily Challenge #97 - Greed is Good 98) Daily Challenge #98 - Make a Spiral 99) Daily Challenge #99 - Balance the Scales 100) Daily Challenge #100 - Round Up 101) Daily Challenge #101 - Parentheses Generator 102) Daily Challenge #102 - Pentabonacci 103) Daily Challenge #103 - Simple Symbols 104) Daily Challenge #104 - Matrixify 105) Daily Challenge #105 - High-Sum Matrix Drop 106) Daily Challenge #106 - Average Fuel Consumption 107) Daily Challenge #107 - Escape the Mines 108) Daily Challenge #108 - Find the Counterfeit Coin 109) Daily Challenge #109 - Decorate with Wallpaper 110) Daily Challenge #110 - Love VS. Friendship 111) Daily Challenge #111 - 99 Bottles of Beer 112) Daily Challenge #112 - Functions of Integers on the Cartesian Plane 113) Daily Challenge #113 - Iterative Rotation Cipher 114) Daily Challenge #114 - Speed Control 115) Daily Challenge #115 - Look and Say Sequence 116) Daily Challenge #116 - Shortest Knight Path 117) Daily Challenge #117 - MinMinMax 118) Daily Challenge #118 - Reversing a Process 119) Daily Challenge #119 - Adding Big Numbers 120) Daily Challenge #120 - Growth of a Population 121) Daily Challenge #121 - Who has the most money? 122) Daily Challenge #122 - Clockwise Spirals

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!

twitter logo DISCUSS (27)
markdown guide
 

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
 

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
 

Just a friendly tip: alphabet really shouldn't be a class variable @@, they are very seldom what you want in Ruby:

railstips.org/blog/archives/2006/1...

In this specific case a constant would be the most common:

ALPHABET = ('a'..'z').to_a
 
 

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")
 

Why the compactMap, you are mapping each letter to itself, works fine without that too.

Also when I tried your solution with the input string "love🐈" it returned -42 since the way you handle the Optional results in non-ASCII characters having a value of -96. The following version simply ignores such characters instead:

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

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 👌

I have totally ignored emojis because the challenger treat only letter a to z

True, but you did add some code to deal with the case were a character may not have an asciiValue, I just offered an alternative to that :-)

 
def wordsToMarks(word)
  alphabet = ("a".."z").to_a
  mark = 0
  word.each_char do |char|
    mark += alphabet.index(char.downcase) + 1
  end
  mark
end
 
 

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... :)

 

Ruby:

def words_to_marks(word)
  word.chars.sum { |c| c.ord - 96 }
end

For fun a second version that builds a lookup table with an endless range (introduced in Ruby 2.6):

ALPHABET = ('a'..'z').zip(1..).to_h

def words_to_marks(word)
  word.chars.sum { |c| ALPHABET.fetch(c, 0) }
end
 

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
 
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
 
 
const wordsToMarks = (word) => word.split("").reduce((acc, curr) => acc + curr.charCodeAt(0) - "a".charCodeAt(0) + 1, 0);
 

You're inefficiently calculating "a".charCodeAt(0) + 1 over and over again. You could use the precalculated value, 96, instead.

 
#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;
}
 

My solution to the challenge using map and reduce in Python. If anyone has any suggestions on how to improve it, I would love to hear! :)

from functools import reduce 
def wordsToMarks(word):
    print(reduce((lambda x,y: x+y), map((lambda x: ord(x) - 96), list(word))))
 

In PHP


$alpha = function (string $string) {
    $al = array_flip(range('a', 'z'));

    $points = 0;
    foreach (str_split($string) as $s) {
        $points += $al[$s] + 1;
    }
    return $points;
};

echo $alpha('friendship');

EDIT:

array_map(function (string $string) {
    $al = array_flip(range('a', 'z'));

    $points = 0;
    foreach (str_split($string) as $s) {
        $points += $al[$s] + 1;
    }
    echo "$string: $points<br>";
}, ['attitude', 'friends', 'family', 'selflessness', 'knowledge']);

attitude: 100
friends: 75
family: 66
selflessness: 154
knowledge: 96
 

Haskell

import Data.Char (ord)

wordsToMarks :: String -> Int
wordsToMarks = sum . map ((flip (-) 96) . ord)

Playground

Here.

 

The prelude defines subtract, so you don't need flip here:

wordsToMarks = sum . map (subtract 96 . ord)

Another relatively common workaround is to use a right-section that adds a negative number, i.e.

wordsToMarks = sum . map ((+(-96)) . ord)
 

Thanks for your insight. I didn't know about subtract and when the second solution is kind of obscure to me it seems very cool and short.

Since - is both subtraction and unary minus one can’t use a right-section like (-1), but considering that subtracting is the same as adding a negative number the slightly obscure form makes sense. I’d still use subtract though.

 

c#, one liner using linq, ignoring non-letters chars:

int WordsToMarks(string word)
{
    return word.Where(c => char.IsLetter(c)).Sum(c => char.ToUpperInvariant(c) - 64);
}
 

My Python Algorithm:

words_to_marks = lambda words: sum(
    map(ord, words.lower()),
    -96 * len(words))
 

Here is my fun solution using Kotlin:

fun wordsToMarks(word: String) = word.toCharArray()
        .map { it + 1 - 'a' }
        .sum()
Classic DEV Post from Jun 12 '18

What The For Loop?

Learning From A Popular Interview Question This is another post in t...

dev.to staff profile image
The hardworking team behind dev.to ❤️

If you are new to DEV, we are a software blogging site visited by over 2 million developers per month.

Get Started