Task: Esthetic numbers




Go: package main

import (
    "fmt"
    "strconv"
)

func uabs(a, b uint64) uint64 {
    if a > b {
        return a - b
    }
    return b - a
}

func isEsthetic(n, b uint64) bool {
    if n == 0 {
        return false
    }
    i := n % b
    n /= b
    for n > 0 {
        j := n % b
        if uabs(i, j) != 1 {
            return false
        }
        n /= b
        i = j
    }
    return true
}

var esths []uint64

func dfs(n, m, i uint64) {
    if i >= n && i <= m {
        esths = append(esths, i)
    }
    if i == 0 || i > m {
        return
    }
    d := i % 10
    i1 := i*10 + d - 1
    i2 := i1 + 2
    if d == 0 {
        dfs(n, m, i2)
    } else if d == 9 {
        dfs(n, m, i1)
    } else {
        dfs(n, m, i1)
        dfs(n, m, i2)
    }
}

func listEsths(n, n2, m, m2 uint64, perLine int, all bool) {
    esths = esths[:0]
    for i := uint64(0); i < 10; i++ {
        dfs(n2, m2, i)
    }
    le := len(esths)
    fmt.Printf("Base 10: %s esthetic numbers between %s and %s:\n",
        commatize(uint64(le)), commatize(n), commatize(m))
    if all {
        for c, esth := range esths {
            fmt.Printf("%d ", esth)
            if (c+1)%perLine == 0 {
                fmt.Println()
            }
        }
    } else {
        for i := 0; i < perLine; i++ {
            fmt.Printf("%d ", esths[i])
        }
        fmt.Println("\n............\n")
        for i := le - perLine; i < le; i++ {
            fmt.Printf("%d ", esths[i])
        }
    }
    fmt.Println("\n")
}

func commatize(n uint64) string {
    s := fmt.Sprintf("%d", n)
    le := len(s)
    for i := le - 3; i >= 1; i -= 3 {
        s = s[0:i] + "," + s[i:]
    }
    return s
}

func main() {
    for b := uint64(2); b <= 16; b++ {
        fmt.Printf("Base %d: %dth to %dth esthetic numbers:\n", b, 4*b, 6*b)
        for n, c := uint64(1), uint64(0); c < 6*b; n++ {
            if isEsthetic(n, b) {
                c++
                if c >= 4*b {
                    fmt.Printf("%s ", strconv.FormatUint(n, int(b)))
                }
            }
        }
        fmt.Println("\n")
    }

    
    listEsths(1000, 1010, 9999, 9898, 16, true)
    listEsths(1e8, 101_010_101, 13*1e7, 123_456_789, 9, true)
    listEsths(1e11, 101_010_101_010, 13*1e10, 123_456_789_898, 7, false)
    listEsths(1e14, 101_010_101_010_101, 13*1e13, 123_456_789_898_989, 5, false)
    listEsths(1e17, 101_010_101_010_101_010, 13*1e16, 123_456_789_898_989_898, 4, false)
}


Java: import java.util.ArrayList;
import java.util.stream.IntStream;
import java.util.stream.LongStream;

public class EstheticNumbers {
    interface RecTriConsumer<A, B, C> {
        void accept(RecTriConsumer<A, B, C> f, A a, B b, C c);
    }

    private static boolean isEsthetic(long n, long b) {
        if (n == 0) {
            return false;
        }
        var i = n % b;
        var n2 = n / b;
        while (n2 > 0) {
            var j = n2 % b;
            if (Math.abs(i - j) != 1) {
                return false;
            }
            n2 /= b;
            i = j;
        }
        return true;
    }

    private static void listEsths(long n, long n2, long m, long m2, int perLine, boolean all) {
        var esths = new ArrayList<Long>();
        var dfs = new RecTriConsumer<Long, Long, Long>() {
            public void accept(Long n, Long m, Long i) {
                accept(this, n, m, i);
            }

            @Override
            public void accept(RecTriConsumer<Long, Long, Long> f, Long n, Long m, Long i) {
                if (n <= i && i <= m) {
                    esths.add(i);
                }
                if (i == 0 || i > m) {
                    return;
                }
                var d = i % 10;
                var i1 = i * 10 + d - 1;
                var i2 = i1 + 2;
                if (d == 0) {
                    f.accept(f, n, m, i2);
                } else if (d == 9) {
                    f.accept(f, n, m, i1);
                } else {
                    f.accept(f, n, m, i1);
                    f.accept(f, n, m, i2);
                }
            }
        };

        LongStream.range(0, 10).forEach(i -> dfs.accept(n2, m2, i));

        var le = esths.size();
        System.out.printf("Base 10: %d esthetic numbers between %d and %d:%n", le, n, m);
        if (all) {
            for (int i = 0; i < esths.size(); i++) {
                System.out.printf("%d ", esths.get(i));
                if ((i + 1) % perLine == 0) {
                    System.out.println();
                }
            }
        } else {
            for (int i = 0; i < perLine; i++) {
                System.out.printf("%d ", esths.get(i));
            }
            System.out.println();
            System.out.println("............");
            for (int i = le - perLine; i < le; i++) {
                System.out.printf("%d ", esths.get(i));
            }
        }
        System.out.println();
        System.out.println();
    }

    public static void main(String[] args) {
        IntStream.rangeClosed(2, 16).forEach(b -> {
            System.out.printf("Base %d: %dth to %dth esthetic numbers:%n", b, 4 * b, 6 * b);
            var n = 1L;
            var c = 0L;
            while (c < 6 * b) {
                if (isEsthetic(n, b)) {
                    c++;
                    if (c >= 4 * b) {
                        System.out.printf("%s ", Long.toString(n, b));
                    }
                }
                n++;
            }
            System.out.println();
        });
        System.out.println();

        
        listEsths(1000, 1010, 9999, 9898, 16, true);
        listEsths((long) 1e8, 101_010_101, 13 * (long) 1e7, 123_456_789, 9, true);
        listEsths((long) 1e11, 101_010_101_010L, 13 * (long) 1e10, 123_456_789_898L, 7, false);
        listEsths((long) 1e14, 101_010_101_010_101L, 13 * (long) 1e13, 123_456_789_898_989L, 5, false);
        listEsths((long) 1e17, 101_010_101_010_101_010L, 13 * (long) 1e16, 123_456_789_898_989_898L, 4, false);
    }
}