DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #253 - Sort Sentences Pseudo-alphabetically

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!

Top comments (7)

Collapse
 
miketalbot profile image
Mike Talbot ⭐ • Edited
     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 • Edited

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(' ');
}