Task: Next highest int from digits
C: #include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

void swap(char* str, int i, int j) {
    char c = str[i];
    str[i] = str[j];
    str[j] = c;
}

void reverse(char* str, int i, int j) {
    for (; i < j; ++i, --j)
        swap(str, i, j);
}

bool next_permutation(char* str) {
    int len = strlen(str);
    if (len < 2)
        return false;
    for (int i = len - 1; i > 0; ) {
        int j = i, k;
        if (str[--i] < str[j]) {
            k = len;
            while (str[i] >= str[--k]) {}
            swap(str, i, k);
            reverse(str, j, len - 1);
            return true;
        }
    }
    return false;
}

uint32_t next_highest_int(uint32_t n) {
    char str[16];
    snprintf(str, sizeof(str), "%u", n);
    if (!next_permutation(str))
        return 0;
    return strtoul(str, 0, 10);
}

int main() {
    uint32_t numbers[] = {0, 9, 12, 21, 12453, 738440, 45072010, 95322020};
    const int count = sizeof(numbers)/sizeof(int);
    for (int i = 0; i < count; ++i)
        printf("%d -> %d\n", numbers[i], next_highest_int(numbers[i]));
    
    const char big[] = "9589776899767587796600";
    char next[sizeof(big)];
    memcpy(next, big, sizeof(big));
    next_permutation(next);
    printf("%s -> %s\n", big, next);
    return 0;
}

Go: package main

import (
    "fmt"
    "sort"
)

func permute(s string) []string {
    var res []string
    if len(s) == 0 {
        return res
    }
    b := []byte(s)
    var rc func(int) 
    rc = func(np int) {
        if np == 1 {
            res = append(res, string(b))
            return
        }
        np1 := np - 1
        pp := len(b) - np1
        rc(np1)
        for i := pp; i > 0; i-- {
            b[i], b[i-1] = b[i-1], b[i]
            rc(np1)
        }
        w := b[0]
        copy(b, b[1:pp+1])
        b[pp] = w
    }
    rc(len(b))
    return res
}

func algorithm1(nums []string) {
    fmt.Println("Algorithm 1")
    fmt.Println("-----------")
    for _, num := range nums {
        perms := permute(num)
        le := len(perms)
        if le == 0 { 
            continue
        }
        sort.Strings(perms)
        ix := sort.SearchStrings(perms, num)
        next := ""
        if ix < le-1 {
            for i := ix + 1; i < le; i++ {
                if perms[i] > num {
                    next = perms[i]
                    break
                }
            }
        }
        if len(next) > 0 {
            fmt.Printf("%29s -> %s\n", commatize(num), commatize(next))
        } else {
            fmt.Printf("%29s -> 0\n", commatize(num))
        }
    }
    fmt.Println()
}

func algorithm2(nums []string) {
    fmt.Println("Algorithm 2")
    fmt.Println("-----------")
outer:
    for _, num := range nums {
        b := []byte(num)
        le := len(b)
        if le == 0 { 
            continue
        }
        max := num[le-1]
        mi := le - 1
        for i := le - 2; i >= 0; i-- {
            if b[i] < max {
                min := max - b[i]
                for j := mi + 1; j < le; j++ {
                    min2 := b[j] - b[i]
                    if min2 > 0 && min2 < min {
                        min = min2
                        mi = j
                    }
                }
                b[i], b[mi] = b[mi], b[i]
                c := (b[i+1:])
                sort.Slice(c, func(i, j int) bool {
                    return c[i] < c[j]
                })
                next := string(b[0:i+1]) + string(c)
                fmt.Printf("%29s -> %s\n", commatize(num), commatize(next))
                continue outer
            } else if b[i] > max {
                max = num[i]
                mi = i
            }
        }
        fmt.Printf("%29s -> 0\n", commatize(num))
    }
}

func commatize(s string) string {
    le := len(s)
    for i := le - 3; i >= 1; i -= 3 {
        s = s[0:i] + "," + s[i:]
    }
    return s
}

func main() {
    nums := []string{"0", "9", "12", "21", "12453", "738440", "45072010", "95322020", "9589776899767587796600"}
    algorithm1(nums[:len(nums)-1]) 
    algorithm2(nums)               
}