Вот метод, который мы будем использовать:
- Мы свернем список, подсчитав, сколько элементов в каждой строке
- Мы, если какие-либо строки заполнены
- мы отфильтровываем координаты элементов в полных строках
Intro
import Data.Map as M
Шаг 1
countInRows :: [(Int,Int)] -> M.Map Int Int
countInRows items =
M.fromListWith (+) [(row,1) | (col,row) <- items]
Работает:
- преобразование элементов списка в вещи, которые говорят: «Я знаю о 1 полном квадрате в строке n »
- Объединение их вместе путем суммирования количества полных квадратов для каждой строки,
- Помещение этого результата в карту, связывающее строку с тем, насколько она заполнена
Шаг 2
isFull :: Int -> M.Map Int Int -> Int -> Bool
isFull width counts row =
M.findWithDefault 0 row counts >= width
Это позволит определить, насколько заполнена строка (еслиего нет на карте, тогда он должен иметь 0 полных квадратов).Если полных квадратов столько, сколько ширины доски, то строка должна быть полной.
Шаг 3 (собрать все вместе)
import Data.Map as M
removeFullRows :: Int -> [(Int,Int)] -> [(Int,Int)]
removeFullRows items =
filter (not . isFull . row) items where
counts = M.fromListWith (+) [(row,1) | (col,row) <- items]
isFull row =
M.findWithDefault 0 row counts >= width
row (x,y) = y
Мы отфильтровываем элементы, получаястрока, проверяя, заполнена ли она, а если нет, то сохраняем элемент.