1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
| #!/usr/bin/env stack
{- stack
--resolver ghc-7.10.3
--install-ghc
runghc
--
-rtsopts -ferror-spans
+RTS -M1024m -K8m -RTS
-}
{-
* GHC used by NCPC:
The Glorious Glasgow Haskell Compilation System version 7.10.3
* Flags required by NCPC:
-O2 -threaded -rtsopts -ferror-spans
+RTS -M{memlim}m -K8m -RTS
... but, due to warnings (ignored), some are removed:
when making flags consistent: Warning:
-O conflicts with --interactive; -O ignored.
Warning: -debug, -threaded and -ticky are ignored by GHCi
* Flags in order to make optimal code (exhaustive):
-Wall -Werror
... but if used, it would require way more code (time is mana)
-}
module Main (main) where
data Runner = Runner
{ surname :: String
, fstleg :: Double
, sndleg :: Double
}
data Runners = Runners
{ number :: Int
, athletes :: [Runner]
}
data RelayTeam = RelayTeam
{ time :: Double
, first :: Runner
, second :: Runner
, third :: Runner
, fourth :: Runner
}
instance Eq Runner where
Runner name1 fstleg1 sndleg1 == Runner name2 fstleg2 sndleg2 =
name1 == name2 && fstleg1 == fstleg2 && sndleg1 == sndleg2
Runner name1 fstleg1 sndleg1 /= Runner name2 fstleg2 sndleg2 =
name1 /= name2 || fstleg1 /= fstleg2 || sndleg1 /= sndleg2
instance Read Runner where
readsPrec _ input =
let
aux [ ] = []
aux (name:fstleg:sndleg:[]) =
[(Runner name (read fstleg) (read sndleg), "")]
aux [ _ ] = []
in
aux $ words input
instance Read Runners where
readsPrec _ input =
let
aux [ ] = []
aux (x:xs) =
let
nr = read x
in
[(Runners nr (aux' nr xs), "")]
aux' 0 [ ] = [ ]
aux' n (x:xs) = (read x) : aux' (n-1) xs
in
aux $ lines input
instance Show Runner where
show (Runner surname _ _) = surname
instance Show RelayTeam where
show (RelayTeam time first second third fourth) =
show time ++ "\n" ++
show first ++ "\n" ++
show second ++ "\n" ++
show third ++ "\n" ++
show fourth ++ "\n"
nrdec :: Double -> Int -> Double
nrdec x n =
fromIntegral (round $ x * z) / z
where z = 10 ^ n
solve :: Runners -> RelayTeam
solve (Runners _ xs) =
let
dummy = Runner "DUMMY" 9999.99 9999.99
init = (dummy,dummy,dummy,dummy)
ftime (Runner _ t _) = t
stime (Runner _ _ t) = t
bstime (a,b,c,d) (w,x,y,z) =
stime a + stime b + stime c + stime d <
stime w + stime x + stime y + stime z
bctime (a,b,c,d) (w,x,y,z) =
ftime a + stime b + stime c + stime d <
ftime w + stime x + stime y + stime z
aux (a,b,c,d) _ [ ] =
RelayTeam (nrdec (ftime a + stime b + stime c + stime d) 2) a b c d
aux acc (a,b,c,d) (y:ys) =
{- Linear time with only 8 extra memory usage -}
let
abcd =
if a == y then
(y,b,c,d)
else
if b == y then
(y,a,c,d)
else
if c == y then
(y,a,b,d)
else
(y,a,b,c)
in
if bctime abcd acc then
aux abcd (a,b,c,d) ys
else
aux acc (a,b,c,d) ys
aux' (a,b,c,d) [ ] = (a,b,c,d)
aux' (a,b,c,d) (y:ys) =
{- Linear time with only 4 extra memory usage -}
if bstime (y,b,c,d) (a,b,c,d) then
aux' (y,b,c,d) (a:ys)
else
if bstime (a,y,c,d) (a,b,c,d) then
aux' (a,y,c,d) (b:ys)
else
if bstime (a,b,y,d) (a,b,c,d) then
aux' (a,b,y,d) (c:ys)
else
if bstime (a,b,c,y) (a,b,c,d) then
aux' (a,b,c,y) (d:ys)
else
aux' (a,b,c,d) ys
in
aux init (aux' init xs) xs
readInput :: String -> Runners
readInput =
read
writeOutput :: RelayTeam -> String
writeOutput =
show
main :: IO ()
main =
interact $ writeOutput . solve . readInput
|