Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Top-rank-per-group/00-META.yaml
Normal file
2
Task/Top-rank-per-group/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Top_rank_per_group
|
||||
22
Task/Top-rank-per-group/00-TASK.txt
Normal file
22
Task/Top-rank-per-group/00-TASK.txt
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
;Task:
|
||||
Find the top ''N'' salaries in each department, where ''N'' is provided as a parameter.
|
||||
|
||||
Use this data as a formatted internal data structure (adapt it to your language-native idioms, rather than parse at runtime), or identify your external data source:
|
||||
<pre>
|
||||
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
|
||||
</pre>
|
||||
<br>
|
||||
|
||||
25
Task/Top-rank-per-group/11l/top-rank-per-group.11l
Normal file
25
Task/Top-rank-per-group/11l/top-rank-per-group.11l
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
V data = [(‘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’)]
|
||||
|
||||
DefaultDict[String, [(String, String, Int, String)]] departments
|
||||
L(rec) data
|
||||
departments[rec[3]].append(rec)
|
||||
|
||||
V n = 3
|
||||
L(department, recs) sorted(departments.items())
|
||||
print(‘Department #.’.format(department))
|
||||
print(‘ #<15 #<15 #<15 #<15 ’.format(‘Employee Name’, ‘Employee ID’, ‘Salary’, ‘Department’))
|
||||
L(rec) sorted(recs, key' rec -> rec[2], reverse' 1B)[0 .< n]
|
||||
print(‘ #<15 #<15 #<15 #<15 ’.format(rec[0], rec[1], rec[2], rec[3]))
|
||||
print()
|
||||
118
Task/Top-rank-per-group/ALGOL-68/top-rank-per-group.alg
Normal file
118
Task/Top-rank-per-group/ALGOL-68/top-rank-per-group.alg
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
BEGIN # show the top rank salaries per department #
|
||||
# NODE to hold the employee data - will be the MODE that is sorted #
|
||||
MODE SITEM = STRUCT( STRING employee name
|
||||
, STRING employee id
|
||||
, INT salary
|
||||
, STRING department
|
||||
);
|
||||
# ---- begin code from the quicksort using a custom comparator task ----- #
|
||||
#--- Swap function ---#
|
||||
PROC swap = (REF[]SITEM array, INT first, INT second) VOID:
|
||||
(
|
||||
SITEM temp := array[first];
|
||||
array[first] := array[second];
|
||||
array[second]:= temp
|
||||
);
|
||||
#--- Quick sort partition arg function with custom comparision function ---#
|
||||
PROC quick = (REF[]SITEM array, INT first, INT last, PROC(SITEM,SITEM)INT compare) VOID:
|
||||
(
|
||||
INT smaller := first + 1,
|
||||
larger := last;
|
||||
SITEM pivot := array[first];
|
||||
WHILE smaller <= larger DO
|
||||
WHILE compare(array[smaller], pivot) < 0 AND smaller < last DO
|
||||
smaller +:= 1
|
||||
OD;
|
||||
WHILE compare( array[larger], pivot) > 0 AND larger > first DO
|
||||
larger -:= 1
|
||||
OD;
|
||||
IF smaller < larger THEN
|
||||
swap(array, smaller, larger);
|
||||
smaller +:= 1;
|
||||
larger -:= 1
|
||||
ELSE
|
||||
smaller +:= 1
|
||||
FI
|
||||
OD;
|
||||
swap(array, first, larger);
|
||||
IF first < larger-1 THEN
|
||||
quick(array, first, larger-1, compare)
|
||||
FI;
|
||||
IF last > larger +1 THEN
|
||||
quick(array, larger+1, last, compare)
|
||||
FI
|
||||
);
|
||||
#--- Quick sort array function with custom comparison function ---#
|
||||
PROC quicksort = (REF[]SITEM array, PROC(SITEM,SITEM)INT compare) VOID:
|
||||
(
|
||||
IF UPB array > LWB array THEN
|
||||
quick(array, LWB array, UPB array, compare)
|
||||
FI
|
||||
);
|
||||
# ==== end code from the quicksort using a custom comparator task ===== #
|
||||
|
||||
# sort comparison routine - sort ascending department, descending salary #
|
||||
PROC sort by department then salary = ( SITEM a, SITEM b )INT:
|
||||
IF department OF a < department OF b THEN -1
|
||||
ELIF department OF a > department OF b THEN 1
|
||||
ELIF salary OF a > salary OF b THEN -1
|
||||
ELIF salary OF a < salary OF b THEN 1
|
||||
ELSE 0
|
||||
FI # sort by department then salary # ;
|
||||
|
||||
# returns s blank padded on the right to at least w characters #
|
||||
PROC pad right = ( STRING s, INT w )STRING:
|
||||
IF INT len = ( UPB s - LWB s ) + 1; len >= w THEN s ELSE s + ( ( w - len ) * " " ) FI;
|
||||
# shows the top n ranked salaries in each department #
|
||||
PROC show top rank = ( []SITEM data, INT n )VOID:
|
||||
BEGIN
|
||||
# copy the data and sort it #
|
||||
[ LWB data : UPB data ]SITEM sorted data := data;
|
||||
quicksort( sorted data, sort by department then salary );
|
||||
# show the top salaries per department #
|
||||
INT d pos := LWB sorted data;
|
||||
WHILE d pos <= UPB sorted data DO
|
||||
STRING curr department := department OF sorted data[ d pos ];
|
||||
print( ( "Department: ", curr department, newline ) );
|
||||
INT e count := 0;
|
||||
WHILE IF e count < n THEN
|
||||
print( ( " "
|
||||
, employee id OF sorted data[ d pos ]
|
||||
, " "
|
||||
, pad right( employee name
|
||||
OF sorted data[ d pos ], 24 )
|
||||
, " "
|
||||
, whole( salary OF sorted data[ d pos ], -6 )
|
||||
, newline
|
||||
)
|
||||
)
|
||||
FI;
|
||||
e count +:= 1;
|
||||
d pos +:= 1;
|
||||
IF d pos > UPB sorted data
|
||||
THEN FALSE
|
||||
ELSE curr department = department OF sorted data[ d pos ]
|
||||
FI
|
||||
DO SKIP OD;
|
||||
print( ( newline ) )
|
||||
OD
|
||||
END # show top rank # ;
|
||||
|
||||
# employee data #
|
||||
[]SITEM employees = ( ( "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" )
|
||||
);
|
||||
# show the top two salaries by department #
|
||||
show top rank( employees, 2 )
|
||||
END
|
||||
45
Task/Top-rank-per-group/AWK/top-rank-per-group.awk
Normal file
45
Task/Top-rank-per-group/AWK/top-rank-per-group.awk
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# syntax: GAWK -f TOP_RANK_PER_GROUP.AWK [n]
|
||||
#
|
||||
# sorting:
|
||||
# PROCINFO["sorted_in"] is used by GAWK
|
||||
# SORTTYPE is used by Thompson Automation's TAWK
|
||||
#
|
||||
BEGIN {
|
||||
arrA[++n] = "Employee Name,Employee ID,Salary,Department" # raw data
|
||||
arrA[++n] = "Tyler Bennett,E10297,32000,D101"
|
||||
arrA[++n] = "John Rappl,E21437,47000,D050"
|
||||
arrA[++n] = "George Woltman,E00127,53500,D101"
|
||||
arrA[++n] = "Adam Smith,E63535,18000,D202"
|
||||
arrA[++n] = "Claire Buckman,E39876,27800,D202"
|
||||
arrA[++n] = "David McClellan,E04242,41500,D101"
|
||||
arrA[++n] = "Rich Holcomb,E01234,49500,D202"
|
||||
arrA[++n] = "Nathan Adams,E41298,21900,D050"
|
||||
arrA[++n] = "Richard Potter,E43128,15900,D101"
|
||||
arrA[++n] = "David Motsinger,E27002,19250,D202"
|
||||
arrA[++n] = "Tim Sampair,E03033,27000,D101"
|
||||
arrA[++n] = "Kim Arlich,E10001,57000,D190"
|
||||
arrA[++n] = "Timothy Grove,E16398,29900,D190"
|
||||
for (i=2; i<=n; i++) { # build internal structure
|
||||
split(arrA[i],arrB,",")
|
||||
arrC[arrB[4]][arrB[3]][arrB[2] " " arrB[1]] # I.E. arrC[dept][salary][id " " name]
|
||||
}
|
||||
show = (ARGV[1] == "") ? 1 : ARGV[1] # employees to show per department
|
||||
printf("DEPT SALARY EMPID NAME\n\n") # produce report
|
||||
PROCINFO["sorted_in"] = "@ind_str_asc" ; SORTTYPE = 1
|
||||
for (i in arrC) {
|
||||
PROCINFO["sorted_in"] = "@ind_str_desc" ; SORTTYPE = 9
|
||||
shown = 0
|
||||
for (j in arrC[i]) {
|
||||
PROCINFO["sorted_in"] = "@ind_str_asc" ; SORTTYPE = 1
|
||||
for (k in arrC[i][j]) {
|
||||
if (shown++ < show) {
|
||||
printf("%-4s %6s %s\n",i,j,k)
|
||||
printed++
|
||||
}
|
||||
}
|
||||
}
|
||||
if (printed > 0) { print("") }
|
||||
printed = 0
|
||||
}
|
||||
exit(0)
|
||||
}
|
||||
105
Task/Top-rank-per-group/Action-/top-rank-per-group.action
Normal file
105
Task/Top-rank-per-group/Action-/top-rank-per-group.action
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
DEFINE PTR="CARD"
|
||||
DEFINE ENTRY_SIZE="8"
|
||||
|
||||
TYPE Employee=[
|
||||
PTR name,id,dep ;CHAR ARRAY
|
||||
CARD salary]
|
||||
|
||||
BYTE ARRAY data(200)
|
||||
BYTE count=[0]
|
||||
|
||||
PTR FUNC GetItemAddr(INT index)
|
||||
PTR addr
|
||||
|
||||
addr=data+index*ENTRY_SIZE
|
||||
RETURN (addr)
|
||||
|
||||
PROC Append(CHAR ARRAY n,i CARD s CHAR ARRAY d)
|
||||
Employee POINTER dst
|
||||
|
||||
dst=GetItemAddr(count)
|
||||
dst.name=n
|
||||
dst.id=i
|
||||
dst.dep=d
|
||||
dst.salary=s
|
||||
count==+1
|
||||
RETURN
|
||||
|
||||
PROC InitData()
|
||||
Append("Tyler Bennett","E10297",32000,"D101")
|
||||
Append("John Rappl","E21437",47000,"D050")
|
||||
Append("George Woltman","E00127",53500,"D101")
|
||||
Append("Adam Smith","E63535",18000,"D202")
|
||||
Append("Claire Buckman","E39876",27800,"D202")
|
||||
Append("David McClellan","E04242",41500,"D101")
|
||||
Append("Rich Holcomb","E01234",49500,"D202")
|
||||
Append("Nathan Adams","E41298",21900,"D050")
|
||||
Append("Richard Potter","E43128",15900,"D101")
|
||||
Append("David Motsinger","E27002",19250,"D202")
|
||||
Append("Tim Sampair","E03033",27000,"D101")
|
||||
Append("Kim Arlich","E10001",57000,"D190")
|
||||
Append("Timothy Grove","E16398",29900,"D190")
|
||||
RETURN
|
||||
|
||||
PROC Swap(Employee POINTER e1,e2)
|
||||
PTR tmp
|
||||
|
||||
tmp=e1.name e1.name=e2.name e2.name=tmp
|
||||
tmp=e1.id e1.id=e2.id e2.id=tmp
|
||||
tmp=e1.dep e1.dep=e2.dep e2.dep=tmp
|
||||
tmp=e1.salary e1.salary=e2.salary e2.salary=tmp
|
||||
RETURN
|
||||
|
||||
PROC Sort()
|
||||
INT i,j,minpos,comp
|
||||
Employee POINTER e1,e2
|
||||
|
||||
FOR i=0 TO count-2
|
||||
DO
|
||||
minpos=i
|
||||
FOR j=i+1 TO count-1
|
||||
DO
|
||||
e1=GetItemAddr(minpos)
|
||||
e2=GetItemAddr(j)
|
||||
comp=SCompare(e1.dep,e2.dep)
|
||||
IF comp>0 OR comp=0 AND e1.salary<e2.salary THEN
|
||||
minpos=j
|
||||
FI
|
||||
OD
|
||||
|
||||
IF minpos#i THEN
|
||||
e1=GetItemAddr(minpos)
|
||||
e2=GetItemAddr(i)
|
||||
Swap(e1,e2)
|
||||
FI
|
||||
OD
|
||||
RETURN
|
||||
|
||||
PROC TopRank(BYTE n)
|
||||
BYTE i,c
|
||||
CHAR ARRAY d
|
||||
Employee POINTER e
|
||||
|
||||
i=0
|
||||
WHILE i<count
|
||||
DO
|
||||
e=GetItemAddr(i)
|
||||
IF i=0 OR SCompare(e.dep,d)#0 THEN
|
||||
d=e.dep c=0
|
||||
IF i>0 THEN PutE() FI
|
||||
PrintF("Department %S:%E",d)
|
||||
c==+1
|
||||
PrintF(" %U %S %S%E",e.salary,e.id,e.name)
|
||||
ELSEIF c<n THEN
|
||||
c==+1
|
||||
PrintF(" %U %S %S%E",e.salary,e.id,e.name)
|
||||
FI
|
||||
i==+1
|
||||
OD
|
||||
RETURN
|
||||
|
||||
PROC Main()
|
||||
InitData()
|
||||
Sort()
|
||||
TopRank(3)
|
||||
RETURN
|
||||
71
Task/Top-rank-per-group/Ada/top-rank-per-group.ada
Normal file
71
Task/Top-rank-per-group/Ada/top-rank-per-group.ada
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
with Ada.Containers.Vectors;
|
||||
with Ada.Text_IO;
|
||||
|
||||
procedure Top is
|
||||
type Departments is (D050, D101, D190, D202);
|
||||
type Employee_Data is record
|
||||
Name : String (1 .. 15);
|
||||
ID : String (1 .. 6);
|
||||
Salary : Positive;
|
||||
Department : Departments;
|
||||
end record;
|
||||
|
||||
package Employee_Vectors is new Ada.Containers.Vectors
|
||||
(Element_Type => Employee_Data, Index_Type => Positive);
|
||||
|
||||
function Compare_Salary (Left, Right : Employee_Data) return Boolean is
|
||||
begin
|
||||
return Left.Salary > Right.Salary;
|
||||
end Compare_Salary;
|
||||
package Salary_Sort is new Employee_Vectors.Generic_Sorting
|
||||
("<" => Compare_Salary);
|
||||
|
||||
function Compare_Department (Left, Right : Employee_Data) return Boolean is
|
||||
begin
|
||||
return Left.Department < Right.Department;
|
||||
end Compare_Department;
|
||||
package Department_Sort is new Employee_Vectors.Generic_Sorting
|
||||
("<" => Compare_Department);
|
||||
|
||||
Example_Data : Employee_Vectors.Vector;
|
||||
begin
|
||||
-- fill data
|
||||
Example_Data.Append (("Tyler Bennett ", "E10297", 32000, D101));
|
||||
Example_Data.Append (("John Rappl ", "E21437", 47000, D050));
|
||||
Example_Data.Append (("George Woltman ", "E00127", 53500, D101));
|
||||
Example_Data.Append (("Adam Smith ", "E63535", 18000, D202));
|
||||
Example_Data.Append (("Claire Buckman ", "E39876", 27800, D202));
|
||||
Example_Data.Append (("David McClellan", "E04242", 41500, D101));
|
||||
Example_Data.Append (("Rich Holcomb ", "E01234", 49500, D202));
|
||||
Example_Data.Append (("Nathan Adams ", "E41298", 21900, D050));
|
||||
Example_Data.Append (("Richard Potter ", "E43128", 15900, D101));
|
||||
Example_Data.Append (("David Motsinger", "E27002", 19250, D202));
|
||||
Example_Data.Append (("Tim Sampair ", "E03033", 27000, D101));
|
||||
Example_Data.Append (("Kim Arlich ", "E10001", 57000, D190));
|
||||
Example_Data.Append (("Timothy Grove ", "E16398", 29900, D190));
|
||||
-- sort by salary
|
||||
Salary_Sort.Sort (Example_Data);
|
||||
-- output each department
|
||||
for Department in Departments loop
|
||||
declare
|
||||
Position : Employee_Vectors.Cursor := Example_Data.First;
|
||||
Employee : Employee_Data;
|
||||
begin
|
||||
Ada.Text_IO.Put_Line ("Department " & Departments'Image (Department));
|
||||
for I in 1 .. 3 loop
|
||||
Employee := Employee_Vectors.Element (Position);
|
||||
while Employee.Department /= Department loop
|
||||
Position := Employee_Vectors.Next (Position);
|
||||
Employee := Employee_Vectors.Element (Position);
|
||||
end loop;
|
||||
Ada.Text_IO.Put_Line (" " & Employee.Name & " | " &
|
||||
Employee.ID & " | " &
|
||||
Positive'Image (Employee.Salary));
|
||||
Position := Employee_Vectors.Next (Position);
|
||||
end loop;
|
||||
exception
|
||||
when Constraint_Error =>
|
||||
null;
|
||||
end;
|
||||
end loop;
|
||||
end Top;
|
||||
54
Task/Top-rank-per-group/Aime/top-rank-per-group.aime
Normal file
54
Task/Top-rank-per-group/Aime/top-rank-per-group.aime
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
Add_Employee(record employees, text name, id, integer salary, text department)
|
||||
{
|
||||
employees[name] = list(name, id, salary, department);
|
||||
}
|
||||
|
||||
collect(record top, employees)
|
||||
{
|
||||
for (, list l in employees) {
|
||||
top.v_index(l[3]).v_list(l[2]).link(-1, l);
|
||||
}
|
||||
for (text department, index x in top) {
|
||||
list t;
|
||||
|
||||
x.ucall(l_ucall, 0, l_append, 1, t);
|
||||
if (N < ~t.reverse) {
|
||||
t.erase(N, -1);
|
||||
}
|
||||
top[department] = t;
|
||||
}
|
||||
}
|
||||
|
||||
print_department(text department, list employees)
|
||||
{
|
||||
o_("Department ", department, "\n");
|
||||
|
||||
for (, list l in employees) {
|
||||
o_form(" ~ | ~ | ~\n", l[0], l[1], l[2]);
|
||||
}
|
||||
}
|
||||
|
||||
main(void)
|
||||
{
|
||||
record employees, top;
|
||||
|
||||
Add_Employee(employees, "Tyler Bennett ", "E10297", 32000, "D101");
|
||||
Add_Employee(employees, "John Rappl ", "E21437", 47000, "D050");
|
||||
Add_Employee(employees, "George Woltman ", "E00127", 53500, "D101");
|
||||
Add_Employee(employees, "Adam Smith ", "E63535", 18000, "D202");
|
||||
Add_Employee(employees, "Claire Buckman ", "E39876", 27800, "D202");
|
||||
Add_Employee(employees, "David McClellan", "E04242", 41500, "D101");
|
||||
Add_Employee(employees, "Rich Holcomb ", "E01234", 49500, "D202");
|
||||
Add_Employee(employees, "Nathan Adams ", "E41298", 21900, "D050");
|
||||
Add_Employee(employees, "Richard Potter ", "E43128", 15900, "D101");
|
||||
Add_Employee(employees, "David Motsinger", "E27002", 19250, "D202");
|
||||
Add_Employee(employees, "Tim Sampair ", "E03033", 27000, "D101");
|
||||
Add_Employee(employees, "Kim Arlich ", "E10001", 57000, "D190");
|
||||
Add_Employee(employees, "Timothy Grove ", "E16398", 29900, "D190");
|
||||
|
||||
collect(top, employees);
|
||||
|
||||
top.wcall(print_department, 0, 1);
|
||||
|
||||
0;
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
use AppleScript version "2.3.1" -- Mac OS X 10.9 (Mavericks) or later.
|
||||
use sorter : script ¬
|
||||
"Custom Iterative Ternary Merge Sort" -- <www.macscripter.net/t/timsort-and-nigsort/71383/3>
|
||||
|
||||
on topNSalariesPerDepartment(employeeRecords, n)
|
||||
set output to {}
|
||||
set employeeCount to (count employeeRecords)
|
||||
if ((employeeCount > 0) and (n > 0)) then
|
||||
-- Sort a copy of the employee record list by department
|
||||
-- with descending subsorts on salary.
|
||||
copy employeeRecords to employeeRecords
|
||||
script comparer
|
||||
on isGreater(a, b)
|
||||
return ((a's department > b's department) or ¬
|
||||
((a's department = b's department) and (a's salary < b's salary)))
|
||||
end isGreater
|
||||
end script
|
||||
considering numeric strings
|
||||
tell sorter to sort(employeeRecords, 1, employeeCount, {comparer:comparer})
|
||||
end considering
|
||||
|
||||
-- Initialise the output with data from the first record in the sorted list,
|
||||
-- then work through the rest of the list.
|
||||
set {department:previousDepartment, salary:previousSalary} to beginning of employeeRecords
|
||||
set {mv, topSalaries} to {"-", {previousSalary}}
|
||||
set end of output to {department:previousDepartment, salaries:topSalaries}
|
||||
repeat with i from 2 to employeeCount
|
||||
set {department:thisDepartment, salary:thisSalary} to item i of employeeRecords
|
||||
if (thisDepartment = previousDepartment) then
|
||||
if ((thisSalary < previousSalary) and ((count topSalaries) < n)) then
|
||||
set end of topSalaries to thisSalary
|
||||
set previousSalary to thisSalary
|
||||
end if
|
||||
else
|
||||
-- First record of the next department.
|
||||
-- Pad out the previous department's salary list if it has fewer than n entries.
|
||||
repeat (n - (count topSalaries)) times
|
||||
set end of topSalaries to mv
|
||||
end repeat
|
||||
-- Start a result record for the new department and add it to the output.
|
||||
set topSalaries to {thisSalary}
|
||||
set end of output to {department:thisDepartment, salaries:topSalaries}
|
||||
set previousDepartment to thisDepartment
|
||||
set previousSalary to thisSalary
|
||||
end if
|
||||
end repeat
|
||||
-- Pad the last department's salary list if necessary.
|
||||
repeat (n - (count topSalaries)) times
|
||||
set end of topSalaries to mv
|
||||
end repeat
|
||||
end if
|
||||
|
||||
return output
|
||||
end topNSalariesPerDepartment
|
||||
|
||||
on join(lst, delim)
|
||||
set astid to AppleScript's text item delimiters
|
||||
set AppleScript's text item delimiters to delim
|
||||
set txt to lst as text
|
||||
set AppleScript's text item delimiters to astid
|
||||
return txt
|
||||
end join
|
||||
|
||||
on task()
|
||||
set employeeRecords to {¬
|
||||
{|name|:"Tyler Bennett", |ID|:"E10297", salary:32000, department:"D101"}, ¬
|
||||
{|name|:"John Rappl", |ID|:"E21437", salary:47000, department:"D050"}, ¬
|
||||
{|name|:"George Woltman", |ID|:"E00127", salary:53500, department:"D101"}, ¬
|
||||
{|name|:"Adam Smith", |ID|:"E63535", salary:18000, department:"D202"}, ¬
|
||||
{|name|:"Claire Buckman", |ID|:"E39876", salary:27800, department:"D202"}, ¬
|
||||
{|name|:"David McClellan", |ID|:"E04242", salary:41500, department:"D101"}, ¬
|
||||
{|name|:"Rich Holcomb", |ID|:"E01234", salary:49500, department:"D202"}, ¬
|
||||
{|name|:"Nathan Adams", |ID|:"E41298", salary:21900, department:"D050"}, ¬
|
||||
{|name|:"Richard Potter", |ID|:"E43128", salary:15900, department:"D101"}, ¬
|
||||
{|name|:"David Motsinger", |ID|:"E27002", salary:19250, department:"D202"}, ¬
|
||||
{|name|:"Tim Sampair", |ID|:"E03033", salary:27000, department:"D101"}, ¬
|
||||
{|name|:"Kim Arlich", |ID|:"E10001", salary:57000, department:"D190"}, ¬
|
||||
{|name|:"Timothy Grove", |ID|:"E16398", salary:29900, department:"D190"}, ¬
|
||||
{|name|:"Simila Pey", |ID|:"E16399", salary:29900, department:"D190"} ¬
|
||||
}
|
||||
set n to 4
|
||||
set topSalaryRecords to topNSalariesPerDepartment(employeeRecords, n)
|
||||
|
||||
-- Derive a text report from the result.
|
||||
set report to {"Top " & n & " salaries per department:"}
|
||||
repeat with thisRecord in topSalaryRecords
|
||||
set end of report to thisRecord's department & ": " & join(thisRecord's salaries, " ")
|
||||
end repeat
|
||||
return join(report, linefeed)
|
||||
end task
|
||||
|
||||
task()
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
"Top 4 salaries per department:
|
||||
D050: 47000 21900 - -
|
||||
D101: 53500 41500 32000 27000
|
||||
D190: 57000 29900 - -
|
||||
D202: 49500 27800 19250 18000"
|
||||
31
Task/Top-rank-per-group/Arturo/top-rank-per-group.arturo
Normal file
31
Task/Top-rank-per-group/Arturo/top-rank-per-group.arturo
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
printTopEmployees: function [count, entries][
|
||||
data: read.csv.withHeaders entries
|
||||
departments: sort unique map data 'row -> row\Department
|
||||
loop departments 'd [
|
||||
print "----------------------"
|
||||
print ["department:" d]
|
||||
print "----------------------"
|
||||
loop first.n: count
|
||||
sort.descending.by:"Salary"
|
||||
select data 'row [row\Department = d] 'employee ->
|
||||
print [get employee "Employee Name" "->" employee\Salary]
|
||||
print ""
|
||||
]
|
||||
]
|
||||
|
||||
printTopEmployees 2 {
|
||||
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
|
||||
}
|
||||
56
Task/Top-rank-per-group/AutoHotkey/top-rank-per-group.ahk
Normal file
56
Task/Top-rank-per-group/AutoHotkey/top-rank-per-group.ahk
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
Departments = D050, D101, D190, D202
|
||||
StringSplit, Department_, Departments, `,, %A_Space%
|
||||
|
||||
; Employee Name, Employee ID, Salary, Department
|
||||
Add_Employee("Tyler Bennett ", "E10297", 32000, "D101")
|
||||
Add_Employee("John Rappl ", "E21437", 47000, "D050")
|
||||
Add_Employee("George Woltman ", "E00127", 53500, "D101")
|
||||
Add_Employee("Adam Smith ", "E63535", 18000, "D202")
|
||||
Add_Employee("Claire Buckman ", "E39876", 27800, "D202")
|
||||
Add_Employee("David McClellan", "E04242", 41500, "D101")
|
||||
Add_Employee("Rich Holcomb ", "E01234", 49500, "D202")
|
||||
Add_Employee("Nathan Adams ", "E41298", 21900, "D050")
|
||||
Add_Employee("Richard Potter ", "E43128", 15900, "D101")
|
||||
Add_Employee("David Motsinger", "E27002", 19250, "D202")
|
||||
Add_Employee("Tim Sampair ", "E03033", 27000, "D101")
|
||||
Add_Employee("Kim Arlich ", "E10001", 57000, "D190")
|
||||
Add_Employee("Timothy Grove ", "E16398", 29900, "D190")
|
||||
|
||||
; display top 3 ranks for each department
|
||||
Loop, %Department_0% ; all departments
|
||||
MsgBox,, % "Department: " Department_%A_Index%
|
||||
, % TopRank(3, Department_%A_Index%)
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
TopRank(N, Department) { ; find the top N salaries in each department
|
||||
;---------------------------------------------------------------------------
|
||||
local Collection := Msg := ""
|
||||
Loop, %m% ; all employees
|
||||
If (Employee_%A_Index%_Dept = Department)
|
||||
; collect all the salaries being paid in this department
|
||||
Collection .= (Collection ? "," : "") Employee_%A_Index%_Salary
|
||||
Sort, Collection, ND,R
|
||||
StringSplit, Collection, Collection, `,
|
||||
Loop, % (N < Collection0) ? N : Collection0 {
|
||||
Salary := Collection%A_Index%
|
||||
Loop, %m% ; find the respective employee
|
||||
If (Employee_%A_Index%_Salary = Salary)
|
||||
; and put out his/her details
|
||||
Msg .= Employee_%A_Index%_Name "`t"
|
||||
. Employee_%A_Index%_ID "`t"
|
||||
. Employee_%A_Index%_Salary "`t"
|
||||
. Employee_%A_Index%_Dept "`t`n"
|
||||
}
|
||||
Return, Msg
|
||||
}
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
Add_Employee(Name, ID, Salary, Department) {
|
||||
;---------------------------------------------------------------------------
|
||||
global
|
||||
m++
|
||||
Employee_%m%_Name := Name
|
||||
Employee_%m%_ID := ID
|
||||
Employee_%m%_Salary := Salary
|
||||
Employee_%m%_Dept := Department
|
||||
}
|
||||
40
Task/Top-rank-per-group/Bracmat/top-rank-per-group.bracmat
Normal file
40
Task/Top-rank-per-group/Bracmat/top-rank-per-group.bracmat
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
(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)
|
||||
: ?employees
|
||||
& ( toprank
|
||||
= employees N n P "Employee Name" "Employee ID" SalaryDepartment
|
||||
. !arg:(?employees.?N)
|
||||
& 1:?P
|
||||
& whl
|
||||
' ( !employees
|
||||
: (?"Employee Name",?"Employee ID",?Salary,?Department)
|
||||
?employees
|
||||
& !Department^(!Salary.!"Employee Name".!"Employee ID")*!P:?P
|
||||
)
|
||||
& out$(Top !N "salaries per department.")
|
||||
& whl
|
||||
' ( !P:%?Department^?employees*?P
|
||||
& out$(str$("Department " !Department ":"))
|
||||
& !N:?n
|
||||
& whl
|
||||
' ( !n+-1:~<0:?n
|
||||
& !employees
|
||||
: ?employees+(?Salary.?"Employee Name".?"Employee ID")
|
||||
& out
|
||||
$ (str$(" " !"Employee Name" " (" !"Employee ID" "):" !Salary))
|
||||
)
|
||||
)
|
||||
)
|
||||
& toprank$(!employees.3)
|
||||
& ;
|
||||
114
Task/Top-rank-per-group/C++/top-rank-per-group.cpp
Normal file
114
Task/Top-rank-per-group/C++/top-rank-per-group.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
#include <string>
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
struct Employee
|
||||
{
|
||||
std::string Name;
|
||||
std::string ID;
|
||||
unsigned long Salary;
|
||||
std::string Department;
|
||||
Employee(std::string _Name = "", std::string _ID = "", unsigned long _Salary = 0, std::string _Department = "")
|
||||
: Name(_Name), ID(_ID), Salary(_Salary), Department(_Department)
|
||||
{ }
|
||||
|
||||
void display(std::ostream& out) const
|
||||
{
|
||||
out << Name << "\t" << ID << "\t" << Salary << "\t" << Department << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
// We'll tell std::set to use this to sort our employees.
|
||||
struct CompareEarners
|
||||
{
|
||||
bool operator()(const Employee& e1, const Employee& e2)
|
||||
{
|
||||
return (e1.Salary > e2.Salary);
|
||||
}
|
||||
};
|
||||
|
||||
// A few typedefs to make the code easier to type, read and maintain.
|
||||
typedef std::list<Employee> EMPLOYEELIST;
|
||||
|
||||
// Notice the CompareEarners; We're telling std::set to user our specified comparison mechanism
|
||||
// to sort its contents.
|
||||
typedef std::set<Employee, CompareEarners> DEPARTMENTPAYROLL;
|
||||
|
||||
typedef std::map<std::string, DEPARTMENTPAYROLL> DEPARTMENTLIST;
|
||||
|
||||
void initialize(EMPLOYEELIST& Employees)
|
||||
{
|
||||
// Initialize our employee list data source.
|
||||
Employees.push_back(Employee("Tyler Bennett", "E10297", 32000, "D101"));
|
||||
Employees.push_back(Employee("John Rappl", "E21437", 47000, "D050"));
|
||||
Employees.push_back(Employee("George Woltman", "E21437", 53500, "D101"));
|
||||
Employees.push_back(Employee("Adam Smith", "E21437", 18000, "D202"));
|
||||
Employees.push_back(Employee("Claire Buckman", "E39876", 27800, "D202"));
|
||||
Employees.push_back(Employee("David McClellan", "E04242", 41500, "D101"));
|
||||
Employees.push_back(Employee("Rich Holcomb", "E01234", 49500, "D202"));
|
||||
Employees.push_back(Employee("Nathan Adams", "E41298", 21900, "D050"));
|
||||
Employees.push_back(Employee("Richard Potter", "E43128", 15900, "D101"));
|
||||
Employees.push_back(Employee("David Motsinger", "E27002", 19250, "D202"));
|
||||
Employees.push_back(Employee("Tim Sampair", "E03033", 27000, "D101"));
|
||||
Employees.push_back(Employee("Kim Arlich", "E10001", 57000, "D190"));
|
||||
Employees.push_back(Employee("Timothy Grove", "E16398", 29900, "D190"));
|
||||
}
|
||||
|
||||
void group(EMPLOYEELIST& Employees, DEPARTMENTLIST& Departments)
|
||||
{
|
||||
// Loop through all of our employees.
|
||||
for( EMPLOYEELIST::iterator iEmployee = Employees.begin();
|
||||
Employees.end() != iEmployee;
|
||||
++iEmployee )
|
||||
{
|
||||
DEPARTMENTPAYROLL& groupSet = Departments[iEmployee->Department];
|
||||
|
||||
// Add our employee to this group.
|
||||
groupSet.insert(*iEmployee);
|
||||
}
|
||||
}
|
||||
|
||||
void present(DEPARTMENTLIST& Departments, unsigned int N)
|
||||
{
|
||||
// Loop through all of our departments
|
||||
for( DEPARTMENTLIST::iterator iDepartment = Departments.begin();
|
||||
Departments.end() != iDepartment;
|
||||
++iDepartment )
|
||||
{
|
||||
std::cout << "In department " << iDepartment->first << std::endl;
|
||||
std::cout << "Name\t\tID\tSalary\tDepartment" << std::endl;
|
||||
// Get the top three employees for each employee
|
||||
unsigned int rank = 1;
|
||||
for( DEPARTMENTPAYROLL::iterator iEmployee = iDepartment->second.begin();
|
||||
( iDepartment->second.end() != iEmployee) && (rank <= N);
|
||||
++iEmployee, ++rank )
|
||||
{
|
||||
iEmployee->display(std::cout);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// Our container for our list of employees.
|
||||
EMPLOYEELIST Employees;
|
||||
|
||||
// Fill our list of employees
|
||||
initialize(Employees);
|
||||
|
||||
// Our departments.
|
||||
DEPARTMENTLIST Departments;
|
||||
|
||||
// Sort our employees into their departments.
|
||||
// This will also rank them.
|
||||
group(Employees, Departments);
|
||||
|
||||
// Display the top 3 earners in each department.
|
||||
present(Departments, 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
70
Task/Top-rank-per-group/C-sharp/top-rank-per-group.cs
Normal file
70
Task/Top-rank-per-group/C-sharp/top-rank-per-group.cs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
public class Program
|
||||
{
|
||||
class Employee
|
||||
{
|
||||
public Employee(string name, string id, int salary, string department)
|
||||
{
|
||||
Name = name;
|
||||
Id = id;
|
||||
Salary = salary;
|
||||
Department = department;
|
||||
}
|
||||
|
||||
public string Name { get; private set; }
|
||||
public string Id { get; private set; }
|
||||
public int Salary { get; private set; }
|
||||
public string Department { get; private set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0, -25}\t{1}\t{2}", Name, Id, Salary);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var employees = new List<Employee>
|
||||
{
|
||||
new Employee("Tyler Bennett", "E10297", 32000, "D101"),
|
||||
new Employee("John Rappl", "E21437", 47000, "D050"),
|
||||
new Employee("George Woltman", "E21437", 53500, "D101"),
|
||||
new Employee("Adam Smith", "E21437", 18000, "D202"),
|
||||
new Employee("Claire Buckman", "E39876", 27800, "D202"),
|
||||
new Employee("David McClellan", "E04242", 41500, "D101"),
|
||||
new Employee("Rich Holcomb", "E01234", 49500, "D202"),
|
||||
new Employee("Nathan Adams", "E41298", 21900, "D050"),
|
||||
new Employee("Richard Potter", "E43128", 15900, "D101"),
|
||||
new Employee("David Motsinger", "E27002", 19250, "D202"),
|
||||
new Employee("Tim Sampair", "E03033", 27000, "D101"),
|
||||
new Employee("Kim Arlich", "E10001", 57000, "D190"),
|
||||
new Employee("Timothy Grove", "E16398", 29900, "D190")
|
||||
};
|
||||
|
||||
DisplayTopNPerDepartment(employees, 2);
|
||||
}
|
||||
|
||||
static void DisplayTopNPerDepartment(IEnumerable<Employee> employees, int n)
|
||||
{
|
||||
var topSalariesByDepartment =
|
||||
from employee in employees
|
||||
group employee by employee.Department
|
||||
into g
|
||||
select new
|
||||
{
|
||||
Department = g.Key,
|
||||
TopEmployeesBySalary = g.OrderByDescending(e => e.Salary).Take(n)
|
||||
};
|
||||
|
||||
foreach (var x in topSalariesByDepartment)
|
||||
{
|
||||
Console.WriteLine("Department: " + x.Department);
|
||||
foreach (var employee in x.TopEmployeesBySalary)
|
||||
Console.WriteLine(employee);
|
||||
Console.WriteLine("----------------------------");
|
||||
}
|
||||
}
|
||||
}
|
||||
55
Task/Top-rank-per-group/C/top-rank-per-group.c
Normal file
55
Task/Top-rank-per-group/C/top-rank-per-group.c
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
const char *name, *id, *dept;
|
||||
int sal;
|
||||
} person;
|
||||
|
||||
person ppl[] = {
|
||||
{"Tyler Bennett", "E10297", "D101", 32000},
|
||||
{"John Rappl", "E21437", "D050", 47000},
|
||||
{"George Woltman", "E00127", "D101", 53500},
|
||||
{"Adam Smith", "E63535", "D202", 18000},
|
||||
{"Claire Buckman", "E39876", "D202", 27800},
|
||||
{"David McClellan", "E04242", "D101", 41500},
|
||||
{"Rich Holcomb", "E01234", "D202", 49500},
|
||||
{"Nathan Adams", "E41298", "D050", 21900},
|
||||
{"Richard Potter", "E43128", "D101", 15900},
|
||||
{"David Motsinger", "E27002", "D202", 19250},
|
||||
{"Tim Sampair", "E03033", "D101", 27000},
|
||||
{"Kim Arlich", "E10001", "D190", 57000},
|
||||
{"Timothy Grove", "E16398", "D190", 29900},
|
||||
};
|
||||
|
||||
int pcmp(const void *a, const void *b)
|
||||
{
|
||||
const person *aa = a, *bb = b;
|
||||
int x = strcmp(aa->dept, bb->dept);
|
||||
if (x) return x;
|
||||
return aa->sal > bb->sal ? -1 : aa->sal < bb->sal;
|
||||
}
|
||||
|
||||
#define N sizeof(ppl)/sizeof(person)
|
||||
void top(int n)
|
||||
{
|
||||
int i, rank;
|
||||
qsort(ppl, N, sizeof(person), pcmp);
|
||||
|
||||
for (i = rank = 0; i < N; i++) {
|
||||
if (i && strcmp(ppl[i].dept, ppl[i - 1].dept)) {
|
||||
rank = 0;
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (rank++ < n)
|
||||
printf("%s %d: %s\n", ppl[i].dept, ppl[i].sal, ppl[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
top(2);
|
||||
return 0;
|
||||
}
|
||||
42
Task/Top-rank-per-group/Ceylon/top-rank-per-group.ceylon
Normal file
42
Task/Top-rank-per-group/Ceylon/top-rank-per-group.ceylon
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
class Employee(name, id, salary, dept) {
|
||||
shared String name;
|
||||
shared String id;
|
||||
shared Integer salary;
|
||||
shared String dept;
|
||||
|
||||
string => "``name`` ``id`` $``salary``.00 ``dept``";
|
||||
}
|
||||
|
||||
Employee[] employees = [
|
||||
Employee("Tyler Bennett", "E10297", 32000, "D101"),
|
||||
Employee("John Rappl", "E21437", 47000, "D050"),
|
||||
Employee("George Woltman", "E00127", 53500, "D101"),
|
||||
Employee("Adam Smith", "E63535", 18000, "D202"),
|
||||
Employee("Claire Buckman", "E39876", 27800, "D202"),
|
||||
Employee("David McClellan", "E04242", 41500, "D101"),
|
||||
Employee("Rich Holcomb", "E01234", 49500, "D202"),
|
||||
Employee("Nathan Adams", "E41298", 21900, "D050"),
|
||||
Employee("Richard Potter", "E43128", 15900, "D101"),
|
||||
Employee("David Motsinger", "E27002", 19250, "D202"),
|
||||
Employee("Tim Sampair", "E03033", 27000, "D101"),
|
||||
Employee("Kim Arlich", "E10001", 57000, "D190"),
|
||||
Employee("Timothy Grove", "E16398", 29900, "D190")
|
||||
];
|
||||
|
||||
"This is the main function."
|
||||
shared void run() {
|
||||
|
||||
value topRanked = topSalaries(employees, 3);
|
||||
|
||||
for (dept -> staff in topRanked) {
|
||||
print(dept);
|
||||
for (employee in staff) {
|
||||
print("\t``employee``");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, {Employee*}> topSalaries({Employee*} employees, Integer n) => map {
|
||||
for (dept -> staff in employees.group(Employee.dept))
|
||||
dept -> staff.sort(byDecreasing(Employee.salary)).take(n)
|
||||
};
|
||||
25
Task/Top-rank-per-group/Clojure/top-rank-per-group.clj
Normal file
25
Task/Top-rank-per-group/Clojure/top-rank-per-group.clj
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
(use '[clojure.contrib.seq-utils :only (group-by)])
|
||||
|
||||
(defstruct employee :Name :ID :Salary :Department)
|
||||
|
||||
(def data
|
||||
(->> '(("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))
|
||||
(map #(apply (partial struct employee) %))))
|
||||
|
||||
|
||||
(doseq [[dep emps] (group-by :Department data)]
|
||||
(println "Department:" dep)
|
||||
(doseq [e (take 3 (reverse (sort-by :Salary emps)))]
|
||||
(println e)))
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
(defun top-n-by-group (n data value-key group-key predicate &key (group-test 'eql))
|
||||
(let ((not-pred (complement predicate))
|
||||
(group-data (make-hash-table :test group-test)))
|
||||
(labels ((value (datum)
|
||||
(funcall value-key datum))
|
||||
(insert (x list)
|
||||
(merge 'list (list x) list not-pred :key #'value))
|
||||
(entry (group)
|
||||
"Return the entry for the group, creating it if
|
||||
necessary. An entry is a list whose first element is
|
||||
k, the number of items currently associated with the
|
||||
group (out of n total), and whose second element is
|
||||
the list of the k current top items for the group."
|
||||
(multiple-value-bind (entry presentp)
|
||||
(gethash group group-data)
|
||||
(if presentp entry
|
||||
(setf (gethash group group-data)
|
||||
(list 0 '())))))
|
||||
(update-entry (entry datum)
|
||||
"Update the entry using datum. If there are already n
|
||||
items associated with the entry, then when datum's value
|
||||
is greater than the current least item, data is merged into
|
||||
the items, and the list (minus the first element) is
|
||||
stored in entry. Otherwise, if there are fewer than n
|
||||
items in the entry, datum is merged in, and the
|
||||
entry's k is increased by 1."
|
||||
(if (= n (first entry))
|
||||
(when (funcall predicate (value datum) (value (first (second entry))))
|
||||
(setf (second entry)
|
||||
(cdr (insert datum (second entry)))))
|
||||
(setf (first entry) (1+ (first entry))
|
||||
(second entry) (insert datum (second entry))))))
|
||||
(dolist (datum data group-data)
|
||||
(update-entry (entry (funcall group-key datum)) datum)))))
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
> (defparameter *employee-data*
|
||||
'(("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))
|
||||
"A list of lists of each employee's name, id, salary, and
|
||||
department.")
|
||||
*EMPLOYEE-DATA*
|
||||
|
||||
> (top-n-by-group 3 *employee-data* 'third 'fourth '>)
|
||||
#<EQL Hash Table{4} 2361A0E7>
|
||||
|
||||
> (describe *)
|
||||
|
||||
#<EQL Hash Table{4} 2361A0E7> is a HASH-TABLE
|
||||
D101 (3 (("Tyler Bennett" E10297 32000 D101) ("David McClellan" E04242 41500 D101) ("George Woltman" E00127 53500 D101)))
|
||||
D050 (2 (("Nathan Adams" E41298 21900 D050) ("John Rappl" E21437 47000 D050)))
|
||||
D202 (3 (("David Motsinger" E27002 19250 D202) ("Claire Buckman" E39876 27800 D202) ("Rich Holcomb" E01234 49500 D202)))
|
||||
D190 (2 (("Timothy Grove" E16398 29900 D190) ("Kim Arlich" E10001 57000 D190)))
|
||||
35
Task/Top-rank-per-group/D/top-rank-per-group.d
Normal file
35
Task/Top-rank-per-group/D/top-rank-per-group.d
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import std.stdio, std.algorithm, std.conv, std.range;
|
||||
|
||||
struct Employee {
|
||||
string name, id;
|
||||
uint salary;
|
||||
string department;
|
||||
}
|
||||
|
||||
immutable Employee[] data = [
|
||||
{"Tyler Bennett", "E10297", 32_000, "D101"},
|
||||
{"John Rappl", "E21437", 47_000, "D050"},
|
||||
{"George Woltman", "E00127", 53_500, "D101"},
|
||||
{"Adam Smith", "E63535", 18_000, "D202"},
|
||||
{"Claire Buckman", "E39876", 27_800, "D202"},
|
||||
{"David McClellan", "E04242", 41_500, "D101"},
|
||||
{"Rich Holcomb", "E01234", 49_500, "D202"},
|
||||
{"Nathan Adams", "E41298", 21_900, "D050"},
|
||||
{"Richard Potter", "E43128", 15_900, "D101"},
|
||||
{"David Motsinger", "E27002", 19_250, "D202"},
|
||||
{"Tim Sampair", "E03033", 27_000, "D101"},
|
||||
{"Kim Arlich", "E10001", 57_000, "D190"},
|
||||
{"Timothy Grove", "E16398", 29_900, "D190"}];
|
||||
|
||||
void main(in string[] args) {
|
||||
immutable n = (args.length == 2) ? to!int(args[1]) : 3;
|
||||
|
||||
Employee[][string] departments;
|
||||
foreach (immutable rec; data)
|
||||
departments[rec.department] ~= rec;
|
||||
|
||||
foreach (dep, recs; departments) {
|
||||
recs.topN!q{a.salary > b.salary}(n);
|
||||
writefln("Department %s\n %(%s\n %)\n", dep, recs.take(n));
|
||||
}
|
||||
}
|
||||
64
Task/Top-rank-per-group/Delphi/top-rank-per-group.delphi
Normal file
64
Task/Top-rank-per-group/Delphi/top-rank-per-group.delphi
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
type TEmployeeInfo = record
|
||||
Name,ID: string;
|
||||
Salary: double;
|
||||
Dept: string;
|
||||
end;
|
||||
|
||||
var EmployeeInfo: array [0..12] of TEmployeeInfo = (
|
||||
(Name: 'Tyler Bennett'; ID: 'E10297'; Salary: 32000; Dept: 'D101'),
|
||||
(Name: 'John Rappl'; ID: 'E21437'; Salary: 47000; Dept: 'D050'),
|
||||
(Name: 'George Woltman'; ID: 'E00127'; Salary: 53500; Dept: 'D101'),
|
||||
(Name: 'Adam Smith'; ID: 'E63535'; Salary: 18000; Dept: 'D202'),
|
||||
(Name: 'Claire Buckman'; ID: 'E39876'; Salary: 27800; Dept: 'D202'),
|
||||
(Name: 'David McClellan'; ID: 'E04242'; Salary: 41500; Dept: 'D101'),
|
||||
(Name: 'Rich Holcomb'; ID: 'E01234'; Salary: 49500; Dept: 'D202'),
|
||||
(Name: 'Nathan Adams'; ID: 'E41298'; Salary: 21900; Dept: 'D050'),
|
||||
(Name: 'Richard Potter'; ID: 'E43128'; Salary: 15900; Dept: 'D101'),
|
||||
(Name: 'David Motsinger'; ID: 'E27002'; Salary: 19250; Dept: 'D202'),
|
||||
(Name: 'Tim Sampair'; ID: 'E03033'; Salary: 27000; Dept: 'D101'),
|
||||
(Name: 'Kim Arlich'; ID: 'E10001'; Salary: 57000; Dept: 'D190'),
|
||||
(Name: 'Timothy Grove'; ID: 'E16398'; Salary: 29900; Dept: 'D190')
|
||||
);
|
||||
|
||||
|
||||
function SalarySort(Item1, Item2: Pointer): Integer;
|
||||
var Info1,Info2: TEmployeeInfo;
|
||||
begin
|
||||
Info1:=TEmployeeInfo(Item1^);
|
||||
Info2:=TEmployeeInfo(Item2^);
|
||||
Result:=AnsiCompareStr(Info1.Dept,Info2.Dept);
|
||||
If Result=0 then Result:=Trunc(Info1.Salary-Info2.Salary);
|
||||
end;
|
||||
|
||||
procedure ShowTopSalaries(Memo: TMemo);
|
||||
var List: TList;
|
||||
var Info: TEmployeeInfo;
|
||||
var I: integer;
|
||||
var S,OldDept: string;
|
||||
|
||||
procedure NewDepartment(Name: string);
|
||||
begin
|
||||
Memo.Lines.Add('');
|
||||
Memo.Lines.Add('Department: '+Name);
|
||||
Memo.Lines.Add('Employee Name Employee ID Salary Department');
|
||||
OldDept:=Name;
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
List:=TList.Create;
|
||||
try
|
||||
for I:=0 to High(EmployeeInfo) do
|
||||
List.Add(@EmployeeInfo[I]);
|
||||
List.Sort(SalarySort);
|
||||
OldDept:='';
|
||||
for I:=0 to List.Count-1 do
|
||||
begin
|
||||
Info:=TEmployeeInfo(List[I]^);
|
||||
if OldDept<>Info.Dept then NewDepartment(Info.Dept);
|
||||
S:=Format('%-18S %9S %11.0m %8S',[Info.Name,Info.ID,Info.Salary,Info.Dept]);
|
||||
Memo.Lines.Add(S);
|
||||
end;
|
||||
|
||||
finally List.Free; end;
|
||||
end;
|
||||
41
Task/Top-rank-per-group/Dyalect/top-rank-per-group.dyalect
Normal file
41
Task/Top-rank-per-group/Dyalect/top-rank-per-group.dyalect
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
type Employee(name,id,salary,department) with Lookup
|
||||
|
||||
func Employee.ToString() {
|
||||
"$\(this.salary) (name: \(this.name), id: \(this.id), department: \(this.department)"
|
||||
}
|
||||
|
||||
let employees = [
|
||||
Employee("Tyler Bennett","E10297",32000,"D101"),
|
||||
Employee("John Rappl","E21437",47000,"D050"),
|
||||
Employee("George Woltman","E00127",53500,"D101"),
|
||||
Employee("Adam Smith","E63535",18000,"D202"),
|
||||
Employee("Claire Buckman","E39876",27800,"D202"),
|
||||
Employee("David McClellan","E04242",41500,"D101"),
|
||||
Employee("Rich Holcomb","E01234",49500,"D202"),
|
||||
Employee("Nathan Adams","E41298",21900,"D050"),
|
||||
Employee("Richard Potter","E43128",15900,"D101"),
|
||||
Employee("David Motsinger","E27002",19250,"D202"),
|
||||
Employee("Tim Sampair","E03033",27000,"D101"),
|
||||
Employee("Kim Arlich","E10001",57000,"D190"),
|
||||
Employee("Timothy Grove","E16398",29900,"D190")
|
||||
]
|
||||
|
||||
func topNSalaries(n) {
|
||||
//We sort employees based on salary
|
||||
employees.Sort((x,y) => y.salary - x.salary)
|
||||
let max =
|
||||
if n > employees.Length() - 1 {
|
||||
employees.Length() - 1
|
||||
} else {
|
||||
n
|
||||
}
|
||||
for i in 0..max {
|
||||
yield employees[i]
|
||||
}
|
||||
}
|
||||
|
||||
var seq = topNSalaries(5)
|
||||
|
||||
for e in seq {
|
||||
print(e)
|
||||
}
|
||||
39
Task/Top-rank-per-group/E/top-rank-per-group.e
Normal file
39
Task/Top-rank-per-group/E/top-rank-per-group.e
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/** Turn a list of arrays into a list of maps with the given keys. */
|
||||
def addKeys(keys, rows) {
|
||||
def res := [].diverge()
|
||||
for row in rows { res.push(__makeMap.fromColumns(keys, row)) }
|
||||
return res.snapshot()
|
||||
}
|
||||
|
||||
def data := addKeys(
|
||||
["name", "id", "salary", "dept"],
|
||||
[["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"]])
|
||||
|
||||
def topSalaries(n, out) {
|
||||
var groups := [].asMap()
|
||||
for row in data {
|
||||
def [=> salary, => dept] | _ := row
|
||||
def top := groups.fetch(dept, fn {[]}).with([-salary, row]).sort()
|
||||
groups with= (dept, top.run(0, top.size().min(n)))
|
||||
}
|
||||
for dept => group in groups.sortKeys() {
|
||||
out.println(`Department $dept`)
|
||||
out.println(`---------------`)
|
||||
for [_, row] in group {
|
||||
out.println(`${row["id"]} $$${row["salary"]} ${row["name"]}`)
|
||||
}
|
||||
out.println()
|
||||
}
|
||||
}
|
||||
14
Task/Top-rank-per-group/EchoLisp/top-rank-per-group-1.l
Normal file
14
Task/Top-rank-per-group/EchoLisp/top-rank-per-group-1.l
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
(lib 'struct) ;; tables are based upon structures
|
||||
(lib 'sql) ;; sql-select function
|
||||
|
||||
;; input table
|
||||
(define emps (make-table (struct emp (name id salary dept))))
|
||||
;; output table
|
||||
(define high (make-table (struct out (dept name salary))))
|
||||
|
||||
;; sort/group procedure
|
||||
(define (get-high num-records: N into: high)
|
||||
(sql-select emp.dept emp.name emp.salary
|
||||
from emps
|
||||
group-by emp.dept
|
||||
order-by emp.salary desc limit N into high))
|
||||
39
Task/Top-rank-per-group/EchoLisp/top-rank-per-group-2.l
Normal file
39
Task/Top-rank-per-group/EchoLisp/top-rank-per-group-2.l
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
(define emps_file
|
||||
'(("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)
|
||||
("Simon Gallubert" E00000 42 D666)
|
||||
("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)))
|
||||
|
||||
(list->table emps_file emps ) ;; load the table
|
||||
|
||||
(get-high 2 high)
|
||||
(table-print high)
|
||||
|
||||
[0] D050 John Rappl 47000
|
||||
[1] D050 Nathan Adams 21900
|
||||
[2] D101 George Woltman 53500
|
||||
[3] D101 David McClellan 41500
|
||||
[4] D190 Kim Arlich 57000
|
||||
[5] D190 Timothy Grove 29900
|
||||
[6] D202 Rich Holcomb 49500
|
||||
[7] D202 Claire Buckman 27800
|
||||
[8] D666 Simon Gallubert 42
|
||||
|
||||
(sql-delete from high)
|
||||
(get-high 1 high)
|
||||
(table-print high)
|
||||
[0] D050 John Rappl 47000
|
||||
[1] D101 George Woltman 53500
|
||||
[2] D190 Kim Arlich 57000
|
||||
[3] D202 Rich Holcomb 49500
|
||||
[4] D666 Simon Gallubert 42
|
||||
65
Task/Top-rank-per-group/Elena/top-rank-per-group.elena
Normal file
65
Task/Top-rank-per-group/Elena/top-rank-per-group.elena
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import system'collections;
|
||||
import system'routines;
|
||||
import extensions;
|
||||
import extensions'routines;
|
||||
import extensions'text;
|
||||
|
||||
class Employee
|
||||
{
|
||||
prop string Name;
|
||||
prop string ID;
|
||||
prop int Salary;
|
||||
prop string Department;
|
||||
|
||||
string toPrintable()
|
||||
= new StringWriter()
|
||||
.writePaddingRight(Name, 25)
|
||||
.writePaddingRight(ID, 12)
|
||||
.writePaddingRight(Salary.toPrintable(), 12)
|
||||
.write:Department;
|
||||
}
|
||||
|
||||
extension reportOp
|
||||
{
|
||||
topNPerDepartment(n)
|
||||
= self.groupBy:(x => x.Department ).selectBy:(x)
|
||||
{
|
||||
^ new {
|
||||
Department = x.Key;
|
||||
|
||||
Employees
|
||||
= x.orderBy:(f,l => f.Salary > l.Salary ).top(n).summarize(new ArrayList());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public program()
|
||||
{
|
||||
var employees := new Employee[]
|
||||
{
|
||||
new Employee{ this Name := "Tyler Bennett"; this ID := "E10297"; this Salary:=32000; this Department:="D101";},
|
||||
new Employee{ this Name := "John Rappl"; this ID := "E21437"; this Salary:=47000; this Department:="D050";},
|
||||
new Employee{ this Name := "George Woltman"; this ID := "E00127"; this Salary:=53500; this Department:="D101";},
|
||||
new Employee{ this Name := "Adam Smith"; this ID := "E63535"; this Salary:=18000; this Department:="D202";},
|
||||
new Employee{ this Name := "Claire Buckman"; this ID := "E39876"; this Salary:=27800; this Department:="D202";},
|
||||
new Employee{ this Name := "David McClellan"; this ID := "E04242"; this Salary:=41500; this Department:="D101";},
|
||||
new Employee{ this Name := "Rich Holcomb"; this ID := "E01234"; this Salary:=49500; this Department:="D202";},
|
||||
new Employee{ this Name := "Nathan Adams"; this ID := "E41298"; this Salary:=21900; this Department:="D050";},
|
||||
new Employee{ this Name := "Richard Potter"; this ID := "E43128"; this Salary:=15900; this Department:="D101";},
|
||||
new Employee{ this Name := "David Motsinger"; this ID := "E27002"; this Salary:=19250; this Department:="D202";},
|
||||
new Employee{ this Name := "Tim Sampair"; this ID := "E03033"; this Salary:=27000; this Department:="D101";},
|
||||
new Employee{ this Name := "Kim Arlich"; this ID := "E10001"; this Salary:=57000; this Department:="D190";},
|
||||
new Employee{ this Name := "Timothy Grove"; this ID := "E16398"; this Salary:=29900; this Department:="D190";}
|
||||
};
|
||||
|
||||
employees.topNPerDepartment:2.forEach:(info)
|
||||
{
|
||||
console.printLine("Department: ",info.Department);
|
||||
|
||||
info.Employees.forEach:printingLn;
|
||||
|
||||
console.writeLine:"---------------------------------------------"
|
||||
};
|
||||
|
||||
console.readChar()
|
||||
}
|
||||
36
Task/Top-rank-per-group/Elixir/top-rank-per-group.elixir
Normal file
36
Task/Top-rank-per-group/Elixir/top-rank-per-group.elixir
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
defmodule TopRank do
|
||||
def per_groupe(data, n) do
|
||||
String.split(data, ~r/(\n|\r\n|\r)/, trim: true)
|
||||
|> Enum.drop(1)
|
||||
|> Enum.map(fn person -> String.split(person,",") end)
|
||||
|> Enum.group_by(fn person -> department(person) end)
|
||||
|> Enum.each(fn {department,group} ->
|
||||
IO.puts "Department: #{department}"
|
||||
Enum.sort_by(group, fn person -> -salary(person) end)
|
||||
|> Enum.take(n)
|
||||
|> Enum.each(fn person -> IO.puts str_format(person) end)
|
||||
end)
|
||||
end
|
||||
|
||||
defp salary([_,_,x,_]), do: String.to_integer(x)
|
||||
defp department([_,_,_,x]), do: x
|
||||
defp str_format([a,b,c,_]), do: " #{a} - #{b} - #{c} annual salary"
|
||||
end
|
||||
|
||||
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
|
||||
"""
|
||||
TopRank.per_groupe(data, 3)
|
||||
39
Task/Top-rank-per-group/Erlang/top-rank-per-group.erl
Normal file
39
Task/Top-rank-per-group/Erlang/top-rank-per-group.erl
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<-module( top_rank_per_group ).
|
||||
|
||||
-export( [employees/0, employees_in_department/2, highest_payed/2, task/1] ).
|
||||
|
||||
-record( employee, {name, id, salery, department} ).
|
||||
|
||||
employees() ->
|
||||
[#employee{name="Tyler Bennett", id="E10297", salery=32000, department="D101"},
|
||||
#employee{name="John Rappl", id="E21437", salery=47000, department="D101"},
|
||||
#employee{name="George Woltman", id="E00127", salery=53500, department="D050"},
|
||||
#employee{name="Adam Smith", id="E63535", salery=18000, department="D202"},
|
||||
#employee{name="Claire Buckman", id="E39876", salery=27800, department="D202"},
|
||||
#employee{name="David McClellan", id="E04242", salery=41500, department="D101"},
|
||||
#employee{name="Rich Holcomb", id="E01234", salery=49500, department="D202"},
|
||||
#employee{name="Nathan Adams", id="E41298", salery=21900, department="D050"},
|
||||
#employee{name="Richard Potter", id="E43128", salery=15900, department="D101"},
|
||||
#employee{name="David Motsinger", id="E27002", salery=19250, department="D202"},
|
||||
#employee{name="Tim Sampair", id="E03033", salery=27000, department="D101"},
|
||||
#employee{name="Kim Arlich", id="E10001", salery=57000, department="D190"},
|
||||
#employee{name="Timothy Grove", id="E16398", salery=29900, department="D190"}].
|
||||
|
||||
employees_in_department( Department, Employees ) -> [X || #employee{department=D}=X <- Employees, D =:= Department].
|
||||
|
||||
highest_payed( N, Employees ) ->
|
||||
{Highest, _T} = lists:split( N, lists:reverse(lists:keysort(#employee.salery, Employees)) ),
|
||||
Highest.
|
||||
|
||||
task( N ) ->
|
||||
Employees = employees(),
|
||||
Departments = lists:usort( [X || #employee{department=X} <- Employees] ),
|
||||
Employees_in_departments = [employees_in_department(X, Employees) || X <- Departments],
|
||||
Highest_payed_in_departments = [highest_payed(N, Xs) || Xs <- Employees_in_departments],
|
||||
[task_write(X) || X <- Highest_payed_in_departments].
|
||||
|
||||
|
||||
|
||||
task_write( Highest_payeds ) ->
|
||||
[io:fwrite( "~p ~p: ~p~n", [Department, Salery, Name]) || #employee{department=Department, salery=Salery, name=Name} <- Highest_payeds],
|
||||
io:nl().
|
||||
20
Task/Top-rank-per-group/F-Sharp/top-rank-per-group.fs
Normal file
20
Task/Top-rank-per-group/F-Sharp/top-rank-per-group.fs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
let data =
|
||||
[
|
||||
"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";
|
||||
]
|
||||
|
||||
let topRank n =
|
||||
Seq.groupBy (fun (_, _, _, d) -> d) data
|
||||
|> Seq.map (snd >> Seq.sortBy (fun (_, _, s, _) -> -s) >> Seq.take n)
|
||||
42
Task/Top-rank-per-group/Factor/top-rank-per-group.factor
Normal file
42
Task/Top-rank-per-group/Factor/top-rank-per-group.factor
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
USING: accessors assocs fry io kernel math.parser sequences
|
||||
sorting ;
|
||||
IN: top-rank
|
||||
|
||||
TUPLE: employee name id salary department ;
|
||||
|
||||
CONSTANT: employees {
|
||||
T{ employee f "Tyler Bennett" "E10297" 32000 "D101" }
|
||||
T{ employee f "John Rappl" "E21437" 47000 "D050" }
|
||||
T{ employee f "George Woltman" "E00127" 53500 "D101" }
|
||||
T{ employee f "Adam Smith" "E63535" 18000 "D202" }
|
||||
T{ employee f "Claire Buckman" "E39876" 27800 "D202" }
|
||||
T{ employee f "David McClellan" "E04242" 41500 "D101" }
|
||||
T{ employee f "Rich Holcomb" "E01234" 49500 "D202" }
|
||||
T{ employee f "Nathan Adams" "E41298" 21900 "D050" }
|
||||
T{ employee f "Richard Potter" "E43128" 15900 "D101" }
|
||||
T{ employee f "David Motsinger" "E27002" 19250 "D202" }
|
||||
T{ employee f "Tim Sampair" "E03033" 27000 "D101" }
|
||||
T{ employee f "Kim Arlich" "E10001" 57000 "D190" }
|
||||
T{ employee f "Timothy Grove" "E16398" 29900 "D190" }
|
||||
}
|
||||
|
||||
: group-by ( seq quot -- hash )
|
||||
H{ } clone [ '[ dup @ _ push-at ] each ] keep ; inline
|
||||
|
||||
: prepare-departments ( seq -- departments )
|
||||
[ department>> ] group-by
|
||||
[ [ salary>> ] inv-sort-with ] assoc-map ;
|
||||
|
||||
: first-n-each ( seq n quot -- )
|
||||
[ short head-slice ] dip each ; inline
|
||||
|
||||
: main ( -- )
|
||||
employees prepare-departments [
|
||||
[ "Department " write write ":" print ] dip
|
||||
3 [
|
||||
[ id>> write " $" write ]
|
||||
[ salary>> number>string write " " write ]
|
||||
[ name>> print ] tri
|
||||
] first-n-each
|
||||
nl
|
||||
] assoc-each ;
|
||||
129
Task/Top-rank-per-group/Forth/top-rank-per-group.fth
Normal file
129
Task/Top-rank-per-group/Forth/top-rank-per-group.fth
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
\ Written in ANS-Forth; tested under VFX.
|
||||
\ Requires the novice package: http://www.forth.org/novice.html
|
||||
\ The following should already be done:
|
||||
\ include novice.4th
|
||||
\ include list.4th
|
||||
|
||||
marker TopRank.4th
|
||||
|
||||
\ This demonstrates how I typically use lists. A program such as this does not need any explicit iteration, so it is more like Factor than C.
|
||||
\ I would define high-level languages as those that allow programs to be written without explicit iteration. Iteration is a major source of bugs.
|
||||
\ The C library has QSORT that hides iteration, but user-written code very rarely uses this technique, and doesn't in the TopRank example.
|
||||
|
||||
|
||||
\ ******
|
||||
\ ****** The following defines our data-structure.
|
||||
\ ****** Pretty much every struct definition has these basic functions.
|
||||
\ ******
|
||||
|
||||
list
|
||||
w field .name \ string
|
||||
w field .id \ string
|
||||
w field .salary \ integer
|
||||
w field .dept \ string
|
||||
constant employee
|
||||
|
||||
: init-employee ( name id salary department node -- node )
|
||||
init-list >r
|
||||
hstr r@ .dept !
|
||||
r@ .salary !
|
||||
hstr r@ .id !
|
||||
hstr r@ .name !
|
||||
r> ;
|
||||
|
||||
: new-employee ( name id salary dept -- node )
|
||||
employee alloc
|
||||
init-employee ;
|
||||
|
||||
: <kill-employee> ( node -- )
|
||||
dup .name @ dealloc
|
||||
dup .id @ dealloc
|
||||
dup .dept @ dealloc
|
||||
dealloc ;
|
||||
|
||||
: kill-employee ( head -- )
|
||||
each[ <kill-employee> ]each ;
|
||||
|
||||
: <clone-employee> ( node -- new-node )
|
||||
clone-node
|
||||
dup .name @ hstr over .name !
|
||||
dup .id @ hstr over .id !
|
||||
dup .dept @ hstr over .dept ! ;
|
||||
|
||||
: clone-employee ( head -- new-head )
|
||||
nil
|
||||
swap each[ <clone-employee> link ]each ;
|
||||
|
||||
: <show-employee> ( node -- )
|
||||
dup .id @ count type 4 spaces
|
||||
dup .dept @ count type 4 spaces
|
||||
dup .salary @ . 4 spaces
|
||||
dup .name @ count type cr
|
||||
drop ;
|
||||
|
||||
: show-employee ( head -- )
|
||||
cr
|
||||
each[ <show-employee> ]each ;
|
||||
|
||||
|
||||
\ ******
|
||||
\ ****** The following code is specific to the query that we want to do in this example problem.
|
||||
\ ******
|
||||
|
||||
: employee-dept-salary ( new-node node -- new-node ? ) \ for use by FIND-PRIOR or INSERT-ORDERED
|
||||
2dup
|
||||
.dept @ count rot .dept @ count compare ?dup if A>B = nip exit then
|
||||
.salary @ over .salary @ < ;
|
||||
|
||||
: <top> ( n rank current-dept head node -- n rank current-dept head )
|
||||
2>r \ -- n rank current-dept
|
||||
dup count r@ .dept @ count compare A=B <> if \ we have a new department
|
||||
2drop \ discard RANK and CURRENT-DEPT
|
||||
0 r@ .dept @ then \ start again with a new RANK and CURRENT-DEPT
|
||||
rover rover > if \ if N > RANK then it is good
|
||||
r> r> over \ -- n rank current-dept node head node
|
||||
<clone-employee> link \ -- n rank current-dept node head
|
||||
>r >r then \ -- n rank current-dept
|
||||
swap 1+ swap \ increment RANK
|
||||
rdrop r> ; \ -- n rank current-dept head
|
||||
|
||||
: top ( n head -- new-head ) \ make a new list of the top N salary earners in each dept \ requires that list be sorted by dept-salary
|
||||
>r
|
||||
0 c" xxx" nil \ -- n rank current-dept new-head \ initially for an invalid department
|
||||
r> ['] <top> each
|
||||
3nip ;
|
||||
|
||||
|
||||
\ ******
|
||||
\ ****** The following is a test of the program using sample data.
|
||||
\ ******
|
||||
|
||||
nil ' employee-dept-salary
|
||||
c" Tyler Bennett" c" E10297" 32000 c" D101" new-employee insert-ordered
|
||||
c" John Rappl" c" E21437" 47000 c" D050" new-employee insert-ordered
|
||||
c" George Woltman" c" E00127" 53500 c" D101" new-employee insert-ordered
|
||||
c" Adam Smith" c" E63535" 18000 c" D202" new-employee insert-ordered
|
||||
c" Claire Buckman" c" E39876" 27800 c" D202" new-employee insert-ordered
|
||||
c" David McClellan" c" E04242" 41500 c" D101" new-employee insert-ordered
|
||||
c" Rich Holcomb" c" E01234" 49500 c" D202" new-employee insert-ordered
|
||||
c" Nathan Adams" c" E41298" 21900 c" D050" new-employee insert-ordered
|
||||
c" Richard Potter" c" E43128" 15900 c" D101" new-employee insert-ordered
|
||||
c" David Motsinger" c" E27002" 19250 c" D202" new-employee insert-ordered
|
||||
c" Tim Sampair" c" E03033" 27000 c" D101" new-employee insert-ordered
|
||||
c" Kim Arlich" c" E10001" 57000 c" D190" new-employee insert-ordered
|
||||
c" Timothy Grove" c" E16398" 29900 c" D190" new-employee insert-ordered
|
||||
drop constant test-data
|
||||
|
||||
cr .( N = 0 )
|
||||
0 test-data top dup show-employee kill-employee
|
||||
|
||||
cr .( N = 1 )
|
||||
1 test-data top dup show-employee kill-employee
|
||||
|
||||
cr .( N = 2 )
|
||||
2 test-data top dup show-employee kill-employee
|
||||
|
||||
cr .( N = 3 )
|
||||
3 test-data top dup show-employee kill-employee
|
||||
|
||||
test-data kill-employee
|
||||
4
Task/Top-rank-per-group/Fortran/top-rank-per-group-1.f
Normal file
4
Task/Top-rank-per-group/Fortran/top-rank-per-group-1.f
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
DATA EMPLOYEE(1:3)/
|
||||
1 GRIST("Tyler Bennett","E10297",32000,"D101"),
|
||||
2 GRIST("John Rappl","E21437",47000,"D050"),
|
||||
3 GRIST("George Woltman","E00127",53500,"D101")/
|
||||
68
Task/Top-rank-per-group/Fortran/top-rank-per-group-2.f
Normal file
68
Task/Top-rank-per-group/Fortran/top-rank-per-group-2.f
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
PROGRAM TOP RANK !Just do it.
|
||||
CHARACTER*28 HEADING(4) !The first line is a header.
|
||||
TYPE GRIST !But this is the stuff.
|
||||
CHARACTER*28 NAME !Arbitrary sizes.
|
||||
CHARACTER*6 ID !Possibly imperfect.
|
||||
REAL*8 SALARY !Single precision is a bit thin.
|
||||
CHARACTER*6 DEPARTMENT !Not a number.
|
||||
END TYPE GRIST !So much for the aggregate.
|
||||
INTEGER HORDE !Some parameterisation.
|
||||
PARAMETER (HORDE = 66) !This should suffice.
|
||||
TYPE(GRIST) EMPLOYEE(HORDE),HIC !An extra for the sort.
|
||||
LOGICAL CURSE !Possible early completion.
|
||||
INTEGER I,N,H !Steppers.
|
||||
INTEGER II,R !Needed for the results.
|
||||
INTEGER KBD,MSG,IN !I/O unit numbers.
|
||||
|
||||
KBD = 5 !Standard input.
|
||||
MSG = 6 !Standard output.
|
||||
IN = 10 !Suitable for an input file.
|
||||
WRITE (MSG,1)
|
||||
1 FORMAT ("Reads a set of employee information from TopRank.csv"/
|
||||
1"Then for each department code, shows the N highest paid.")
|
||||
OPEN (IN,NAME = "TopRank.csv",FORM = "FORMATTED")
|
||||
READ (IN,*) HEADING !Column headings: the "Salary" heading is not numeric.
|
||||
Chug through the input.
|
||||
N = 0 !None so far.
|
||||
10 READ (IN,*,END = 20) EMPLOYEE(N + 1) !Get the next record.
|
||||
N = N + 1 !We did. Count it in.
|
||||
IF (N.GT.HORDE) STOP "Too many employee records!" !Ah, suspicion.
|
||||
GO TO 10 !Perhaps there will be another.
|
||||
Collate the collection.
|
||||
20 CLOSE(IN) !Finished with the input.
|
||||
Crank up a comb sort, which requires only one comparison statement. Especially good for compound fields.
|
||||
H = N - 1 !Last - first, and not + 1.
|
||||
21 H = MAX(1,H*10/13) !The special feature.
|
||||
CURSE = .FALSE. !So far, so good.
|
||||
DO I = N - H,1,-1 !If H = 1, this is a Bubblesort.
|
||||
IF (EMPLOYEE(I).DEPARTMENT.LT.EMPLOYEE(I + H).DEPARTMENT) CYCLE !In order by department.
|
||||
IF (EMPLOYEE(I).DEPARTMENT.EQ.EMPLOYEE(I + H).DEPARTMENT !Or, Equal department,
|
||||
* .AND. EMPLOYEE(I).SALARY.GT.EMPLOYEE(I + H).SALARY) CYCLE !And in decreasing order by salary.
|
||||
CURSE = .TRUE. !No escape. the elements are in the wrong order.
|
||||
HIC = EMPLOYEE(I) !So a SWAP statement would be good. But alas.
|
||||
EMPLOYEE(I) = EMPLOYEE(I + H) !For large data aggregates, an indexed sort would be good.
|
||||
EMPLOYEE(I + H) = HIC !But, just slog away.
|
||||
END DO !Consider the next pairing.
|
||||
IF (CURSE .OR. H.GT.1) GO TO 21 !Work remains?
|
||||
|
||||
Cast forth results.
|
||||
30 WRITE (6,31) N !Announce, and solicit a parameter.
|
||||
31 FORMAT (I0," employees. How many per dept? ",$) !The $ sez "don't start a new line."
|
||||
READ (KBD,*) R !The parameter.
|
||||
IF (R.LE.0) STOP !bah.
|
||||
WRITE (MSG,32) "Rank",HEADING
|
||||
32 FORMAT (/,A6,1X,A28,2X,A12,1X,A10,A) !Compare to FORMAT 33.
|
||||
HIC.DEPARTMENT = "...Not this" !Different from all departmental codes.
|
||||
DO I = 1,N !Scan the sorted data.
|
||||
IF (HIC.DEPARTMENT.EQ.EMPLOYEE(I).DEPARTMENT) THEN !Another?
|
||||
II = II + 1 !Same department, so count another adherent.
|
||||
ELSE !But with a change of department code,
|
||||
II = 1 !Start a fresh count.
|
||||
HIC.DEPARTMENT = EMPLOYEE(I).DEPARTMENT !And remember the new code.
|
||||
WRITE (MSG,*) "For ",HIC.DEPARTMENT !Announce the new department's code.
|
||||
END IF !So much for grouping.
|
||||
IF (II.LE.R) WRITE (MSG,33) II,EMPLOYEE(I) !Still within the desired rank?
|
||||
33 FORMAT (I6,1X,A28,1X,A12,F11.2,1X,A) !Some layout. Includes the repeated departmental code name.
|
||||
END DO !On to the next.
|
||||
|
||||
END !That was straightforward.
|
||||
57
Task/Top-rank-per-group/FreeBASIC/top-rank-per-group.basic
Normal file
57
Task/Top-rank-per-group/FreeBASIC/top-rank-per-group.basic
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#define N 3 'show the top three employees of each rank
|
||||
|
||||
'here is all the data to be read in
|
||||
|
||||
data "Tyler Bennett","E10297",32000,"D101"
|
||||
data "John Rappl","E21437",47000,"D050"
|
||||
data "George Woltman","E00127",53500,"D101"
|
||||
data "Adam Smith","E63535",18000,"D202"
|
||||
data "Claire Buckman","E39876",27800,"D202"
|
||||
data "David McClellan","E04242",41500,"D101"
|
||||
data "Rich Holcomb","E01234",49500,"D202"
|
||||
data "Nathan Adams","E41298",21900,"D050"
|
||||
data "Richard Potter","E43128",15900,"D101"
|
||||
data "David Motsinger","E27002",19250,"D202"
|
||||
data "Tim Sampair","E03033",27000,"D101"
|
||||
data "Kim Arlich","E10001",57000,"D190"
|
||||
data "Timothy Grove","E16398",29900,"D190"
|
||||
|
||||
type employee
|
||||
'define a data type for employees
|
||||
nm as string*32 'name
|
||||
en as string*6 'employee number
|
||||
sl as uinteger 'salary
|
||||
dp as string*4 'department
|
||||
fl as boolean 'a flag
|
||||
end type
|
||||
|
||||
dim as employee emp(1 to 13)
|
||||
dim as uinteger e, d, x, ce, cs
|
||||
dim as string*4 dept(1 to 4) = {"D050", "D101", "D190", "D202"}
|
||||
|
||||
for e = 1 to 13
|
||||
'put all the employee data into an array
|
||||
read emp(e).nm
|
||||
read emp(e).en
|
||||
read emp(e).sl
|
||||
read emp(e).dp
|
||||
emp(e).fl = false
|
||||
next e
|
||||
|
||||
for d = 1 to 4 'look at each department
|
||||
print "Department ";dept(d);":"
|
||||
for x = 1 to N 'top N employees
|
||||
cs = 0
|
||||
ce = 0
|
||||
for e = 1 to 13 'look through employees
|
||||
if emp(e).dp = dept(d) andalso emp(e).fl = false andalso emp(e).sl > cs then
|
||||
emp(ce).fl = false 'unflag the previous champion so they can be found on the next pass
|
||||
ce = e
|
||||
cs = emp(e).sl
|
||||
emp(e).fl = true 'flag this employee so that on the next pass we can get the next richest
|
||||
endif
|
||||
next e
|
||||
if ce>0 then print emp(ce).nm;" ";emp(ce).en;" ";emp(ce).sl;" ";emp(ce).dp
|
||||
next x
|
||||
print
|
||||
next d
|
||||
27
Task/Top-rank-per-group/FunL/top-rank-per-group.funl
Normal file
27
Task/Top-rank-per-group/FunL/top-rank-per-group.funl
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
data Employee( name, id, salary, dept )
|
||||
|
||||
employees = [
|
||||
Employee( 'Tyler Bennett', 'E10297', 32000, 'D101' ),
|
||||
Employee( 'John Rappl', 'E21437', 47000, 'D050' ),
|
||||
Employee( 'George Woltman', 'E00127', 53500, 'D101' ),
|
||||
Employee( 'Adam Smith', 'E63535', 18000, 'D202' ),
|
||||
Employee( 'Claire Buckman', 'E39876', 27800, 'D202' ),
|
||||
Employee( 'David McClellan', 'E04242', 41500, 'D101' ),
|
||||
Employee( 'Rich Holcomb', 'E01234', 49500, 'D202' ),
|
||||
Employee( 'Nathan Adams', 'E41298', 21900, 'D050' ),
|
||||
Employee( 'Richard Potter', 'E43128', 15900, 'D101' ),
|
||||
Employee( 'David Motsinger', 'E27002', 19250, 'D202' ),
|
||||
Employee( 'Tim Sampair', 'E03033', 27000, 'D101' ),
|
||||
Employee( 'Kim Arlich', 'E10001', 57000, 'D190' ),
|
||||
Employee( 'Timothy Grove', 'E16398', 29900, 'D190' )
|
||||
]
|
||||
|
||||
N = 2
|
||||
|
||||
for (dept, empl) <- employees.groupBy( e -> e.dept ).>toList().sortWith( (<) )
|
||||
println( dept )
|
||||
|
||||
for e <- empl.sortWith( \a, b -> a.salary > b.salary ).take( N )
|
||||
printf( " %-16s %6s %7d\n", e.name, e.id, e.salary )
|
||||
|
||||
println()
|
||||
121
Task/Top-rank-per-group/Go/top-rank-per-group.go
Normal file
121
Task/Top-rank-per-group/Go/top-rank-per-group.go
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// language-native data description
|
||||
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"},
|
||||
// Extra data to demonstrate ties
|
||||
{"Tie A", "E16399", 29900, "D190"},
|
||||
{"Tie B", "E16400", 29900, "D190"},
|
||||
{"No Tie", "E16401", 29899, "D190"},
|
||||
}
|
||||
|
||||
// We only need one type of ordering/grouping for this task so we could directly
|
||||
// implement sort.Interface on EmployeeList (or a byDeptSalary alias type) with
|
||||
// the appropriate Less method.
|
||||
//
|
||||
// Instead, we'll add a bit here that makes it easier to use arbitrary orderings.
|
||||
// This is like the "SortKeys" Planet sorting example in the sort package
|
||||
// documentation, see https://golang.org/pkg/sort
|
||||
|
||||
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]) }
|
||||
|
||||
// For this specific task we could just write the data to an io.Writer
|
||||
// but in general it's better to return the data in a usable form (for
|
||||
// example, perhaps other code want's to do something like compare the
|
||||
// averages of the top N by department).
|
||||
//
|
||||
// So we go through the extra effort of returning an []EmployeeList, a
|
||||
// list of employee lists, one per deparment. The lists are trimmed to
|
||||
// to the top 'n', which can be larger than n if there are ties for the
|
||||
// nth salary (callers that don't care about ties could just trim more.)
|
||||
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
|
||||
}
|
||||
// Always have some unique field as the last one in a sort list
|
||||
return e1.ID < e2.ID
|
||||
}
|
||||
|
||||
// We could just sort the data in place for this task. But
|
||||
// perhaps messing with the order is undesirable or there is
|
||||
// other concurrent access. So we'll make a copy and sort that.
|
||||
// It's just pointers so the amount to copy is relatively small.
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Task/Top-rank-per-group/Groovy/top-rank-per-group.groovy
Normal file
28
Task/Top-rank-per-group/Groovy/top-rank-per-group.groovy
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
def displayRank(employees, number) {
|
||||
employees.groupBy { it.Department }.sort().each { department, staff ->
|
||||
println "Department $department"
|
||||
println " Name ID Salary"
|
||||
staff.sort { e1, e2 -> e2.Salary <=> e1.Salary }
|
||||
staff[0..<Math.min(number, staff.size())].each { e ->
|
||||
println " ${e.Name.padRight(20)}${e.ID}${sprintf('%8d', e.Salary)}"
|
||||
}
|
||||
println()
|
||||
}
|
||||
}
|
||||
|
||||
def employees = [
|
||||
[Name: 'Tyler Bennett', ID: 'E10297', Salary: 32000, Department: 'D101'],
|
||||
[Name: 'John Rappl', ID: 'E21437', Salary: 47000, Department: 'D050'],
|
||||
[Name: 'George Woltman', ID: 'E00127', Salary: 53500, Department: 'D101'],
|
||||
[Name: 'Adam Smith', ID: 'E63535', Salary: 18000, Department: 'D202'],
|
||||
[Name: 'Claire Buckman', ID: 'E39876', Salary: 27800, Department: 'D202'],
|
||||
[Name: 'David McClellan', ID: 'E04242', Salary: 41500, Department: 'D101'],
|
||||
[Name: 'Rich Holcomb', ID: 'E01234', Salary: 49500, Department: 'D202'],
|
||||
[Name: 'Nathan Adams', ID: 'E41298', Salary: 21900, Department: 'D050'],
|
||||
[Name: 'Richard Potter', ID: 'E43128', Salary: 15900, Department: 'D101'],
|
||||
[Name: 'David Motsinger', ID: 'E27002', Salary: 19250, Department: 'D202'],
|
||||
[Name: 'Tim Sampair', ID: 'E03033', Salary: 27000, Department: 'D101'],
|
||||
[Name: 'Kim Arlich', ID: 'E10001', Salary: 57000, Department: 'D190'],
|
||||
[Name: 'Timothy Grove', ID: 'E16398', Salary: 29900, Department: 'D190']
|
||||
]
|
||||
displayRank(employees, 3)
|
||||
79
Task/Top-rank-per-group/Haskell/top-rank-per-group-1.hs
Normal file
79
Task/Top-rank-per-group/Haskell/top-rank-per-group-1.hs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import Data.List (sortBy, groupBy)
|
||||
|
||||
import Text.Printf (printf)
|
||||
|
||||
import Data.Ord (comparing)
|
||||
|
||||
import Data.Function (on)
|
||||
|
||||
type ID = Int
|
||||
|
||||
type DEP = String
|
||||
|
||||
type NAME = String
|
||||
|
||||
type SALARY = Double
|
||||
|
||||
data Employee = Employee
|
||||
{ nr :: ID
|
||||
, dep :: DEP
|
||||
, name :: NAME
|
||||
, sal :: SALARY
|
||||
}
|
||||
|
||||
employees :: [Employee]
|
||||
employees =
|
||||
fmap
|
||||
(\(i, d, n, s) -> Employee i d n s)
|
||||
[ (1001, "AB", "Janssen A.H.", 41000)
|
||||
, (101, "KA", "'t Woud B.", 45000)
|
||||
, (1013, "AB", "de Bont C.A.", 65000)
|
||||
, (1101, "CC", "Modaal A.M.J.", 30000)
|
||||
, (1203, "AB", "Anders H.", 50000)
|
||||
, (100, "KA", "Ezelbips P.J.", 52000)
|
||||
, (1102, "CC", "Zagt A.", 33000)
|
||||
, (1103, "CC", "Ternood T.R.", 21000)
|
||||
, (1104, "CC", "Lageln M.", 23000)
|
||||
, (1105, "CC", "Amperwat A.", 19000)
|
||||
, (1106, "CC", "Boon T.J.", 25000)
|
||||
, (1107, "CC", "Beloop L.O.", 31000)
|
||||
, (1009, "CD", "Janszoon A.", 38665)
|
||||
, (1026, "CD", "Janszen H.P.", 41000)
|
||||
, (1011, "CC", "de Goeij J.", 39000)
|
||||
, (106, "KA", "Pragtweik J.M.V.", 42300)
|
||||
, (111, "KA", "Bakeuro S.", 31000)
|
||||
, (105, "KA", "Clubdrager C.", 39800)
|
||||
, (104, "KA", "Karendijk F.", 23000)
|
||||
, (107, "KA", "Centjes R.M.", 34000)
|
||||
, (119, "KA", "Tegenstroom H.L.", 39000)
|
||||
, (1111, "CD", "Telmans R.M.", 55500)
|
||||
, (1093, "AB", "de Slegte S.", 46987)
|
||||
, (1199, "CC", "Uitlaat G.A.S.", 44500)
|
||||
]
|
||||
|
||||
firstN :: Int
|
||||
-> (Employee -> DEP)
|
||||
-> (Employee -> SALARY)
|
||||
-> [Employee]
|
||||
-> [[Employee]]
|
||||
firstN n o1 o2 x =
|
||||
fmap
|
||||
(take n . sortBy (comparingDown o2))
|
||||
(groupBy (groupingOn o1) (sortBy (comparing o1) x))
|
||||
|
||||
groupingOn
|
||||
:: Eq a1
|
||||
=> (a -> a1) -> a -> a -> Bool
|
||||
groupingOn = ((==) `on`)
|
||||
|
||||
comparingDown
|
||||
:: Ord a
|
||||
=> (b -> a) -> b -> b -> Ordering
|
||||
comparingDown = flip . comparing
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
printf "%-16s %3s %10s\n" "NAME" "DEP" "TIP"
|
||||
putStrLn $ replicate 31 '='
|
||||
mapM_ (traverse ((printf "%-16s %3s %10.2g\n" . name) <*> dep <*> sal)) $
|
||||
firstN 3 dep sal employees
|
||||
98
Task/Top-rank-per-group/Haskell/top-rank-per-group-2.hs
Normal file
98
Task/Top-rank-per-group/Haskell/top-rank-per-group-2.hs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import Data.List (intercalate, nub, sort, sortBy, transpose)
|
||||
import qualified Data.Map as M
|
||||
import Data.Maybe (fromJust)
|
||||
import Data.Ord (comparing)
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
(putStrLn . unlines) $
|
||||
table
|
||||
" "
|
||||
( (reportLines <*> highSalaryKeys 3)
|
||||
=<< (sort . nub) (M.elems mapDepts)
|
||||
)
|
||||
|
||||
reportLines :: String -> [(Int, Int)] -> [[String]]
|
||||
reportLines dept =
|
||||
fmap
|
||||
( \(k, n) ->
|
||||
[ fromJust $ M.lookup k mapNames,
|
||||
dept,
|
||||
show n
|
||||
]
|
||||
)
|
||||
|
||||
highSalaryKeys :: Int -> String -> [(Int, Int)]
|
||||
highSalaryKeys n dept =
|
||||
take n $
|
||||
sortBy ((flip . comparing) snd) $
|
||||
(,) <*> (fromJust . flip M.lookup mapSalaries)
|
||||
<$> M.keys (M.filter (== dept) mapDepts)
|
||||
|
||||
mapNames, mapDepts :: M.Map Int String
|
||||
[mapNames, mapDepts] =
|
||||
(readPairs <$> [nameKV, deptKV]) <*> [xs]
|
||||
|
||||
mapSalaries :: M.Map Int Int
|
||||
mapSalaries = readPairs salaryKV xs
|
||||
|
||||
xs :: [(Int, String, String, Int)]
|
||||
xs =
|
||||
[ (1001, "AB", "Janssen A.H.", 41000),
|
||||
(101, "KA", "'t Woud B.", 45000),
|
||||
(1013, "AB", "de Bont C.A.", 65000),
|
||||
(1101, "CC", "Modaal A.M.J.", 30000),
|
||||
(1203, "AB", "Anders H.", 50000),
|
||||
(100, "KA", "Ezelbips P.J.", 52000),
|
||||
(1102, "CC", "Zagt A.", 33000),
|
||||
(1103, "CC", "Ternood T.R.", 21000),
|
||||
(1104, "CC", "Lageln M.", 23000),
|
||||
(1105, "CC", "Amperwat A.", 19000),
|
||||
(1106, "CC", "Boon T.J.", 25000),
|
||||
(1107, "CC", "Beloop L.O.", 31000),
|
||||
(1009, "CD", "Janszoon A.", 38665),
|
||||
(1026, "CD", "Janszen H.P.", 41000),
|
||||
(1011, "CC", "de Goeij J.", 39000),
|
||||
(106, "KA", "Pragtweik J.M.V.", 42300),
|
||||
(111, "KA", "Bakeuro S.", 31000),
|
||||
(105, "KA", "Clubdrager C.", 39800),
|
||||
(104, "KA", "Karendijk F.", 23000),
|
||||
(107, "KA", "Centjes R.M.", 34000),
|
||||
(119, "KA", "Tegenstroom H.L.", 39000),
|
||||
(1111, "CD", "Telmans R.M.", 55500),
|
||||
(1093, "AB", "de Slegte S.", 46987),
|
||||
(1199, "CC", "Uitlaat G.A.S.", 44500)
|
||||
]
|
||||
|
||||
readPairs ::
|
||||
Ord k =>
|
||||
(a1 -> (k, a)) ->
|
||||
[a1] ->
|
||||
M.Map k a
|
||||
readPairs f xs = M.fromList (f <$> xs)
|
||||
|
||||
nameKV,
|
||||
deptKV ::
|
||||
(Int, String, String, Int) -> (Int, String)
|
||||
nameKV (k, _, name, _) = (k, name)
|
||||
deptKV (k, dept, _, _) = (k, dept)
|
||||
|
||||
salaryKV :: (Int, String, String, Int) -> (Int, Int)
|
||||
salaryKV (k, _, _, salary) = (k, salary)
|
||||
|
||||
table :: String -> [[String]] -> [String]
|
||||
table delim rows =
|
||||
let justifyLeft c n s = take n (s <> replicate n c)
|
||||
justifyRight c n s =
|
||||
drop
|
||||
(length s)
|
||||
(replicate n c <> s)
|
||||
in intercalate delim
|
||||
<$> transpose
|
||||
( ( fmap
|
||||
=<< justifyLeft ' '
|
||||
. maximum
|
||||
. fmap length
|
||||
)
|
||||
<$> transpose rows
|
||||
)
|
||||
30
Task/Top-rank-per-group/HicEst/top-rank-per-group.hicest
Normal file
30
Task/Top-rank-per-group/HicEst/top-rank-per-group.hicest
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
CHARACTER source="Test.txt", outP='Top_rank.txt', fmt='A20,A8,i6,2x,A10'
|
||||
CHARACTER name*20, employee_ID*10, department*10, temp*10
|
||||
REAL :: idx(1), N_top_salaries=3
|
||||
|
||||
! Open the source with 4 "," separated columns, skip line 1:
|
||||
OPEN(FIle=source, Format='SL=1;4,;', LENgth=L)
|
||||
ALLOCATE(idx, L)
|
||||
|
||||
! Sort salary column 3 descending, then department column 4, store in idx:
|
||||
SORT(FIle=source, Column=3, Descending=1, Column=4, Index=idx)
|
||||
|
||||
! Display a spreadsheet-like scrolling dialog of the presorted source:
|
||||
DLG(Text=idx, Text=source, Format=fmt, Y)
|
||||
|
||||
! Output the first N top salaries of each department_
|
||||
OPEN(FIle=outP)
|
||||
DO i = 1, L
|
||||
rank = rank + 1
|
||||
READ(FIle=source, Row=idx(i)) name, employee_ID, salary, department
|
||||
IF(temp /= department) THEN
|
||||
rank = 1
|
||||
WRITE(FIle=outP)
|
||||
temp = department
|
||||
ENDIF
|
||||
IF(rank <= N_top_salaries) THEN
|
||||
WRITE(FIle=outP, Format=fmt) name, employee_ID, salary, department
|
||||
ENDIF
|
||||
ENDDO
|
||||
|
||||
END
|
||||
51
Task/Top-rank-per-group/IS-BASIC/top-rank-per-group.basic
Normal file
51
Task/Top-rank-per-group/IS-BASIC/top-rank-per-group.basic
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
100 PROGRAM "Employee.bas"(N)
|
||||
110 LET NR=100:LET X=0
|
||||
120 STRING NAME$(1 TO NR)*20,ID$(1 TO NR)*6,DEPT$(1 TO NR)*4
|
||||
130 NUMERIC SALARY(1 TO NR)
|
||||
140 DO UNTIL N>0 AND N<=NR
|
||||
150 INPUT PROMPT "Enter the number of ranks: ":N$
|
||||
160 LET N=VAL(N$)
|
||||
170 LOOP
|
||||
180 CALL READDATA
|
||||
190 CALL SORT
|
||||
200 CALL LST
|
||||
210 END
|
||||
220 DEF READDATA
|
||||
230 LET EOF=0
|
||||
240 OPEN #1:"Employee.dat"
|
||||
250 WHEN EXCEPTION USE IOERROR
|
||||
260 DO
|
||||
270 LET X=X+1
|
||||
280 INPUT #1:NAME$(X),ID$(X),SALARY(X),DEPT$(X)
|
||||
290 LOOP UNTIL EOF OR X=NR
|
||||
300 END WHEN
|
||||
310 HANDLER IOERROR
|
||||
320 IF EXTYPE<>8001 THEN PRINT EXSTRING$(EXTYPE)
|
||||
330 CLOSE #1
|
||||
340 LET X=X-1:LET EOF=-1
|
||||
350 IF X=0 THEN PRINT "No data.":STOP
|
||||
360 CONTINUE
|
||||
370 END HANDLER
|
||||
380 END DEF
|
||||
390 DEF SORT
|
||||
400 LET GAP=X:LET SW=1
|
||||
410 DO WHILE GAP>1 OR SW
|
||||
420 LET GAP=MAX(INT(GAP/1.3),1):LET SW=0
|
||||
430 FOR I=1 TO X-GAP
|
||||
440 IF DEPT$(I)>DEPT$(I+GAP) OR DEPT$(I)=DEPT$(I+GAP) AND SALARY(I)<SALARY(I+GAP) THEN
|
||||
450 LET T$=NAME$(I):LET NAME$(I)=NAME$(I+GAP):LET NAME$(I+GAP)=T$
|
||||
460 LET T$=DEPT$(I):LET DEPT$(I)=DEPT$(I+GAP):LET DEPT$(I+GAP)=T$
|
||||
470 LET T$=ID$(I):LET ID$(I)=ID$(I+GAP):LET ID$(I+GAP)=T$
|
||||
480 LET T=SALARY(I):LET SALARY(I)=SALARY(I+GAP):LET SALARY(I+GAP)=T
|
||||
490 LET SW=1
|
||||
500 END IF
|
||||
510 NEXT
|
||||
520 LOOP
|
||||
530 END DEF
|
||||
540 DEF LST
|
||||
550 LET J=1:LET PREV$=""
|
||||
560 FOR I=1 TO X
|
||||
570 IF DEPT$(I)<>PREV$ THEN PRINT "Department ";DEPT$(I):LET PREV$=DEPT$(I):LET J=1
|
||||
580 IF J<=N THEN PRINT " ";NAME$(I);TAB(23);ID$(I),SALARY(I):LET J=J+1
|
||||
590 NEXT
|
||||
600 END DEF
|
||||
44
Task/Top-rank-per-group/Icon/top-rank-per-group.icon
Normal file
44
Task/Top-rank-per-group/Icon/top-rank-per-group.icon
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
record Employee(name,id,salary,dept)
|
||||
|
||||
procedure getEmployees ()
|
||||
employees := [
|
||||
Employee("Tyler Bennett","E10297",32000,"D101"),
|
||||
Employee("John Rappl","E21437",47000,"D050"),
|
||||
Employee("George Woltman","E00127",53500,"D101"),
|
||||
Employee("Adam Smith","E63535",18000,"D202"),
|
||||
Employee("Claire Buckman","E39876",27800,"D202"),
|
||||
Employee("David McClellan","E04242",41500,"D101"),
|
||||
Employee("Rich Holcomb","E01234",49500,"D202"),
|
||||
Employee("Nathan Adams","E41298",21900,"D050"),
|
||||
Employee("Richard Potter","E43128",15900,"D101"),
|
||||
Employee("David Motsinger","E27002",19250,"D202"),
|
||||
Employee("Tim Sampair","E03033",27000,"D101"),
|
||||
Employee("Kim Arlich","E10001",57000,"D190"),
|
||||
Employee("Timothy Grove","E16398",29900,"D190")
|
||||
]
|
||||
return employees
|
||||
end
|
||||
|
||||
procedure show_employee (employee)
|
||||
every writes (!employee || " ")
|
||||
write ()
|
||||
end
|
||||
|
||||
procedure main (args)
|
||||
N := integer(args[1]) # N set from command line
|
||||
employees := getEmployees ()
|
||||
groups := set()
|
||||
every employee := !employees do insert(groups, employee.dept)
|
||||
|
||||
every group := !groups do {
|
||||
write ("== Top " || N || " in group " || group)
|
||||
employeesInGroup := []
|
||||
every employee := !employees do {
|
||||
if employee.dept == group then put(employeesInGroup, employee)
|
||||
}
|
||||
# sort by third field and reverse, so highest salary comes first
|
||||
employeesInGroup := reverse(sortf(employeesInGroup, 3))
|
||||
# show the first N records, up to the end of the list
|
||||
every show_employee (!employeesInGroup[1:(1+min(N,*employeesInGroup))])
|
||||
}
|
||||
end
|
||||
5
Task/Top-rank-per-group/J/top-rank-per-group-1.j
Normal file
5
Task/Top-rank-per-group/J/top-rank-per-group-1.j
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
NB. Dynamically generate convenience functions
|
||||
('`',,;:^:_1: N=:{.Employees) =:, (_&{"1)`'' ([^:(_ -: ])L:0)"0 _~ i.# E =: {: Employees
|
||||
|
||||
NB. Show top six ranked employees in each dept
|
||||
N , (<@:>"1@:|:@:((6 <. #) {. ] \: SALARY)/.~ DEPT) |: <"1&> E
|
||||
1
Task/Top-rank-per-group/J/top-rank-per-group-2.j
Normal file
1
Task/Top-rank-per-group/J/top-rank-per-group-2.j
Normal file
|
|
@ -0,0 +1 @@
|
|||
reportTopSalaries=: 3 :'N , (<@:>"1@:|:@:((y <. #) {. ] \: SALARY)/.~ DEPT) |: <"1&> E'
|
||||
49
Task/Top-rank-per-group/Java/top-rank-per-group.java
Normal file
49
Task/Top-rank-per-group/Java/top-rank-per-group.java
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
58
Task/Top-rank-per-group/JavaScript/top-rank-per-group-1.js
Normal file
58
Task/Top-rank-per-group/JavaScript/top-rank-per-group-1.js
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
var data = [
|
||||
{name: "Tyler Bennett", id: "E10297", salary: 32000, dept: "D101"},
|
||||
{name: "John Rappl", id: "E21437", salary: 47000, dept: "D050"},
|
||||
{name: "George Woltman", id: "E00127", salary: 53500, dept: "D101"},
|
||||
{name: "Adam Smith", id: "E63535", salary: 18000, dept: "D202"},
|
||||
{name: "Claire Buckman", id: "E39876", salary: 27800, dept: "D202"},
|
||||
{name: "David McClellan", id: "E04242", salary: 41500, dept: "D101"},
|
||||
{name: "Rich Holcomb", id: "E01234", salary: 49500, dept: "D202"},
|
||||
{name: "Nathan Adams", id: "E41298", salary: 21900, dept: "D050"},
|
||||
{name: "Richard Potter", id: "E43128", salary: 15900, dept: "D101"},
|
||||
{name: "David Motsinger", id: "E27002", salary: 19250, dept: "D202"},
|
||||
{name: "Tim Sampair", id: "E03033", salary: 27000, dept: "D101"},
|
||||
{name: "Kim Arlich", id: "E10001", salary: 57000, dept: "D190"},
|
||||
{name: "Timothy Grove", id: "E16398", salary: 29900, dept: "D190"},
|
||||
];
|
||||
|
||||
function top_rank(n) {
|
||||
var by_dept = group_by_dept(data);
|
||||
for (var dept in by_dept) {
|
||||
output(dept);
|
||||
for (var i = 0; i < n && i < by_dept[dept].length; i++) {
|
||||
var emp = by_dept[dept][i];
|
||||
output(emp.name + ", id=" + emp.id + ", salary=" + emp.salary);
|
||||
}
|
||||
output("");
|
||||
}
|
||||
}
|
||||
|
||||
// group by dept, and sort by salary
|
||||
function group_by_dept(data) {
|
||||
var by_dept = {};
|
||||
for (var idx in data) {
|
||||
var dept = data[idx].dept;
|
||||
if ( ! has_property(by_dept, dept)) {
|
||||
by_dept[dept] = new Array();
|
||||
}
|
||||
by_dept[dept].push(data[idx]);
|
||||
}
|
||||
for (var dept in by_dept) {
|
||||
// numeric sort
|
||||
by_dept[dept].sort(function (a,b){return b.salary - a.salary});
|
||||
}
|
||||
return by_dept;
|
||||
}
|
||||
|
||||
function has_property(obj, propname) {
|
||||
return typeof(obj[propname]) != "undefined";
|
||||
}
|
||||
|
||||
function output(str) {
|
||||
try {
|
||||
WScript.Echo(str); // WSH
|
||||
} catch(err) {
|
||||
print(str); // Rhino
|
||||
}
|
||||
}
|
||||
|
||||
top_rank(3);
|
||||
31
Task/Top-rank-per-group/JavaScript/top-rank-per-group-2.js
Normal file
31
Task/Top-rank-per-group/JavaScript/top-rank-per-group-2.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
var collectDept = function (arrOfObj) {
|
||||
var collect = arrOfObj.reduce(function (rtnObj, obj) {
|
||||
if (rtnObj[obj.dept] === undefined) {
|
||||
rtnObj[obj.dept] = [];
|
||||
}
|
||||
rtnObj[obj.dept].push(obj);
|
||||
return rtnObj;
|
||||
}, {});
|
||||
|
||||
return Object.keys(collect).map(function (key) {
|
||||
return collect[key];
|
||||
});
|
||||
};
|
||||
|
||||
var sortSalary = function (arrOfSalaryArrs) {
|
||||
return arrOfSalaryArrs.map(function (item) {
|
||||
return item.sort(function (a, b) {
|
||||
if (a.salary > b.salary) { return -1; }
|
||||
if (a.salary < b.salary) { return 1; }
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var getNTopSalariesByDept = function (n, data) {
|
||||
if (n < 0) { return; }
|
||||
|
||||
return sortSalary(collectDept(data)).map(function (list) {
|
||||
return list.slice(0,n);
|
||||
});
|
||||
};
|
||||
158
Task/Top-rank-per-group/JavaScript/top-rank-per-group-3.js
Normal file
158
Task/Top-rank-per-group/JavaScript/top-rank-per-group-3.js
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// topNSalariesPerDept :: Int -> [[String]] -> [String]
|
||||
const topNSalariesPerDept = (n, records) =>
|
||||
foldl(
|
||||
(a, k, i) => (a[toLower(k)] = x => x[i], a),
|
||||
this,
|
||||
head(records)
|
||||
) && map(intercalate(','),
|
||||
concatMap(take(n),
|
||||
reverse(
|
||||
groupBy(
|
||||
on(same, department),
|
||||
sortBy(
|
||||
flip(
|
||||
mappendComparing([
|
||||
department,
|
||||
salary
|
||||
])
|
||||
),
|
||||
tail(records)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// GENERIC FUNCTIONS -----------------------------------------------------
|
||||
|
||||
// comparing :: (a -> b) -> (a -> a -> Ordering)
|
||||
const comparing = f =>
|
||||
(x, y) => {
|
||||
const
|
||||
a = f(x),
|
||||
b = f(y);
|
||||
return a < b ? -1 : (a > b ? 1 : 0);
|
||||
};
|
||||
|
||||
// concatMap :: (a -> [b]) -> [a] -> [b]
|
||||
const concatMap = (f, xs) =>
|
||||
xs.length > 0 ? (() => {
|
||||
const unit = typeof xs[0] === 'string' ? '' : [];
|
||||
return unit.concat.apply(unit, xs.map(f));
|
||||
})() : [];
|
||||
|
||||
// curry :: Function -> Function
|
||||
const curry = (f, ...args) => {
|
||||
const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :
|
||||
function () {
|
||||
return go(xs.concat(Array.from(arguments)));
|
||||
};
|
||||
return go([].slice.call(args, 1));
|
||||
};
|
||||
|
||||
// flip :: (a -> b -> c) -> b -> a -> c
|
||||
const flip = f => (a, b) => f.apply(null, [b, a]);
|
||||
|
||||
// foldl :: (b -> a -> b) -> b -> [a] -> b
|
||||
const foldl = (f, a, xs) => xs.reduce(f, a);
|
||||
|
||||
// groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
|
||||
const groupBy = (f, xs) => {
|
||||
const dct = xs.slice(1)
|
||||
.reduce((a, x) => {
|
||||
const
|
||||
h = a.active.length > 0 ? a.active[0] : undefined,
|
||||
blnGroup = h !== undefined && f(h, x);
|
||||
return {
|
||||
active: blnGroup ? a.active.concat([x]) : [x],
|
||||
sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])
|
||||
};
|
||||
}, {
|
||||
active: xs.length > 0 ? [xs[0]] : [],
|
||||
sofar: []
|
||||
});
|
||||
return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);
|
||||
};
|
||||
|
||||
// head :: [a] -> a
|
||||
const head = xs => xs.length ? xs[0] : undefined;
|
||||
|
||||
// intercalate :: String -> [a] -> String
|
||||
const intercalate = curry((s, xs) => xs.join(s));
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = (f, xs) => xs.map(f);
|
||||
|
||||
// mappendComparing :: [(a -> b)] -> (a -> a -> Ordering)
|
||||
const mappendComparing = fs => (x, y) =>
|
||||
fs.reduce((ord, f) => (ord !== 0) ? (
|
||||
ord
|
||||
) : (() => {
|
||||
const
|
||||
a = f(x),
|
||||
b = f(y);
|
||||
return a < b ? -1 : a > b ? 1 : 0
|
||||
})(), 0);
|
||||
|
||||
// on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
|
||||
const on = (f, g) => (a, b) => f(g(a), g(b));
|
||||
|
||||
// reverse :: [a] -> [a]
|
||||
const reverse = xs =>
|
||||
typeof xs === 'string' ? (
|
||||
xs.split('')
|
||||
.reverse()
|
||||
.join('')
|
||||
) : xs.slice(0)
|
||||
.reverse();
|
||||
|
||||
// same :: a -> a -> Bool
|
||||
const same = (a, b) => a === b
|
||||
|
||||
// show :: Int -> a -> Indented String
|
||||
// show :: a -> String
|
||||
const show = (...x) =>
|
||||
JSON.stringify.apply(
|
||||
null, x.length > 1 ? [x[1], null, x[0]] : x
|
||||
);
|
||||
|
||||
// sortBy :: (a -> a -> Ordering) -> [a] -> [a]
|
||||
const sortBy = (f, xs) =>
|
||||
xs.slice()
|
||||
.sort(f);
|
||||
|
||||
// tail :: [a] -> [a]
|
||||
const tail = xs => xs.length ? xs.slice(1) : undefined;
|
||||
|
||||
// take :: Int -> [a] -> [a]
|
||||
const take = curry((n, xs) => xs.slice(0, n));
|
||||
|
||||
// toLower :: Text -> Text
|
||||
const toLower = s => s.toLowerCase();
|
||||
|
||||
// TEST ------------------------------------------------------------------
|
||||
|
||||
const xs = [
|
||||
["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"]
|
||||
];
|
||||
|
||||
return show(2,
|
||||
topNSalariesPerDept(3, xs)
|
||||
);
|
||||
})();
|
||||
6
Task/Top-rank-per-group/Jq/top-rank-per-group-1.jq
Normal file
6
Task/Top-rank-per-group/Jq/top-rank-per-group-1.jq
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"Employee Name": "Tyler Bennett",
|
||||
"Employee ID": "E10297",
|
||||
"Salary": "32000",
|
||||
"Department": "D101"
|
||||
}
|
||||
10
Task/Top-rank-per-group/Jq/top-rank-per-group-2.jq
Normal file
10
Task/Top-rank-per-group/Jq/top-rank-per-group-2.jq
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
def top_rank_per_department(n):
|
||||
group_by(.Department)
|
||||
| reduce .[] as $dept
|
||||
([]; ($dept
|
||||
| map(.Salary)
|
||||
| sort # from least to most
|
||||
| .[length - n:] # top n salaries
|
||||
| reverse) as $max
|
||||
| ($dept[0] | .Department) as $dept
|
||||
| . + [ { "Department": $dept, "top_salaries": $max } ] );
|
||||
31
Task/Top-rank-per-group/Jq/top-rank-per-group-3.jq
Normal file
31
Task/Top-rank-per-group/Jq/top-rank-per-group-3.jq
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
$ jq 'top_rank_per_department(2) data.json
|
||||
[
|
||||
{
|
||||
"Department": "D050",
|
||||
"top_salaries": [
|
||||
"47000",
|
||||
"21900"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Department": "D101",
|
||||
"top_salaries": [
|
||||
"53500",
|
||||
"41500"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Department": "D190",
|
||||
"top_salaries": [
|
||||
"57000",
|
||||
"29900"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Department": "D202",
|
||||
"top_salaries": [
|
||||
"49500",
|
||||
"27800"
|
||||
]
|
||||
}
|
||||
]
|
||||
72
Task/Top-rank-per-group/Jsish/top-rank-per-group.jsish
Normal file
72
Task/Top-rank-per-group/Jsish/top-rank-per-group.jsish
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env jsish
|
||||
/* Top rank per group, in Jsish */
|
||||
function top_rank(n) {
|
||||
var by_dept = group_by_dept(data);
|
||||
for (var dept in by_dept) {
|
||||
puts(dept);
|
||||
for (var i = 0; i < n && i < by_dept[dept].length; i++) {
|
||||
var emp = by_dept[dept][i];
|
||||
puts(emp.name + ", id=" + emp.id + ", salary=" + emp.salary);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
||||
// group by dept, and sort by salary
|
||||
function group_by_dept(data) {
|
||||
var by_dept = {};
|
||||
for (var idx in data) {
|
||||
var dept = data[idx].dept;
|
||||
if ( !by_dept.hasOwnProperty(dept)) {
|
||||
by_dept[dept] = new Array();
|
||||
}
|
||||
by_dept[dept].push(data[idx]);
|
||||
}
|
||||
for (var dept in by_dept) {
|
||||
by_dept[dept].sort(function (a,b) { return b.salary - a.salary; });
|
||||
}
|
||||
return by_dept;
|
||||
}
|
||||
|
||||
if (Interp.conf('unitTest')) {
|
||||
var data = [
|
||||
{name: "Tyler Bennett", id: "E10297", salary: 32000, dept: "D101"},
|
||||
{name: "John Rappl", id: "E21437", salary: 47000, dept: "D050"},
|
||||
{name: "George Woltman", id: "E00127", salary: 53500, dept: "D101"},
|
||||
{name: "Adam Smith", id: "E63535", salary: 18000, dept: "D202"},
|
||||
{name: "Claire Buckman", id: "E39876", salary: 27800, dept: "D202"},
|
||||
{name: "David McClellan", id: "E04242", salary: 41500, dept: "D101"},
|
||||
{name: "Rich Holcomb", id: "E01234", salary: 49500, dept: "D202"},
|
||||
{name: "Nathan Adams", id: "E41298", salary: 21900, dept: "D050"},
|
||||
{name: "Richard Potter", id: "E43128", salary: 15900, dept: "D101"},
|
||||
{name: "David Motsinger", id: "E27002", salary: 19250, dept: "D202"},
|
||||
{name: "Tim Sampair", id: "E03033", salary: 27000, dept: "D101"},
|
||||
{name: "Kim Arlich", id: "E10001", salary: 57000, dept: "D190"},
|
||||
{name: "Timothy Grove", id: "E16398", salary: 29900, dept: "D190"}
|
||||
];
|
||||
|
||||
top_rank(3);
|
||||
}
|
||||
|
||||
/*
|
||||
=!EXPECTSTART!=
|
||||
D050
|
||||
John Rappl, id=E21437, salary=47000
|
||||
Nathan Adams, id=E41298, salary=21900
|
||||
|
||||
D101
|
||||
George Woltman, id=E00127, salary=53500
|
||||
David McClellan, id=E04242, salary=41500
|
||||
Tyler Bennett, id=E10297, salary=32000
|
||||
|
||||
D190
|
||||
Kim Arlich, id=E10001, salary=57000
|
||||
Timothy Grove, id=E16398, salary=29900
|
||||
|
||||
D202
|
||||
Rich Holcomb, id=E01234, salary=49500
|
||||
Claire Buckman, id=E39876, salary=27800
|
||||
David Motsinger, id=E27002, salary=19250
|
||||
|
||||
=!EXPECTEND!=
|
||||
*/
|
||||
58
Task/Top-rank-per-group/Julia/top-rank-per-group.julia
Normal file
58
Task/Top-rank-per-group/Julia/top-rank-per-group.julia
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# v0.6.0
|
||||
|
||||
using DataFrames
|
||||
|
||||
df = DataFrame(
|
||||
EmployeeName=["Tyler Bennett", "John Rappl", "George Woltman", "Adam Smith",
|
||||
"Claire Buckman", "David McClellan", "Rich Holcomb", "Nathan Adams",
|
||||
"Richard Potter", "David Motsinger", "Tim Sampair", "Kim Arlich", "Timothy Grove"],
|
||||
EmployeeID = ["E10297", "E21437", "E00127", "E63535", "E39876", "E04242",
|
||||
"E01234", "E41298", "E43128", "E27002", "E03033", "E10001", "E16398"],
|
||||
Salary = [32000, 47000, 53500, 18000, 27800, 41500, 49500, 21900, 15900, 19250,
|
||||
27000, 57000, 29900],
|
||||
Department = ["D101", "D050", "D101", "D202", "D202", "D101", "D202", "D050",
|
||||
"D101", "D202", "D101", "D190", "D190"])
|
||||
|
||||
# To get only values
|
||||
function firstnby(n::Int, y::Array, by::Array)
|
||||
# Check that each value belong to one and one only class
|
||||
if length(y) != length(by); error("y and by must have the same length"); end
|
||||
|
||||
# Initialize resulting dictionary
|
||||
rst = Dict{eltype(by), Array{eltype(y)}}()
|
||||
|
||||
# For each class...
|
||||
for cl in unique(by)
|
||||
# ...select the values of that class...
|
||||
i = find(x -> x == cl, by)
|
||||
# ...sort them and store them in result...
|
||||
rst[cl] = sort(y[i]; rev=true)
|
||||
# ...if length is greater than n select only first n elements
|
||||
if length(i) > n
|
||||
rst[cl] = rst[cl][1:n]
|
||||
end
|
||||
end
|
||||
return rst
|
||||
end
|
||||
|
||||
for (cl, val) in firstnby(3, Array(df[:Salary]), Array(df[:Department]))
|
||||
println("$cl => $val")
|
||||
end
|
||||
|
||||
# To get the full row...
|
||||
function firstnby(n::Int, df::DataFrame, y::Symbol, by::Symbol)
|
||||
rst = Dict{eltype(df[by]), DataFrame}()
|
||||
|
||||
for cl in unique(df[by])
|
||||
i = find(x -> x == cl, df[by])
|
||||
rst[cl] = sort(df[i, :]; cols=order(y; rev=true))
|
||||
if length(i) > n
|
||||
rst[cl] = rst[cl][1:n, :]
|
||||
end
|
||||
end
|
||||
return rst
|
||||
end
|
||||
|
||||
for (cl, data) in firstnby(3, df, :Salary, :Department)
|
||||
println("\n$cl:\n$data")
|
||||
end
|
||||
31
Task/Top-rank-per-group/Kotlin/top-rank-per-group.kotlin
Normal file
31
Task/Top-rank-per-group/Kotlin/top-rank-per-group.kotlin
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// version 1.1.2
|
||||
|
||||
data class Employee(val name: String, val id: String, val salary: Int, val dept: String)
|
||||
|
||||
const val N = 2 //say
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val employees = listOf(
|
||||
Employee("Tyler Bennett", "E10297", 32000, "D101"),
|
||||
Employee("John Rappl", "E21437", 47000, "D050"),
|
||||
Employee("George Woltman" , "E00127", 53500, "D101"),
|
||||
Employee("Adam Smith", "E63535", 18000, "D202"),
|
||||
Employee("Claire Buckman", "E39876", 27800, "D202"),
|
||||
Employee("David McClellan", "E04242", 41500, "D101"),
|
||||
Employee("Rich Holcomb", "E01234", 49500, "D202"),
|
||||
Employee("Nathan Adams", "E41298", 21900, "D050"),
|
||||
Employee("Richard Potter", "E43128", 15900, "D101"),
|
||||
Employee("David Motsinger", "E27002", 19250, "D202"),
|
||||
Employee("Tim Sampair", "E03033", 27000, "D101"),
|
||||
Employee("Kim Arlich", "E10001", 57000, "D190"),
|
||||
Employee("Timothy Grove", "E16398", 29900, "D190")
|
||||
)
|
||||
val employeesByDept = employees.sortedBy { it.dept }.groupBy { it.dept }
|
||||
println("Highest $N salaries by department:\n")
|
||||
for ((key, value) in employeesByDept) {
|
||||
val topRanked = value.sortedByDescending { it.salary }.take(N)
|
||||
println("Dept $key => ")
|
||||
for (i in 0 until N) with (topRanked[i]) { println("${name.padEnd(15)} $id $salary") }
|
||||
println()
|
||||
}
|
||||
}
|
||||
75
Task/Top-rank-per-group/Ksh/top-rank-per-group.ksh
Normal file
75
Task/Top-rank-per-group/Ksh/top-rank-per-group.ksh
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#!/bin/ksh
|
||||
exec 2> /tmp/Top_rank_per_group.err
|
||||
|
||||
# Top rank per group
|
||||
|
||||
# # Variables:
|
||||
#
|
||||
integer TOP_NUM=2
|
||||
|
||||
typeset -T Empsal_t=(
|
||||
typeset -h 'Employee Name' ename=''
|
||||
typeset -h 'Employee ID' eid=''
|
||||
typeset -i -h 'Employee Salary' esalary
|
||||
typeset -h 'Emplyee Department' edept=''
|
||||
|
||||
function init_employee {
|
||||
typeset buff ; buff="$1"
|
||||
|
||||
typeset oldIFS ; oldIFS="$IFS"
|
||||
typeset arr ; typeset -a arr
|
||||
IFS=\,
|
||||
arr=( ${buff} )
|
||||
|
||||
_.ename="${arr[0]}"
|
||||
_.eid="${arr[1]}"
|
||||
_.esalary=${arr[2]}
|
||||
_.edept="${arr[3]}"
|
||||
|
||||
IFS="${oldIFS}"
|
||||
}
|
||||
)
|
||||
|
||||
edata='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'
|
||||
|
||||
######
|
||||
# main #
|
||||
######
|
||||
|
||||
# # Employee data into array of Types
|
||||
#
|
||||
typeset -a empsal_t # array of Type variables (objects)
|
||||
integer j i=0
|
||||
echo "${edata}" | while read; do
|
||||
Empsal_t empsal_t[i] # Create Type (object)
|
||||
empsal_t[i++].init_employee "$REPLY" # Initialize Type (object)
|
||||
done
|
||||
|
||||
# # Sort the array of Type variables
|
||||
#
|
||||
set -a -s -A empsal_t -K edept,esalary:n:r,ename
|
||||
|
||||
# # BUG work around! duplicate the now sorted Type array and use it for output
|
||||
#
|
||||
sorted=$(typeset -p empsal_t) && sorted=${sorted/empsal_t/sorted} && eval ${sorted}
|
||||
|
||||
for ((i=0; i<${#sorted[*]}; i++)); do
|
||||
if [[ ${sorted[i].edept} != ${prevdept} ]] || (( j < TOP_NUM )); then
|
||||
[[ ${sorted[i].edept} != ${prevdept} ]] && j=0
|
||||
print "${sorted[i].edept} ${sorted[i].esalary} ${sorted[i].eid} ${sorted[i].ename}"
|
||||
prevdept=${sorted[i].edept}
|
||||
(( j++ ))
|
||||
fi
|
||||
done
|
||||
36
Task/Top-rank-per-group/Lua/top-rank-per-group-1.lua
Normal file
36
Task/Top-rank-per-group/Lua/top-rank-per-group-1.lua
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
N = 2
|
||||
|
||||
lst = { { "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" }
|
||||
}
|
||||
|
||||
dep = {}
|
||||
for i = 1, #lst do
|
||||
if dep[ lst[i][4] ] == nil then
|
||||
dep[ lst[i][4] ] = {}
|
||||
dep[ lst[i][4] ][1] = lst[i]
|
||||
else
|
||||
dep[ lst[i][4] ][#dep[lst[i][4]]+1] = lst[i]
|
||||
end
|
||||
end
|
||||
|
||||
for i, _ in pairs( dep ) do
|
||||
table.sort( dep[i], function (a,b) return a[3] > b[3] end )
|
||||
|
||||
print( "Department:", dep[i][1][4] )
|
||||
for l = 1, math.min( N, #dep[i] ) do
|
||||
print( "", dep[i][l][1], dep[i][l][2], dep[i][l][3] )
|
||||
end
|
||||
print ""
|
||||
end
|
||||
94
Task/Top-rank-per-group/Lua/top-rank-per-group-2.lua
Normal file
94
Task/Top-rank-per-group/Lua/top-rank-per-group-2.lua
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
--Employee Class
|
||||
local EmployeeMethods = {
|
||||
|
||||
}
|
||||
local EmployeeMetamethods = {
|
||||
__index=EmployeeMethods,
|
||||
__tostring=function(self)
|
||||
return ("%s %s %s %s"):format(self.Name,self.EmployeeId,self.Salary,self.DepartmentName)
|
||||
end,
|
||||
__metatable="Locked",
|
||||
}
|
||||
local EmployeeBase = {}
|
||||
|
||||
EmployeeBase.new = function(Name,EmployeeId,Salary,DepartmentName)
|
||||
return setmetatable({
|
||||
Name=Name,
|
||||
EmployeeId=EmployeeId,
|
||||
Salary=Salary,
|
||||
DepartmentName=DepartmentName,
|
||||
},EmployeeMetamethods)
|
||||
end
|
||||
|
||||
--Department Class
|
||||
local DepartmentMethods = {
|
||||
NewEmployee=function(self,Employee)
|
||||
table.insert(self.__Employees,Employee)
|
||||
end,
|
||||
CalculateHighestSalaries=function(self,Amount)
|
||||
local Highest = {}
|
||||
local EL = #self.__Employees
|
||||
table.sort(self.__Employees,function(a,b)
|
||||
return a.Salary > b.Salary
|
||||
end)
|
||||
for i=1,Amount do
|
||||
if i>EL then
|
||||
break
|
||||
end
|
||||
table.insert(Highest,self.__Employees[i])
|
||||
end
|
||||
return Highest
|
||||
end,
|
||||
}
|
||||
local DepartmentMetamethods = {
|
||||
__index=DepartmentMethods,
|
||||
__tostring=function(self)
|
||||
return ("Department %s"):format(self.Name)
|
||||
end,
|
||||
__metatable="Locked",
|
||||
}
|
||||
local DepartmentBase = {
|
||||
__Departments={},
|
||||
}
|
||||
|
||||
DepartmentBase.new = function(Name)
|
||||
local Department = DepartmentBase.__Departments[Name]
|
||||
if Department then return Department end
|
||||
Department = setmetatable({
|
||||
__Employees={},
|
||||
Name=Name,
|
||||
},DepartmentMetamethods)
|
||||
DepartmentBase.__Departments[Name] = Department
|
||||
return Department
|
||||
end
|
||||
|
||||
--Main Program
|
||||
|
||||
local Employees = {
|
||||
EmployeeBase.new("Tyler Bennett","E10297",32000,"D101"),
|
||||
EmployeeBase.new("John Rappl","E21437",47000,"D050"),
|
||||
EmployeeBase.new("George Woltman","E00127",53500,"D101"),
|
||||
EmployeeBase.new("Adam Smith","E63535",18000,"D202"),
|
||||
EmployeeBase.new("Claire Buckman","E39876",27800,"D202"),
|
||||
EmployeeBase.new("David McClellan","E04242",41500,"D101"),
|
||||
EmployeeBase.new("Rich Holcomb","E01234",49500,"D202"),
|
||||
EmployeeBase.new("Nathan Adams","E41298",21900,"D050"),
|
||||
EmployeeBase.new("Richard Potter","E43128",15900,"D101"),
|
||||
EmployeeBase.new("David Motsinger","E27002",19250,"D202"),
|
||||
EmployeeBase.new("Tim Sampair","E03033",27000,"D101"),
|
||||
EmployeeBase.new("Kim Arlich","E10001",57000,"D190"),
|
||||
EmployeeBase.new("Timothy Grove","E16398",29900,"D190"),
|
||||
}
|
||||
|
||||
for _,Employee in next,Employees do
|
||||
local Department = DepartmentBase.new(Employee.DepartmentName)
|
||||
Department:NewEmployee(Employee)
|
||||
end
|
||||
|
||||
for _,Department in next,DepartmentBase.__Departments do
|
||||
local Highest = Department:CalculateHighestSalaries(2)
|
||||
print(Department)
|
||||
for _,Employee in next,Highest do
|
||||
print("\t"..tostring(Employee))
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
Module Checkit {
|
||||
' erase stack of values, so we can add data
|
||||
Flush
|
||||
Input "N=",N
|
||||
Enum Departments {D050,D101,D190,D202}
|
||||
|
||||
\\ Inventory Department need unique keys
|
||||
Inventory Department
|
||||
\\ each item in this inventory should be an inventory too
|
||||
Class Empl {
|
||||
name$, id$, salary
|
||||
Class:
|
||||
Module Empl(.name$, .id$, .salary) {}
|
||||
}
|
||||
Data "Tyler Bennett","E10297",32000,D101
|
||||
Data "John Rappl","E21437",47000,D050
|
||||
Data "George Woltman","E00127",53500,D101
|
||||
Data "Adam Smith","E63535",18000,D202
|
||||
Data "Claire Buckman","E39876",27800,D202
|
||||
Data "David McClellan","E04242",41500,D101
|
||||
Data "Rich Holcomb","E01234",49500,D202
|
||||
Data "Nathan Adams","E41298",21900,D050
|
||||
Data "Richard Potter","E43128",15900,D101
|
||||
Data "David Motsinger","E27002",19250,D202
|
||||
Data "Tim Sampair","E03033",27000,D101
|
||||
Data "Kim Arlich","E10001",57000,D190
|
||||
Data "Timothy Grove","E16398",29900,D190
|
||||
Data ""
|
||||
Read name$
|
||||
While name$<>"" {
|
||||
Read id$, salary, dep
|
||||
Rem : Print name$, id$, salary, dep
|
||||
If Exist(Department, dep) Then {
|
||||
z=Eval(Department) ' get pointer to inventory
|
||||
AppendOne()
|
||||
} Else {
|
||||
z=queue
|
||||
AppendDep()
|
||||
AppendOne()
|
||||
}
|
||||
Read name$
|
||||
}
|
||||
Sort Department as number
|
||||
i=each(Department)
|
||||
\\ make depname as type of Departments
|
||||
depname=D050
|
||||
Print "Dep. Employee Name Emp. ID Salary"
|
||||
While i {
|
||||
\\ when we pass a number to a enum variable
|
||||
\\ if the number exist, get that enum item else raise error
|
||||
depname=val(eval$(i, i^))
|
||||
\\ z is a pointer to inventory
|
||||
z=Eval(i)
|
||||
Sort descending z as number
|
||||
k=each(z,1,N)
|
||||
While k {
|
||||
Empl=Eval(k)
|
||||
For Empl {
|
||||
\\ eval$(depname) return the name of enum variable (like D050)
|
||||
Print Format$("{0:6}{1:20}{2:8}{3::-8}",Eval$(depname), .name$, .id$, .salary)
|
||||
}
|
||||
}
|
||||
}
|
||||
Print "Done"
|
||||
Sub AppendDep()
|
||||
Append Department, dep:=z
|
||||
End Sub
|
||||
Sub AppendOne()
|
||||
Append z, salary:=Empl(name$, id$, salary)
|
||||
End Sub
|
||||
}
|
||||
Checkit
|
||||
14
Task/Top-rank-per-group/Mathematica/top-rank-per-group.math
Normal file
14
Task/Top-rank-per-group/Mathematica/top-rank-per-group.math
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
InitialList ={{"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"}};
|
||||
|
||||
TrimmedList=Map[ If[Length[#]>3,Take[#,3],#]& ,
|
||||
Map[Reverse[SortBy[#,#[[3]]&]]&,GatherBy[InitialList,Last]]
|
||||
];
|
||||
|
||||
Scan[((Print["Department ",#[[1,4]],"\n","Employee","\t","Id","\t","Salary"]&[#])&[#];
|
||||
(Scan[Print[#[[1]],"\t",#[[2]],"\t",#[[3]]]&,#] )& [#])&,TrimmedList]
|
||||
35
Task/Top-rank-per-group/Nim/top-rank-per-group.nim
Normal file
35
Task/Top-rank-per-group/Nim/top-rank-per-group.nim
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import algorithm
|
||||
|
||||
type Record = tuple[name, id: string; salary: int; department: string]
|
||||
|
||||
var people = [("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")]
|
||||
|
||||
proc pcmp(a, b: Record): int =
|
||||
result = cmp(a.department, b.department)
|
||||
if result == 0:
|
||||
result = cmp(b.salary, a.salary)
|
||||
|
||||
proc printTop(people: openArray[Record]; n: Positive) =
|
||||
var people = sorted(people, pcmp)
|
||||
var rank = 0
|
||||
for i, p in people:
|
||||
if i > 0 and p.department != people[i-1].department:
|
||||
rank = 0
|
||||
echo()
|
||||
if rank < n:
|
||||
echo p.department, " ", p.salary, " ", p.name
|
||||
inc rank
|
||||
|
||||
people.printTop(2)
|
||||
50
Task/Top-rank-per-group/OCaml/top-rank-per-group.ocaml
Normal file
50
Task/Top-rank-per-group/OCaml/top-rank-per-group.ocaml
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
open StdLabels
|
||||
|
||||
let to_string (name,_,s,_) = (Printf.sprintf "%s (%d)" name s)
|
||||
|
||||
let take n li =
|
||||
let rec aux i acc = function
|
||||
| _ when i >= n -> (List.rev acc)
|
||||
| [] -> (List.rev acc)
|
||||
| x::xs -> aux (succ i) (x::acc) xs
|
||||
in
|
||||
aux 0 [] li ;;
|
||||
|
||||
let toprank data n =
|
||||
let len = List.length data in
|
||||
let h = Hashtbl.create len in
|
||||
List.iter data ~f:(fun ((_,_,_,dep) as employee) ->
|
||||
Hashtbl.add h dep employee);
|
||||
let deps =
|
||||
List.fold_left data ~init:[] ~f:
|
||||
(fun ac (_,_,_,v) -> if List.mem v ac then ac else v::ac) in
|
||||
let f dep =
|
||||
Printf.printf "Department: %s\n " dep;
|
||||
let l = Hashtbl.find_all h dep in
|
||||
let l2 = List.sort (fun (_,_,v1,_) (_,_,v2,_) -> compare v2 v1) l in
|
||||
let l3 = (take n l2) in
|
||||
print_endline(String.concat ", " (List.map to_string l3));
|
||||
print_newline()
|
||||
in
|
||||
List.iter f deps;
|
||||
;;
|
||||
|
||||
let data = [
|
||||
"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";
|
||||
]
|
||||
|
||||
let () =
|
||||
toprank data 3;
|
||||
;;
|
||||
27
Task/Top-rank-per-group/Oforth/top-rank-per-group.fth
Normal file
27
Task/Top-rank-per-group/Oforth/top-rank-per-group.fth
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
Object Class new: Employee(name, id, salary, dep)
|
||||
|
||||
Employee method: initialize := dep := salary := id := name ;
|
||||
Employee method: salary @salary ;
|
||||
Employee method: dep @dep ;
|
||||
Employee method: << "[" << @dep << "," << @name << "," << @salary << "]" << ;
|
||||
|
||||
: topRank(n)
|
||||
| employees |
|
||||
ListBuffer new ->employees
|
||||
|
||||
Employee new("Tyler Bennett", "E10297", 32000, "D101") employees add
|
||||
Employee new("John Rappl", "E21437", 47000, "D050") employees add
|
||||
Employee new("George Woltman", "E00127", 53500, "D101") employees add
|
||||
Employee new("Adam Smith", "E63535", 18000, "D202") employees add
|
||||
Employee new("Claire Buckman", "E39876", 27800, "D202") employees add
|
||||
Employee new("David McClellan", "E04242", 41500, "D101") employees add
|
||||
Employee new("Rich Holcomb", "E01234", 49500, "D202") employees add
|
||||
Employee new("Nathan Adams", "E41298", 21900, "D050") employees add
|
||||
Employee new("Richard Potter", "E43128", 15900, "D101") employees add
|
||||
Employee new("David Motsinger", "E27002", 19250, "D202") employees add
|
||||
Employee new("Tim Sampair", "E03033", 27000, "D101") employees add
|
||||
Employee new("Kim Arlich", "E10001", 57000, "D190") employees add
|
||||
Employee new("Timothy Grove", "E16398", 29900, "D190") employees add
|
||||
|
||||
#dep employees sortBy groupWith( #dep )
|
||||
map(#[ sortBy(#[ salary neg ]) left(n) ]) apply(#println) ;
|
||||
46
Task/Top-rank-per-group/Oz/top-rank-per-group.oz
Normal file
46
Task/Top-rank-per-group/Oz/top-rank-per-group.oz
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
declare
|
||||
%% Create a list of employee records.
|
||||
Data = {Map
|
||||
[['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]]
|
||||
|
||||
fun {$ [Name Id Salary Department]}
|
||||
employee(name:Name id:Id salary:Salary department:Department)
|
||||
end}
|
||||
|
||||
fun {TopEarners Employees N}
|
||||
{Record.map {GroupBy Employees department}
|
||||
fun {$ Employees}
|
||||
{List.take
|
||||
{Sort Employees CompareSalary}
|
||||
N}
|
||||
end}
|
||||
end
|
||||
|
||||
fun {CompareSalary E1 E2}
|
||||
E1.salary > E2.salary
|
||||
end
|
||||
|
||||
%% Groups the records Xs by the value of feature F and returns
|
||||
%% the result as a record that maps values of F to list of records.
|
||||
fun {GroupBy Xs F}
|
||||
Groups = {Dictionary.new}
|
||||
in
|
||||
for X in Xs do
|
||||
Groups.(X.F) := X|{CondSelect Groups X.F nil}
|
||||
end
|
||||
{Dictionary.toRecord unit Groups}
|
||||
end
|
||||
in
|
||||
{Inspect {TopEarners Data 3}}
|
||||
28
Task/Top-rank-per-group/PARI-GP/top-rank-per-group.parigp
Normal file
28
Task/Top-rank-per-group/PARI-GP/top-rank-per-group.parigp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{V=[["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"]]};
|
||||
|
||||
top(n,V)={
|
||||
my(dept=vecsort(vector(#V,i,V[i][4]),,8),d,v);
|
||||
for(i=1,#dept,
|
||||
d=dept[i];
|
||||
print(d);
|
||||
v=select(u->u[4]==d,V);
|
||||
v=vecsort(v,3,4); \\ Sort by salary (#3) descending (flag 0x4)
|
||||
for(j=1,min(n,#v),
|
||||
print("\t",v[j][1],"\t",v[j][2],"\t",v[j][3])
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
top(2,V)
|
||||
48
Task/Top-rank-per-group/PHP/top-rank-per-group.php
Normal file
48
Task/Top-rank-per-group/PHP/top-rank-per-group.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
$data = Array(
|
||||
Array("Tyler Bennett","E10297",32000,"D101"),
|
||||
Array("John Rappl","E21437",47000,"D050"),
|
||||
Array("George Woltman","E00127",53500,"D101"),
|
||||
Array("Adam Smith","E63535",18000,"D202"),
|
||||
Array("Claire Buckman","E39876",27800,"D202"),
|
||||
Array("David McClellan","E04242",41500,"D101"),
|
||||
Array("Rich Holcomb","E01234",49500,"D202"),
|
||||
Array("Nathan Adams","E41298",21900,"D050"),
|
||||
Array("Richard Potter","E43128",15900,"D101"),
|
||||
Array("David Motsinger","E27002",19250,"D202"),
|
||||
Array("Tim Sampair","E03033",27000,"D101"),
|
||||
Array("Kim Arlich","E10001",57000,"D190"),
|
||||
Array("Timothy Grove","E16398",29900,"D190")
|
||||
);
|
||||
function top_sal($num){
|
||||
global $data;
|
||||
$depts = Array();
|
||||
foreach($data as $key => $arr){
|
||||
if(!isset($depts[$arr[3]])) $depts[$arr[3]] = Array();
|
||||
$depts[$arr[3]][] = $key;
|
||||
}
|
||||
function topsalsort($a,$b){
|
||||
global $data;
|
||||
if ($data[$a][2] == $data[$b][2]) {
|
||||
return 0;
|
||||
}
|
||||
return ($data[$a][2] < $data[$b][2]) ? 1 : -1;
|
||||
}
|
||||
foreach ($depts as $key => $val){
|
||||
usort($depts[$key],"topsalsort");
|
||||
}
|
||||
ksort($depts);
|
||||
echo '<pre>';
|
||||
foreach ($depts as $key => $val){
|
||||
echo $key . '<br>';
|
||||
echo 'Name ID Salary<br>';
|
||||
$count = 0;
|
||||
foreach($val as $value){
|
||||
echo $data[$value][0] . ' ' . $data[$value][1] . ' ' . $data[$value][2] . '<br>';
|
||||
$count++;
|
||||
if($count>=$num) break;
|
||||
}
|
||||
echo '<br>';
|
||||
}
|
||||
echo '</pre>';
|
||||
}
|
||||
top_sal(3);
|
||||
83
Task/Top-rank-per-group/PL-I/top-rank-per-group.pli
Normal file
83
Task/Top-rank-per-group/PL-I/top-rank-per-group.pli
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
(subrg, stringrange, stringsize):
|
||||
rank: procedure options (main); /* 10 November 2013 */
|
||||
|
||||
declare 1 employee (13),
|
||||
2 name char (15) varying,
|
||||
2 ID char (6),
|
||||
2 salary fixed (5),
|
||||
2 department char (4);
|
||||
declare done(hbound(employee)) bit (1);
|
||||
declare ptr(hbound(employee)) fixed binary;
|
||||
declare true bit(1) value ('1'b), false bit(1) value ('0'b);
|
||||
declare dept character (4);
|
||||
declare text character (80) varying;
|
||||
declare (i, j, l, k, m, n, p, t) fixed binary;
|
||||
declare in file input;
|
||||
|
||||
open file (in) title ('/TOP-RANK.DAT, RECSIZE(80), TYPE(TEXT)' );
|
||||
|
||||
on endfile (in) go to completed_input;
|
||||
j = 0;
|
||||
do forever;
|
||||
get file (in) edit (text) (L);
|
||||
j = j + 1;
|
||||
i = index(text, ',');
|
||||
name(j) = substr(text, 1, i-1);
|
||||
k = index(text, ',', i+1);
|
||||
ID(j) = substr(text, i+1, k-(i+1));
|
||||
i = k; k = index(text, ',', i+1);
|
||||
salary(j) = substr(text, i+1, k-(i+1));
|
||||
department(j) = substr(text, k+1);
|
||||
end;
|
||||
|
||||
completed_input:
|
||||
m = hbound(employee);
|
||||
put skip list ('How many highest-paid employees do you want?');
|
||||
get (n);
|
||||
put skip edit ('Looking for the ', trim(n),
|
||||
' highest-paid employees in each department') (a);
|
||||
done = false;
|
||||
do i = 1 to m;
|
||||
do j = 1 to m;
|
||||
if done(j) then iterate;
|
||||
dept = department(j);
|
||||
/* done(j) = true; */
|
||||
leave;
|
||||
end;
|
||||
/* Locate all the employees of this department. */
|
||||
k = 0;
|
||||
do j = 1 to m;
|
||||
if ^done(j) & (department(j) = dept) then
|
||||
do;
|
||||
k = k + 1;
|
||||
ptr(k) = j;
|
||||
done(j) = true;
|
||||
end;
|
||||
end;
|
||||
if k = 0 then leave; /* (No more departments.) */
|
||||
|
||||
put skip list ('Employees in department ' || dept || ' are:-' );
|
||||
do j = 1 to k;
|
||||
put skip list (employee(ptr(j)));
|
||||
end;
|
||||
/* We now have k employees in "dept". Now find the maximum n salaries. */
|
||||
/* ptr points to all of them. */
|
||||
/* Use a bubble sort to move n values to one end. */
|
||||
do p = 1 to min(n, k);
|
||||
do j = 1 to k-1;
|
||||
if salary(ptr(j)) > salary(ptr(j+1)) then
|
||||
do;
|
||||
t = ptr(j+1); ptr(j+1) = ptr(j); ptr(j) = t;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
/* Having moved the largest n values to the end of our list, */
|
||||
/* we print them. */
|
||||
put skip list ('Highest-paid employees in department ' || dept || ':-');
|
||||
do j = k to k-min(k,n)+1 by -1;
|
||||
put skip list (employee(ptr(j)) );
|
||||
end;
|
||||
end;
|
||||
put skip list ('FINISHED');
|
||||
end rank;
|
||||
108
Task/Top-rank-per-group/PL-SQL/top-rank-per-group.sql
Normal file
108
Task/Top-rank-per-group/PL-SQL/top-rank-per-group.sql
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
create or replace procedure "Top rank per group"(TOP_N in pls_integer default 3) as
|
||||
cursor CSR_EMP(TOP_N pls_integer) is
|
||||
select case LINE
|
||||
when 10 then
|
||||
'Tot.' || LPAD(POPULATION, 2) || ' Employees in ' || TIE_COUNT ||
|
||||
' deps.Avg salary:' || TO_CHAR(SALARY, '99990.99')
|
||||
when 30 then
|
||||
'-'
|
||||
when 50 then
|
||||
'Department: ' || DEPT_ID || ', pop: ' || POPULATION ||
|
||||
'. Avg Salary: ' || TO_CHAR(SALARY, '99990.99')
|
||||
when 70 then
|
||||
LPAD('Employee ID', 14) || LPAD('Employee name', 20) ||
|
||||
LPAD('Salary', 9) || 'Rank'
|
||||
when 90 then
|
||||
LPAD('+', 14, '-') || LPAD('+', 20, '-') || LPAD('+', 9, '-') ||
|
||||
LPAD('+', 4, '-')
|
||||
else
|
||||
LPAD(' ', 8) || LPAD(EMP_ID, 6) || LPAD(EMP_NAME, 20) ||
|
||||
TO_CHAR(SALARY, '99990.99') ||
|
||||
LPAD(case when TIE_COUNT = 1 then ' ' else 'T' end || RANK, 4)
|
||||
end "Top rank per group"
|
||||
from (select 10 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,' ' DEPT_ID
|
||||
,avg(SALARY) SALARY
|
||||
,0 RANK
|
||||
,count(distinct DEPT_ID) TIE_COUNT
|
||||
,count(*) POPULATION
|
||||
from EMP
|
||||
union all
|
||||
select 30 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,0 SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 50 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,avg(SALARY) SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,count(*) POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 70 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,0 SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 90 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,0 SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 110 LINE
|
||||
,EMP_ID
|
||||
,EMP_NAME
|
||||
,DEPT_ID
|
||||
,SALARY
|
||||
,(select count(distinct EMP4.SALARY)
|
||||
from EMP EMP4
|
||||
where EMP4.DEPT_ID = EMP3.DEPT_ID
|
||||
and EMP4.SALARY >= EMP3.SALARY) RANK
|
||||
,(select count(*)
|
||||
from EMP EMP2
|
||||
where EMP2.DEPT_ID = EMP3.DEPT_ID
|
||||
and EMP2.SALARY = EMP3.SALARY) TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP EMP3
|
||||
where TOP_N >= -- Here is the meat, Correlated subquery
|
||||
(select count(distinct EMP4.SALARY)
|
||||
from EMP EMP4
|
||||
where EMP4.DEPT_ID = EMP3.DEPT_ID
|
||||
and EMP4.SALARY >= EMP3.SALARY))
|
||||
order by DEPT_ID
|
||||
,LINE
|
||||
,SALARY desc
|
||||
,EMP_ID;
|
||||
|
||||
V_EMP CSR_EMP%rowtype;
|
||||
begin
|
||||
for V_EMP in CSR_EMP(TOP_N)
|
||||
loop
|
||||
DBMS_OUTPUT.PUT_LINE(v_emp."Top rank per group");
|
||||
end loop;
|
||||
end;
|
||||
69
Task/Top-rank-per-group/Pascal/top-rank-per-group.pas
Normal file
69
Task/Top-rank-per-group/Pascal/top-rank-per-group.pas
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
program TopRankPerGroup(output);
|
||||
|
||||
uses
|
||||
Classes, Math;
|
||||
|
||||
type
|
||||
TData = record
|
||||
name: string;
|
||||
ID: string;
|
||||
salary: longint;
|
||||
dept: string
|
||||
end;
|
||||
PTData = ^TData;
|
||||
|
||||
const
|
||||
data: array [1..13] of TData =
|
||||
( (name: 'Tyler Bennett'; ID: 'E10297'; salary: 32000; dept: 'D101'),
|
||||
(name: 'John Rappl'; ID: 'E21437'; salary: 47000; dept: 'D050'),
|
||||
(name: 'George Woltman'; ID: 'E00127'; salary: 53500; dept: 'D101'),
|
||||
(name: 'Adam Smith'; ID: 'E63535'; salary: 18000; dept: 'D202'),
|
||||
(name: 'Claire Buckman'; ID: 'E39876'; salary: 27800; dept: 'D202'),
|
||||
(name: 'David McClellan'; ID: 'E04242'; salary: 41500; dept: 'D101'),
|
||||
(name: 'Rich Holcomb'; ID: 'E01234'; salary: 49500; dept: 'D202'),
|
||||
(name: 'Nathan Adams'; ID: 'E41298'; salary: 21900; dept: 'D050'),
|
||||
(name: 'Richard Potter'; ID: 'E43128'; salary: 15900; dept: 'D101'),
|
||||
(name: 'David Motsinger'; ID: 'E27002'; salary: 19250; dept: 'D202'),
|
||||
(name: 'Tim Sampair'; ID: 'E03033'; salary: 27000; dept: 'D101'),
|
||||
(name: 'Kim Arlich'; ID: 'E10001'; salary: 57000; dept: 'D190'),
|
||||
(name: 'Timothy Grove'; ID: 'E16398'; salary: 29900; dept: 'D190')
|
||||
);
|
||||
|
||||
function CompareSalary(Item1, Item2: PTData): longint;
|
||||
begin
|
||||
CompareSalary := Item2^.salary - Item1^.salary;
|
||||
end;
|
||||
|
||||
var
|
||||
depts : TStringList;
|
||||
deptList: Tlist;
|
||||
number, i, j: integer;
|
||||
|
||||
begin
|
||||
write ('Enter the number of ranks: ');
|
||||
readln (number);
|
||||
depts := TStringList.Create;
|
||||
depts.Sorted := true;
|
||||
depts.Duplicates := dupIgnore;
|
||||
for i := low(data) to high(data) do
|
||||
depts.Add(data[i].dept);
|
||||
|
||||
for i := 0 to depts.Count - 1 do
|
||||
begin
|
||||
writeln;
|
||||
writeln('Department: ', depts.Strings[i]);
|
||||
deptList := TList.Create;
|
||||
for j := low(data) to high(data) do
|
||||
if data[j].dept = depts.Strings[i] then
|
||||
deptList.Add(@data[j]);
|
||||
deptList.Sort(TListSortCompare(@CompareSalary));
|
||||
for j := 0 to min(deptList.count, number) - 1 do
|
||||
begin
|
||||
write (PTData(deptList.Items[j])^.name, ', ');
|
||||
write ('ID: ', PTData(deptList.Items[j])^.ID, ', ');
|
||||
write ('Salary: ', PTData(deptList.Items[j])^.Salary);
|
||||
writeln;
|
||||
end;
|
||||
deptList.Destroy;
|
||||
end;
|
||||
end.
|
||||
47
Task/Top-rank-per-group/Perl/top-rank-per-group.pl
Normal file
47
Task/Top-rank-per-group/Perl/top-rank-per-group.pl
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
sub zip {
|
||||
my @a = @{shift()};
|
||||
my @b = @{shift()};
|
||||
my @l;
|
||||
push @l, shift @a, shift @b while @a and @b;
|
||||
return @l;
|
||||
}
|
||||
|
||||
sub uniq {
|
||||
my %h;
|
||||
grep {!$h{$_}++} @_;
|
||||
}
|
||||
|
||||
my @data =
|
||||
map {{ zip [qw(name id salary dept)], [split ','] }}
|
||||
split "\n",
|
||||
<<'EOF';
|
||||
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
|
||||
EOF
|
||||
|
||||
my $N = shift || 3;
|
||||
|
||||
foreach my $d (uniq sort map {$_->{dept}} @data) {
|
||||
print "$d\n";
|
||||
my @es =
|
||||
sort {$b->{salary} <=> $a->{salary}}
|
||||
grep {$_->{dept} eq $d}
|
||||
@data;
|
||||
foreach (1 .. $N) {
|
||||
@es or last;
|
||||
my $e = shift @es;
|
||||
printf "%-15s | %-6s | %5d\n", @{$e}{qw(name id salary)};
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
44
Task/Top-rank-per-group/Phix/top-rank-per-group.phix
Normal file
44
Task/Top-rank-per-group/Phix/top-rank-per-group.phix
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">N</span><span style="color: #0000FF;">=</span><span style="color: #000000;">3</span>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">-- Employee Name,Employee ID,Salary,Department</span>
|
||||
<span style="color: #008080;">enum</span> <span style="color: #000080;font-style:italic;">/*NAME,*/ /*ID,*/</span> <span style="color: #000000;">SAL</span><span style="color: #0000FF;">=</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">DEPT</span><span style="color: #0000FF;">=</span><span style="color: #000000;">4</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">employees</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">"Tyler Bennett"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"E10297"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">32000</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D101"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"John Rappl"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"E21437"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">47000</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D050"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"George Woltman"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"E00127"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">53500</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D101"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Adam Smith"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"E63535"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">18000</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D202"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Claire Buckman"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"E39876"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">27800</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D202"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"David McClellan"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"E04242"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">41500</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D101"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Rich Holcomb"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"E01234"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">49500</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D202"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Nathan Adams"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"E41298"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">21900</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D050"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Richard Potter"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"E43128"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15900</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D101"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"David Motsinger"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"E27002"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">19250</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D202"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Tim Sampair"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"E03033"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">27000</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D101"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Kim Arlich"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"E10001"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">57000</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D190"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Timothy Grove"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"E16398"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">29900</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"D190"</span><span style="color: #0000FF;">}}</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">by_dept_sal</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">employees</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">DEPT</span><span style="color: #0000FF;">]&-</span><span style="color: #000000;">employees</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">SAL</span><span style="color: #0000FF;">],</span>
|
||||
<span style="color: #000000;">employees</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">DEPT</span><span style="color: #0000FF;">]&-</span><span style="color: #000000;">employees</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">SAL</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tags</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">by_dept_sal</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">employees</span><span style="color: #0000FF;">)))</span>
|
||||
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">lastdep</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">dcount</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Top %d salaries by department\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">N</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">employees</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">emp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">employees</span><span style="color: #0000FF;">[</span><span style="color: #000000;">tags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">emp</span><span style="color: #0000FF;">[</span><span style="color: #000000;">DEPT</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">lastdep</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">lastdep</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">emp</span><span style="color: #0000FF;">[</span><span style="color: #000000;">DEPT</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">dcount</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000000;">dcount</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">dcount</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">N</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #0000FF;">?</span><span style="color: #000000;">emp</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
30
Task/Top-rank-per-group/Picat/top-rank-per-group-1.picat
Normal file
30
Task/Top-rank-per-group/Picat/top-rank-per-group-1.picat
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
go =>
|
||||
Emp = [
|
||||
% 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"]
|
||||
],
|
||||
print_top_ranks(Emp,3),
|
||||
nl.
|
||||
|
||||
print_top_ranks(Emp,N) =>
|
||||
printf("Top %d ranks per department:\n", N),
|
||||
foreach(Dept in [Dept : [_,_,_,Dept] in Emp].sort_remove_dups())
|
||||
printf("Department %s\n", Dept),
|
||||
Emp2 = sort_down([[Salary,Name] : [Name,_,Salary,D] in Emp, D = Dept]),
|
||||
foreach({[Salary,Name],E} in zip(Emp2,1..Emp2.length), E <= N)
|
||||
printf("%-20s %-10s\n", Name, Salary)
|
||||
end,
|
||||
nl
|
||||
end.
|
||||
18
Task/Top-rank-per-group/Picat/top-rank-per-group-2.picat
Normal file
18
Task/Top-rank-per-group/Picat/top-rank-per-group-2.picat
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
go2 =>
|
||||
Emp = findall([Name,ID,Salary,Dept],emp(Name,ID,Salary,Dept)),
|
||||
print_top_ranks(Emp,3),
|
||||
nl.
|
||||
|
||||
emp("Tyler Bennett","E10297","32000","D101").
|
||||
emp("John Rappl","E21437","47000","D050").
|
||||
emp("George Woltman","E00127","53500","D101").
|
||||
emp("Adam Smith","E63535","18000","D202").
|
||||
emp("Claire Buckman","E39876","27800","D202").
|
||||
emp("David McClellan","E04242","41500","D101").
|
||||
emp("Rich Holcomb","E01234","49500","D202").
|
||||
emp("Nathan Adams","E41298","21900","D050").
|
||||
emp("Richard Potter","E43128","15900","D101").
|
||||
emp("David Motsinger","E27002","19250","D202").
|
||||
emp("Tim Sampair","E03033","27000","D101").
|
||||
emp("Kim Arlich","E10001","57000","D190").
|
||||
emp("Timothy Grove","E16398","29900","D190").
|
||||
27
Task/Top-rank-per-group/PicoLisp/top-rank-per-group.l
Normal file
27
Task/Top-rank-per-group/PicoLisp/top-rank-per-group.l
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Employee Name, ID, Salary, Department
|
||||
(de *Employees
|
||||
("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) )
|
||||
|
||||
(de topEmployees (N)
|
||||
(let Fmt (4 -16 -7 7)
|
||||
(for Dept (by cadddr group *Employees)
|
||||
(prinl "Department " (cadddr (car Dept)) ":")
|
||||
(tab Fmt NIL "Name" "ID" "Salary")
|
||||
(for (I . D) (flip (by caddr sort Dept))
|
||||
(tab Fmt (pack I ". ") (car D) (cadr D) (caddr D))
|
||||
(T (= I N)) )
|
||||
(prinl) ) ) )
|
||||
|
||||
(topEmployees 3)
|
||||
32
Task/Top-rank-per-group/PowerShell/top-rank-per-group.psh
Normal file
32
Task/Top-rank-per-group/PowerShell/top-rank-per-group.psh
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
function New-Employee ($Name, $ID, $Salary, $Department) {
|
||||
New-Object PSObject `
|
||||
| Add-Member -PassThru NoteProperty EmployeeName $Name `
|
||||
| Add-Member -PassThru NoteProperty EmployeeID $ID `
|
||||
| Add-Member -PassThru NoteProperty Salary $Salary `
|
||||
| Add-Member -PassThru NoteProperty Department $Department
|
||||
}
|
||||
|
||||
$data = (New-Employee 'Tyler Bennett' E10297 32000 D101),
|
||||
(New-Employee 'John Rappl' E21437 47000 D050),
|
||||
(New-Employee 'George Woltman' E00127 53500 D101),
|
||||
(New-Employee 'Adam Smith' E63535 18000 D202),
|
||||
(New-Employee 'Claire Buckman' E39876 27800 D202),
|
||||
(New-Employee 'David McClellan' E04242 41500 D101),
|
||||
(New-Employee 'Rich Holcomb' E01234 49500 D202),
|
||||
(New-Employee 'Nathan Adams' E41298 21900 D050),
|
||||
(New-Employee 'Richard Potter' E43128 15900 D101),
|
||||
(New-Employee 'David Motsinger' E27002 19250 D202),
|
||||
(New-Employee 'Tim Sampair' E03033 27000 D101),
|
||||
(New-Employee 'Kim Arlich' E10001 57000 D190),
|
||||
(New-Employee 'Timothy Grove' E16398 29900 D190)
|
||||
|
||||
function Get-TopRank ($n) {
|
||||
$data `
|
||||
| Group-Object Department `
|
||||
| ForEach-Object {
|
||||
$_.Group `
|
||||
| Sort-Object Salary -Descending `
|
||||
| Select-Object -First $n
|
||||
} `
|
||||
| Format-Table -GroupBy Department
|
||||
}
|
||||
53
Task/Top-rank-per-group/Prolog/top-rank-per-group.pro
Normal file
53
Task/Top-rank-per-group/Prolog/top-rank-per-group.pro
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
% emp(name,id,salary,dpt)
|
||||
emp('Tyler Bennett','E10297',32000,'D101').
|
||||
emp('John Rappl','E21437',47000,'D050').
|
||||
emp('George Woltman','E00127',53500,'D101').
|
||||
emp('Adam Smith','E63535',18000,'D202').
|
||||
emp('Claire Buckman','E39876',27800,'D202').
|
||||
emp('David McClellan','E04242',41500,'D101').
|
||||
emp('Rich Holcomb','E01234',49500,'D202').
|
||||
emp('Nathan Adams','E41298',21900,'D050').
|
||||
emp('Richard Potter','E43128',15900,'D101').
|
||||
emp('David Motsinger','E27002',19250,'D202').
|
||||
emp('Tim Sampair','E03033',27000,'D101').
|
||||
emp('Kim Arlich','E10001',57000,'D190').
|
||||
emp('Timothy Grove','E16398',29900,'D190').
|
||||
|
||||
departments(Depts) :- % Find the set of departments
|
||||
findall(Dpt, emp(_,_,_,Dpt), DList), list_to_set(DList, Depts).
|
||||
|
||||
greater(emp(_,_,Sal1,_), emp(_,_,Sal2,_)) :-
|
||||
Sal1 > Sal2. % First employee salary greater than second
|
||||
|
||||
% Maintains a decreasing ordered list of employees truncated after (N) items.
|
||||
% Rule 1: For N=0, always return an empty set.
|
||||
% Rule 2: Add employee with greater salary at start of list, call with N-1
|
||||
% Rule 3: Try to add new employee at N-1
|
||||
% Rule 4: for an empty input list regardless of N, add the new employee
|
||||
topSalary(0, _, _, []).
|
||||
topSalary(N, Emp, [E|R], [Emp|Res]) :-
|
||||
greater(Emp,E), N0 is N - 1, !, topSalary(N0, E, R, Res).
|
||||
topSalary(N, Emp, [E|R], [E|Res]) :-
|
||||
N0 is N - 1, !, topSalary(N0, Emp, R, Res).
|
||||
topSalary(_, Emp, [], [Emp]).
|
||||
|
||||
% For each employee, add him to the list if top salary
|
||||
topEmps(N, [Emp|Emps], R, Res) :-
|
||||
topSalary(N, Emp, R, Rt), !, topEmps(N, Emps, Rt, Res).
|
||||
topEmps(_, [], Res, Res).
|
||||
|
||||
% For each department, find the list of top employees in that department
|
||||
topDeps(N, [Dept|T], [dept(Dept,Ro)|Res]) :-
|
||||
findall(emp(Name, Id, Sal, Dept), emp(Name, Id, Sal, Dept), Emps),
|
||||
topEmps(N, Emps, [], Ro), !, topDeps(N, T, Res).
|
||||
topDeps(_, [], []).
|
||||
|
||||
% Calculate and report the list of highest salaried employees per department
|
||||
topDeps(N) :-
|
||||
departments(D), topDeps(N, D, Res),
|
||||
member(dept(Dept,R), Res),
|
||||
writef('Department: %w\n', [Dept]),
|
||||
member(emp(Name,Id,Sal,_), R),
|
||||
writef(' ID: %w\t%w\tSalary: %w\n', [Id,Name,Sal]),
|
||||
fail.
|
||||
topDeps(_).
|
||||
58
Task/Top-rank-per-group/PureBasic/top-rank-per-group.basic
Normal file
58
Task/Top-rank-per-group/PureBasic/top-rank-per-group.basic
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
Structure Employees
|
||||
Name$
|
||||
ID$
|
||||
Salary.i
|
||||
Department$
|
||||
EndStructure
|
||||
|
||||
Procedure displayTopEarners(List MyEmployees.Employees(), n)
|
||||
Protected filename$ = OpenFileRequester("Top rank per group", "DataFile.txt", "", 0)
|
||||
If ReadFile(0, filename$)
|
||||
Protected InData.Employees, txt.s, MaxNameLength
|
||||
|
||||
While Eof(0) = 0
|
||||
AddElement(MyEmployees())
|
||||
txt = ReadString(0)
|
||||
With MyEmployees()
|
||||
\Name$ = StringField(txt, 1, ",")
|
||||
\ID$ = StringField(txt, 2, ",")
|
||||
\Salary = Val(StringField(txt, 3, ","))
|
||||
\Department$ = StringField(txt, 4, ",")
|
||||
If Len(\Name$) > MaxNameLength: MaxNameLength = Len(\Name$): EndIf
|
||||
EndWith
|
||||
Wend
|
||||
CloseFile(0)
|
||||
Else
|
||||
MessageRequester("Information", "Couldn't open the file!")
|
||||
End
|
||||
EndIf
|
||||
|
||||
If OpenConsole()
|
||||
Protected OldDepartment$, count
|
||||
|
||||
SortStructuredList(MyEmployees(), #PB_Sort_Descending, OffsetOf(Employees\Salary), #PB_Sort_integer)
|
||||
SortStructuredList(MyEmployees(), #PB_Sort_Ascending, OffsetOf(Employees\Department$), #PB_Sort_String)
|
||||
ForEach MyEmployees()
|
||||
With MyEmployees()
|
||||
If \Department$ <> OldDepartment$
|
||||
If OldDepartment$ <> ""
|
||||
PrintN(#CRLF$)
|
||||
EndIf
|
||||
OldDepartment$ = \Department$
|
||||
PrintN("Department " + \Department$ + #CRLF$ + "---------------")
|
||||
PrintN(LSet("Name", MaxNameLength + 3) + LSet("ID", 7) + LSet("Salary", 7))
|
||||
count = 0
|
||||
EndIf
|
||||
count + 1
|
||||
If count <= n
|
||||
PrintN(LSet(\Name$, MaxNameLength + 1) + " " + RSet(\ID$, 7) + " $" + Str(\Salary))
|
||||
EndIf
|
||||
EndWith
|
||||
Next
|
||||
PrintN(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
|
||||
EndIf
|
||||
EndProcedure
|
||||
|
||||
NewList MyEmployees.Employees()
|
||||
|
||||
displayTopEarners(MyEmployees(), 3)
|
||||
30
Task/Top-rank-per-group/Python/top-rank-per-group-1.py
Normal file
30
Task/Top-rank-per-group/Python/top-rank-per-group-1.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
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('')
|
||||
34
Task/Top-rank-per-group/Python/top-rank-per-group-2.py
Normal file
34
Task/Top-rank-per-group/Python/top-rank-per-group-2.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
from collections import namedtuple
|
||||
from itertools import groupby
|
||||
|
||||
N = 2
|
||||
|
||||
db = '''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'''
|
||||
|
||||
rows = db.split('\n')
|
||||
DBRecord = namedtuple('DBRecord', rows[0].replace(' ', '_'))
|
||||
|
||||
records = [DBRecord(*row.split(',')) for row in rows[1:]]
|
||||
|
||||
records.sort(key=lambda record: (record.Department, -float(record.Salary)))
|
||||
|
||||
print('\n\n'.join(
|
||||
'\n '.join([dpt] + [str(g) for g in grp][:N])
|
||||
for dpt, grp in groupby(
|
||||
records,
|
||||
lambda record: record.Department
|
||||
)
|
||||
))
|
||||
15
Task/Top-rank-per-group/R/top-rank-per-group-1.r
Normal file
15
Task/Top-rank-per-group/R/top-rank-per-group-1.r
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
dfr <- read.csv(tc <- textConnection(
|
||||
"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")); close(tc)
|
||||
1
Task/Top-rank-per-group/R/top-rank-per-group-2.r
Normal file
1
Task/Top-rank-per-group/R/top-rank-per-group-2.r
Normal file
|
|
@ -0,0 +1 @@
|
|||
with(dfr, tapply(Salary, Department, max))
|
||||
13
Task/Top-rank-per-group/R/top-rank-per-group-3.r
Normal file
13
Task/Top-rank-per-group/R/top-rank-per-group-3.r
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
get.top.N.salaries <- function(N)
|
||||
{
|
||||
with(dfr, tapply(Salary, Department,
|
||||
function(x)
|
||||
{
|
||||
sort(x);
|
||||
lx <- length(x)
|
||||
if(N >= lx) return(x)
|
||||
x[-1:(N-lx)]
|
||||
}))
|
||||
}
|
||||
|
||||
get.top.N.salaries(3)
|
||||
15
Task/Top-rank-per-group/R/top-rank-per-group-4.r
Normal file
15
Task/Top-rank-per-group/R/top-rank-per-group-4.r
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
get.top.N.salaries2 <- function(N)
|
||||
{
|
||||
#Sort data frame by Department, then by Salary
|
||||
sorted <- dfr[with(dfr, order(Department, Salary, decreasing=TRUE)),]
|
||||
#Split the dataframe up, by Department
|
||||
bydept <- split(sorted, sorted$Department)
|
||||
#Return the first N values (or all of them
|
||||
lapply(bydept,
|
||||
function(x)
|
||||
{
|
||||
n <- min(N, nrow(x))
|
||||
x[1:n,]
|
||||
})
|
||||
}
|
||||
get.top.N.salaries2(3)
|
||||
4
Task/Top-rank-per-group/R/top-rank-per-group-5.r
Normal file
4
Task/Top-rank-per-group/R/top-rank-per-group-5.r
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
library(dplyr)
|
||||
dfr %>%
|
||||
group_by(Department) %>%
|
||||
top_n(2, Salary)
|
||||
37
Task/Top-rank-per-group/REXX/top-rank-per-group-1.rexx
Normal file
37
Task/Top-rank-per-group/REXX/top-rank-per-group-1.rexx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*REXX program displays the top N salaries in each department (internal table). */
|
||||
parse arg topN . /*get optional # for the top N salaries*/
|
||||
if topN=='' | topN=="," then topN= 1 /*Not specified? Then use the default.*/
|
||||
say 'Finding the top ' topN " salaries in each department."; say
|
||||
@.= /*════════ employee name ID salary dept. ═══════ */
|
||||
@.1 = "Tyler Bennett ,E10297, 32000, D101"
|
||||
@.2 = "John Rappl ,E21437, 47000, D050"
|
||||
@.3 = "George Woltman ,E00127, 53500, D101"
|
||||
@.4 = "Adam Smith ,E63535, 18000, D202"
|
||||
@.5 = "Claire Buckman ,E39876, 27800, D202"
|
||||
@.6 = "David McClellan ,E04242, 41500, D101"
|
||||
@.7 = "Rich Holcomb ,E01234, 49500, D202"
|
||||
@.8 = "Nathan Adams ,E41298, 21900, D050"
|
||||
@.9 = "Richard Potter ,E43128, 15900, D101"
|
||||
@.10 = "David Motsinger ,E27002, 19250, D202"
|
||||
@.11 = "Tim Sampair ,E03033, 27000, D101"
|
||||
@.12 = "Kim Arlich ,E10001, 57000, D190"
|
||||
@.13 = "Timothy Grove ,E16398, 29900, D190"
|
||||
depts= /*build people database from @ array.*/
|
||||
do j=1 until @.j==''; parse var @.j name.j ',' id.j "," sal.j ',' dept.j .
|
||||
if wordpos(dept.j, depts)==0 then depts= depts dept.j /*a new DEPT?*/
|
||||
end /*j*/
|
||||
employees= j-1 /*adjust for the bumped DO loop index.*/
|
||||
say 'There are ' employees "employees, " words(depts) 'departments: ' depts
|
||||
say
|
||||
do dep=1 for words(depts); say /*process each of the departments. */
|
||||
Xdept= word(depts, dep) /*current department being processed. */
|
||||
do topN; h= 0; highSal= 0 /*process the top N salaries. */
|
||||
do e=1 for employees /*process each employee in department. */
|
||||
if dept.e\==Xdept | sal.e<highSal then iterate /*is this the wrong info?*/
|
||||
highSal= sal.e; h= e /*a higher salary was just discovered. */
|
||||
end /*e*/
|
||||
if h==0 then iterate /*do we have no highest paid this time?*/
|
||||
say 'department: ' dept.h " $" || sal.h+0 id.h space(name.h)
|
||||
dept.h= /*make sure we see the employee again. */
|
||||
end /*topN*/
|
||||
end /*dep*/ /*stick a fork in it, we're all done. */
|
||||
75
Task/Top-rank-per-group/REXX/top-rank-per-group-2.rexx
Normal file
75
Task/Top-rank-per-group/REXX/top-rank-per-group-2.rexx
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/* REXX ---------------------------------------------------------------
|
||||
* 12.02.2014 Walter Pachl
|
||||
*--------------------------------------------------------------------*/
|
||||
Parse Arg topn . /* get number for top N salaries. */
|
||||
Select
|
||||
When topn='' Then /* no argument */
|
||||
topn=1 /* assume only 1. */
|
||||
When topn='?' Then /* user wants help */
|
||||
Call help
|
||||
When datatype(topn)<>'NUM' Then /* Argument is not a number */
|
||||
Call exit 'Invalid argument ('topn'). Must be a number!'
|
||||
Otherwise
|
||||
Nop
|
||||
End
|
||||
Parse Value '0 0 0 0' with en dn esal. de. deptl
|
||||
/*employee name, ID, salary, dept.*/
|
||||
Call read "Tyler Bennett,E10297,32000,D101"
|
||||
Call read "George Woltman,E00127,53500,D101"
|
||||
Call read "John Rappl,E21437,47000,D050"
|
||||
Call read "Adam Smith,E63535,18000,D202"
|
||||
Call read "Claire Buckman,E39876,27800,D202"
|
||||
Call read "David McClellan,E04242,41500,D101"
|
||||
Call read "Rich Holcomb,E01234,49500,D202"
|
||||
Call read "Nathan Adams,E41298,21900,D050"
|
||||
Call read "Richard Potter,E43128,15900,D101"
|
||||
Call read "David Motsinger,E27002,19250,D202"
|
||||
Call read "Tim Sampair,E03033,27000,D101"
|
||||
Call read "Kim Arlich,E10001,57000,D190"
|
||||
Call read "Timothy Grove,E16398,29900,D190"
|
||||
Say en 'employees,' dn "departments:" deptl
|
||||
Do e=1 To en
|
||||
d=dept.e
|
||||
Do di=1 To de.d
|
||||
If esal.d.di<sal.e Then
|
||||
Leave
|
||||
End
|
||||
Do j=de.d To di By -1
|
||||
j1=j+1
|
||||
esal.d.j1=esal.d.j
|
||||
enum.d.j1=enum.d.j
|
||||
End
|
||||
esal.d.di=sal.e
|
||||
enum.d.di=id.e
|
||||
de.d=de.d+1
|
||||
End
|
||||
/*---------------------------------------------------------------------
|
||||
* Output
|
||||
*--------------------------------------------------------------------*/
|
||||
Say ' '
|
||||
Say 'Showing top' topn 'salaries in each department.'
|
||||
Say ' '
|
||||
Do While deptl<>''
|
||||
Parse Var deptl d deptl
|
||||
Do i=1 To min(topn,de.d)
|
||||
id=enum.d.i
|
||||
Say 'department: 'd' $'esal.d.i id name.id
|
||||
End
|
||||
Say ' '
|
||||
End
|
||||
Exit
|
||||
|
||||
read:
|
||||
en=en+1
|
||||
Parse Arg name ',' id.en "," sal.en ',' dept.en
|
||||
If wordpos(dept.en,deptl)=0 Then Do
|
||||
dn=dn+1
|
||||
deptl=deptl dept.en
|
||||
End
|
||||
z=id.en
|
||||
name.z=name
|
||||
Return
|
||||
|
||||
exit: Say arg(1)
|
||||
help: Say 'Syntax: rexx topsal [topn]'
|
||||
Exit
|
||||
31
Task/Top-rank-per-group/Racket/top-rank-per-group.rkt
Normal file
31
Task/Top-rank-per-group/Racket/top-rank-per-group.rkt
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#lang racket
|
||||
|
||||
(struct employee (name id salary dept))
|
||||
(define employees
|
||||
(list (employee "Tyler Bennett" "E10297" 32000 "D101")
|
||||
(employee "John Rappl" "E21437" 47000 "D050")
|
||||
(employee "George Woltman" "E00127" 53500 "D101")
|
||||
(employee "Adam Smith" "E63535" 18000 "D202")
|
||||
(employee "Claire Buckman" "E39876" 27800 "D202")
|
||||
(employee "David McClellan" "E04242" 41500 "D101")
|
||||
(employee "Rich Holcomb" "E01234" 49500 "D202")
|
||||
(employee "Nathan Adams" "E41298" 21900 "D050")
|
||||
(employee "Richard Potter" "E43128" 15900 "D101")
|
||||
(employee "David Motsinger" "E27002" 19250 "D202")
|
||||
(employee "Tim Sampair" "E03033" 27000 "D101")
|
||||
(employee "Kim Arlich" "E10001" 57000 "D190")
|
||||
(employee "Timothy Grove" "E16398" 29900 "D190")))
|
||||
|
||||
(define (top/dept N)
|
||||
(for/list ([dept (remove-duplicates (map employee-dept employees))])
|
||||
(define people
|
||||
(filter (λ(e) (equal? dept (employee-dept e))) employees))
|
||||
(cons dept (take (sort people > #:key employee-salary) N))))
|
||||
|
||||
(for ([dept (top/dept 2)])
|
||||
(printf "Department ~a:\n" (car dept))
|
||||
(for ([e (cdr dept)])
|
||||
(printf " $~a: ~a (~a)\n"
|
||||
(employee-salary e)
|
||||
(employee-name e)
|
||||
(employee-id e))))
|
||||
29
Task/Top-rank-per-group/Raku/top-rank-per-group.raku
Normal file
29
Task/Top-rank-per-group/Raku/top-rank-per-group.raku
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
my @data = do for q:to/---/.lines -> $line {
|
||||
E10297 32000 D101 Tyler Bennett
|
||||
E21437 47000 D050 John Rappl
|
||||
E00127 53500 D101 George Woltman
|
||||
E63535 18000 D202 Adam Smith
|
||||
E39876 27800 D202 Claire Buckman
|
||||
E04242 41500 D101 David McClellan
|
||||
E01234 49500 D202 Rich Holcomb
|
||||
E41298 21900 D050 Nathan Adams
|
||||
E43128 15900 D101 Richard Potter
|
||||
E27002 19250 D202 David Motsinger
|
||||
E03033 27000 D101 Tim Sampair
|
||||
E10001 57000 D190 Kim Arlich
|
||||
E16398 29900 D190 Timothy Grove
|
||||
---
|
||||
|
||||
$%( < Id Salary Dept Name >
|
||||
Z=>
|
||||
$line.split(/ \s\s+ /)
|
||||
)
|
||||
}
|
||||
|
||||
sub MAIN(Int $N = 3) {
|
||||
for @data.classify({ .<Dept> }).sort».value {
|
||||
my @es = .sort: { -.<Salary> }
|
||||
say '' if (state $bline)++;
|
||||
say .< Dept Id Salary Name > for @es[^$N]:v;
|
||||
}
|
||||
}
|
||||
59
Task/Top-rank-per-group/Ring/top-rank-per-group.ring
Normal file
59
Task/Top-rank-per-group/Ring/top-rank-per-group.ring
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# Project : Top rank per group
|
||||
|
||||
load "stdlib.ring"
|
||||
salary = "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"
|
||||
|
||||
temp = substr(salary, ",", nl)
|
||||
temp = str2list(temp)
|
||||
depsal = newlist(13,4)
|
||||
for n = 1 to len(temp)
|
||||
n1 = ceil(n/4)
|
||||
n2 = n%4
|
||||
if n2 = 0
|
||||
n2 = 4
|
||||
ok
|
||||
depsal[n1][n2] = temp[n]
|
||||
next
|
||||
for n = 1 to len(depsal)-1
|
||||
for m = n+1 to len(depsal)
|
||||
if strcmp(depsal[m][4], depsal[n][4]) < 0
|
||||
tmp = depsal[n]
|
||||
depsal[n] = depsal[m]
|
||||
depsal[m] = tmp
|
||||
ok
|
||||
next
|
||||
next
|
||||
for n = 1 to len(depsal)-1
|
||||
for m = n+1 to len(depsal)
|
||||
if (depsal[m][4] = depsal[n][4]) and (depsal[m][3] > depsal[n][3])
|
||||
tmp = depsal[n]
|
||||
depsal[n] = depsal[m]
|
||||
depsal[m] = tmp
|
||||
ok
|
||||
next
|
||||
next
|
||||
see "Department : " + depsal[1][4] + nl
|
||||
see "Name " + "Id " + "Salary" + nl + nl
|
||||
see "" + depsal[1][1] + " " + depsal[1][2] + " " + depsal[1][3]+ nl
|
||||
for n = 1 to len(depsal)-1
|
||||
if (depsal[n+1][4] != depsal[n][4])
|
||||
see nl
|
||||
see "Department : " + depsal[n+1][4] + nl
|
||||
see "Name " + "Id " + "Salary" + nl + nl
|
||||
see "" + depsal[n+1][1] + " " + depsal[n+1][2] + " " + depsal[n+1][3]+ nl
|
||||
else
|
||||
see "" + depsal[n+1][1] + " " + depsal[n+1][2] + " " + depsal[n+1][3]+ nl
|
||||
ok
|
||||
next
|
||||
33
Task/Top-rank-per-group/Ruby/top-rank-per-group.rb
Normal file
33
Task/Top-rank-per-group/Ruby/top-rank-per-group.rb
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
require "csv"
|
||||
|
||||
data = <<EOS
|
||||
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
|
||||
EOS
|
||||
|
||||
def show_top_salaries_per_group(data, n)
|
||||
table = CSV.parse(data, :headers=>true, :header_converters=>:symbol)
|
||||
groups = table.group_by{|emp| emp[:department]}.sort
|
||||
groups.each do |dept, emps|
|
||||
puts dept
|
||||
# max by salary
|
||||
emps.max_by(n) {|emp| emp[:salary].to_i}.each do |e|
|
||||
puts " %-16s %6s %7d" % [e[:employee_name], e[:employee_id], e[:salary]]
|
||||
end
|
||||
puts
|
||||
end
|
||||
end
|
||||
|
||||
show_top_salaries_per_group(data, 3)
|
||||
39
Task/Top-rank-per-group/Run-BASIC/top-rank-per-group.basic
Normal file
39
Task/Top-rank-per-group/Run-BASIC/top-rank-per-group.basic
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
perSal$ = "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"
|
||||
|
||||
while word$(perSal$,n+1,chr$(13)) <> "" : n = n + 1 : wend ' get count of employees
|
||||
dim depSal$(n)
|
||||
for i = 1 to n
|
||||
depSal$(i) = word$(perSal$,i,chr$(13))
|
||||
next i
|
||||
sw = 1
|
||||
while sw = 1
|
||||
sw = 0
|
||||
for i = 1 to n -1
|
||||
if word$(depSal$(i),4,",")+word$(depSal$(i),3,",") > word$(depSal$(i+1),4,",")+word$(depSal$(i+1),3,",") then
|
||||
temp$ = depSal$(i)
|
||||
depSal$(i) = depSal$(i+1)
|
||||
depSal$(i+1) = temp$
|
||||
sw = 1
|
||||
end if
|
||||
next i
|
||||
wend
|
||||
print "Employee Name";chr$(9);"ID";chr$(9);"Salary"
|
||||
for i = 1 to n
|
||||
if dep$ <> word$(depSal$(i),4,",") then
|
||||
dep$ = word$(depSal$(i),4,",")
|
||||
print : print"Department:";dep$
|
||||
end if
|
||||
print word$(depSal$(i),1,",");chr$(9);word$(depSal$(i),2,",");chr$(9);word$(depSal$(i),3,",")
|
||||
next i
|
||||
93
Task/Top-rank-per-group/Rust/top-rank-per-group.rust
Normal file
93
Task/Top-rank-per-group/Rust/top-rank-per-group.rust
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#[derive(Debug)]
|
||||
struct Employee<S> {
|
||||
// Allow S to be any suitable string representation
|
||||
id: S,
|
||||
name: S,
|
||||
department: S,
|
||||
salary: u32,
|
||||
}
|
||||
|
||||
impl<S> Employee<S> {
|
||||
fn new(name: S, id: S, salary: u32, department: S) -> Self {
|
||||
Self {
|
||||
id,
|
||||
name,
|
||||
department,
|
||||
salary,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn load_data() -> Vec<Employee<&'static str>> {
|
||||
vec![
|
||||
Employee::new("Tyler Bennett", "E10297", 32000, "D101"),
|
||||
Employee::new("John Rappl", "E21437", 47000, "D050"),
|
||||
Employee::new("George Woltman", "E00127", 53500, "D101"),
|
||||
Employee::new("Adam Smith", "E63535", 18000, "D202"),
|
||||
Employee::new("Claire Buckman", "E39876", 27800, "D202"),
|
||||
Employee::new("David McClellan", "E04242", 41500, "D101"),
|
||||
Employee::new("Rich Holcomb", "E01234", 49500, "D202"),
|
||||
Employee::new("Nathan Adams", "E41298", 21900, "D050"),
|
||||
Employee::new("Richard Potter", "E43128", 15900, "D101"),
|
||||
Employee::new("David Motsinger", "E27002", 19250, "D202"),
|
||||
Employee::new("Tim Sampair", "E03033", 27000, "D101"),
|
||||
Employee::new("Kim Arlich", "E10001", 57000, "D190"),
|
||||
Employee::new("Timothy Grove", "E16398", 29900, "D190"),
|
||||
// Added to demonstrate various tie situations
|
||||
Employee::new("Kim Tie", "E16400", 57000, "D190"),
|
||||
Employee::new("Timothy Tie", "E16401", 29900, "D190"),
|
||||
Employee::new("Timothy Kim", "E16401", 19900, "D190"),
|
||||
]
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let n = {
|
||||
println!("How many top salaries to list? ");
|
||||
let mut buf = String::new();
|
||||
std::io::stdin().read_line(&mut buf)?;
|
||||
buf.trim().parse::<u32>()?
|
||||
};
|
||||
|
||||
let mut employees = load_data();
|
||||
|
||||
// Reverse order, then just pick top N employees
|
||||
employees.sort_by(|a, b| b.salary.cmp(&a.salary));
|
||||
|
||||
let sorted = employees
|
||||
.into_iter()
|
||||
.fold(std::collections::BTreeMap::new(), |mut acc, next| {
|
||||
// We store the number of unique salaries as well to handle
|
||||
// ties (and list always all employees with the same salary)
|
||||
let mut bucket = acc
|
||||
.entry(next.department)
|
||||
.or_insert_with(|| (0, Vec::<Employee<_>>::new()));
|
||||
|
||||
match bucket.1.last().map(|e| e.salary) {
|
||||
Some(last_salary) if last_salary == next.salary => {
|
||||
if bucket.0 <= n {
|
||||
bucket.1.push(next);
|
||||
}
|
||||
}
|
||||
|
||||
_ => {
|
||||
if bucket.0 < n {
|
||||
bucket.0 += 1; // Next unique salary
|
||||
bucket.1.push(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
acc
|
||||
});
|
||||
|
||||
for (department, (_, employees)) in sorted {
|
||||
println!("{}", department);
|
||||
|
||||
employees
|
||||
.iter()
|
||||
.for_each(|employee| println!(" {:?}", employee));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
6
Task/Top-rank-per-group/SMEQL/top-rank-per-group-1.smeql
Normal file
6
Task/Top-rank-per-group/SMEQL/top-rank-per-group-1.smeql
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
table: Employees
|
||||
----------------
|
||||
empID
|
||||
dept
|
||||
empName
|
||||
salary
|
||||
3
Task/Top-rank-per-group/SMEQL/top-rank-per-group-2.smeql
Normal file
3
Task/Top-rank-per-group/SMEQL/top-rank-per-group-2.smeql
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
srt = orderBy(Employees, [dept, salary], order)
|
||||
top = group(srt, [(dept) dept2, max(order) order])
|
||||
join(srt, top, a.dept=b.dept2 and b.order - a.order < 6)
|
||||
39
Task/Top-rank-per-group/SQL/top-rank-per-group-1.sql
Normal file
39
Task/Top-rank-per-group/SQL/top-rank-per-group-1.sql
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
create table EMP
|
||||
(
|
||||
EMP_ID varchar2(6 char),
|
||||
EMP_NAMEvarchar2(20 char),
|
||||
DEPT_ID varchar2(4 char),
|
||||
SALARY number(10,2)
|
||||
);
|
||||
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E21437','John Rappl','D050',47000);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E10297','Tyler Bennett','D101',32000);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E00127','George Woltman','D101',53500);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E63535','Adam Smith','D202',18000);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E39876','Claire Buckman','D202',27800);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E04242','David McClellan','D101',41500);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E41298','Nathan Adams','D050',21900);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E43128','Richard Potter','D101',15900);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E27002','David Motsinger','D202',19250);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E03033','Tim Sampair','D101',27000);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E10001','Kim Arlich','D190',57000);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E16398','Timothy Grove','D190',29900);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E01234','Rich Holcomb','D202',49500);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E16399','Timothy Grave','D190',29900);
|
||||
insert into EMP (EMP_ID, EMP_NAME, DEPT_ID, SALARY)
|
||||
values ('E16400','Timothy Grive','D190',29900);
|
||||
COMMIT;
|
||||
94
Task/Top-rank-per-group/SQL/top-rank-per-group-2.sql
Normal file
94
Task/Top-rank-per-group/SQL/top-rank-per-group-2.sql
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
select case LINE
|
||||
when 10 then
|
||||
'Tot.' || LPAD(POPULATION, 2) || ' Employees in ' || TIE_COUNT ||
|
||||
' deps.Avg salary:' || TO_CHAR(SALARY, '99990.99')
|
||||
when 30 then
|
||||
'-'
|
||||
when 50 then
|
||||
'Department: ' || DEPT_ID || ', pop: ' || POPULATION ||
|
||||
'. Avg Salary: ' || TO_CHAR(SALARY, '99990.99')
|
||||
when 70 then
|
||||
LPAD('Employee ID', 14) || LPAD('Employee name', 20) ||
|
||||
LPAD('Salary', 9) || 'Rank'
|
||||
when 90 then
|
||||
LPAD('+', 14, '-') || LPAD('+', 20, '-') || LPAD('+', 9, '-') ||
|
||||
LPAD('+', 4, '-')
|
||||
else
|
||||
LPAD(' ', 8) || LPAD(EMP_ID, 6) || LPAD(EMP_NAME, 20) ||
|
||||
TO_CHAR(SALARY, '99990.99') || LPAD(case when TIE_COUNT = 1 then ' ' else 'T' end || RANK, 4)
|
||||
end "Top rank per group"
|
||||
from (select 10 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,' ' DEPT_ID
|
||||
,avg(SALARY) SALARY
|
||||
,0 RANK
|
||||
,count(distinct DEPT_ID) TIE_COUNT
|
||||
,count(*) POPULATION
|
||||
from EMP
|
||||
union all
|
||||
select 30 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,0 SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 50 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,avg(SALARY) SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,count(*) POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 70 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,0 SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 90 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,0 SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 110 LINE
|
||||
,EMP_ID
|
||||
,EMP_NAME
|
||||
,DEPT_ID
|
||||
,SALARY
|
||||
,(select count(distinct EMP4.SALARY)
|
||||
from EMP EMP4
|
||||
where EMP4.DEPT_ID = EMP3.DEPT_ID
|
||||
and EMP4.SALARY >= EMP3.SALARY) RANK
|
||||
,(select count(*)
|
||||
from EMP EMP2
|
||||
where EMP2.DEPT_ID = EMP3.DEPT_ID
|
||||
and EMP2.SALARY = EMP3.SALARY) TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP EMP3
|
||||
where $topN >= -- Here is the meat, Correlated subquery
|
||||
(select count(distinct EMP4.SALARY)
|
||||
from EMP EMP4
|
||||
where EMP4.DEPT_ID = EMP3.DEPT_ID
|
||||
and EMP4.SALARY >= EMP3.SALARY))
|
||||
order by DEPT_ID ,LINE ,SALARY desc, EMP_ID;
|
||||
14
Task/Top-rank-per-group/SQL/top-rank-per-group-3.sql
Normal file
14
Task/Top-rank-per-group/SQL/top-rank-per-group-3.sql
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
WITH ranked_emp AS (
|
||||
SELECT emp_name
|
||||
,dept_id
|
||||
,salary
|
||||
,DENSE_RANK() OVER (PARTITION BY dept_id ORDER BY salary ) ranking
|
||||
FROM emp
|
||||
)
|
||||
SELECT dept_id
|
||||
,ranking
|
||||
,emp_name
|
||||
,salary
|
||||
FROM ranked_emp
|
||||
WHERE ranking <= 2
|
||||
ORDER BY dept_id, ranking;
|
||||
58
Task/Top-rank-per-group/Scala/top-rank-per-group-1.scala
Normal file
58
Task/Top-rank-per-group/Scala/top-rank-per-group-1.scala
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import scala.io.Source
|
||||
import scala.language.implicitConversions
|
||||
import scala.language.reflectiveCalls
|
||||
import scala.collection.immutable.TreeMap
|
||||
|
||||
object TopRank extends App {
|
||||
val topN = 3
|
||||
|
||||
val rawData = """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""".stripMargin
|
||||
|
||||
class Employee(name: String, id: String,
|
||||
val salary: Int,
|
||||
val department: String) {
|
||||
override def toString = s"$id\t$salary\t$name"
|
||||
}
|
||||
|
||||
// A TreeMap has sorted keys
|
||||
val data: TreeMap[String, Seq[TopRank.Employee]] = // TreeMap is a sorted map
|
||||
TreeMap((Source.fromString(rawData) getLines ()).toSeq // Runtime parsing
|
||||
.drop(1) // Drop header
|
||||
.map(_.split(";")) //read fields into list of employees
|
||||
.map(emp => new Employee(emp(0), emp(1), emp(2).toInt, emp(3)))
|
||||
.groupBy(_.department).toSeq: _*)
|
||||
|
||||
implicit def iterableWithAvg[T: Numeric](data: Iterable[T]) = new {
|
||||
def average[T](ts: Iterable[T])(implicit num: Numeric[T]) = {
|
||||
num.toDouble(ts.sum) / ts.size
|
||||
}
|
||||
def avg = average(data)
|
||||
}
|
||||
|
||||
val a = data.flatMap { case (_, emps) => emps.map(_.salary) }.avg
|
||||
|
||||
println(s"Reporting top $topN salaries in each department.\n")
|
||||
|
||||
println(s"Total of ${data.foldLeft(0)(_ + _._2.size)} employees in ${data.size} departments")
|
||||
|
||||
println(f"Average salary: $a%8.2f\n")
|
||||
|
||||
data.foreach {
|
||||
case (dep, emps) => println(f"Department: $dep pop: ${emps.size} avg: ${emps.map(_.salary).avg}%8.2f\n"
|
||||
+ emps.sortBy(-_.salary).take(topN)
|
||||
.map(_.toString).mkString("\t", "\n\t", ""))
|
||||
}
|
||||
}
|
||||
152
Task/Top-rank-per-group/Scala/top-rank-per-group-2.scala
Normal file
152
Task/Top-rank-per-group/Scala/top-rank-per-group-2.scala
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
import scala.slick.driver.H2Driver.simple._
|
||||
import scala.slick.lifted.ProvenShape
|
||||
|
||||
// A Employees table with 4 columns: Employee ID, Employee Name, Department, Salary
|
||||
class Emp(tag: Tag) extends Table[(String, String, String, Double)](tag, "EMP") {
|
||||
def id: Column[String] = column[String]("EMP_ID", O.PrimaryKey) // This is the primary key column
|
||||
def name: Column[String] = column[String]("EMP_NAME", O.NotNull)
|
||||
def deptId: Column[String] = column[String]("DEPT_ID", O.NotNull)
|
||||
def salary: Column[Double] = column[Double]("SALARY", O.NotNull)
|
||||
|
||||
// Every table needs a * projection with the same type as the table's type parameter
|
||||
def * : ProvenShape[(String, String, String, Double)] = (id, name, deptId, salary)
|
||||
}
|
||||
|
||||
// The main application
|
||||
object TopNrankSLICK extends App {
|
||||
|
||||
val topN = 3
|
||||
|
||||
// The query interface for the Emp table
|
||||
val employees = TableQuery[Emp]
|
||||
|
||||
// Create a connection (called a "session") to an in-memory H2 database
|
||||
Database.forURL("jdbc:h2:mem:hello", driver = "org.h2.Driver").withSession {
|
||||
implicit session =>
|
||||
|
||||
// Create the schema
|
||||
employees.ddl.create
|
||||
|
||||
// Fill the database
|
||||
val employeesInsertResult: Option[Int] = employees ++= Seq(
|
||||
("E10297", "Tyler Bennett", "D101", 32000),
|
||||
("E21437", "John Rappl", "D050", 47000),
|
||||
("E00127", "George Woltman", "D101", 53500),
|
||||
("E63535", "Adam Smith", "D202", 18000),
|
||||
("E39876", "Claire Buckman", "D202", 27800),
|
||||
("E04242", "David McClellan", "D101", 41500),
|
||||
("E01234", "Rich Holcomb", "D202", 49500),
|
||||
("E41298", "Nathan Adams", "D050", 21900),
|
||||
("E43128", "Richard Potter", "D101", 15900),
|
||||
("E27002", "David Motsinger", "D202", 19250),
|
||||
("E03033", "Tim Sampair", "D101", 27000),
|
||||
("E10001", "Kim Arlich", "D190", 57000),
|
||||
("E16398", "Timothy Grove", "D190", 29900),
|
||||
("E16399", "Timothy Grave", "D190", 29900),
|
||||
("E16400", "Timothy Grive", "D190", 29900))
|
||||
|
||||
/* Manual SQL / String Interpolation */
|
||||
// Required import for the sql interpolator
|
||||
import scala.slick.jdbc.StaticQuery.interpolation
|
||||
|
||||
// Construct a SQL statement manually with an interpolated value
|
||||
val plainQuery = // First the bun - formatting SELECT clause
|
||||
sql"""select case LINE
|
||||
when 10 then
|
||||
'Tot.' || LPAD(POPULATION, 2) || ' Employees in ' || TIE_COUNT ||
|
||||
' deps.Avg salary:' || TO_CHAR(SALARY, '99990.99')
|
||||
when 30 then
|
||||
'-'
|
||||
when 50 then
|
||||
'Department: ' || DEPT_ID || ', pop: ' || POPULATION ||
|
||||
'. Avg Salary: ' || TO_CHAR(SALARY, '99990.99')
|
||||
when 70 then
|
||||
LPAD('Employee ID', 14) || LPAD('Employee name', 20) ||
|
||||
LPAD('Salary', 9) || 'Rank'
|
||||
when 90 then
|
||||
LPAD('+', 14, '-') || LPAD('+', 20, '-') || LPAD('+', 9, '-') ||
|
||||
LPAD('+', 4, '-')
|
||||
else
|
||||
LPAD(' ', 8) || LPAD(EMP_ID, 6) || LPAD(EMP_NAME, 20) ||
|
||||
TO_CHAR(SALARY, '99990.99') || LPAD(case when TIE_COUNT = 1 then ' ' else 'T' end || RANK, 4)
|
||||
end "Top rank per group"
|
||||
from (select 10 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,' ' DEPT_ID
|
||||
,avg(SALARY) SALARY
|
||||
,0 RANK
|
||||
,count(distinct DEPT_ID) TIE_COUNT
|
||||
,count(*) POPULATION
|
||||
from EMP
|
||||
union all
|
||||
select 30 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,0 SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 50 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,avg(SALARY) SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,count(*) POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 70 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,0 SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 90 LINE
|
||||
,null EMP_ID
|
||||
,null EMP_NAME
|
||||
,DEPT_ID
|
||||
,0 SALARY
|
||||
,0 RANK
|
||||
,0 TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP
|
||||
group by DEPT_ID
|
||||
union all
|
||||
select 110 LINE
|
||||
,EMP_ID
|
||||
,EMP_NAME
|
||||
,DEPT_ID
|
||||
,SALARY
|
||||
,(select count(distinct EMP4.SALARY)
|
||||
from EMP EMP4
|
||||
where EMP4.DEPT_ID = EMP3.DEPT_ID
|
||||
and EMP4.SALARY >= EMP3.SALARY) RANK
|
||||
,(select count(*)
|
||||
from EMP EMP2
|
||||
where EMP2.DEPT_ID = EMP3.DEPT_ID
|
||||
and EMP2.SALARY = EMP3.SALARY) TIE_COUNT
|
||||
,0 POPULATION
|
||||
from EMP EMP3
|
||||
where $topN >= -- Here is the meat, Correlated subquery
|
||||
(select count(distinct EMP4.SALARY)
|
||||
from EMP EMP4
|
||||
where EMP4.DEPT_ID = EMP3.DEPT_ID
|
||||
and EMP4.SALARY >= EMP3.SALARY))
|
||||
order by DEPT_ID ,LINE ,SALARY desc, EMP_ID""".as[String]
|
||||
|
||||
// Execute the query
|
||||
plainQuery.foreach(println(_))
|
||||
} // session
|
||||
} // TopNrankSLICK
|
||||
57
Task/Top-rank-per-group/Scheme/top-rank-per-group.ss
Normal file
57
Task/Top-rank-per-group/Scheme/top-rank-per-group.ss
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
(use gauche.record)
|
||||
|
||||
;; This will let us treat a list as though it is a structure (record).
|
||||
(define-record-type (employee (pseudo-rtd <list>)) #t #t
|
||||
name id salary dept)
|
||||
|
||||
(define (get-fields str)
|
||||
(map (^x (if (#/^\d/ x) (string->number x) x))
|
||||
(string-split str #\,)))
|
||||
|
||||
(define (print-record column-widths record)
|
||||
(display " ")
|
||||
(print (string-join
|
||||
(map
|
||||
(^(x width)
|
||||
(if (number? x)
|
||||
(format "~vD" width x)
|
||||
(format "~vA" width x)))
|
||||
record
|
||||
column-widths))))
|
||||
|
||||
(define (get-column-widths records)
|
||||
(apply
|
||||
map
|
||||
(lambda column
|
||||
(apply max (map (compose string-length x->string) column)))
|
||||
records))
|
||||
|
||||
(define records
|
||||
(map get-fields
|
||||
(string-split
|
||||
"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"
|
||||
#/\s*\n\s*/)))
|
||||
|
||||
(define (top-salaries n records)
|
||||
(let ((departments (sort (delete-duplicates (map employee-dept records))))
|
||||
(col-widths (get-column-widths records))
|
||||
(sorted-by-salary (sort records > employee-salary)))
|
||||
(dolist (dept departments)
|
||||
(print dept)
|
||||
(let1 matches (filter (^x (string=? dept (employee-dept x)))
|
||||
sorted-by-salary)
|
||||
(for-each
|
||||
(pa$ print-record col-widths)
|
||||
(take* matches n))))))
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue