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)
        }
    }
}




Python: from collections import defaultdict
from heapq import nlargest
 
data = [('Employee Name', 'Employee ID', 'Salary', 'Department'),
        ('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')]
 
departments = defaultdict(list)
for rec in data[1:]:
    departments[rec[-1]].append(rec)
 
N = 3
format = " %-15s " * len(data[0])
for department, recs in sorted(departments.items()):
    print ("Department %s" % department)
    print (format % data[0])
    for rec in nlargest(N, recs, key=lambda rec: rec[-2]):
        print (format % rec)
    print('')