Faces from a mesh: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(Added Wren)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(12 intermediate revisions by 9 users not shown)
Line 76:
 
Show your output here.
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F perim_equal(p1, =p2)
I p1.len != p2.len | Set(p1) != Set(p2)
R 0B
I any((0 .< p1.len).map(n -> @p2 == (@p1[n ..] [+] @p1[0 .< n])))
R 1B
p2 = reversed(p2)
R any((0 .< p1.len).map(n -> @p2 == (@p1[n ..] [+] @p1[0 .< n])))
 
F edge_to_periphery(e)
V edges = sorted(e)
[Int] p
I !edges.empty
p = [edges[0][0], edges[0][1]]
edges.pop(0)
V last = I !p.empty {p.last} E -1
L !edges.empty
L(ij) edges
V (i, j) = ij
I i == last
p.append(j)
last = j
edges.pop(L.index)
L.break
E I j == last
p.append(i)
last = i
edges.pop(L.index)
L.break
L.was_no_break
R ‘>>>Error! Invalid edge format<<<’
R String(p[0 .< (len)-1])
 
print(‘Perimeter format equality checks:’)
L(eq_check) [(‘Q’, [8, 1, 3],
‘R’, [1, 3, 8]),
(‘U’, [18, 8, 14, 10, 12, 17, 19],
‘V’, [8, 14, 10, 12, 17, 19, 18])]
V (n1, p1, n2, p2) = eq_check
V eq = I perim_equal(p1, p2) {‘==’} E ‘!=’
print(‘ ’n1‘ ’eq‘ ’n2)
 
print("\nEdge to perimeter format translations:")
V 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)]]
L(name, edges) edge_d
print(‘ ’name‘: ’edges"\n -> "edge_to_periphery(edges))</syntaxhighlight>
 
{{out}}
<pre>
Perimeter format equality checks:
Q == R
U == V
 
Edge to perimeter format translations:
E: [(1, 11), (7, 11), (1, 7)]
-> [1, 7, 11]
F: [(11, 23), (1, 17), (17, 23), (1, 11)]
-> [1, 11, 23, 17]
G: [(8, 14), (17, 19), (10, 12), (10, 14), (12, 17), (8, 18), (18, 19)]
-> [8, 14, 10, 12, 17, 19, 18]
H: [(1, 3), (9, 11), (3, 11), (1, 11)]
-> >>>Error! Invalid edge format<<<
</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="c++">
 
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
 
typedef std::pair<int32_t, int32_t> Edge;
 
std::string to_string(const int32_t& value) {
return std::to_string(value);
}
 
std::string to_string(const Edge& edge) {
return "(" + std::to_string(edge.first) + ", " + std::to_string(edge.second) + ")";
}
 
template <typename T>
std::string vector_to_string(const std::vector<T>& list) {
std::string result = "[";
for ( uint64_t i = 0; i < list.size() - 1; ++i ) {
result += to_string(list[i]) + ", ";
}
result += to_string(list.back()) + "]";
return result;
}
 
bool is_same_face(const std::vector<int32_t>& list_1, const std::vector<int32_t>& list_2) {
if ( list_1.size() != list_2.size() || list_1.empty() ) {
return false;
}
 
std::vector<int32_t> copy_2(list_2);
for ( int32_t i = 0; i < 2; ++i ) {
int32_t start;
if ( auto iterator = std::find(copy_2.begin(), copy_2.end(), list_1.front()); iterator != copy_2.end() ) {
start = std::distance(copy_2.begin(), iterator);
} else {
return false;
}
std::vector<int32_t> test(copy_2.begin() + start, copy_2.end());
test.insert(test.end(), copy_2.begin(), copy_2.begin() + start);//addAll(copyTwo.subList(0, start));
if ( list_1 == test ) {
return true;
}
std::reverse(copy_2.begin(), copy_2.end());
}
 
return false;
}
 
std::vector<int32_t> to_perimeter_format_face(const std::vector<Edge>& edge_format_face) {
if ( edge_format_face.empty() ) {
return std::vector<int32_t>();
}
 
std::vector<Edge> edges(edge_format_face);
std::vector<int32_t> result;
Edge first_edge = edges.front();
edges.erase(edges.begin());
int next_vertex = first_edge.first;
result.push_back(next_vertex);
 
while ( ! edges.empty() ) {
int32_t index = -1;
for ( Edge edge : edges ) {
if ( edge.first == next_vertex || edge.second == next_vertex ) {
if ( auto iterator = std::find(edges.begin(), edges.end(), edge); iterator != edges.end() ) {
index = std::distance(edges.begin(), iterator);
}
next_vertex = ( next_vertex == edge.first ) ? edge.second : edge.first;
break;
}
}
if ( index == -1 ) {
return std::vector<int32_t>();
}
result.push_back(next_vertex);
edges.erase(edges.begin() + index);
}
 
if ( next_vertex != first_edge.second ) {
return std::vector<int32_t>();
}
return result;
}
 
