-3

Description: I've been playing around with Codingames today, and came across this problem in a Clash of Code.

Problem: Given a word, output the sum of the word's index according to it's place in the ABC.

Example: word = "HI" result = 15

Explanation: H = 7 and I = 8, the sum of that is 15. This is because the H and I are at the 7th and 8th index in the alpahabet, if we determine that A = 0;

My solution: I've got it working with a nested loop, but it's not very efficient. Other solution 1:

print(readline().split("").reduce((a,b)=>b.match(/[A-Z]/)?a+b.charCodeAt(0)-65:a,0))

Other solution 2:

s=0
readline().split``.map(e=>/[A-Z]/.test(e)?s+=e.charCodeAt(0)-'A'.charCodeAt(0):0)
print(s)

Can someone explaing these codes to me? I've tried AI but I didn't get the hang of it. I also welcome suggestions of websites etc. that helps me understand these codes better.

Thank you!

Beca_1923
  • 19
  • 3
  • What part you don't understand ? – Brewal Aug 07 '23 at 12:26
  • My understanding of this code: It reads the input of the testcase, let's say "HI". Then, the split method creates an array of the input so it's array = ["HI"]. Then the reduce method takes a value and an accumulator (?) and if b value matches a letter from A-Z, that's defined as a regex it does something with a+b. I don't really understand from this a+b part, including what's that -65?? – Beca_1923 Aug 07 '23 at 12:34
  • 1
    The easiest way to understand this would be to convert all those chained calls to assignments to variables to hold the intermediate values and then console.logging the intermediate variables to see what they are... but per your comment the split gives you `['H', 'I']` the -65 is related to the character's position in the [ASCII table](https://www.asciitable.com/) so that you can get the alphabetical index. Remember all English characters map to unsigned 8 bit integers. – Jared Smith Aug 07 '23 at 12:42

1 Answers1

2

Using normal split, reduce and match plus a ternary:

const res = "HeLLo"
  .split("")
  .reduce((a,b)=> 
    b.match(/[A-Z]/)? // does the current letter match an uppercase?
    a+b.charCodeAt(0)-65 // return accumulator plus current letter value minus A's letter value of 65
    :a  // otherwise return the accumulator
    ,0) // start with an accumulator of 0

console.log(res);

Using tagged template split, a map (no need for a map here) and a ternary

s=0;
"HeLLo"
  .split``  // split on anything
  .map(e=>/[A-Z]/.test(e)? // if from A-Z
  s+=e.charCodeAt(0)-'A'.charCodeAt(0) // add each charcode minus the charCode for A
  :0 // otherwise 0
  )
console.log(s);

Don't use a map when you need a forEach - and a ternary as above:

s=0;
const res = "HeLLo"
  .split``  // split on anything 
  .forEach(e=> s+= /[A-Z]/.test(e) ? e.charCodeAt(0)-65 : 0)
console.log(s);
mplungjan
  • 169,008
  • 28
  • 173
  • 236