Task: Lychrel numbers




Go: package main

import (
	"flag"
	"fmt"
	"math"
	"math/big"
	"os"
)

var maxRev = big.NewInt(math.MaxUint64 / 10) 
var ten = big.NewInt(10)




func reverseInt(v *big.Int, result *big.Int) *big.Int {
	if v.Cmp(maxRev) <= 0 {
		
		result.SetUint64(reverseUint64(v.Uint64()))
	} else {
		if true {
			
			s := reverseString(v.String())
			result.SetString(s, 10)
		} else {
			
			
			v := new(big.Int).Set(v)
			digit := new(big.Int)
			result.SetUint64(0)
			for v.BitLen() > 0 {
				v.QuoRem(v, ten, digit)
				result.Mul(result, ten)
				result.Add(result, digit)
			}
		}
	}
	return result
}

func reverseUint64(v uint64) uint64 {
	var r uint64
	for v > 0 {
		r *= 10
		r += v % 10
		v /= 10
	}
	return r
}

func reverseString(s string) string {
	b := make([]byte, len(s))
	for i, j := 0, len(s)-1; j >= 0; i, j = i+1, j-1 {
		b[i] = s[j]
	}
	return string(b)
}

var known = make(map[string]bool)

func Lychrel(n uint64, iter uint) (isLychrel, isSeed bool) {
	v, r := new(big.Int).SetUint64(n), new(big.Int)
	reverseInt(v, r)
	seen := make(map[string]bool)
	isLychrel = true
	isSeed = true
	for i := iter; i > 0; i-- {
		str := v.String()
		if seen[str] {
			
			isLychrel = true
			break
		}
		if ans, ok := known[str]; ok {
			
			isLychrel = ans
			isSeed = false
			break
		}
		seen[str] = true

		v = v.Add(v, r)
		
		reverseInt(v, r)
		if v.Cmp(r) == 0 {
			
			isLychrel = false
			isSeed = false
			break
		}
	}
	for k := range seen {
		known[k] = isLychrel
	}
	
	return isLychrel, isSeed
}

func main() {
	max := flag.Uint64("max", 10000, "search in the range 1..`N` inclusive")
	iter := flag.Uint("iter", 500, "limit palindrome search to `N` iterations")
	flag.Parse()
	if flag.NArg() != 0 {
		flag.Usage()
		os.Exit(2)
	}

	fmt.Printf("Calculating using n = 1..%v and %v iterations:\n", *max, *iter)
	var seeds []uint64
	var related int
	var pals []uint64
	for i := uint64(1); i <= *max; i++ {
		if l, s := Lychrel(i, *iter); l {
			if s {
				seeds = append(seeds, i)
			} else {
				related++
			}
			if i == reverseUint64(i) {
				pals = append(pals, i)
			}
		}
	}

	fmt.Println("      Number of Lychrel seeds:", len(seeds))
	fmt.Println("                Lychrel seeds:", seeds)
	fmt.Println("            Number of related:", related)
	fmt.Println("Number of Lychrel palindromes:", len(pals))
	fmt.Println("          Lychrel palindromes:", pals)
}


Java: import java.math.BigInteger;
import java.util.*;

public class Lychrel {

    static Map<BigInteger, Tuple> cache = new HashMap<>();

    static class Tuple {
        final Boolean flag;
        final BigInteger bi;

        Tuple(boolean f, BigInteger b) {
            flag = f;
            bi = b;
        }
    }

    static BigInteger rev(BigInteger bi) {
        String s = new StringBuilder(bi.toString()).reverse().toString();
        return new BigInteger(s);
    }

    static Tuple lychrel(BigInteger n) {
        Tuple res;
        if ((res = cache.get(n)) != null)
            return res;

        BigInteger r = rev(n);
        res = new Tuple(true, n);
        List<BigInteger> seen = new ArrayList<>();

        for (int i = 0; i < 500; i++) {
            n = n.add(r);
            r = rev(n);

            if (n.equals(r)) {
                res = new Tuple(false, BigInteger.ZERO);
                break;
            }

            if (cache.containsKey(n)) {
                res = cache.get(n);
                break;
            }

            seen.add(n);
        }

        for (BigInteger bi : seen)
            cache.put(bi, res);

        return res;
    }

    public static void main(String[] args) {

        List<BigInteger> seeds = new ArrayList<>();
        List<BigInteger> related = new ArrayList<>();
        List<BigInteger> palin = new ArrayList<>();

        for (int i = 1; i <= 10_000; i++) {
            BigInteger n = BigInteger.valueOf(i);

            Tuple t = lychrel(n);

            if (!t.flag)
                continue;

            if (n.equals(t.bi))
                seeds.add(t.bi);
            else
                related.add(t.bi);

            if (n.equals(t.bi))
                palin.add(t.bi);
        }

        System.out.printf("%d Lychrel seeds: %s%n", seeds.size(), seeds);
        System.out.printf("%d Lychrel related%n", related.size());
        System.out.printf("%d Lychrel palindromes: %s%n", palin.size(), palin);
    }
}