int main() {
const std::vector<int32_t> perimeter_format_q = { 8, 1, 3 };
const std::vector<int32_t> perimeter_format_r = { 1, 3, 8 };
const std::vector<int32_t> perimeter_format_u = { 18, 8, 14, 10, 12, 17, 19 };
const std::vector<int32_t> perimeter_format_v = { 8, 14, 10, 12, 17, 19, 18 };
 
const std::vector<Edge> edge_format_e = { Edge(1, 11), Edge(7, 11), Edge(1, 7) };
const std::vector<Edge> edge_format_f = { Edge(11, 23), Edge(1, 17), Edge(17, 23), Edge(1, 11) };
const std::vector<Edge> edge_format_g =
{ Edge(8, 14), Edge(17, 19), Edge(10, 12), Edge(10, 14), Edge(12, 17), Edge(8, 18), Edge(18, 19) };
const std::vector<Edge> edge_format_h = { Edge(1, 3), Edge(9, 11), Edge(3, 11), Edge(1, 11) };
 
std::cout << "PerimeterFormat equality checks:" << std::endl;
bool same_face = is_same_face(perimeter_format_q, perimeter_format_r);
std::cout << vector_to_string(perimeter_format_q) << " == "
<< vector_to_string(perimeter_format_r) << ": " << std::boolalpha << same_face << std::endl;
same_face = is_same_face(perimeter_format_u, perimeter_format_v);
std::cout << vector_to_string(perimeter_format_u) << " == "
<< vector_to_string(perimeter_format_v) << ": " << std::boolalpha << same_face << std::endl;
 
std::cout << "\nEdgeFormat to PerimeterFormat conversions:" << std::endl;
std::vector<std::vector<Edge>> edge_format_faces = { edge_format_e, edge_format_f, edge_format_g, edge_format_h };
for ( std::vector<Edge> edge_format_face : edge_format_faces ) {
std::vector<int32_t> perimeter_format_face = to_perimeter_format_face(edge_format_face);
if ( perimeter_format_face.empty() ) {
std::cout << vector_to_string(edge_format_face) << " has invalid edge format" << std::endl;
} else {
std::cout << vector_to_string(edge_format_face) << " => "
<< vector_to_string(perimeter_format_face) << std::endl;
}
}
}
</syntaxhighlight>
{{ out }}
<pre>
PerimeterFormat equality checks:
[8, 1, 3] == [1, 3, 8]: true
[18, 8, 14, 10, 12, 17, 19] == [8, 14, 10, 12, 17, 19, 18]: true
 
EdgeFormat to PerimeterFormat conversions:
[(1, 11), (7, 11), (1, 7)] => [1, 7, 11]
[(11, 23), (1, 17), (17, 23), (1, 11)] => [11, 1, 17, 23]
[(8, 14), (17, 19), (10, 12), (10, 14), (12, 17), (8, 18), (18, 19)] => [8, 18, 19, 17, 12, 10, 14]
[(1, 3), (9, 11), (3, 11), (1, 11)] has invalid edge format
</pre>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 222 ⟶ 425:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 236 ⟶ 439:
H => Invalid edge format
</pre>
 
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">import Data.List (find, delete, (\\))
import Control.Applicative ((<|>))
 
------------------------------------------------------------
 
newtype Perimeter a = Perimeter [a]
deriving Show
 
instance Eq a => Eq (Perimeter a) where
Perimeter p1 == Perimeter p2 =
null (p1 \\ p2)
&& ((p1 `elem` zipWith const (iterate rotate p2) p1)
|| Perimeter p1 == Perimeter (reverse p2))
 
rotate lst = zipWith const (tail (cycle lst)) lst
 
toEdges :: Ord a => Perimeter a -> Maybe (Edges a)
toEdges (Perimeter ps)
| allDifferent ps = Just . Edges $ zipWith ord ps (tail (cycle ps))
| otherwise = Nothing
where
ord a b = if a < b then (a, b) else (b, a)
 
