Skip to content

Instantly share code, notes, and snippets.

@ivanovsaleksejs
Last active August 29, 2015 14:10
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save ivanovsaleksejs/0048d95401ffa459cd4d to your computer and use it in GitHub Desktop.
My solution to Secret Santa problem
module Main where
-- Pierakstīju komentārus katrai funkcijai
-- Tipus neaprakstīju, jo lol nau veerc, kompilātors visu saprot, bet kods bez tipiem ir vieglāk lasāms
-- Nepieciešamas pakas, kas nenāk ar default haskell-platform: monad-loops, random-shuffle
import Control.Applicative
import Control.Monad.Loops
import System.Environment
import System.Random.Shuffle
--
-- Pāri, kas nevar dāvināt viens otram
--
pairs = [(2,7), (3,9), (10,1)]
--
-- Dalībnieku vārdi
--
persons = ["Valdis", "Guntis", "Dainis", "Vilnis", "Agris", "Dzintars",
"Līga", "Aina", "Skaidrīte", "Ilga", "Daiga", "Indra", "Rasma", "Austra", "Rudīte"]
personsTo = ["Valdim", "Guntim", "Dainim", "Vilnim", "Agrim", "Dzintaram",
"Līgai", "Ainai", "Skaidrītei", "Ilgai", "Daigai", "Indrai", "Rasmai", "Austrai", "Rudītei"]
--
-- Generējam Just listi vai Nothing, ja liste neatbilst
--
getList l
| isValid zipped = Just zipped
| otherwise = Nothing
where
zipped = zip [0 .. length l - 1] l
--
-- Filtrs listes ģenerēšanai
-- Apvieno pārbaudi uz davināšanu pašam sev un uz neatļautiem pāriem
--
isValid list =
checkSelfGifts list
&& checkPairs list pairs
&& checkPairs list pairsReversed
where
-- pairsReversed = map (\(a,b) -> (b,a)) pairs
-- Tīri demonstrācijai - tas pats rezultāts, bet map vietā
-- izmantojam list comprehensions
-- Rezultātā tiekam vaļā no lambda funkcijas
pairsReversed = [(b,a) | (a,b) <- pairs]
--
-- Pārbaudam, vai neviens nedāvinā pats(-i) sev
--
checkSelfGifts = all $ uncurry (/=)
--
-- Pārbaudam, vai sarakstā nav neatļautie pāri
--
checkPairs list = not . any (`elem` list)
--
-- Atgriežam pirmo valido listi
--
firstValid n = untilJust $ getList <$> shuffleM [0 .. n - 1]
--
-- Galvēna funkcija
-- Dalībnieku skaitu ņēmam no args, piemēram ./santa 15
-- Pēc noklusējuma tiek izmantots skaitlis 15
--
main = putStrLn =<< unlines . map gifterLine <$> (firstValid . personCount =<< getArgs)
where
gifterLine (from, to) = (persons !! from) ++ " dāvina dāvanu " ++ (personsTo !! to)
personCount = head . filter (\x -> 2 <= x && x <= cnt) . map read . (++ [show cnt])
cnt = length persons
--
-- Piemēri
--
$ ./santa
Valdis dāvina dāvanu Vilnim
Guntis dāvina dāvanu Ilgai
Dainis dāvina dāvanu Agrim
Vilnis dāvina dāvanu Līgai
Agris dāvina dāvanu Daigai
Dzintars dāvina dāvanu Skaidrītei
Līga dāvina dāvanu Rasmai
Aina dāvina dāvanu Indrai
Skaidrīte dāvina dāvanu Guntim
Ilga dāvina dāvanu Dzintaram
Daiga dāvina dāvanu Rudītei
Indra dāvina dāvanu Ainai
Rasma dāvina dāvanu Dainim
Austra dāvina dāvanu Valdim
Rudīte dāvina dāvanu Austrai
$ ./santa 15
Valdis dāvina dāvanu Agrim
Guntis dāvina dāvanu Ainai
Dainis dāvina dāvanu Līgai
Vilnis dāvina dāvanu Austrai
Agris dāvina dāvanu Rasmai
Dzintars dāvina dāvanu Daigai
Līga dāvina dāvanu Ilgai
Aina dāvina dāvanu Indrai
Skaidrīte dāvina dāvanu Dainim
Ilga dāvina dāvanu Skaidrītei
Daiga dāvina dāvanu Rudītei
Indra dāvina dāvanu Valdim
Rasma dāvina dāvanu Dzintaram
Austra dāvina dāvanu Vilnim
Rudīte dāvina dāvanu Guntim
$ ./santa 10
Valdis dāvina dāvanu Agrim
Guntis dāvina dāvanu Līgai
Dainis dāvina dāvanu Ilgai
Vilnis dāvina dāvanu Valdim
Agris dāvina dāvanu Skaidrītei
Dzintars dāvina dāvanu Vilnim
Līga dāvina dāvanu Ainai
Aina dāvina dāvanu Dzintaram
Skaidrīte dāvina dāvanu Dainim
Ilga dāvina dāvanu Guntim
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment