Skip to content

Instantly share code, notes, and snippets.

@mastoj
Created October 7, 2016 22:30
Show Gist options
  • Save mastoj/03c347f9a9a250783022a9b26d271973 to your computer and use it in GitHub Desktop.
Save mastoj/03c347f9a9a250783022a9b26d271973 to your computer and use it in GitHub Desktop.
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