Go の例(1)
Go ではクロージャーで実装しました。イテレーターを表すもの(構造体)などを型ごとに複数作っているので長くなります。Goはこのようなプログラムには向いていないようです。xyz は構造体の自分自身を表す名前なのですが self などは使えないようで何が良いのかわからないので xyz になっています。
package main import ( "fmt" "strconv" ) type IteratorSimpleImpl_int struct { next func() bool getCurrent func() int setCurrent func(int) } func newIteratorSimpleImpl_int(next func() bool, getCurrent func() int, setCurrent func(int)) *IteratorSimpleImpl_int { xyz := new(IteratorSimpleImpl_int) xyz.next = next xyz.getCurrent = getCurrent xyz.setCurrent = setCurrent return xyz } func (xyz *IteratorSimpleImpl_int) GetCurrent() int { return xyz.getCurrent() } func (xyz *IteratorSimpleImpl_int) SetCurrent(value int) { xyz.setCurrent(value) } func (xyz *IteratorSimpleImpl_int) MoveNext() bool { return xyz.next() } func (xyz *IteratorSimpleImpl_int) Take(count int) []int { res := make([]int, count) iter := xyz for i := 0; i < count && iter.MoveNext(); i++ { res[i] = iter.getCurrent() } return res } type IteratorSimpleImpl_Numbers struct { next func() bool getCurrent func() *Numbers setCurrent func(*Numbers) } func newIteratorSimpleImpl_Numbers(next func() bool, getCurrent func() *Numbers, setCurrent func(*Numbers)) *IteratorSimpleImpl_Numbers { xyz := new(IteratorSimpleImpl_Numbers) xyz.next = next xyz.getCurrent = getCurrent xyz.setCurrent = setCurrent return xyz } func (xyz *IteratorSimpleImpl_Numbers) GetCurrent() *Numbers { return xyz.getCurrent() } func (xyz *IteratorSimpleImpl_Numbers) SetCurrent(value *Numbers) { xyz.setCurrent(value) } func (xyz *IteratorSimpleImpl_Numbers) MoveNext() bool { return xyz.next() } func (xyz *IteratorSimpleImpl_Numbers) Take(count int) []*Numbers { res := make([]*Numbers, count) iter := xyz for i := 0; i < count && iter.MoveNext(); i++ { res[i] = iter.getCurrent() } return res } func Max(x int, y int) int { if x > y { return x } else { return y } } func Align0(xs []int, leng int, z int) []int { m := Max(len(xs), leng) res := make([]int, m) for i := 0; i < m; i++ { if i < len(xs) { res[i] = xs[i] } else { res[i] = z } } return res } func ZipWith0_int(z int, f func(int, int) int, xs []int, ys []int) []int { xsx := Align0(xs, len(ys), z) ysx := Align0(ys, len(xs), z) res := make([]int, len(xsx)) for i := 0; i < len(xsx); i++ { res[i] = f(xsx[i], ysx[i]) } return res } func ZipWith0_bool(z int, f func(int, int) bool, xs []int, ys []int) []bool { xsx := Align0(xs, len(ys), z) ysx := Align0(ys, len(xs), z) res := make([]bool, len(xsx)) for i := 0; i < len(xsx); i++ { res[i] = f(xsx[i], ysx[i]) } return res } func ZipWith0_EqualAndLess(z int, f func(int, int) EqualAndLess, xs []int, ys []int) []EqualAndLess { xsx := Align0(xs, len(ys), z) ysx := Align0(ys, len(xs), z) res := make([]EqualAndLess, len(xsx)) for i := 0; i < len(xsx); i++ { res[i] = f(xsx[i], ysx[i]) } return res } func Iterate_Numbers(step func(*Numbers) *Numbers, init *Numbers) *IteratorSimpleImpl_Numbers { cur := init next := func() bool { cur = step(cur) return true } getCurrent := func() *Numbers { return cur } setCurrent := func(val *Numbers) { } return newIteratorSimpleImpl_Numbers(next, getCurrent, setCurrent) } func ShiftR0(ds []int, e int) []int { nds := make([]int, e) nds = append(nds, ds...) return nds } func FoldL0(f func(*LongDecimal, *LongDecimal) *LongDecimal, ds []*LongDecimal, z *LongDecimal) *LongDecimal { res := z for _, d := range ds { res = f(res, d) } return res } func FoldR0(f func(CarryAndDec, int) CarryAndDec, ds []int, z CarryAndDec) CarryAndDec { res := z for i := len(ds) - 1; i >= 0; i-- { res = f(res, ds[i]) } return res } func Map_int_int(f func(int) int, xs []int) []int { res := make([]int, len(xs)) for i, x := range xs { res[i] = f(x) } return res } func Map_Numbers_int(f func(*Numbers) int, xs *IteratorSimpleImpl_Numbers) *IteratorSimpleImpl_int { cur := xs next := func() bool { return cur.next() } getCurrent := func() int { return f(cur.getCurrent()) } setCurrent := func(val int) { } return newIteratorSimpleImpl_int(next, getCurrent, setCurrent) } func Find_EqualAndLess(f func(EqualAndLess) bool, xs []EqualAndLess) EqualAndLess { for _, x := range xs { if f(x) { return x } } return EqualAndLess{false, false} } func All(xs []bool) bool { for _, x := range xs { if !x { return false } } return true } type CarryAndDec struct { carry int dec *LongDecimal } type EqualAndLess struct { equal bool less bool } func Concat(xs []int, ys []int) []int { res := xs res = append(res, ys...) return res } func CarryStep(carry_and_dec CarryAndDec, x int) CarryAndDec { carry := carry_and_dec.carry dec := carry_and_dec.dec newdec := newLongDecimal(Concat([]int{(x + carry) % 10}, dec.decimals)) return CarryAndDec{(x + carry) / 10, newdec} } type LongDecimal struct { decimals []int } func newLongDecimal(ds []int) *LongDecimal { xyz := new(LongDecimal) xyz.decimals = ds return xyz } func (xyz *LongDecimal) Decimalize(c int, leave bool) *LongDecimal { carry_and_dec := FoldR0(CarryStep, xyz.decimals, CarryAndDec{c, newLongDecimal([]int{})}) carry := carry_and_dec.carry dec := carry_and_dec.dec if leave && carry != 0 { return dec.Sum1(carry * 10) } else { return dec } } func (xyz *LongDecimal) Shift(e int) *LongDecimal { return newLongDecimal(ShiftR0(xyz.decimals, e)) } func (xyz *LongDecimal) CollectShiftMult(y *LongDecimal) []*LongDecimal { lds := make([]*LongDecimal, len(xyz.decimals)) for e, xd := range xyz.decimals { lds[e] = y.Product1(xd).Shift(e) } return lds } func (xyz *LongDecimal) Sum1(y int) *LongDecimal { ds := Concat([]int{xyz.decimals[0] + y}, xyz.decimals[1:]) return newLongDecimal(ds) } func (xyz *LongDecimal) Sum(y *LongDecimal) *LongDecimal { return newLongDecimal(ZipWith0_int(0, func(a, b int) int { return a + b }, xyz.decimals, y.decimals)).Decimalize(0, true) } func (xyz *LongDecimal) Difference(y *LongDecimal) *LongDecimal { yds := Align0(y.decimals, len(xyz.decimals), 0) return newLongDecimal(ZipWith0_int(0, func(a, b int) int { return a + b }, xyz.decimals, Map_int_int(func(a int) int { return 9 - a }, yds))).Decimalize(1, false) } func (xyz *LongDecimal) Product1(y int) *LongDecimal { return newLongDecimal(Map_int_int(func(x int) int { return x * y }, xyz.decimals)) } func (xyz *LongDecimal) Product(y *LongDecimal) *LongDecimal { return FoldL0(func(a, b *LongDecimal) *LongDecimal { return a.Sum(b) }, xyz.CollectShiftMult(y), newLongDecimal([]int{})) } func (xyz *LongDecimal) LessOrEqual(y *LongDecimal) bool { equal := All(ZipWith0_bool(0, func(a, b int) bool { return a == b }, xyz.decimals, y.decimals)) if equal { return false } else { get_eq_and_lt := func(a, b int) EqualAndLess { return EqualAndLess{a == b, a < b} } get_not_eq := func(equal_and_less EqualAndLess) bool { return !equal_and_less.equal } equal_and_less := Find_EqualAndLess(get_not_eq, ZipWith0_EqualAndLess(0, get_eq_and_lt, xyz.decimals, y.decimals)) return equal_and_less.less } } func (xyz *LongDecimal) Print() string { res := "" for count, dd := range xyz.decimals { if count == 1 { res += "." } res += strconv.Itoa(dd) } return res } type Numbers struct { current_digit int number *LongDecimal square_difference *LongDecimal scale int } func newNumbers(number *LongDecimal, square_difference *LongDecimal, scale int) *Numbers { xyz := new(Numbers) xyz.current_digit = 0 xyz.number = number xyz.square_difference = square_difference xyz.scale = scale return xyz } func (xyz *Numbers) CurrentDigit() int { return xyz.current_digit } func (xyz *Numbers) GetNextDecimalDigit() int { two := newLongDecimal([]int{2}) for dd := 9; dd >= 0; dd-- { zd := newLongDecimal([]int{dd}).Shift(xyz.scale) number_sq_diff := xyz.number.Product(zd).Product(two).Sum(zd.Product(zd)) if number_sq_diff.LessOrEqual(xyz.square_difference) { xyz.number = xyz.number.Sum(zd) xyz.square_difference = xyz.square_difference.Difference(number_sq_diff) xyz.scale++ xyz.current_digit = dd return dd } } return 0 } type NumbersGenerator struct { generator *IteratorSimpleImpl_int } func newNumbersGenerator() *NumbersGenerator { xyz := new(NumbersGenerator) xyz.generator = xyz.GenerateDecimal() return xyz } func (xyz *NumbersGenerator) GetNextDecimalDigit() int { xyz.generator.MoveNext() return xyz.generator.GetCurrent() } func (xyz *NumbersGenerator) GenerateDecimal() *IteratorSimpleImpl_int { number := newLongDecimal([]int{}) square_difference := newLongDecimal([]int{3}) nums := newNumbers(number, square_difference, 0) current_digit := 0 next := func() bool { current_digit = nums.GetNextDecimalDigit() return true } getCurrent := func() int { return current_digit } setCurrent := func(val int) { } return newIteratorSimpleImpl_int(next, getCurrent, setCurrent) } type NumbersServer struct { current_numbers *Numbers generator_server *IteratorSimpleImpl_Numbers } func newNumbersServer() *NumbersServer { xyz := new(NumbersServer) xyz.current_numbers = newNumbers(newLongDecimal([]int{}), newLongDecimal([]int{}), 0) xyz.generator_server = xyz.GenerateDecimalServer() return xyz } func (xyz *NumbersServer) GetNumbers() *Numbers { xyz.generator_server.MoveNext() return xyz.generator_server.GetCurrent() } func (xyz *NumbersServer) SetNumbers(numbers *Numbers) { xyz.generator_server.SetCurrent(numbers) } func (xyz *NumbersServer) GenerateDecimalServer() *IteratorSimpleImpl_Numbers { number := newLongDecimal([]int{}) square_difference := newLongDecimal([]int{3}) current_numbers := newNumbers(number, square_difference, 0) next := func() bool { return true } getCurrent := func() *Numbers { return current_numbers } setCurrent := func(val *Numbers) { current_numbers = val } return newIteratorSimpleImpl_Numbers(next, getCurrent, setCurrent) } type Calc struct { count int generator *NumbersGenerator generator_server *NumbersServer result_number *LongDecimal } func newCalc() *Calc { xyz := new(Calc) xyz.count = 21 xyz.generator = newNumbersGenerator() xyz.generator_server = newNumbersServer() xyz.result_number = newLongDecimal([]int{}) return xyz } func (xyz *Calc) RepeatGenerator() string { for e := 0; e < xyz.count; e++ { zd := newLongDecimal([]int{xyz.generator.GetNextDecimalDigit()}).Shift(e) xyz.result_number = xyz.result_number.Sum(zd) } return xyz.result_number.Print() } func (xyz *Calc) RepeatServer() string { for e := 0; e < xyz.count; e++ { numbers := xyz.generator_server.GetNumbers() dd := numbers.GetNextDecimalDigit() xyz.generator_server.SetNumbers(numbers) xyz.result_number = xyz.result_number.Sum(newLongDecimal([]int{dd}).Shift(e)) } return xyz.result_number.Print() } func (xyz *Calc) IterateGenerator() string { dec := xyz.generator.GenerateDecimal().Take(xyz.count) return newLongDecimal(dec).Print() } func (xyz *Calc) IterateServer() string { number := newLongDecimal([]int{}) square_difference := newLongDecimal([]int{3}) init_numbers := newNumbers(number, square_difference, 0) dec := Map_Numbers_int(GetCurrentDigit, Iterate_Numbers(NextNumbers, init_numbers)).Take(xyz.count) return newLongDecimal(dec).Print() } func NextNumbers(numbers *Numbers) *Numbers { numbers.GetNextDecimalDigit() return numbers } func GetCurrentDigit(numbers *Numbers) int { return numbers.CurrentDigit() } func main() { fmt.Printf("%s\n", newCalc().RepeatGenerator()) fmt.Printf("%s\n", newCalc().RepeatServer()) fmt.Printf("%s\n", newCalc().IterateGenerator()) fmt.Printf("%s\n", newCalc().IterateServer()) }