Task: Sorting algorithms_Cocktail sort with shifting bounds

C: #include <stdio.h>
#include <string.h>

void swap(char* p1, char* p2, size_t size) {
    for (; size-- > 0; ++p1, ++p2) {
        char tmp = *p1;
        *p1 = *p2;
        *p2 = tmp;
    }
}

void cocktail_shaker_sort(void* base, size_t count, size_t size,
                          int (*cmp)(const void*, const void*)) {
    char* begin = base;
    char* end = base + size * count;
    if (end == begin)
        return;
    for (end -= size; begin < end; ) {
        char* new_begin = end;
        char* new_end = begin;
        for (char* p = begin; p < end; p += size) {
            char* q = p + size;
            if (cmp(p, q) > 0) {
                swap(p, q, size);
                new_end = p;
            }
        }
        end = new_end;
        for (char* p = end; p > begin; p -= size) {
            char* q = p - size;
            if (cmp(q, p) > 0) {
                swap(p, q, size);
                new_begin = p;
            }
        }
        begin = new_begin;
    }
}

int string_compare(const void* p1, const void* p2) {
    const char* const* s1 = p1;
    const char* const* s2 = p2;
    return strcmp(*s1, *s2);
}

void print(const char** a, size_t len) {
    for (size_t i = 0; i < len; ++i)
        printf("%s ", a[i]);
    printf("\n");
}

int main() {
    const char* a[] = { "one", "two", "three", "four", "five",
        "six", "seven", "eight" };
    const size_t len = sizeof(a)/sizeof(a[0]);
    printf("before: ");
    print(a, len);
    cocktail_shaker_sort(a, len, sizeof(char*), string_compare);
    printf("after: ");
    print(a, len);
    return 0;
}




Go: package main

import (
    "fmt"
    "math/rand"
    "time"
)


func cocktailShakerSort(a []int) {
    var begin = 0
    var end = len(a) - 2
    for begin <= end {
        newBegin := end
        newEnd := begin
        for i := begin; i <= end; i++ {
            if a[i] > a[i+1] {
                a[i+1], a[i] = a[i], a[i+1]
                newEnd = i
            }
        }
        end = newEnd - 1
        for i := end; i >= begin; i-- {
            if a[i] > a[i+1] {
                a[i+1], a[i] = a[i], a[i+1]
                newBegin = i
            }
        }
        begin = newBegin + 1
    }
}


func cocktailSort(a []int) {
    last := len(a) - 1
    for {
        swapped := false
        for i := 0; i < last; i++ {
            if a[i] > a[i+1] {
                a[i], a[i+1] = a[i+1], a[i]
                swapped = true
            }
        }
        if !swapped {
            return
        }
        swapped = false
        for i := last - 1; i >= 0; i-- {
            if a[i] > a[i+1] {
                a[i], a[i+1] = a[i+1], a[i]
                swapped = true
            }
        }
        if !swapped {
            return
        }
    }
}

func main() {
    
    a := []int{21, 4, -9, 62, -7, 107, -62, 4, 0, -170}
    fmt.Println("Original array:", a)
    b := make([]int, len(a))
    copy(b, a) 
    cocktailSort(a)
    fmt.Println("Cocktail sort :", a)
    cocktailShakerSort(b)
    fmt.Println("C/Shaker sort :", b)

    
    rand.Seed(time.Now().UnixNano())
    fmt.Println("\nRelative speed of the two sorts")
    fmt.Println("  N    x faster (CSS v CS)")
    fmt.Println("-----  -------------------")
    const runs = 10 
    for _, n := range []int{1000, 2000, 4000, 8000, 10000, 20000} {
        sum := 0.0
        for i := 1; i <= runs; i++ {
            
            
            nums := make([]int, n)
            for i := 0; i < n; i++ {
                rn := rand.Intn(100000)
                if i%2 == 1 {
                    rn = -rn
                }
                nums[i] = rn
            }
            
            nums2 := make([]int, n)
            copy(nums2, nums)

            start := time.Now()
            cocktailSort(nums)
            elapsed := time.Since(start)
            start2 := time.Now()
            cocktailShakerSort(nums2)
            elapsed2 := time.Since(start2)
            sum += float64(elapsed) / float64(elapsed2)
        }
        fmt.Printf(" %2dk      %0.3f\n", n/1000, sum/runs)
    }
}