Skip to content

Instantly share code, notes, and snippets.

@mml
Created August 4, 2009 00:46
Show Gist options
  • Save mml/160954 to your computer and use it in GitHub Desktop.
Save mml/160954 to your computer and use it in GitHub Desktop.
starts = [
1248637121,
1248818005,
1248819043,
1248819661,
1248820029,
1248862668,
1248976328,
1248989370,
1249036736,
]
stops = [
1248817256,
1248817974,
1248819674,
1248819680,
1248819813,
1248819936,
1248819977,
1248820035,
1248820188,
1248873042,
1248978031,
1248992420,
1249036746,
]
def count_times(starts, stops)
stops_with_a_safety = stops + [Time.new.to_i]
get_next(starts.map(&:-@), stops_with_a_safety).reduce &:+
end
def get_next(foos, bars)
if bars.empty?
[foos[0]]
else
befores, afters = foos.span {|foo| foo.abs < bars[0].abs}
[befores[0]] + get_next(bars, afters)
end
end
class Array
# In practice, we could probably take this from
# http://rubyforge.org/projects/prelude
def span
befores = []
i = 0
while i < self.size
if yield self[i]
befores.push self[i]
else
return befores, self[i..-1]
end
i += 1
end
return befores, []
end
end
if __FILE__ == $0
puts 'with stopper'
seconds = count_times(starts, stops)
puts "#{seconds.to_f/60/60} hours"
puts 'without stopper'
stops.pop
seconds = count_times(starts, stops)
puts "#{seconds.to_f/60/60} hours"
end
starts = [
1248637121,
1248818005,
1248819043,
1248819661,
1248820029,
1248862668,
1248976328,
1248989370,
1249036736,
]
stops = [
1248817256,
1248817974,
1248819674,
1248819680,
1248819813,
1248819936,
1248819977,
1248820035,
1248820188,
1248873042,
1248978031,
1248992420,
1249036746,
]
def count_times(starts, stops)
stops_with_a_safety = stops + [Time.new.to_i]
timeclock_pairs = get_next(starts, stops_with_a_safety)
pairwise_differences(timeclock_pairs).reduce &:+
end
def pairwise_differences(l)
diffs = []
l.each_slice(2) do |pair|
diffs.push(pair[1] - pair[0])
end
diffs
end
def get_next(foos, bars)
if bars.empty?
[foos[0]]
else
befores, afters = foos.span {|foo| foo < bars[0]}
[befores[0]] + get_next(bars, afters)
end
end
class Array
# In practice, we could probably take this from
# http://rubyforge.org/projects/prelude
def span
befores = []
i = 0
while i < self.size
if yield self[i]
befores.push self[i]
else
return befores, self[i..-1]
end
i += 1
end
return befores, []
end
end
if __FILE__ == $0
puts 'with stopper'
seconds = count_times(starts, stops)
puts "#{seconds.to_f/60/60} hours"
puts 'without stopper'
stops.pop
seconds = count_times(starts, stops)
puts "#{seconds.to_f/60/60} hours"
end
from time import time
starts = [
1248637121,
1248818005,
1248819043,
1248819661,
1248820029,
1248862668,
1248976328,
1248989370,
1249036736,
]
stops = [
1248817256,
1248817974,
1248819674,
1248819680,
1248819813,
1248819936,
1248819977,
1248820035,
1248820188,
1248873042,
1248978031,
1248992420,
1249036746,
]
def zip_to_type(starts, stops):
tuples = []
for start in starts:
tuples.append(('start', start))
for stop in stops:
tuples.append(('stop', stop))
tuples.sort(lambda x, y: cmp(x[1],y[1]))
return tuples
def flush_spurious(tuples):
good = []
last_seen = None
for flag, timestamp in tuples:
if not last_seen and flag == 'stop': # keep going until we hit a start
continue
if flag == last_seen: # Already saw one of these, skip it
continue
good.append((flag, timestamp))
last_seen = flag
if good[-1][0] != 'stop': # if the last thing is a start, end it with now
good.append(('stop', time()))
return good
def totaller(tuples):
total = 0
for i in range(len(tuples))[::2]: # take even indices of tuples
start = tuples[i][1]
stop = tuples[i+1][1]
total += (stop - start)
return total
def count_times(starts, stops):
return totaller(flush_spurious(zip_to_type(starts, stops)))
if __name__ == '__main__':
print "with stopper"
seconds = count_times(starts, stops)
print float(seconds)/(60*60), 'hours'
print "without stopper"
stops.pop()
seconds = count_times(starts, stops)
print float(seconds)/(60*60), 'hours'
starts = [
1248637121,
1248818005,
1248819043,
1248819661,
1248820029,
1248862668,
1248976328,
1248989370,
1249036736,
]
stops = [
1248817256,
1248817974,
1248819674,
1248819680,
1248819813,
1248819936,
1248819977,
1248820035,
1248820188,
1248873042,
1248978031,
1248992420,
1249036746,
]
def count_times(starts, stops)
timeclock_pairs = get_next_start(starts, stops)
pairwise_differences(timeclock_pairs).reduce &:+
end
def pairwise_differences(l)
diffs = []
l.each_slice(2) do |pair|
diffs.push(pair[1] - pair[0])
end
diffs
end
def get_next_start(starts, stops)
if stops.empty?
[starts[0], Time.new.to_i]
else
befores, afters = starts.span {|start| start < stops[0]}
[befores[0]] + get_next_stop(afters, stops)
end
end
def get_next_stop(starts, stops)
if starts.empty?
[stops.first]
else
befores, afters = stops.span {|stop| stop < starts[0]}
[befores.first] + get_next_start(starts, afters)
end
end
class Array
# In practice, we could probably take this from
# http://rubyforge.org/projects/prelude
def span
befores = []
i = 0
while i < self.size
if yield self[i]
befores.push self[i]
else
return befores, self[i..-1]
end
i += 1
end
return befores, []
end
end
if __FILE__ == $0
puts 'with stopper'
seconds = count_times(starts, stops)
puts "#{seconds.to_f/60/60} hours"
puts 'without stopper'
stops.pop
seconds = count_times(starts, stops)
puts "#{seconds.to_f/60/60} hours"
end
test:
python fiddle.py
ruby fiddle.rb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment