NLinker icon

Haskell russian DSL

NLinker | PRO | 02/10/22 02:29:55 PM UTC | 0 ⭐ | 13661 👁️ | Never ⏰ | []
Haskell |

3.25 KB

|

None

|

0 👍

/

0 👎

import Data.List
 
{- Задача. Есть некоторое количество участников, которых нужно разбить
на две равные команды.-}
 
участников = ["Антон", "Маша", "Дима", "Юра", "Андрей", "Инна", "Олег", "Света"]
 
{- При этом некоторые пары участников хотят обязательно
быть в одной команде, а некоторые - обязательно в разных. -}
 
будутВместе = [("Антон", "Маша"), ("Олег", "Света")]
будутПорознь = [("Андрей", "Инна"), ("Олег", "Юра")]
 
{- Нужно найти все подходящие варианты разбиений. -}
 
main = показать $ подходящие `из` всехРазбиений участников
 
{- Немножко русских синонимов для стандартных функций. -}
 
размер = length
будетВ = (:)
infixr 5 `будетВ`
но = flip ($)
infixl 6 `но`
из = filter
в = elem
иначе = otherwise
пополам = (`quot` 2)
когдаИ True True = True
когдаИ False False = True
когдаИ _ _ = False
наоборот = not
одно `либо` другое = одно `когдаИ` другое `но` наоборот
все = all
черезЗапятую = intercalate ", "
показать =
    mapM_ $ \(первые, вторые) ->
        putStrLn $ черезЗапятую первые ++ " и их оппоненты " ++ черезЗапятую вторые
отобрать = filter
 
{- Ну и собственно простой переборный алгоритм. -}
 
ктоХочет вместе команде =
    все (\(первый, второй) ->
        (первый `в` команде) `когдаИ` (второй `в` команде)) вместе
 
ктоНеХочет вместе команде =
    все (\(первый, второй) ->
        (первый `в` команде) `либо` (второй `в` команде)) вместе
 
размерКоманды = размер участников `но` пополам
 
всехРазбиений = безДублей . разбиения [] [] where
    безДублей [] = []
    безДублей (вотЭта:пропустить:остальных) =
        вотЭта `будетВ` остальных `но` безДублей
    разбиения первой второй другие
        | размер первой == размерКоманды = [(первой, второй ++ другие)]
        | размер второй == размерКоманды = [(первой ++ другие, второй)]
        | иначе = let новый : остальные = другие in.
            разбиения (новый `будетВ` первой) второй остальные ++
            разбиения первой (новый `будетВ` второй) остальные
 
подходящие (вПервой, воВторой) =
    ктоХочет будутВместе вПервой &&
    ктоНеХочет будутПорознь вПервой
 

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