allDifferent [] = True
allDifferent (x:xs) = all (x /=) xs && allDifferent xs
 
------------------------------------------------------------
 
newtype Edges a = Edges [(a, a)]
deriving Show
 
instance Eq a => Eq (Edges a) where
e1 == e2 = toPerimeter e1 == toPerimeter e2
 
toPerimeter :: Eq a => Edges a -> Maybe (Perimeter a)
toPerimeter (Edges ((a, b):es)) = Perimeter . (a :) <$> go b es
where
go x rs
| x == a = return []
| otherwise = do
p <- find ((x ==) . fst) rs <|> find ((x ==) . snd) rs
let next = if fst p == x then snd p else fst p
(x :) <$> go next (delete p rs)</syntaxhighlight>
 
First task.
 
<pre>λ> Perimeter [8,1,3] == Perimeter [1,3,8]
True
 
λ> Perimeter [8,1,3] == Perimeter [1,8,3]
True
 
λ> Perimeter [18,8,14,10,12,17,19] == Perimeter [8,14,10,12,17,19,18]
True
 
λ> Perimeter [18,8,14,10,12,17,19] == Perimeter [8,14,10,12,17,19]
False
 
λ> Perimeter [18,8,14,10,12,17,19] == Perimeter [8,14,10,12,17,18,19]
False</pre>
 
Second task
<pre>λ> toPerimeter (Edges [(1,11),(7,11),(1,7)])
Just (Perimeter [1,11,7])
 
λ> toPerimeter (Edges [(11,23),(1,17),(17,23),(1,11)])
Just (Perimeter [11,23,17,1])
 
λ> toPerimeter (Edges [(8,14),(17,19),(10,12),(10,14),(12,17),(8,18),(18,19)])
Just (Perimeter [8,14,10,12,17,19,18])
 
λ> toPerimeter (Edges [(1,3),(9,11),(3,11),(1,11)])
Nothing</pre>
 
=={{header|J}}==
Line 258 ⟶ 536:
</pre>
Secondly:
<syntaxhighlight lang="j">
<lang J>
edge_to_node=: 3 :0
assert. 2 = #/.~ , y [ 'expect each node to appear twice'
Line 271 ⟶ 549:
~. , oel
)
</syntaxhighlight>
</lang>
 
<pre>
Line 303 ⟶ 581:
|assertion failure: edge_to_node
| 2=#/.~,y['expect each node to appear twice'
</pre>
 
=={{header|Java}}==
<syntaxhighlight lang="java">
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
 
public final class FacesFromMesh {
 
public static void main(String[] aArgs) {
final List<Integer> perimeterFormatQ = Arrays.asList( 8, 1, 3 );
final List<Integer> perimeterFormatR = Arrays.asList( 1, 3, 8 );
final List<Integer> perimeterFormatU = Arrays.asList( 18, 8, 14, 10, 12, 17, 19 );
final List<Integer> perimeterFormatV = Arrays.asList( 8, 14, 10, 12, 17, 19, 18 );
final List<Edge> edgeFormatE = Arrays.asList( new Edge(1, 11), new Edge(7, 11), new Edge(1, 7) );
final List<Edge> edgeFormatF =
Arrays.asList( new Edge(11, 23), new Edge(1, 17), new Edge(17, 23), new Edge(1, 11) );
final List<Edge> edgeFormatG = Arrays.asList( new Edge(8, 14), new Edge(17, 19),
new Edge(10, 12), new Edge(10, 14), new Edge(12, 17), new Edge(8, 18), new Edge(18, 19) );
final List<Edge> edgeFormatH =
Arrays.asList( new Edge(1, 3), new Edge(9, 11), new Edge(3, 11), new Edge(1, 11) );
System.out.println("PerimeterFormat equality checks:");
boolean sameFace = isSameFace(perimeterFormatQ, perimeterFormatR);
System.out.println(perimeterFormatQ + " == " + perimeterFormatR + ": " + sameFace);
sameFace = isSameFace(perimeterFormatU, perimeterFormatV);
System.out.println(perimeterFormatU + " == " + perimeterFormatV + ": " + sameFace);
 
System.out.println(System.lineSeparator() + "EdgeFormat to PerimeterFormat conversions:");
List<List<Edge>> edgeFormatFaces = List.of( edgeFormatE, edgeFormatF, edgeFormatG, edgeFormatH );
for ( List<Edge> edgeFormatFace : edgeFormatFaces ) {
List<Integer> perimeterFormatFace = toPerimeterFormatFace(edgeFormatFace);
if ( perimeterFormatFace.isEmpty() ) {
System.out.println(edgeFormatFace + " has invalid edge format");
} else {
System.out.println(edgeFormatFace + " => " + perimeterFormatFace);
}
}
}
private static boolean isSameFace(List<Integer> aOne, List<Integer> aTwo) {
if ( aOne.size() != aTwo.size() || aOne.isEmpty() ||
! new HashSet<Integer>(aOne).equals( new HashSet<Integer>(aTwo) )) {
return false;
}
 
List<Integer> copyTwo = new ArrayList<Integer>(aTwo);
for ( int i = 0; i < 2; i++ ) {
int start = copyTwo.indexOf(aOne.get(0));
List<Integer> test = new ArrayList<Integer>(copyTwo.subList(start, copyTwo.size()));
test.addAll(copyTwo.subList(0, start));
if ( aOne.equals(test) ) {
return true;
}
Collections.reverse(copyTwo);
}
return false;
}
private static List<Integer> toPerimeterFormatFace(List<Edge> aEdgeFormatFace) {
if ( aEdgeFormatFace.isEmpty() ) {
return Collections.emptyList();
}
List<Edge> edges = new ArrayList<Edge>(aEdgeFormatFace);
List<Integer> result = new ArrayList<Integer>();
Edge firstEdge = edges.remove(0);
int nextVertex = firstEdge.first;
result.add(nextVertex);
while ( ! edges.isEmpty() ) {
int index = -1;
for ( Edge edge : edges ) {
if ( edge.first == nextVertex || edge.second == nextVertex ) {
index = edges.indexOf(edge);
nextVertex = ( nextVertex == edge.first ) ? edge.second : edge.first;
break;
}
}
if ( index == -1 ) {
return Collections.emptyList();
}
result.add(nextVertex);
edges.remove(index);
}
if ( nextVertex != firstEdge.second ) {
return Collections.emptyList();
}
return result;
}
private static class Edge {
public Edge(int aFirst, int aSecond) {
first = aFirst;
second = aSecond;
}
@Override
public String toString() {
return "(" + first + ", " + second + ")";
}
private int first, second;
}
 
}
</syntaxhighlight>
{{ out }}
<pre>
PerimeterFormat equality checks:
[8, 1, 3] == [1, 3, 8]: true
[18, 8, 14, 10, 12, 17, 19] == [8, 14, 10, 12, 17, 19, 18]: true
 
EdgeFormat to PerimeterFormat conversions:
[(1, 11), (7, 11), (1, 7)] => [1, 7, 11]
[(11, 23), (1, 17), (17, 23), (1, 11)] => [11, 1, 17, 23]
[(8, 14), (17, 19), (10, 12), (10, 14), (12, 17), (8, 18), (18, 19)] => [8, 18, 19, 17, 12, 10, 14]
[(1, 3), (9, 11), (3, 11), (1, 11)] has invalid edge format
</pre>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">iseq(f, g) = any(n -> f == circshift(g, n), 1:length(g))
 
function toface(evec)
Line 341 ⟶ 745:
println(toface(face))
end
</langsyntaxhighlight>{{out}}
<pre>
Faces are equivalent.
Line 350 ⟶ 754:
Invalid edges vector: Tuple{Int64,Int64}[(1, 3), (9, 11), (3, 11), (1, 11)]
</pre>
 
=={{header|Koka}}==
<syntaxhighlight lang="koka">
alias perimeter = list<int>
alias face = (char, perimeter)
alias edge = (int, int)
 
