Task: List rooted trees




Go: package main

import (
    "fmt"
    "log"
    "os"
    "strconv"
)

type tree uint64

var (
    list   []tree
    offset = [32]uint{1: 1}
)

func add(t tree) {
    list = append(list, 1|t<<1)
}

func show(t tree, l uint) {
    for ; l > 0; t >>= 1 {
        l--
        var paren byte
        if (t & 1) != 0 {
            paren = '('
        } else {
            paren = ')'
        }
        fmt.Printf("%c", paren)
    }
}

func listTrees(n uint) {
    for i := offset[n]; i < offset[n+1]; i++ {
        show(list[i], n*2)
        fmt.Println()
    }
}



func assemble(n uint, t tree, sl, pos, rem uint) {
    if rem == 0 {
        add(t)
        return
    }

    if sl > rem { 
        sl = rem
        pos = offset[sl]
    } else if pos >= offset[sl+1] {
        
        sl--
        if sl == 0 {
            return
        }
        pos = offset[sl]
    }

    assemble(n, t<<(2*sl)|list[pos], sl, pos, rem-sl)
    assemble(n, t, sl, pos+1, rem)
}

func mktrees(n uint) {
    if offset[n+1] > 0 {
        return
    }
    if n > 0 {
        mktrees(n - 1)
    }

    assemble(n, 0, n-1, offset[n-1], n-1)
    offset[n+1] = uint(len(list))
}

func main() {
    if len(os.Args) != 2 {
        log.Fatal("There must be exactly 1 command line argument")
    }
    n, err := strconv.Atoi(os.Args[1])
    if err != nil {
        log.Fatal("Argument is not a valid number")
    }
    if n <= 0 || n > 19 { 
        n = 5
    }
    
    add(0)

    mktrees(uint(n))
    fmt.Fprintf(os.Stderr, "Number of %d-trees: %d\n", n, offset[n+1]-offset[n])
    listTrees(uint(n))
}


Java: import java.util.ArrayList;
import java.util.List;

public class ListRootedTrees {
    private static final List<Long> TREE_LIST = new ArrayList<>();

    private static final List<Integer> OFFSET = new ArrayList<>();

    static {
        for (int i = 0; i < 32; i++) {
            if (i == 1) {
                OFFSET.add(1);
            } else {
                OFFSET.add(0);
            }
        }
    }

    private static void append(long t) {
        TREE_LIST.add(1 | (t << 1));
    }

    private static void show(long t, int l) {
        while (l-- > 0) {
            if (t % 2 == 1) {
                System.out.print('(');
            } else {
                System.out.print(')');
            }
            t = t >> 1;
        }
    }

    private static void listTrees(int n) {
        for (int i = OFFSET.get(n); i < OFFSET.get(n + 1); i++) {
            show(TREE_LIST.get(i), n * 2);
            System.out.println();
        }
    }

    private static void assemble(int n, long t, int sl, int pos, int rem) {
        if (rem == 0) {
            append(t);
            return;
        }

        var pp = pos;
        var ss = sl;

        if (sl > rem) {
            ss = rem;
            pp = OFFSET.get(ss);
        } else if (pp >= OFFSET.get(ss + 1)) {
            ss--;
            if (ss == 0) {
                return;
            }
            pp = OFFSET.get(ss);
        }

        assemble(n, t << (2 * ss) | TREE_LIST.get(pp), ss, pp, rem - ss);
        assemble(n, t, ss, pp + 1, rem);
    }

    private static void makeTrees(int n) {
        if (OFFSET.get(n + 1) != 0) {
            return;
        }
        if (n > 0) {
            makeTrees(n - 1);
        }
        assemble(n, 0, n - 1, OFFSET.get(n - 1), n - 1);
        OFFSET.set(n + 1, TREE_LIST.size());
    }

    private static void test(int n) {
        if (n < 1 || n > 12) {
            throw new IllegalArgumentException("Argument must be between 1 and 12");
        }

        append(0);

        makeTrees(n);
        System.out.printf("Number of %d-trees: %d\n", n, OFFSET.get(n + 1) - OFFSET.get(n));
        listTrees(n);
    }

    public static void main(String[] args) {
        test(5);
    }
}