Uptime is a very important metric, as we all know, so we'd like to measure the uptime since our service was first launched. The SLA specifies an uptime of a certain number of nines, such as 3 nines for at least 99.9%
uptime, or 1 nine for at least 90%
uptime, and you're wondering if you've actually met the SLA or not. Since you know the service went down last friday night when someone pushed to production, and since this is basically standard practice here, you figure there's no need for your code to handle 100% uptime as a special case.
Everytime a server stops or starts, Nagios sends you an email. The service in question has some level of fault tolerance, so only m
servers have to be online for the service to be available. You just wrote a quick script to extract the important information from these emails. Now it's time for the fun part, and you're in the mood for golfing.
Your task is to write a program or function that analyzes the input, figures out the uptime, and prints the largest integer number of nines achieved by the service.
Input:
The number of servers required to be running for the service to be considered online:
m
> 0.Followed by at least one line, one for each server. Each line contains start/stop times for that server. Since we've measured this since the service was launched, the first number is the time the server started the first time. The second time is a stop time, the third another start time etc.
No single server is ever started and stopped at the same time.
This means that if the server is currently running, you haven't gotten an email about it shutting down yet, so the number of numbers on that line would be odd.
The lines are sorted, but the ordering between different lines is not enforced.
The input is EOF-terminated. The last character of the input will be
\n
followed byEOF
(ctrl+D).The time starts at time
0
and ends at the last recorded start/stop of a single server, since that's all the information we have so far. This can be done by adding max(last number on each line) to the end of all odd-length lines.Time is discrete.
All input numbers are guaranteed to fit inside a 32bit integer.
The service will never have 100% uptime.
If you would like to add an integer telling you how many servers there are, you may do so. You may also add an integer in the beginning of each server line telling you how many measurements there are for that server. See example in first testcase. You may also use whatever native format you'd like.
Output:
The output consists of a single integer; the highest number of nines that you can guarantee you had in hindsight, i.e. 3
for at least 99.9%
uptime or 4
for at least 99.99%
uptime.
Testcases:
First:
1
0 5 8 10
0 1 7
-> 1
First, with counts (if you prefer that):
1 2
4 0 5 8 10
3 0 1 7
-> 1
Second:
1
0 999 1001 2000
-> 3
Third:
3
0 42
-> 0
Reference implementation: (Python 2)
"""
Slow and huge, but useful for checking smaller inputs.
input: m, followed by n lines of start and stop times, all servers are turned off in the beginning, all numbers fit inside 32bit signed integers, counts are optional
output: number of nines of uptime
example:
1
0 5 8 9
0 1 7
parsed:
1st node: on 0:5, 7:9
2nd node: on 0:1, 6:9
at least one server is running during:
0:5, 7:9
known time interval: 0:9, only timestep 6 is down, so 90% uptime during the part we can see.
output:
1
"""
import sys
def rangeify(l):
res = []
for i in range(0, len(l), 2):
res += range(l[i], l[i + 1] + 1)
return res
def parse():
m = input()
lines = [map(int, x.split()) for x in sys.stdin.read().split("\n")[:-1]]
if not lines:
return [], m
top = max(map(max, lines))
nlines = [x + [top] if len(x) % 2 else x for x in lines]
n2lines = map(rangeify, nlines)
return n2lines, m
def flatten(ls):
res = []
for l in ls:
res += l
return sorted(res)
def join(ups):
res = {}
for up in ups:
if up not in res:
res[up] = 0
res[up] += 1
return res
def bin(ups, m):
res = []
for up in range(max(ups)+1):
res += [up in ups and ups[up] >= m]
return res
def nines(a):
s = ("%.15f" % a)[2:]
s2 = s.lstrip("9")
return len(s) - len(s2)
def solve(l, m):
if len(l) < m:
return nines(0)
b = bin(join(flatten(l)), m)
return nines(sum(b) / float(len(b)))
print solve(*parse())
EOF
is not an actual byte in a stream - it's a signal from the I/O library back to the code to inform you that the end of file has been reached. 2) This challenge would be a lot better if you were more flexible with the input format (allowing lists/arrays and such instead of requiring string parsing, which detracts from the actual challenge). You should post challenges in the Sandbox to get feedback before posting on Main. \$\endgroup\$12:00
you of course assume that this is12:00:59
, as that might actually have been the case. \$\endgroup\$