Skip to content

Instantly share code, notes, and snippets.

@jake-87
Last active August 27, 2025 05:49
Show Gist options
  • Select an option

  • Save jake-87/55d04a43ea42ca71eaabcfbb79d566d4 to your computer and use it in GitHub Desktop.

Select an option

Save jake-87/55d04a43ea42ca71eaabcfbb79d566d4 to your computer and use it in GitHub Desktop.
let rand =
let x = ref 10 in
fun () ->
x := (!x * 27527 + 27791) mod 41231;
!x
type tree =
| Leaf
| Branch of int * tree * tree
let rec make_tree max depth =
if depth <= 1 then Leaf
else
let r = rand () mod max in
Branch(r, make_tree max (depth - 1), make_tree max (depth - 1))
let rec is_sub t k =
match t, k with
| Leaf, _ -> true
| Branch(x,a,b), Branch(y,q,w) ->
if x = y && is_sub a q && is_sub b w then true
else
is_sub t q || is_sub t w
| _, _ -> false
let bti = function
| true -> 1
| false -> 0
let rec count_subtrees a t =
match a with
| Leaf -> 1
| Branch(_, x, y) ->
bti (is_sub a t) + count_subtrees x t + count_subtrees y t
let () =
let t = make_tree 10 19 in
let f = make_tree 9 19 in
let time = Sys.time () in
print_int (count_subtrees f t);
Printf.printf "\nDONE: %fs\n" (Sys.time () -. time);
flush stdout
(* if you've implemented your version correctly it should output 512105 *)
@jake-87
Copy link
Author

jake-87 commented Aug 27, 2025

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>

typedef struct tree {
    int is_branch;
    int x;
    struct tree *left;
    struct tree *right;
} tree;

long x = 10;

int rand() {
    x = (x * 27527 + 27791) % 41231;
    return x;
}

tree *make_tree(int max, int depth) {
    struct tree *p = malloc(sizeof(*p));
    if (depth <= 1) {
        p->is_branch = false;
    } else {
        p->is_branch = true;
        p->x = rand() % max;
        p->left = make_tree(max, depth - 1);
        p->right = make_tree(max, depth - 1);
    }
    return p;
}

bool is_sub(tree *a, tree *b) {
    if (!a->is_branch) return true;
    if (a->is_branch && b->is_branch) {
        if (a->x == b->x && is_sub(a->left, b->left) && is_sub(a->right, b->right)) {
            return true;
        } else {
            return (is_sub(a, b->left) || is_sub(a, b->right));
        }
    }
    return false;
}

int count_subtrees(tree *a, tree *b) {
    if (!a->is_branch) return 1;
    return is_sub(a,b) + count_subtrees(a->left, b) + count_subtrees(a->right, b);
}

int main() {
    tree *t = make_tree(10, 19);
    tree *f = make_tree(9, 19);
    clock_t begin = clock();

    int res = count_subtrees(f, t);

    clock_t end = clock();
    double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    printf("count: %d time: %lf\n", res, time_spent);
}

a C version for further comparison

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment