Я студент cs, который недавно начал изучать Haskell. Я изо всех сил пытался найти способ интерпретировать на Haskell, но пока не мог. Мне нужна помощь. Вот объяснение. Есть три типа контента.
type Coord = (Int, Int)
-- Type-definition of a Cell: it is just a coordinate and an optional
AgentType.
-- Note: the agent type is optional and is Nothing in case the cell is
empty.
type Cell = (Coord, Maybe AgentType)
-- data definition for the agent types
data AgentType
= Red -- ^ Red agent
| Green -- ^ Green agent
| Blue -- ^ Blue agent
deriving (Eq, Show) -- Needed to compare for equality, otherwise would need to implement by ourself
Каждая ячейка имеет либо содержимое (может быть красным, зеленым или синим), либо пустое. Я пытаюсь найти соседей, у которых одинаковый контент со всех сторон, включая диагональные пути, которых всего 8. Если 40% соседей ячейки совпадают с ячейкой, вернуть true.
-- Returns True if an agent on a given cell is happy or not
isHappy :: Double -- ^ The satisfaction factor
-> [Cell] -- ^ All cells
-> Cell -- ^ The cell with the agent
-> Bool -- ^ True in case the agent is happy, False otherwise
isHappy ratio cs c
| ratio < 0.4 = False
| otherwise = True
where
moore = [(x-1,y-1),(x-1,y),(x-1,y+1),(x,y+1),(x+1,y+1),(x+1,y),(x+1,y-1),(x,y-1)]
-- here is where I got stuck
Я составил список «Moore», который содержит все направления, но я не уверен, как сравнивать «Cell» с «Neighbours [Cell]». Моя мысль следует на другом языке программирования,
if (TheCell[X-1,Y] == TheCell)){
stack ++;
}
...
...
ratio = stack / len(8);
Я искал, как интерпретировать в Haskell, но пока не нашел. Может быть, мой мыслительный процесс неверен. Пожалуйста, помогите мне в любом случае
-- Определение типа ячейки: это просто координата и необязательный тип агента. -- Примечание: тип агента является необязательным и имеет значение Ничего, если ячейка пуста. type Cell = (Coord, Возможно, AgentType)
@ATayler Спасибо за совет. Я чувствую, что мне нужно попытаться понять все это больше, потому что я еще больше запутался в вашем совете. Спасибо хоть
тип Координата = (Int, Int)
Сетка бесконечна? В каком случае входной список ячеек - это только непустые?
@ATayler, о, я понял, что ты имеешь в виду. так что я должен сначала изменить список Мура .. хм
у него есть границы. worldSize :: (Int, Int) worldSize = (20, 20)
data Cell = Cell Coord (Maybe AgentType)
inBounds :: Coord -> Bool
inBounds (x,y) = 0 <= x && x <= fst worldSize
&& 0 <= y && y <= snd worldSize
isHappy cs (Cell (x,y) a) = ratioSameNeighbours >= 0.4
where neighbourCoords = filter inBounds [(x-1,y-1),(x-1,y),(x-1,y+1),(x,y+1),(x+1,y+1),(x+1,y),(x+1,y-1),(x,y-1)]
sameNeighbours = filter ((\(Cell p ma) -> p `elem` neighbourCoords && ma == a) cs
ratioSameNeighbours = fromIntegral (length sameNeighbours) / fromIntegral (length neighbours)
То, что вы сказали, все еще немного занижено (например, может ли пустая ячейка быть счастливой?), но это только начало. Если входной массив ячеек должен быть двумерным (а не «разреженным» представлением, то есть одномерным списком только непустых ячеек), то ratio
должен быть немного другим.
Ваш исходный пост должен содержать все необходимое для ответа на вопрос. Пожалуйста, отредактируйте его, если есть дополнительная информация, которую вы хотите предоставить.
isHappy cs (Cell (x, y) a) = ratio >= 0.4 where …
, и я думаю, вам нужен fromIntegral
для результатов length
, так как Int
не Fractional
.
@JonPurdy imo первое изменение ухудшило читабельность, но оно более приемлемо с лучшими именами переменных. добавил fromIntegral
s.
Формат ввода, по-видимому, содержит только список ячеек, т.е. массив 1D, а не матрица 2D. Вам нужно сказать, откуда берутся
x
иy
(возможно, путем сопоставления по параметруc
). Вы не дали определениеCell
. Расчетratio
может быть выражен какfold
. Можете ли вы написать функцию для этого, учитывая некоторый список чисел? Тогда как вы будете генерировать этот список из координат ячеек?