Task: Faces from a mesh




Go: package main

import (
    "fmt"
    "sort"
)


func contains(s []int, f int) bool {
    for _, e := range s {
        if e == f {
            return true
        }
    }
    return false
}


func sliceEqual(s1, s2 []int) bool {
    for i := 0; i < len(s1); i++ {
        if s1[i] != s2[i] {
            return false
        }
    }
    return true
}


func reverse(s []int) {
    for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
        s[i], s[j] = s[j], s[i]
    }
}


func perimEqual(p1, p2 []int) bool {
    le := len(p1)
    if le != len(p2) {
        return false
    }
    for _, p := range p1 {
        if !contains(p2, p) {
            return false
        }
    }
    
    c := make([]int, le)
    copy(c, p1)
    for r := 0; r < 2; r++ {
        for i := 0; i < le; i++ {
            if sliceEqual(c, p2) {
                return true
            }
            
            t := c[le-1]
            copy(c[1:], c[0:le-1])
            c[0] = t
        }
        
        reverse(c)
    }
    return false
}

type edge [2]int


func faceToPerim(face []edge) []int {
    
    le := len(face)
    if le == 0 {
        return nil
    }
    edges := make([]edge, le)
    for i := 0; i < le; i++ {
        
        if face[i][1] <= face[i][0] {
            return nil
        }
        edges[i] = face[i]
    }
    
    sort.Slice(edges, func(i, j int) bool {
        if edges[i][0] != edges[j][0] {
            return edges[i][0] < edges[j][0]
        }
        return edges[i][1] < edges[j][1]
    })
    var perim []int
    first, last := edges[0][0], edges[0][1]
    perim = append(perim, first, last)
    
    copy(edges, edges[1:])
    edges = edges[0 : le-1]
    le--
outer:
    for le > 0 {
        for i, e := range edges {
            found := false
            if e[0] == last {
                perim = append(perim, e[1])
                last, found = e[1], true
            } else if e[1] == last {
                perim = append(perim, e[0])
                last, found = e[0], true
            }
            if found {
                
                copy(edges[i:], edges[i+1:])
                edges = edges[0 : le-1]
                le--
                if last == first {
                    if le == 0 {
                        break outer
                    } else {
                        return nil
                    }
                }
                continue outer
            }
        }
    }
    return perim[0 : len(perim)-1]
}

func main() {
    fmt.Println("Perimeter format equality checks:")
    areEqual := perimEqual([]int{8, 1, 3}, []int{1, 3, 8})
    fmt.Printf("  Q == R is %t\n", areEqual)
    areEqual = perimEqual([]int{18, 8, 14, 10, 12, 17, 19}, []int{8, 14, 10, 12, 17, 19, 18})
    fmt.Printf("  U == V is %t\n", areEqual)
    e := []edge{{7, 11}, {1, 11}, {1, 7}}
    f := []edge{{11, 23}, {1, 17}, {17, 23}, {1, 11}}
    g := []edge{{8, 14}, {17, 19}, {10, 12}, {10, 14}, {12, 17}, {8, 18}, {18, 19}}
    h := []edge{{1, 3}, {9, 11}, {3, 11}, {1, 11}}
    fmt.Println("\nEdge to perimeter format translations:")
    for i, face := range [][]edge{e, f, g, h} {
        perim := faceToPerim(face)
        if perim == nil {
            fmt.Printf("  %c => Invalid edge format\n", i + 'E')
        } else {
            fmt.Printf("  %c => %v\n", i + 'E', perim)
        }
    }
}




Python: def perim_equal(p1, p2):
    
    if len(p1) != len(p2) or set(p1) != set(p2):
        return False
    if any(p2 == (p1[n:] + p1[:n]) for n in range(len(p1))):
        return True
    p2 = p2[::-1] 
    return any(p2 == (p1[n:] + p1[:n]) for n in range(len(p1)))

def edge_to_periphery(e):
    edges = sorted(e)
    p = list(edges.pop(0)) if edges else []
    last = p[-1] if p else None
    while edges:
        for n, (i, j) in enumerate(edges):
            if i == last:
                p.append(j)
                last = j
                edges.pop(n)
                break
            elif j == last:
                p.append(i)
                last = i
                edges.pop(n)
                break
        else:
            
            return ">>>Error! Invalid edge format<<<"
    return p[:-1]

if __name__ == '__main__':
    print('Perimeter format equality checks:')
    for eq_check in [
            { 'Q': (8, 1, 3),
              'R': (1, 3, 8)},
            { 'U': (18, 8, 14, 10, 12, 17, 19),
              'V': (8, 14, 10, 12, 17, 19, 18)} ]:
        (n1, p1), (n2, p2) = eq_check.items()
        eq = '==' if perim_equal(p1, p2) else '!='
        print(' ', n1, eq, n2)

    print('\nEdge to perimeter format translations:')
    edge_d = {
     'E': {(1, 11), (7, 11), (1, 7)},
     'F': {(11, 23), (1, 17), (17, 23), (1, 11)},
     'G': {(8, 14), (17, 19), (10, 12), (10, 14), (12, 17), (8, 18), (18, 19)},
     'H': {(1, 3), (9, 11), (3, 11), (1, 11)}
            }
    for name, edges in edge_d.items():
        print(f"  {name}: {edges}\n     -> {edge_to_periphery(edges)}")