Home > Blockchain >  Letter Count - How to return the first word with the highest amount of repeating letters?
Letter Count - How to return the first word with the highest amount of repeating letters?

Time:03-25

For example: "Today, is the greatest day ever!" should return greatest because it has 2 e's (and 2 t's) and it comes before ever which also has 2 e's. If there are no words with repeating letters return -1. Words will be separated by spaces. Input:"Hello Apple Pie" Output should be:"Hello" Do not understand what is wrong with my code, also if you think there is a simpler and shorter way to solve I would love to hear it. Thanks in advance for the help.

  function LetterCountI(str) { 
    let unique=[... new Set(str)]
    if(unique==str){ 
      return -1}
    
    let arr= str.split(" ") 
    
    let array=arr.map(item=>{ 

    let temparr=item.split("")

      return temparr.reduce((acc,curr)=>{ 
    acc[curr]=acc[curr]? acc[curr] 1:1 
    if(acc[curr]>acc.max){ 
      acc.max=acc[curr]}
return acc},{max:1, word:item})}) 
    
    let amount=1
    let largest=""
    
    for(let item of arr){ 
      if( item.max>amount){ 
        amount=item.max 
        largest=item.word
      }
    } 
    
    return largest
    
   }

CodePudding user response:

Start with the simpler problem of getting the frequency of each letter in a word...

// given "sassy", will return { s:3, a:1, y:1 }
function letterFrequency(word) {
  return word.split('').reduce((acc, letter) => {
    if (!acc[letter]) acc[letter] = 0;
    acc[letter]  ;
    return acc;
  }, {});
}

A simple problem to get the max frequency...

// given { s:3, a:1, y:1 }, will return 3
function maxLetterFrequency(word) {
  return Math.max(...Object.values(letterFrequency(word)));
}

Another simple problem to sort a sentence by frequency...

// given "She sells seashells by the seashore"
// returns ["seashells", "sells", "seashore", "She", "by", "the"]
function wordsOrderedByMaxLetterFrequency(sentence) {
  let words = sentence.split(' ');
  words.sort((a, b) => {
    return maxLetterFrequency(b) - maxLetterFrequency(a);
  });
  return words;
}

The first word in the resulting array is the answer. You can retest max frequencies in that word to determine of the answer should be -1.

Demo...

// given "sassy", will return { s:3, a:1, y:1 }
function letterFrequency(word) {
  return word.split('').reduce((acc, letter) => {
    if (!acc[letter]) acc[letter] = 0;
    acc[letter]  ;
    return acc;
  }, {});
}

// given { s:3, a:1, y:1 }, will return 3
function maxLetterFrequency(word) {
  return Math.max(...Object.values(letterFrequency(word)));
}

// given "She sells seashells by the seashore"
// returns ["seashells", "sells", "seashore", "She", "by", "the"]
function wordsOrderedByMaxLetterFrequency(sentence) {
  let words = sentence.split(' ');
  words.sort((a, b) => {
    return maxLetterFrequency(b) - maxLetterFrequency(a);
  });
  return words;
}

const sentence = "She sells seashells by the seashore";
const sorted = wordsOrderedByMaxLetterFrequency(sentence);
console.log(sorted);
console.log('best word:', sorted[0]);
console.log('max freq in best word:', maxLetterFrequency(sorted[0]));

CodePudding user response:

Staying with the OP's reduce based approach one would provide a single function which incorporates two specific nested reduce tasks responsible for 1) aggregating the word specific statistics of a sentence and 2) the letter specific statistics for each word. This approach also ensures the result of '' (suggested) or -1 (the OP'S requirement) in case there are only words of unique (non repeating) letters/characters.

function getFirstOccurringWordOfMaximumSameCharacterCount(value) {

  function aggregateCharCountData(wordStats, char, idx, arr) {
    const { charStats } = wordStats;

    // aggregate character specific array.
    (charStats[char] ??= []).push(char);

    if (idx >= (arr.length - 1)) {
      // console.log({ charStats });

      // aggregate maximum character count data
      // at the end of the last character reduce step.
      const maxCharList = Object
        .values(charStats)
        .sort((aCharList, bCharList) =>
          bCharList.length - aCharList.length
        )[0];

      wordStats.maxCharCount = maxCharList.length;
      wordStats.maxCountChar = maxCharList[0];
    }
    return wordStats;
  }
  function aggregateWordSpecificCharCountData(collector, word, idx, arr) {
    const { statistics } = collector;

    statistics.push(
      word
        .split('')
        .reduce(aggregateCharCountData, { word, charStats: {} })
    );
    if (idx >= (arr.length - 1)) {

      // find the first occurring word of maximum same character count
      // at the end of the last word reduce step.
      const wordStats = statistics
        .sort((aWordStats, bWordStats) =>
          bWordStats.maxCharCount - aWordStats.maxCharCount
        )[0];
      // console.log({ statistics });

      collector.result = (wordStats.maxCharCount >= 2)
        ? wordStats.word
        : ''; // : -1;
    }
    return collector;
  }

  const {

    // statistics,
    result,

  } = String(value)
    .split(/\s /)

    .reduce(aggregateWordSpecificCharCountData, {
      statistics: [],
      result: '',
    });
  // console.log({ statistics });

  return result;
}

console.log([

  'Today is the day.',                  // ''
  'Today, is the greatest day ever!',   // 'greatest'
  'Hello Apple Pie',                    // 'Hello'
  'She sells seashells by the seashore' // 'seashells'

].map(getFirstOccurringWordOfMaximumSameCharacterCount));
.as-console-wrapper { min-height: 100%!important; top: 0; }

  • Related