Skip to content

Instantly share code, notes, and snippets.

@miketwo
Last active May 9, 2022 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miketwo/2e24627dd6023178dc6596b4a47d9cce to your computer and use it in GitHub Desktop.
Save miketwo/2e24627dd6023178dc6596b4a47d9cce to your computer and use it in GitHub Desktop.
Streaming pairwise implementation
import random
import time
def counts_to_pairs(counts, target):
pairs, incomplete = {}, {}
for a in range(int(target/2)+1):
b = target-a
matching_pair = counts.get(a,0) >= 1 and counts.get(b, 0) >= 1
if matching_pair:
if a == b:
# special case for midpoint
pairs[(a,b)] = int(counts[a]/2)
incomplete[a] = counts[a]%2
else:
pairs[(a,b)] = min(counts[a], counts[b])
incomplete[a] = max(counts[a] - counts[b], 0)
incomplete[b] = max(counts[b] - counts[a], 0)
else:
incomplete[a] = counts.get(a,0)
incomplete[b] = counts.get(b,0)
return pairs, incomplete
class Pairwise():
def __init__(self, target) -> None:
self.counts = {}
self.target = target
self.start = time.time()
def next_num(self, number):
if number not in self.counts:
self.counts[number] = 0
self.counts[number] += 1
def short_stats(self):
pairs, incomplete = counts_to_pairs(self.counts, self.target)
total_pairs = sum(pairs.values())
return f"Number of pairs: {total_pairs}"
def print_results(self):
pairs, incomplete = counts_to_pairs(self.counts, self.target)
self.end = time.time()
print("Unmatched:")
for k in sorted(incomplete):
if incomplete[k]>0:
print(f" {k}: {incomplete[k]}")
print("Complete Pairs:")
for k in sorted(pairs):
if pairs[k]>0:
print(f" {k}: {pairs[k]}")
print()
print(f"Executed in {self.end - self.start} seconds")
print("===")
def progress_meter(count, total, additional_string_fn=lambda:""):
width = 60
resolution = int(total/(width*4))
if count%resolution !=0:
return
charlen = int(count*width/total)
sequence = "-\\|/"
s = int(count/resolution)%4
percent = (count/total) * 100
print('\r', "|", "-"*charlen, sequence[s], "."*(width-charlen-1), "|", f"{percent:.2f}% {additional_string_fn()}", end="", flush=True)
def main():
# Example that was given
numbers = [1,12,4,6,8,5,7,12,11,6,7,5,0,6,6]
p1 = Pairwise(target=12)
for number in numbers:
p1.next_num(number)
p1.print_results()
# Many random numbers
p2 = Pairwise(target=12)
total = 10000000
print(f"Running {total} numbers")
for count in range(total):
progress_meter(count, total, p2.short_stats)
number = random.randint(0,12)
p2.next_num(number)
print()
p2.print_results()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment