Advertisement
Guest User

raetsel-der-woche-welches-streichholz-muss-umgelegt-werden

a guest
Aug 17th, 2019
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module Main where
  2.  
  3. import Data.List as List
  4. import Data.Maybe as Maybe
  5. import Data.Char
  6. import System.IO (readFile)
  7.  
  8. -- Hölzchen umlegen https://www.spiegel.de/forum/karriere/raetsel-der-woche-welches-streichholz-muss-umgelegt-werden-thread-935117-8.html
  9.  
  10. data Zeichen = Plus | Minus | Gleich | Z0 | Z1 | Z2 | Z3 | Z4 | Z5 | Z6 | Z7 | Z8 | Z9
  11.   deriving (Eq, Show)
  12.  
  13. data Position = Position   H   --   0     -
  14.                          H H H -- 1 2 3  |-|  zwei Zeichen für Gleich
  15.                           H H  --  4 5    +   zwei Zeichen für Plus
  16.                          H H H -- 6 7 8  |-|  zwei Zeichen für Gleich
  17.                            H   --   9     -
  18.   deriving (Eq)
  19.  
  20. data H = Holz | Frei
  21.   deriving (Eq)
  22.  
  23. instance Show Position where
  24.   show p@(Position h0 h1 h2 h3 h4 h5 h6 h7 h8 h9) =
  25.     if p == plus then "+"
  26.     else if p == minus then "-"
  27.     else if p == gleich then "="
  28.     else if p == leer then " "
  29.     else show (head $ findIndices (\e -> e == p) [z0, z1, z2, z3, z4, z5, z6, z7, z8, z9])
  30.  
  31. plus   = Position Frei  Frei Frei Frei  Holz Holz  Frei Frei Frei  Frei
  32. minus  = Position Frei  Frei Frei Frei  Holz Frei  Frei Frei Frei  Frei
  33. gleich = Position Frei  Frei Holz Frei  Frei Frei  Frei Holz Frei  Frei
  34. leer   = Position Frei  Frei Frei Frei  Frei Frei  Frei Frei Frei  Frei
  35.  
  36. z0 = Position Holz  Holz Frei Holz  Frei Frei  Holz Frei Holz  Holz
  37. z1 = Position Frei  Frei Frei Holz  Frei Frei  Frei Frei Holz  Frei
  38. z2 = Position Holz  Frei Frei Holz  Holz Frei  Holz Frei Frei  Holz
  39. z3 = Position Holz  Frei Frei Holz  Holz Frei  Frei Frei Holz  Holz
  40. z4 = Position Frei  Holz Frei Holz  Holz Frei  Frei Frei Holz  Frei
  41. z5 = Position Holz  Holz Frei Frei  Holz Frei  Frei Frei Holz  Holz
  42. z6 = Position Holz  Holz Frei Frei  Holz Frei  Holz Frei Holz  Holz
  43. z7 = Position Holz  Frei Frei Holz  Frei Frei  Frei Frei Holz  Frei
  44. z8 = Position Holz  Holz Frei Holz  Holz Frei  Holz Frei Holz  Holz
  45. z9 = Position Holz  Holz Frei Holz  Holz Frei  Frei Frei Holz  Holz
  46.  
  47. wegnehmenPosition :: Position -> [Position]
  48. wegnehmenPosition (Position h0 h1 h2 h3 h4 h5 h6 h7 h8 h9) = catMaybes [
  49.     if h0 == Holz then Just (Position Frei h1 h2 h3 h4 h5 h6 h7 h8 h9) else Nothing,
  50.     if h1 == Holz then Just (Position h0 Frei h2 h3 h4 h5 h6 h7 h8 h9) else Nothing,
  51.     if h2 == Holz then Just (Position h0 h1 Frei h3 h4 h5 h6 h7 h8 h9) else Nothing,
  52.     if h3 == Holz then Just (Position h0 h1 h2 Frei h4 h5 h6 h7 h8 h9) else Nothing,
  53.     if h4 == Holz then Just (Position h0 h1 h2 h3 Frei h5 h6 h7 h8 h9) else Nothing,
  54.     if h5 == Holz then Just (Position h0 h1 h2 h3 h4 Frei h6 h7 h8 h9) else Nothing,
  55.     if h6 == Holz then Just (Position h0 h1 h2 h3 h4 h5 Frei h7 h8 h9) else Nothing,
  56.     if h7 == Holz then Just (Position h0 h1 h2 h3 h4 h5 h6 Frei h8 h9) else Nothing,
  57.     if h8 == Holz then Just (Position h0 h1 h2 h3 h4 h5 h6 h7 Frei h9) else Nothing,
  58.     if h9 == Holz then Just (Position h0 h1 h2 h3 h4 h5 h6 h7 h8 Frei) else Nothing]
  59.  
  60. hinzufuegenPosition :: Position -> [Position]
  61. hinzufuegenPosition (Position h0 h1 h2 h3 h4 h5 h6 h7 h8 h9) = catMaybes [
  62.     if h0 == Frei then Just (Position Holz h1 h2 h3 h4 h5 h6 h7 h8 h9) else Nothing,
  63.     if h1 == Frei then Just (Position h0 Holz h2 h3 h4 h5 h6 h7 h8 h9) else Nothing,
  64.     if h2 == Frei then Just (Position h0 h1 Holz h3 h4 h5 h6 h7 h8 h9) else Nothing,
  65.     if h3 == Frei then Just (Position h0 h1 h2 Holz h4 h5 h6 h7 h8 h9) else Nothing,
  66.     if h4 == Frei then Just (Position h0 h1 h2 h3 Holz h5 h6 h7 h8 h9) else Nothing,
  67.     if h5 == Frei then Just (Position h0 h1 h2 h3 h4 Holz h6 h7 h8 h9) else Nothing,
  68.     if h6 == Frei then Just (Position h0 h1 h2 h3 h4 h5 Holz h7 h8 h9) else Nothing,
  69.     if h7 == Frei then Just (Position h0 h1 h2 h3 h4 h5 h6 Holz h8 h9) else Nothing,
  70.     if h8 == Frei then Just (Position h0 h1 h2 h3 h4 h5 h6 h7 Holz h9) else Nothing,
  71.     if h9 == Frei then Just (Position h0 h1 h2 h3 h4 h5 h6 h7 h8 Holz) else Nothing]
  72.  
  73. data Gleichung = Gleichung [Position]
  74.     deriving (Eq)
  75. gleichungToPositions (Gleichung positions) = positions
  76. positionsToGleichung positions = Gleichung positions
  77.  
  78. instance Show Gleichung where
  79.   show (Gleichung positions) =
  80.     foldl (++) "" (map show positions)
  81.  
  82. wegnehmenGleichung :: [Position] -> [[Position]]
  83. wegnehmenGleichung [] = [[]]
  84. wegnehmenGleichung (p:ps) =
  85.   let positions = wegnehmenPosition p -- aktuelles Zeichen mutieren
  86.       subPositions = wegnehmenGleichung ps -- oder ein folgendes Zeichen mutieren
  87.   in ((map (\ x -> x : ps) positions) ++ (map (\ xs -> p : xs) subPositions))
  88.  
  89. hinzufuegenGleichung :: [Position] -> [[Position]]
  90. hinzufuegenGleichung [] = [[]]
  91. hinzufuegenGleichung (p:ps) =
  92.   ((map (\ x -> x : ps) (hinzufuegenPosition p)) ++ -- aktuelles Zeichen mutieren
  93.   (map (\ xs -> p : xs) (hinzufuegenGleichung ps))) -- oder ein folgendes Zeichen mutieren
  94.  
  95. umlegenGleichung :: Gleichung -> [Gleichung]
  96. umlegenGleichung gl = concatMap (\g -> map positionsToGleichung $ hinzufuegenGleichung g) (wegnehmenGleichung $ gleichungToPositions  gl)
  97.  
  98. umlegenGleichung' :: Gleichung -> [Gleichung]
  99. umlegenGleichung' gl = concatMap (\g -> map positionsToGleichung $ wegnehmenGleichung g) (hinzufuegenGleichung $ gleichungToPositions  gl)
  100.  
  101. isBalanced :: Gleichung -> Bool
  102. isBalanced g = isValid g
  103.   && let ps = gleichungToPositions g
  104.          gleichPos = head $ findIndices (\p -> p==gleich) ps
  105.          s1 = take gleichPos ps
  106.          s2 = drop (1+gleichPos) ps
  107.     in (berechne s1) == (berechne s2)
  108.  
  109. isValid :: Gleichung -> Bool
  110. isValid g =
  111.   all (\ p -> p == z0 || p == z1 || p == z2 || p == z3 || p == z4
  112.            || p == z5 || p == z6 || p == z7 || p == z8 || p == z9
  113.            || p == plus || p == minus || p == gleich || p == leer) (gleichungToPositions g)
  114.   && 1 == (length $ findIndices (\p -> p==gleich) (gleichungToPositions g))
  115.   && False == isInfixOf [minus, gleich] (gleichungToPositions g)
  116.   && False == isInfixOf [plus, gleich] (gleichungToPositions g)
  117.   && minus /= last (gleichungToPositions g)
  118.   && plus /= last (gleichungToPositions g)
  119.  
  120. berechne :: [Position] -> Int
  121. berechne s =
  122.   let
  123.       plusPos = findIndices (\ p -> p == plus) s
  124.       minusPos = findIndices (\ p -> p == minus) s
  125.       leerPos = findIndices (\ p -> p == leer) s
  126.   in  if 0 == (length s) then 0
  127.       else if 0 < (length plusPos) then (berechne (take (head plusPos) s)) + (berechne (drop (1+(head plusPos)) s))
  128.       else if 0 < (length minusPos) then (berechne (take (head minusPos) s)) - (berechne (drop (1+(head minusPos)) s))
  129.       else if 0 < (length leerPos) then (berechne ((take (head leerPos) s) ++ (drop (1+(head leerPos)) s)))
  130.       else if 1 == (length s) then head $ findIndices (\e -> e == (head s)) [z0, z1, z2, z3, z4, z5, z6, z7, z8, z9]
  131.       else ((berechne [head s]) * 10^(length $ tail s)) + (berechne (tail s))
  132.  
  133. rotatePosition :: Position -> Position
  134. rotatePosition z | z == z1 = z1
  135. rotatePosition (Position h0 h1 h2 h3 h4 h5 h6 h7 h8 h9) = Position h9 h8 h7 h6 h4 h5 h3 h2 h1 h0
  136. rotateGleichung g =
  137.     Gleichung $ reverse $ map (\ p -> rotatePosition p) (gleichungToPositions g)
  138.  
  139.  
  140. parse :: [Char] -> Gleichung
  141. parse s = positionsToGleichung (map charToPosition s)
  142.  
  143. charToPosition :: Char -> Position
  144. charToPosition c
  145.   | c == '0' = z0 | c == '1' = z1 | c == '2' = z2 | c == '3' = z3 | c == '4' = z4
  146.   | c == '5' = z5 | c == '6' = z6 | c == '7' = z7 | c == '8' = z8 | c == '9' = z9
  147.   | c == '+' = plus | c == '-' = minus | c == '=' = gleich  | c == ' ' = leer
  148.  
  149. gleichung = "  185 + 15 = 270  "
  150.  
  151. main :: IO ()
  152. main = do
  153.   putStrLn $ "Die Lösung für " ++ gleichung
  154.   putStrLn (show (filter isBalanced (umlegenGleichung (parse gleichung))))
  155.   putStrLn (show (filter isBalanced (umlegenGleichung' (parse gleichung))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement