Task: Top rank per group




Go: package main

import (
    "fmt"
    "sort"
)


type Employee struct {
    Name, ID string
    Salary   int
    Dept     string
}

type EmployeeList []*Employee

var data = EmployeeList{
    {"Tyler Bennett", "E10297", 32000, "D101"},
    {"John Rappl", "E21437", 47000, "D050"},
    {"George Woltman", "E00127", 53500, "D101"},
    {"Adam Smith", "E63535", 18000, "D202"},
    {"Claire Buckman", "E39876", 27800, "D202"},
    {"David McClellan", "E04242", 41500, "D101"},
    {"Rich Holcomb", "E01234", 49500, "D202"},
    {"Nathan Adams", "E41298", 21900, "D050"},
    {"Richard Potter", "E43128", 15900, "D101"},
    {"David Motsinger", "E27002", 19250, "D202"},
    {"Tim Sampair", "E03033", 27000, "D101"},
    {"Kim Arlich", "E10001", 57000, "D190"},
    {"Timothy Grove", "E16398", 29900, "D190"},
    
    {"Tie A", "E16399", 29900, "D190"},
    {"Tie B", "E16400", 29900, "D190"},
    {"No Tie", "E16401", 29899, "D190"},
}









type By func(e1, e2 *Employee) bool
type employeeSorter struct {
    list EmployeeList
    by   func(e1, e2 *Employee) bool
}

func (by By) Sort(list EmployeeList)         { sort.Sort(&employeeSorter{list, by}) }
func (s *employeeSorter) Len() int           { return len(s.list) }
func (s *employeeSorter) Swap(i, j int)      { s.list[i], s.list[j] = s.list[j], s.list[i] }
func (s *employeeSorter) Less(i, j int) bool { return s.by(s.list[i], s.list[j]) }










func (el EmployeeList) TopSalariesByDept(n int) []EmployeeList {
    if n <= 0 || len(el) == 0 {
        return nil
    }
    deptSalary := func(e1, e2 *Employee) bool {
        if e1.Dept != e2.Dept {
            return e1.Dept < e2.Dept
        }
        if e1.Salary != e2.Salary {
            return e1.Salary > e2.Salary
        }
        
        return e1.ID < e2.ID
    }

    
    
    
    
    sorted := make(EmployeeList, len(el))
    copy(sorted, el)
    By(deptSalary).Sort(sorted)

    perDept := []EmployeeList{}
    var lastDept string
    var lastSalary int
    for _, e := range sorted {
        if e.Dept != lastDept || len(perDept) == 0 {
            lastDept = e.Dept
            perDept = append(perDept, EmployeeList{e})
        } else {
            i := len(perDept) - 1
            if len(perDept[i]) >= n && e.Salary != lastSalary {
                continue
            }
            perDept[i] = append(perDept[i], e)
            lastSalary = e.Salary
        }
    }
    return perDept
}

func main() {
    const n = 3
    top := data.TopSalariesByDept(n)
    if len(top) == 0 {
        fmt.Println("Nothing to show.")
        return
    }
    fmt.Printf("Top %d salaries per department\n", n)
    for _, list := range top {
        fmt.Println(list[0].Dept)
        for _, e := range list {
            fmt.Printf("    %s %16s %7d\n", e.ID, e.Name, e.Salary)
        }
    }
}


Java: import java.io.File;
import java.util.*;

public class TopRankPerGroup {

    private static class Employee {
        final String name;
        final String id;
        final String department;
        final int salary;

        Employee(String[] rec) {
            name = rec[0];
            id = rec[1];
            salary = Integer.parseInt(rec[2]);
            department = rec[3];
        }

        @Override
        public String toString() {
            return String.format("%s %s %d %s", id, name, salary, department);
        }
    }

    public static void main(String[] args) throws Exception {
        int N = args.length > 0 ? Integer.parseInt(args[0]) : 3;

        Map<String, List<Employee>> records = new TreeMap<>();
        try (Scanner sc = new Scanner(new File("data.txt"))) {
            while (sc.hasNextLine()) {
                String[] rec = sc.nextLine().trim().split(", ");

                List<Employee> lst = records.get(rec[3]);
                if (lst == null) {
                    lst = new ArrayList<>();
                    records.put(rec[3], lst);
                }
                lst.add(new Employee(rec));
            }
        }

        records.forEach((key, val) -> {
            System.out.printf("%nDepartment %s%n", key);
            val.stream()
                .sorted((a, b) -> Integer.compare(b.salary, a.salary))
                .limit(N).forEach(System.out::println);
        });
    }
}