Faces from a mesh: Difference between revisions

→‎{{header|Haskell}}: added solution
(Added 11l)
(→‎{{header|Haskell}}: added solution)
Line 305:
H => Invalid edge format
</pre>
 
=={{header|Haskell}}==
<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)</lang>
 
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}}==
Anonymous user