fun isSame(p1: perimeter, p2: perimeter, noSwitch: list<int> = []): div bool
match (p1, p2)
([], []) -> True
(Cons(x1, xs1), Cons(x2, xs2)) | x1 == x2 -> isSame(xs1, xs2)
_ ->
match p2
Nil -> False
Cons(x2, xs2) ->
if noSwitch.any(fn(x') x' == x2) then False else p1.isSame(xs2 ++ [x2], Cons(x2, noSwitch))
 
fun show(f: face)
val (c, p) = f
c.core/show ++ " " ++ p.core/show
 
fun findRemove(l: list<a>, acc: ctx<list<a>>, pred: (a) -> bool): maybe<(a, list<a>)>
match l
[] -> Nothing
Cons(x, xs) -> match pred(x)
True -> Just((x, acc ++. xs))
False -> findRemove(xs, acc ++ ctx Cons(x, _), pred)
 
fun toPerimeter(search: int, edges: list<edge>, acc: ctx<perimeter>): <div,exn> perimeter
match edges
[] -> acc ++. Cons(search, Nil) // Assume the search matches the first edge's missing
_ -> match edges.findRemove(ctx _, fn((a, b)) a == search || b == search)
Just(((a, b), xs')) -> if search == a then
toPerimeter(b, xs', acc ++ ctx Cons(a, _))
else
toPerimeter(a, xs', acc ++ ctx Cons(b, _))
Nothing -> throw("Cannot find the next edge for " ++ search.show ++ " current perimeter is " ++ (acc ++. Nil).show ++ " and the rest of the edges are: " ++ edges.show-list(fn(s) s.show-tuple(show, show)))
 
fun main()
val fp = [(('P', [8, 1, 3]), ('R', [1, 3, 8])),
(('U', [18, 8, 14, 10, 12, 17, 19]), ('V', [8, 14, 10, 12, 17, 19, 18]))]
fp.foreach() fn((f1, f2))
val same = f1.snd.isSame(f2.snd)
print(f1.show ++ (if same then " is " else " is not ") ++ "the same as " ++ f2.show ++ "\n")
val fe = [('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)])]
fe.foreach() fn((f, edges))
match edges
[] -> ()
Cons((initX, _), edges') ->
val p = toPerimeter(initX, edges', ctx _)
print(f.show ++ " perimeter is " ++ p.show ++ "\n")
</syntaxhighlight>
{{out}}
<pre>
'P' [8,1,3] is the same as 'R' [1,3,8]
'U' [18,8,14,10,12,17,19] is the same as 'V' [8,14,10,12,17,19,18]
'E' perimeter is [1,7,11]
'F' perimeter is [11,1,17,23]
'G' perimeter is [8,18,19,17,12,10,14]
uncaught exception: Cannot find the next edge for 9 current perimeter is [1,11] and the rest of the edges are: [(3,11)]
</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">-- support
function T(t) return setmetatable(t, {__index=table}) end
table.eql = function(t,u) if #t~=#u then return false end for i=1,#t do if t[i]~=u[i] then return false end end return true end
table.rol = function(t,n) local s=T{} for i=1,#t do s[i]=t[(i+n-1)%#t+1] end return s end
table.rev = function(t) local s=T{} for i=1,#t do s[#t-i+1]=t[i] end return s end
 
-- 1
function pfeq(pf1, pf2)
if #pf1 ~= #pf2 then return false end -- easy case
for w = 0,1 do -- exhaustive cases
local pfw = pf1 -- w:winding
if w==1 then pfw=pfw:rev() end
for r = 0,#pfw do
local pfr = pfw -- r:rotate
if r>0 then pfr=pfr:rol(r) end
if pf2:eql(pfr) then return true end
end
end
return false
end
 
Q = T{8, 1, 3}
R = T{1, 3, 8}
U = T{18, 8, 14, 10, 12, 17, 19}
V = T{8, 14, 10, 12, 17, 19, 18}
print("pfeq(Q,R): ", pfeq(Q, R))
print("pfeq(U,V): ", pfeq(U, V))
 
-- 2
function ef2pf(ef)
local pf, hse = T{}, T{} -- hse:hash of sorted edges
for i,e in ipairs(ef) do table.sort(e) hse[e]=e end
local function nexte(e)
if not e then return ef[1] end
for k,v in pairs(hse) do
if e[2]==v[1] then return v end
if e[2]==v[2] then v[1],v[2]=v[2],v[1] return v end
end
end
local e = nexte()
while e do
pf[#pf+1] = e[1]
hse[e] = nil
e = nexte(e)
end
if #pf ~= #ef then pf=T{"failed to convert edge format to perimeter format"} end
return pf
end
 
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}}
print("ef2pf(E): ", ef2pf(E):concat(","))
print("ef2pf(F): ", ef2pf(F):concat(","))
print("ef2pf(G): ", ef2pf(G):concat(","))
print("ef2pf(H): ", ef2pf(H):concat(","))</syntaxhighlight>
{{out}}
<pre>pfeq(Q,R): true
pfeq(U,V): true
ef2pf(E): 1,11,7
ef2pf(F): 11,23,17,1
ef2pf(G): 8,14,10,12,17,19,18
ef2pf(H): failed to convert edge format to perimeter format</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import algorithm, strutils
 
type
Perimeter = seq[int]
Face = tuple[name: char; perimeter: Perimeter]
Edge = tuple[first, last: int]
 
const None = -1 # No point.
 
#---------------------------------------------------------------------------------------------------
 
func isSame(p1, p2: Perimeter): bool =
## Return "true" if "p1" and "p2" represent the same face.
 
if p1.len != p2.len: return false
 
for p in p1:
if p notin p2: return false
 
var start = p2.find(p1[0])
if p1 == p2[start..^1] & p2[0..<start]:
return true
 
let p3 = reversed(p2)
start = p3.find(p1[0])
if p1 == p3[start..^1] & p3[0..<start]:
return true
 
#---------------------------------------------------------------------------------------------------
 
func `$`(perimeter: Perimeter): string =
## Convert a perimeter to a string.
'(' & perimeter.join(", ") & ')'
 
func `$`(face: Face): string =
## Convert a perimeter formatted face to a string.
face.name & $face.perimeter
 
#---------------------------------------------------------------------------------------------------
 
func toPerimeter(edges: seq[Edge]): Perimeter =
## Convert a list of edges to perimeter representation.
## Return an empty perimeter if the list of edges doesn’t represent a face.
 
var edges = edges
let firstEdge = edges.pop() # First edge taken in account.
var nextPoint = firstEdge.first # Next point to search in remaining edges.
result.add(nextpoint)
 
while edges.len > 0:
# Search an edge.
var idx = None
for i, e in edges:
if e.first == nextPoint or e.last == nextPoint:
idx = i
nextPoint = if nextpoint == e.first: e.last else: e.first
break
if idx == None:
return @[] # No edge found containing "newPoint".
 
# Add next point to perimeter and remove the edge.
result.add(nextPoint)
edges.del(idx)
 
# Check that last added point is the expected one.
if nextPoint != firstEdge.last:
return @[]
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
when isMainModule:
 
# List of pairs of perimeter formatted faces to compare.
const FP = [(('P', @[8, 1, 3]), ('R', @[1, 3, 8])),
(('U', @[18, 8, 14, 10, 12, 17, 19]), ('V', @[8, 14, 10, 12, 17, 19, 18]))]
 
echo "Perimeter comparison:"
for (p1, p2) in FP:
echo p1, if isSame(p1[1], p2[1]): " is same as " else: "is not same as", p2
 
# List of edge formatted faces.
const FE = {'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)]}
 
echo ""
echo "Conversion from edge to perimeter format:"
for (faceName, edges) in FE:
let perimeter = edges.toPerimeter()
echo faceName, ": ", if perimeter.len == 0: "Invalid edge list" else: $perimeter</syntaxhighlight>
 
{{out}}
<pre>Perimeter comparison:
P(8, 1, 3) is same as R(1, 3, 8)
U(18, 8, 14, 10, 12, 17, 19) is same as V(8, 14, 10, 12, 17, 19, 18)
 
Conversion from edge to perimeter format:
E: (1, 11, 7)
F: (1, 17, 23, 11)
G: (18, 8, 14, 10, 12, 17, 19)
H: Invalid edge list</pre>
 
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
Line 409 ⟶ 1,047:
[[1, 3], [9, 11], [3, 11], [1, 11]]) {
say show($_) . ' ==> (' . (join ' ', edge_to_periphery(@$_) or 'Invalid edge format') . ')'
}</langsyntaxhighlight>
{{out}}
<pre>Perimeter format equality checks:
Line 422 ⟶ 1,060:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function perequiv(sequence a, b)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
-- Works by aligning and rotating in one step, so theoretically much faster on massive sets.
<span style="color: #008080;">function</span> <span style="color: #000000;">perequiv</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
-- (ahem, faster than multiple rotates, index-only loops would obviously be even faster...)
<span style="color: #000080;font-style:italic;">-- Works by aligning and rotating in one step, so theoretically much faster on massive sets.
bool res = (length(a)==length(b))
-- (ahem, faster than multiple rotates, index-only loops would obviously be even faster...)</span>
if res and length(a)>0 then
<span style="color: #004080;">bool</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)==</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">))</span>
integer k = find(a[1],b)
<span style="color: #008080;">if</span> <span style="color: #000000;">res</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
if k=0 then
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
res = false
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
else
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
-- align with a (ie make b[1]==a[1], by
<span style="color: #008080;">else</span>
-- rotating b k places in one operation)
<span style="color: #000080;font-style:italic;">-- align with a (ie make b[1]==a[1], by
b = b[k..$]&b[1..k-1]
if a!=-- rotating b thenk places in one operation)</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">..$]&</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
-- eg {8,3,4,5} <=> {8,5,4,3}, ie
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">b</span> <span style="color: #008080;">then</span>
-- rotate *and* keep in alignment.
<span style="color: #000080;font-style:italic;">-- eg {8,3,4,5} &lt;=&gt; {8,5,4,3}, ie
b[2..$] = reverse(b[2..$])
res =-- (a==b)rotate *and* keep in alignment.</span>
<span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$])</span>
end if
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">==</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
-- return res
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return {"false","true"}[res+1]
<span style="color: #000080;font-style:italic;">-- return res</span>
end function
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"false"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"true"</span><span style="color: #0000FF;">}[</span><span style="color: #000000;">res</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function edge2peri(sequence edges)
sequence was = edges, res = {}
<span style="color: #008080;">function</span> <span style="color: #000000;">edge2peri</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">edges</span><span style="color: #0000FF;">)</span>
string error = ""
<span style="color: #004080;">sequence</span> <span style="color: #000000;">was</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">edges</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
integer lnk = 0
<span style="color: #004080;">string</span> <span style="color: #000000;">error</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
if length(edges)<2 then
<span style="color: #004080;">integer</span> <span style="color: #000000;">lnk</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
error = "too short"
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">edges</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span>
else
<span style="color: #000000;">error</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"too short"</span>
-- edges = sort(edges) -- (see note below)
<span style="color: #008080;">else</span>
res = edges[1]
<span style="color: #000080;font-style:italic;">-- edges = sort(deep_copy(edges)) -- (see note below)</span>
edges = edges[2..$]
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">edges</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
lnk = res[2]
<span style="color: #000000;">edges</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">edges</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]</span>
while length(edges) and error="" do
<span style="color: #000000;">lnk</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
bool found = false
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">edges</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">error</span><span style="color: #0000FF;">=</span><span style="color: #008000;">""</span> <span style="color: #008080;">do</span>
for i=1 to length(edges) do
<span style="color: #004080;">bool</span> <span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
integer k = find(lnk,edges[i])
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">edges</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
if k then
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lnk</span><span style="color: #0000FF;">,</span><span style="color: #000000;">edges</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
lnk = edges[i][3-k]
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span> <span style="color: #008080;">then</span>
edges[i..i] = {}
<span style="color: #000000;">lnk</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">edges</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">3</span><span style="color: #0000FF;">-</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
if edges={} then
<span style="color: #000000;">edges</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
if lnk!=res[1] then error = "oh dear" end if
<span style="color: #008080;">if</span> <span style="color: #000000;">edges</span><span style="color: #0000FF;">={}</span> <span style="color: #008080;">then</span>
else
<span style="color: #008080;">if</span> <span style="color: #000000;">lnk</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #000000;">error</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"oh dear"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if find(lnk,res) then error = "oops" end if
<span res &style="color: lnk#008080;">else</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lnk</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000000;">error</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"oops"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">lnk</span>
found = true
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
exit
<span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
end if
<span style="color: #008080;">exit</span>
end for
if not found then error =<span style="badcolor: link#008080;">end</span> exit<span endstyle="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end while
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">found</span> <span style="color: #008080;">then</span> <span style="color: #000000;">error</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"bad link"</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
if length(error) then res = {error,res,lnk,edges,was} end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return res
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">error</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">error</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lnk</span><span style="color: #0000FF;">,</span><span style="color: #000000;">edges</span><span style="color: #0000FF;">,</span><span style="color: #000000;">was</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
constant ptests = {{{8, 1, 3}, {1, 3, 8}},
{{18, 8, 14, 10, 12, 17, 19}, {8, 14, 10, 12, 17, 19, 18}},
<span style="color: #008080;">constant</span> <span style="color: #000000;">ptests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">}},</span>
-- (check our results below against Go etc)
<span style="color: #0000FF;">{{</span><span style="color: #000000;">18</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">17</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">19</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">17</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">19</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">18</span><span style="color: #0000FF;">}},</span>
{{1,11,7},{1,7,11}},
<span style="color: #000080;font-style:italic;">-- (check our results below against Go etc)</span>
{{11,23,17,1},{1,11,23,17}}}
<span style="color: #0000FF;">{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">}},</span>
for i=1 to length(ptests) do
<span style="color: #0000FF;">{{</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #000000;">23</span><span style="color: #0000FF;">,</span><span style="color: #000000;">17</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #000000;">23</span><span style="color: #0000FF;">,</span><span style="color: #000000;">17</span><span style="color: #0000FF;">}}}</span>
sequence {p,q} = ptests[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ptests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
printf(1,"%v equivalent to %v: %s\n",{p,q,perequiv(p,q)})
<span style="color: #004080;">sequence</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ptests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
end for
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v equivalent to %v: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q</span><span style="color: #0000FF;">,</span><span style="color: #000000;">perequiv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q</span><span style="color: #0000FF;">)})</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
constant etests = {{{1, 11}, {7, 11}, {1, 7}},
{{11, 23}, {1, 17}, {17, 23}, {1, 11}},
<span style="color: #008080;">constant</span> <span style="color: #000000;">etests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">}},</span>
{{8, 14}, {17, 19}, {10, 12}, {10, 14}, {12, 17}, {8, 18}, {18, 19}},
<span style="color: #0000FF;">{{</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">23</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">17</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">17</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">23</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">}},</span>
{{1, 3}, {9, 11}, {3, 11}, {1, 11}}}
<span style="color: #0000FF;">{{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">17</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">19</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">17</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">18</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">18</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">19</span><span style="color: #0000FF;">}},</span>
for i=1 to length(etests) do
<span style="color: #0000FF;">{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">},</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">}}}</span>
printf(1,"%v\n",{edge2peri(etests[i])})
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">etests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
end for</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">edge2peri</span><span style="color: #0000FF;">(</span><span style="color: #000000;">etests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
(second part matches Julia/Perl: un-comment that sort above to match Go/Python/zkl)
Line 512 ⟶ 1,153:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">def perim_equal(p1, p2):
# Cheap tests first
if len(p1) != len(p2) or set(p1) != set(p2):
Line 561 ⟶ 1,202:
}
for name, edges in edge_d.items():
print(f" {name}: {edges}\n -> {edge_to_periphery(edges)}")</langsyntaxhighlight>
 
{{out}}
Line 582 ⟶ 1,223:
{{works with|Rakudo|2019.11}}
 
<syntaxhighlight lang="raku" perl6line>sub check-equivalence ($a, $b) { so $a.Bag eqv $b.Bag }
 
sub edge-to-periphery (@a is copy) {
Line 622 ⟶ 1,263:
.gist.print;
say " ==> ({.&edge-to-periphery || 'Invalid edge format'})";
}</langsyntaxhighlight>
{{out}}
<pre>Perimeter format equality checks:
Line 637 ⟶ 1,278:
{{trans|Go}}
{{libheader|Wren-sort}}
{{libheader|Wren-seq}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./sort" for Sort
import "./fmtseq" for FmtLst
import "./fmt" for Fmt
 
// Assumes s1, s2 are of same length.
var sliceEqual = Fn.new { |s1, s2|
for (i in 0...s1.count) {
if (s1[i] != s2[i]) return false
}
return true
}
 
// Check two perimeters are equal.
var perimEqual = Fn.new { |p1, p2|
Line 660 ⟶ 1,295:
for (r in 0..1) {
for (i in 0...le) {
if (sliceEqualLst.callareEqual(c, p2)) return true
// do circular shift to right
var t = Lst.rshift(c[-1])
for (i in le-2..0) c[i+1] = c[i]
c[0] = t
}
// now process in opposite direction
SortLst.reverse(c) // reverses 'c' in place
}
return false
}
 
var faceToPerim = Fn.new { |face|
// use copy to avoid mutating 'face'
Line 732 ⟶ 1,365:
return perim[0..-2]
}
 
System.print("Perimeter format equality checks:")
var areEqual = perimEqual.call([8, 1, 3], [1, 3, 8])
Line 751 ⟶ 1,384:
Fmt.print(" $c => $n", i + 69, perim)
}
}</langsyntaxhighlight>
 
{{out}}
Line 768 ⟶ 1,401:
=={{header|zkl}}==
{{trans|Python}}
<langsyntaxhighlight lang="zkl">fcn perimSame(p1, p2){
if(p1.len() != p2.len()) return(False);
False == p1.filter1('wrap(p){ (not p2.holds(p)) })
Line 784 ⟶ 1,417:
}
p[0,-1] // last element not part of result
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">println("Perimeter format equality checks:");
ps:=T( T( T(8,1,3), T(1,3,8) ),
T( T(18, 8, 14, 10, 12, 17, 19), T(8, 14, 10, 12, 17, 19, 18) ) );
Line 802 ⟶ 1,435:
 
fcn pp(a){ a.concat(", ","(",")") }
fcn ppp(edges){ pp(edges.apply(pp)) }</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits