Created
October 7, 2016 22:30
-
-
Save mastoj/03c347f9a9a250783022a9b26d271973 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Time = int*int | |
type Day = int | |
type OpeningHour = Day*Time | |
type DayGroup = | |
{ | |
Days: int list | |
Time: Time | |
} | |
let openingHour day startTime endTime = day,(startTime,endTime) | |
let openingHours = | |
[ | |
(openingHour 0 8 18) | |
(openingHour 1 8 16) | |
(openingHour 2 8 20) | |
(openingHour 3 10 18) | |
(openingHour 4 10 18) | |
(openingHour 5 8 18) | |
(openingHour 6 8 18) | |
] | |
let connectedDays = function | |
| 0 -> [6;1] | |
| 6 -> [5;0] | |
| x -> [x-1;x+1] | |
let dayToString = function | |
| 0 -> "Man" | |
| 1 -> "Tirs" | |
| 2 -> "Ons" | |
| 3 -> "Tors" | |
| 4 -> "Fre" | |
| 5 -> "Lør" | |
| 6 -> "Søn" | |
let isConnected (day1,day2) = | |
day1 |> connectedDays |> List.contains day2 | |
let partitionGroup grp = | |
let first = grp |> List.head | |
let time = first |> snd | |
let firstDay = first |> fst | |
let rec collect currentDays acc rem = | |
let candidateDays = currentDays |> List.collect connectedDays | |
let connectedDays,rem' = rem |> List.partition (fun y -> candidateDays |> List.contains y) | |
let accDays = connectedDays @ currentDays | |
match connectedDays,rem with | |
| [],[] -> [{Days = accDays; Time = time}]::acc | |
| _,[] -> [{Days = accDays; Time = time}]::acc | |
| _,_ -> | |
collect (currentDays@connectedDays) acc rem' | |
collect [firstDay] [] (grp |> List.map fst |> List.tail) | |
let getStartAndEndDay daysUnordered = | |
let days = daysUnordered |> List.sort | |
let lastDay = days |> List.last | |
let xs = (lastDay::(days |> List.rev |> List.tail |> List.rev)) |> List.zip days | |
match xs |> List.tryFind (isConnected>>not) with | |
| None -> | |
(days |> List.min),(days |> List.max) | |
| Some (startDay, endDay) -> | |
(startDay, endDay) | |
let getDayStringForDays days = | |
let startDay, endDay = getStartAndEndDay days | |
if startDay = endDay | |
then sprintf "%s" (startDay |> dayToString) | |
else sprintf "%s-%s" (startDay |> dayToString) (endDay |> dayToString) | |
let getTimeStringForGroup (startTime,endTime) = | |
sprintf "%i:00-%i:00" startTime endTime | |
let printHours dayGroup = | |
let dayString = getDayStringForDays dayGroup.Days | |
let timeString = getTimeStringForGroup dayGroup.Time | |
printfn "%s %s" dayString timeString | |
openingHours | |
|> List.groupBy snd | |
|> List.map snd | |
|> List.map partitionGroup | |
|> List.concat | |
|> List.concat | |
|> List.iter printHours |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment