loading...

Daily Challenge #253 - Sort Sentences Pseudo-alphabetically

thepracticaldev profile image dev.to staff ・1 min read

Given a standard English sentence passed as a string, write a method that will return that sentence but with the words sorted by first letter.

All words that begin with a lower case letter should be at the beginning of the sorted sentence, and sorted in ascending order. All words that begin with an upper case letter should come after that, and should be sorted in descending order.

If a word appears multiple times in the sentence, it should be returned multiple times. Any punctuation can be discarded.

Example
input: "Land of the Old Thirteen! Massachusetts land! land of Vermont and Connecticut!"
return: "and land land of of the Vermont Thirteen Old Massachusetts Land Connecticut"
Lower case letters are sorted a -> l -> l -> o -> o -> t
Upper case letters are sorted V -> T -> O -> M -> L -> C.

Tests
sort("take up the task eternal, and the burden and the lesson")
sort("Pioneers, O Pioneers!")

Good luck!


This challenge comes from Daremyth 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!

Discussion

pic
Editor guide
Collapse
miketalbot profile image
Mike Talbot
     result = input=> (input = input.split(' '), [...input.filter(s=>/^[a-z]/.test(s)).sort(), ...input.filter(s=>/^[A-Z]/.test(s)).sort((a,b)=>a===b ? 0 : a < b ? 1 : -1)].join(' '))

If any punctuation "can" be discarded - it isn't.

This if is "must" be discarded:

     result = input=> (input = input.replace(/[^a-zA-Z\s]/g, '').split(' '), [...input.filter(s=>/^[a-z]/.test(s)).sort(), ...input.filter(s=>/^[A-Z]/.test(s)).sort((a,b)=>a===b ? 0 : a < b ? 1 : -1)].join(' '))
Collapse
vidit1999 profile image
Vidit Sarkar

Here is a Python solution,

from string import punctuation

def sort(s):
    lowerStart = []
    upperStart = []

    for word in ''.join(c for c in s if c not in punctuation).split():
        if(word[0].islower()):
            lowerStart.append(word)
        elif(word[0].isupper()):
            upperStart.append(word)

    return ' '.join(sorted(lowerStart) + sorted(upperStart, reverse=True))

Output,

print(sort("Land of the Old Thirteen! Massachusetts land! land of Vermont and Connecticut!")) # output -> 'and land land of of the Vermont Thirteen Old Massachusetts Land Connecticut'
print(sort("take up the task eternal, and the burden and the lesson")) # output -> 'and and burden eternal lesson take task the the the up'
print(sort("Pioneers, O Pioneers!")) # output -> 'Pioneers Pioneers O'
Collapse
rrampage profile image
Raunak Ramakrishnan

Python

import re

# Pat to check if first letter is capital
pat = re.compile("[A-Z].*")

def pseudo_alphabet(s):
    # Replace all non alphabets and spaces from sentence
    ss = re.sub("[^a-zA-Z0-9 ]+", "", s)
    # Split by space
    l = ss.split()
    # Separate lists for upper and lower case words
    uw, lw = [], []
    for w in l:
        # If word matches first letter upper-case, add to "uw" else to "lw"
        if pat.match(w):
            uw.append(w) 
        else: 
             lw.append(w)
    return ' '.join(sorted(lw)) + ' ' + ' '.join(sorted(uw, reverse=True))

print(pseudo_alphabet(s))
Collapse
quoll profile image
Paula Gearon
(refer-clojure :exclude '[sort])
(require '[clojure.string :as s])
(defn sort
  [s]
  (->> (s/split s #"[^\w]+")
       (sort-by first
                (fn [a b]
                  (if (Character/isUpperCase a)
                    (compare b a)
                    (if (Character/isLowerCase b) (compare a b) -1))))
       (s/join " ")))
Collapse
aminnairi profile image
Amin

Go

package sentence

import (
    "sort"
    "strings"
    "unicode"
)

func Sort(sentence string) string {
    words := strings.FieldsFunc(sentence, func (character rune) bool {
        return !unicode.IsLetter(character)
    })

    sort.Slice(words, func (first, second int) bool {
        firstWord := words[first]
        secondWord := words[second]

        if unicode.IsLower(rune(firstWord[0])) && unicode.IsLower(rune(secondWord[0])) {
            return firstWord < secondWord
        }

        return secondWord < firstWord
    })

    return strings.Join(words, " ")
}
Collapse
raiman264 profile image
Braulio Ruiz

JS

function sort(sentence){
  const wordReg = /\w+/;
  const isCapitalized = /^[A-Z]/;

  const words = sentence
    .split(' ')
    .map(w => wordReg.exec(w)[0])
    .sort((a, b) => {
      const aCapital = isCapitalized.test(a);
      const bCapital = isCapitalized.test(b);
      if(aCapital !== bCapital) {
        return aCapital ? 1 : -1;
      }

      return a.localeCompare(b) * (aCapital ? -1 : 1);
    })

  return words.join(' ');
}