Skip to content

Instantly share code, notes, and snippets.

@no1xsyzy
Created March 31, 2020 06:32
Show Gist options
  • Save no1xsyzy/088c44304d4186e0bea5704b0b8c2e66 to your computer and use it in GitHub Desktop.
Save no1xsyzy/088c44304d4186e0bea5704b0b8c2e66 to your computer and use it in GitHub Desktop.
import random
from decimal import *
from fractions import *
from typing import *
PRECISION = Decimal('0.0001')
def create_randoms(size: int = 30) -> List[int]:
return [random.randrange(1, 100) for _ in range(size)]
def decimaldiv(data: List[int]) -> Iterator[Decimal]:
s = sum(data)
for datum in data:
yield (Decimal(datum)/Decimal(s)).quantize(PRECISION, rounding=ROUND_HALF_EVEN)
def rest2last(data: List[int]) -> Iterator[Decimal]:
s = sum(data)
rest = Decimal('1.0000')
for datum in data[:-1]:
this = (Decimal(datum)/Decimal(s)).quantize(PRECISION, rounding=ROUND_HALF_EVEN)
rest -= this
yield this
yield rest
def rest2max(data: List[int]) -> Iterator[Decimal]:
s = sum(data)
result = []
for datum in data:
result.append((Decimal(datum) / Decimal(s)).quantize(PRECISION, rounding=ROUND_DOWN))
sre = sum(result)
result[max(enumerate(result), key=lambda x: x[1])[0]] += Decimal('1.0000') - sre
return iter(result)
def dipping(data: List[int]) -> Iterator[Decimal]:
s = sum(data)
rest = 0
for datum in data:
datum = datum / PRECISION + rest
div, mod = divmod(datum, s)
if random.randrange(s) < mod:
div += 1
rest = mod - s
else:
rest = mod
yield Decimal(div)*PRECISION
if __name__ == '__main__':
# data = create_randoms()
data = [1]*943
for method in (decimaldiv, rest2last, rest2max, dipping):
print(method.__name__+":")
dd = list(method(data))
print(' '.join(map(str, dd)))
print(sum(dd))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment