module CompanyContracts =
type employee =
| Manager of int
| Marketolog of int
| Engineer of int
| Analist of int
| Boss of employee
member private emp.Compute (manVal, marVal, engVal, anaVal, bosVal, ?growth) =
let defaultGrowth xVal rank = int ((float rank-1.0)*0.25*float xVal)
let growth = Option.fold (fun _ g -> g) defaultGrowth growth
match emp with
| Manager rank -> manVal + growth manVal rank
| Marketolog rank -> marVal + growth marVal rank
| Engineer rank -> engVal + growth engVal rank
| Analist rank -> anaVal + growth anaVal rank
| Boss emp
-> int (bosVal*float (emp.Compute (manVal, marVal, engVal, anaVal, bosVal, growth)))
member emp.Tugriki = emp.Compute (500, 400, 200, 800, 1.5)
member emp.Koffee = emp.Compute (20, 15, 5, 50, 2.0)
member emp.Pages = emp.Compute (200, 150, 50, 5, 0.0, fun _ _ -> 0)
static member (*) (n : int, emp : employee) = List.replicate n emp
let me = Manager
let ma = Marketolog
let en = Engineer
let an = Analist
type department =
| Buys of employee list
| Sales of employee list
| Marketing of employee list
| Logistics of employee list
member dept.Employees =
match dept with
| Buys emps | Sales emps | Marketing emps | Logistics emps -> emps
member dept.
Name = ((sprintf "%A" dept
).
Split [| ' ' |]).
[0].
Trim() // yolo
type company =
| Company of string * department list
member corp.Name =
match corp with Company (name, _) -> name
member corp.Departments =
match corp with Company (_, depts) -> depts
module DepartmentStats =
open CompanyContracts
let inline private compute f (dept : department) =
dept.Employees
|> List.map f
|> List.sum
let computeEmployeeCount = compute (fun emp -> 1)
let computeEmployeeTotalWage = compute (fun emp -> emp.Tugriki)
let computeEmployeeTotalKoffee = compute (fun emp -> emp.Koffee)
let computeEmployeeTotalPages = compute (fun emp -> emp.Pages)
module Bekmop =
open CompanyContracts
let buysDept = Buys <| List.concat [ 9*me 1; 3*me 2; 2*me 3; 2*ma 1; [Boss (en 2)]]
let salesDept = Sales <| List.concat [12*me 1; 6*ma 1; 3*an 1; 2*an 2; [Boss (me 2)]]
let marketingDept = Marketing <| List.concat [15*ma 1; 10*ma 2; 8*me 1; 2*en 1; [Boss (me 3)]]
let logisticsDept = Logistics <| List.concat [13*me 1; 5*me 2; 5*en 1; [Boss (me 1)]]
let departments = [buysDept; salesDept; marketingDept; logisticsDept]
let Bekmop = Company ("BEKTOP", departments)
module Manya =
open Bekmop
open DepartmentStats
[<EntryPoint>]
let manya _ =
let
puts s
= printf "%s" <| (s
: string
).
PadRight(10).
Substring(0, 10) let putx x
= puts <| x.
ToString()
List.
iter puts ["dept"; "sotr."; "tugr."; "kofe"; "str."; "tugr./str."] printfn ""
let stats =
[ computeEmployeeCount
computeEmployeeTotalWage
computeEmployeeTotalKoffee
computeEmployeeTotalPages ]
let baseStats =
Bekmop.Departments
|> List.map (fun d -> d.Name, List.map ((|>) d) stats)
let totals =
List.map snd baseStats
|> List.fold (List.map2 (+)) (List.replicate stats.Length 0)
let averages = List.map (fun total -> int <| float total / float stats.Length) totals
baseStats
|> List.iteri (fun i (dName, stats) ->
List.iter putx stats
putx (float stats.[1] / float stats.[3]) //
printfn "")
List.iter putx averages
printfn ""
List.iter putx totals
666*0*1488
bW9kdWxlIENvbXBhbnlDb250cmFjdHMgPSAKICAgIHR5cGUgZW1wbG95ZWUgPSAKICAgICAgICB8IE1hbmFnZXIgICAgb2YgaW50CiAgICAgICAgfCBNYXJrZXRvbG9nIG9mIGludAogICAgICAgIHwgRW5naW5lZXIgICBvZiBpbnQKICAgICAgICB8IEFuYWxpc3QgICAgb2YgaW50CiAgICAgICAgfCBCb3NzICAgICAgIG9mIGVtcGxveWVlCiAgICAKICAgICAgICBtZW1iZXIgcHJpdmF0ZSBlbXAuQ29tcHV0ZSAobWFuVmFsLCBtYXJWYWwsIGVuZ1ZhbCwgYW5hVmFsLCBib3NWYWwsID9ncm93dGgpID0gCiAgICAgICAgICAgIGxldCBkZWZhdWx0R3Jvd3RoIHhWYWwgcmFuayA9IGludCAoKGZsb2F0IHJhbmstMS4wKSowLjI1KmZsb2F0IHhWYWwpCiAgICAgICAgICAgIGxldCBncm93dGggPSBPcHRpb24uZm9sZCAoZnVuIF8gZyAtPiBnKSBkZWZhdWx0R3Jvd3RoIGdyb3d0aAogICAgICAgICAgICBtYXRjaCBlbXAgd2l0aAogICAgICAgICAgICB8IE1hbmFnZXIgcmFuayAgICAtPiBtYW5WYWwgKyBncm93dGggbWFuVmFsIHJhbmsKICAgICAgICAgICAgfCBNYXJrZXRvbG9nIHJhbmsgLT4gbWFyVmFsICsgZ3Jvd3RoIG1hclZhbCByYW5rCiAgICAgICAgICAgIHwgRW5naW5lZXIgcmFuayAgIC0+IGVuZ1ZhbCArIGdyb3d0aCBlbmdWYWwgcmFuawogICAgICAgICAgICB8IEFuYWxpc3QgcmFuayAgICAtPiBhbmFWYWwgKyBncm93dGggYW5hVmFsIHJhbmsgCiAgICAgICAgICAgIHwgQm9zcyBlbXAgICAgICAgIAogICAgICAgICAgICAgICAgLT4gaW50IChib3NWYWwqZmxvYXQgKGVtcC5Db21wdXRlIChtYW5WYWwsIG1hclZhbCwgZW5nVmFsLCBhbmFWYWwsIGJvc1ZhbCwgZ3Jvd3RoKSkpCgogICAgICAgIG1lbWJlciBlbXAuVHVncmlraSA9IGVtcC5Db21wdXRlICg1MDAsIDQwMCwgMjAwLCA4MDAsIDEuNSkKICAgICAgICBtZW1iZXIgZW1wLktvZmZlZSAgPSBlbXAuQ29tcHV0ZSAoMjAsICAxNSwgIDUsICAgNTAsICAyLjApCiAgICAgICAgbWVtYmVyIGVtcC5QYWdlcyAgID0gZW1wLkNvbXB1dGUgKDIwMCwgMTUwLCA1MCwgIDUsICAgMC4wLCBmdW4gXyBfIC0+IDApCgogICAgICAgIHN0YXRpYyBtZW1iZXIgKCopIChuIDogaW50LCBlbXAgOiBlbXBsb3llZSkgPSBMaXN0LnJlcGxpY2F0ZSBuIGVtcAoKICAgIGxldCBtZSA9IE1hbmFnZXIKICAgIGxldCBtYSA9IE1hcmtldG9sb2cKICAgIGxldCBlbiA9IEVuZ2luZWVyCiAgICBsZXQgYW4gPSBBbmFsaXN0CgogICAgdHlwZSBkZXBhcnRtZW50ID0gCiAgICAgICAgfCBCdXlzICAgICAgb2YgZW1wbG95ZWUgbGlzdAogICAgICAgIHwgU2FsZXMgICAgIG9mIGVtcGxveWVlIGxpc3QKICAgICAgICB8IE1hcmtldGluZyBvZiBlbXBsb3llZSBsaXN0CiAgICAgICAgfCBMb2dpc3RpY3Mgb2YgZW1wbG95ZWUgbGlzdAoKICAgICAgICBtZW1iZXIgZGVwdC5FbXBsb3llZXMgPSAKICAgICAgICAgICAgbWF0Y2ggZGVwdCB3aXRoCiAgICAgICAgICAgIHwgQnV5cyBlbXBzIHwgU2FsZXMgZW1wcyB8IE1hcmtldGluZyBlbXBzIHwgTG9naXN0aWNzIGVtcHMgLT4gZW1wcwoKICAgICAgICBtZW1iZXIgZGVwdC5OYW1lID0gKChzcHJpbnRmICIlQSIgZGVwdCkuU3BsaXQgW3wgJyAnIHxdKS5bMF0uVHJpbSgpICAgIC8vIHlvbG8KCiAgICB0eXBlIGNvbXBhbnkgPSAKICAgICAgICB8IENvbXBhbnkgb2Ygc3RyaW5nICogZGVwYXJ0bWVudCBsaXN0CgogICAgICAgIG1lbWJlciBjb3JwLk5hbWUgPSAKICAgICAgICAgICAgbWF0Y2ggY29ycCB3aXRoIENvbXBhbnkgKG5hbWUsIF8pIC0+IG5hbWUKICAgICAgICBtZW1iZXIgY29ycC5EZXBhcnRtZW50cyA9IAogICAgICAgICAgICBtYXRjaCBjb3JwIHdpdGggQ29tcGFueSAoXywgZGVwdHMpIC0+IGRlcHRzCgoKbW9kdWxlIERlcGFydG1lbnRTdGF0cyA9IAogICAgb3BlbiBDb21wYW55Q29udHJhY3RzCgogICAgbGV0IGlubGluZSBwcml2YXRlIGNvbXB1dGUgZiAoZGVwdCA6IGRlcGFydG1lbnQpID0gCiAgICAgICAgZGVwdC5FbXBsb3llZXMKICAgICAgICB8PiBMaXN0Lm1hcCBmCiAgICAgICAgfD4gTGlzdC5zdW0KICAgIAogICAgbGV0IGNvbXB1dGVFbXBsb3llZUNvdW50ICAgICAgID0gY29tcHV0ZSAoZnVuIGVtcCAtPiAxKQogICAgbGV0IGNvbXB1dGVFbXBsb3llZVRvdGFsV2FnZSAgID0gY29tcHV0ZSAoZnVuIGVtcCAtPiBlbXAuVHVncmlraSkKICAgIGxldCBjb21wdXRlRW1wbG95ZWVUb3RhbEtvZmZlZSA9IGNvbXB1dGUgKGZ1biBlbXAgLT4gZW1wLktvZmZlZSkKICAgIGxldCBjb21wdXRlRW1wbG95ZWVUb3RhbFBhZ2VzICA9IGNvbXB1dGUgKGZ1biBlbXAgLT4gZW1wLlBhZ2VzKQoKCm1vZHVsZSBCZWttb3AgPSAKICAgIG9wZW4gQ29tcGFueUNvbnRyYWN0cwoKICAgIGxldCBidXlzRGVwdCAgICAgID0gQnV5cyAgICAgIDx8IExpc3QuY29uY2F0IFsgOSptZSAxOyAgMyptZSAyOyAyKm1lIDM7IDIqbWEgMTsgW0Jvc3MgKGVuIDIpXV0KICAgIGxldCBzYWxlc0RlcHQgICAgID0gU2FsZXMgICAgIDx8IExpc3QuY29uY2F0IFsxMiptZSAxOyAgNiptYSAxOyAzKmFuIDE7IDIqYW4gMjsgW0Jvc3MgKG1lIDIpXV0gCiAgICBsZXQgbWFya2V0aW5nRGVwdCA9IE1hcmtldGluZyA8fCBMaXN0LmNvbmNhdCBbMTUqbWEgMTsgMTAqbWEgMjsgOCptZSAxOyAyKmVuIDE7IFtCb3NzIChtZSAzKV1dCiAgICBsZXQgbG9naXN0aWNzRGVwdCA9IExvZ2lzdGljcyA8fCBMaXN0LmNvbmNhdCBbMTMqbWUgMTsgIDUqbWUgMjsgNSplbiAxOyAgICAgICAgIFtCb3NzIChtZSAxKV1dCgogICAgbGV0IGRlcGFydG1lbnRzID0gW2J1eXNEZXB0OyBzYWxlc0RlcHQ7IG1hcmtldGluZ0RlcHQ7IGxvZ2lzdGljc0RlcHRdCgogICAgbGV0IEJla21vcCA9IENvbXBhbnkgKCJCRUtUT1AiLCBkZXBhcnRtZW50cykKCgptb2R1bGUgTWFueWEgPSAKICAgIG9wZW4gQmVrbW9wCiAgICBvcGVuIERlcGFydG1lbnRTdGF0cwoKICAgIFs8RW50cnlQb2ludD5dCiAgICBsZXQgbWFueWEgXyA9IAogICAgICAgIGxldCBwdXRzIHMgPSBwcmludGYgIiVzIiA8fCAocyA6IHN0cmluZykuUGFkUmlnaHQoMTApLlN1YnN0cmluZygwLCAxMCkKICAgICAgICBsZXQgcHV0eCB4ID0gcHV0cyA8fCB4LlRvU3RyaW5nKCkKCiAgICAgICAgTGlzdC5pdGVyIHB1dHMgWyJkZXB0IjsgInNvdHIuIjsgInR1Z3IuIjsgImtvZmUiOyAic3RyLiI7ICJ0dWdyLi9zdHIuIl0KICAgICAgICBwcmludGZuICIiCgogICAgICAgIGxldCBzdGF0cyA9IAogICAgICAgICAgICBbIGNvbXB1dGVFbXBsb3llZUNvdW50CiAgICAgICAgICAgICAgY29tcHV0ZUVtcGxveWVlVG90YWxXYWdlCiAgICAgICAgICAgICAgY29tcHV0ZUVtcGxveWVlVG90YWxLb2ZmZWUKICAgICAgICAgICAgICBjb21wdXRlRW1wbG95ZWVUb3RhbFBhZ2VzIF0KCiAgICAgICAgbGV0IGJhc2VTdGF0cyA9IAogICAgICAgICAgICBCZWttb3AuRGVwYXJ0bWVudHMKICAgICAgICAgICAgfD4gTGlzdC5tYXAgKGZ1biBkIC0+IGQuTmFtZSwgTGlzdC5tYXAgKCh8PikgZCkgc3RhdHMpCiAgICAgICAgbGV0IHRvdGFscyA9IAogICAgICAgICAgICBMaXN0Lm1hcCBzbmQgYmFzZVN0YXRzCiAgICAgICAgICAgIHw+IExpc3QuZm9sZCAoTGlzdC5tYXAyICgrKSkgKExpc3QucmVwbGljYXRlIHN0YXRzLkxlbmd0aCAwKQogICAgICAgIGxldCBhdmVyYWdlcyA9IExpc3QubWFwIChmdW4gdG90YWwgLT4gaW50IDx8IGZsb2F0IHRvdGFsIC8gZmxvYXQgc3RhdHMuTGVuZ3RoKSB0b3RhbHMKICAgICAgICAgCiAgICAgICAgYmFzZVN0YXRzCiAgICAgICAgfD4gTGlzdC5pdGVyaSAoZnVuIGkgKGROYW1lLCBzdGF0cykgLT4gCiAgICAgICAgICAgIHB1dHMgZE5hbWUKICAgICAgICAgICAgTGlzdC5pdGVyIHB1dHggc3RhdHMKICAgICAgICAgICAgcHV0eCAoZmxvYXQgc3RhdHMuWzFdIC8gZmxvYXQgc3RhdHMuWzNdKSAvLyAKICAgICAgICAgICAgcHJpbnRmbiAiIikKCiAgICAgICAgcHV0cyAiQXZlcmFnZXMiCiAgICAgICAgTGlzdC5pdGVyIHB1dHggYXZlcmFnZXMKICAgICAgICBwcmludGZuICIiCiAgICAgICAgcHV0cyAiVG90YWxzIgogICAgICAgIExpc3QuaXRlciBwdXR4IHRvdGFscwogICAgICAgIAogICAgICAgIDY2NiowKjE0ODg=