Python の例
PythonはVisual Studioからインストールしました。PythonのイテレーターはC#と同様なので、だいたい同じように書けました。next は next(イテレーターの式) のように書かないといけません。この書き方がバージョンによって違うようでウェブに書いてあるようにやるとうまくできません。
Python のコード
def Align0(xs, leng, z): return xs + [z] * (leng - len(xs)) def ZipWith0(z, f, xs, ys): xsx = Align0(xs, len(ys), z) ysx = Align0(ys, len(xs), z) return list(map(lambda cpl: f(cpl[0], cpl[1]), list(zip(xsx, ysx)))) def Iterate(next, init): cur = init while True: yield cur cur = next(cur) def Take(count, seq): c = count for e in seq: if c == 0: break c -= 1 yield e def CarryStep(carry_and_dec, x): carry, dec = carry_and_dec newdec = LongDecimal([(x + carry) % 10] + dec.decimals, 0) return ((x + carry) // 10, newdec) from functools import reduce class LongDecimal: def __init__(self, ns, e): self.decimals = [0] * e + ns def Decimalize(self, c, leave): carry, dec = reduce(CarryStep, self.decimals[::-1], (c, LongDecimal([], 0))) if leave and carry != 0: return dec.Sum(carry * 10) else: return dec def Shift(self, e): return LongDecimal(self.decimals, e) def Product(self, n): if isinstance(n, int): LongDecimal(list(map(lambda yd: n * yd, self.decimals)), 0) def CollectShiftMult(self, y): e = 0 for xd in self.decimals: yield y.Product(xd).Shift(e) e += 1 def Sum(self, y): if isinstance(y, int): return LongDecimal([self.decimals[0] + y] + self.decimals[1:], 0) else: return LongDecimal(ZipWith0(0, lambda a, b: a + b, self.decimals, y.decimals), 0).Decimalize(0, True) def Difference(self, y): yds = Align0(y.decimals, len(self.decimals), 0) return LongDecimal(ZipWith0(0, lambda a, b: a + b, self.decimals,list(map(lambda a: 9 - a, yds))), 0).Decimalize(1, False) def Product(self, y): if isinstance(y, int): return LongDecimal(list(map(lambda x: x * y, self.decimals)), 0) else: return reduce(lambda a, b: a.Sum(b), self.CollectShiftMult(y), LongDecimal([], 0)) def LessOrEqual(self, y): equal = all(ZipWith0(0, lambda a, b: a == b, self.decimals, y.decimals)) if equal: return False else: ne_index = (ZipWith0(0, lambda a, b: a == b, self.decimals, y.decimals)).index(False) return (ZipWith0(0, lambda a, b: a < b, self.decimals, y.decimals))[ne_index] def Print(self): res = "" count = 0 for d in self.decimals: if count == 1: res += "." res += str(d) count += 1 return res class Numbers: def __init__(self, number, square_difference, scale): self.current_digit = 0 self.number = number self.square_difference = square_difference self.scale = scale def CurrentDigit(self): return self.current_digit def GetNextDecimalDigit(self): two = LongDecimal([2], 0) self.current_digit = -1 for dd in range(9, -1, -1): if self.current_digit < 0: zd = LongDecimal([dd], self.scale) number_sq_diff = self.number.Product(zd).Product(two).Sum(zd.Product(zd)) if number_sq_diff.LessOrEqual(self.square_difference): self.number = self.number.Sum(zd) self.square_difference = self.square_difference.Difference(number_sq_diff) self.scale += 1 self.current_digit = dd return self.current_digit class NumbersGenerator: def __init__(self): self.generator = self.GenerateDecimal() def GetNextDecimalDigit(self): return next(self.generator) def GenerateDecimal(self): number = LongDecimal([], 0) square_difference = LongDecimal([3], 0) nums = Numbers(number, square_difference, 0) while True: yield nums.GetNextDecimalDigit() class NumbersServer: def __init__(self): self.current_numbers = Numbers(LongDecimal([], 0), LongDecimal([], 0), 0) self.generator_server = self.GenerateDecimalServer() def GetNumbers(self): return next(self.generator_server) def SetNumbers(self, numbers): self.current_numbers = numbers def GenerateDecimalServer(self): number = LongDecimal([], 0) square_difference = LongDecimal([3], 0) current_numbers = Numbers(number, square_difference, 0) while True: yield current_numbers class Calc: def __init__(self): self.count = 21 self.generator = NumbersGenerator() self.generator_server = NumbersServer() self.result_number = LongDecimal([], 0) def RepeatGenerator(self): for e in range(self.count): zd = LongDecimal([self.generator.GetNextDecimalDigit()], e) self.result_number = self.result_number.Sum(zd) return self.result_number.Print() def RepeatServer(self): for e in range(self.count): numbers = self.generator_server.GetNumbers() dd = numbers.GetNextDecimalDigit() self.generator_server.SetNumbers(numbers) self.result_number = self.result_number.Sum(LongDecimal([dd], e)) return self.result_number.Print() def IterateGenerator(self): dec = list(Take(self.count, self.generator.GenerateDecimal())) return LongDecimal(dec, 0).Print() def IterateServer(self): number = LongDecimal([], 0) square_difference = LongDecimal([3], 0) init_numbers = Numbers(number, square_difference, 0) init_numbers.GetNextDecimalDigit() dec = list(Take(self.count, map(lambda numbers: numbers.CurrentDigit(), Iterate(NextNumbers, init_numbers)))) return LongDecimal(dec, 0).Print() def NextNumbers(numbers): numbers.GetNextDecimalDigit() return numbers print(Calc().RepeatGenerator()) print(Calc().RepeatServer()) print(Calc().IterateGenerator()) print(Calc().IterateServer())
実行結果
1.73205080756887729352
1.73205080756887729352
1.73205080756887729352
1.73205080756887729352