Go: Remainder Sorting
Implement a function that receives an array of strings and sorts them based on the following heuristics:
- The primary sort is by increasing remainder of the strings’ lengths, modulo 3.
- If multiple strings have the same remainder, they should be sorted in alphabetical order.
Example
strArr = [“Colorado”, “Utah”, “Wisconsin”, “Oregon”]
Their lengths are [8, 4, 9, 6]. The remainders, modulo 3, are [2, 1, 0, 0]. Oregon and Wisconsin have the same remainder and are further sorted alphabetically. Here is the sorted array showing (string, length, length modulo 3): [(‘Oregon’, 6, 0), (‘Wisconsin’, 9, 0), (‘Utah’, 4, 1), (‘Colorado’, 8, 2)]. Return the sorted array [“Oregon”, Wisconsin”, “Utah”, “Colorado”].
Function Description
Complete the function RemainderSorting in the editor below. The function return an array of strings.
RemainderSorting has the following parameter(s):
strArr [n]string: an array of strings
Constraints
- 1 ≤ length of strArr ≤ 700
- 1 ≤ length of each string ≤ 100
SOLUTION:
package main
import (
"bufio"
"fmt"
"io"
"os"
"sort"
"strconv"
"strings"
)
/*
* Complete the 'RemainderSorting' function below (and other code for sorting if needed).
*
* The function is expected to return a STRING_ARRAY.
* The function accepts STRING_ARRAY strArr as parameter.
*/
// Custom struct to hold string, length, and length modulo 3
type StringInfo struct {
Str string
Length int
Remain int
}
func RemainderSorting(strArr []string) []string {
// Create an array of StringInfo struct
strInfos := make([]StringInfo, len(strArr))
// Populate the array with string, length, and length modulo 3
for i, str := range strArr {
strInfos[i] = StringInfo{
Str: str,
Length: len(str),
Remain: len(str) % 3,
}
}
// Sort the array using custom comparator
sort.Slice(strInfos, func(i, j int) bool {
// Sort by remainder
if strInfos[i].Remain != strInfos[j].Remain {
return strInfos[i].Remain < strInfos[j].Remain
}
// Sort alphabetically if remainders are the same
return strInfos[i].Str < strInfos[j].Str
})
// Extract the sorted strings from the struct array
sortedStrArr := make([]string, len(strArr))
for i, strInfo := range strInfos {
sortedStrArr[i] = strInfo.Str
}
return sortedStrArr
}
func main() {
reader := bufio.NewReaderSize(os.Stdin, 16*1024*1024)
stdout, err := os.Create(os.Getenv("OUTPUT_PATH"))
checkError(err)
defer stdout.Close()
writer := bufio.NewWriterSize(stdout, 16*1024*1024)
strArrCount, err := strconv.ParseInt(strings.TrimSpace(readLine(reader)), 10, 64)
checkError(err)
var strArr []string
for i := 0; i < int(strArrCount); i++ {
strArrItem := readLine(reader)
strArr = append(strArr, strArrItem)
}
result := RemainderSorting(strArr)
for i, resultItem := range result {
fmt.Fprintf(writer, "%s", resultItem)
if i != len(result)-1 {
fmt.Fprintf(writer, "\n")
}
}
fmt.Fprintf(writer, "\n")
writer.Flush()
}
func readLine(reader *bufio.Reader) string {
str, _, err := reader.ReadLine()
if err == io.EOF {
return ""
}
return strings.TrimRight(string(str), "\r\n")
}
func checkError(err error) {
if err != nil {
panic(err)
}
}