学生们成对地做项目。
规则:不允许任何人独自工作;每个项目都由两名学生完成。没有两个学生可以在一个以上的项目上合作。
每个项目由执行项目的两名学生的姓名和标记(0到100之间的整数)组成。
我正在编写一个名为legalCourse
的函数,该函数将CourseData
作为参数并返回Bool
。返回
True
如果课程数据是“合法的”,则表示它不包含上面列出的各种错误。对于所有剩余的功能。
样本输出:
*legalCourse [("John","Mary",75)]
True
* legalCourse [("John","John",75)]
False
* legalCourse [("John","Mary",75),("Peter","Paul",90),("John","Mary",90)]
False
* legalCourse [("John","Mary",75),("Peter","Paul",90),("Mary","John",90)]
False
*Assignment2> legalCourse [("John","Mary",75),("Peter","Paul",90),("Mary","Fred",90)]
True
代码:
type CourseData = [(String, String, Int)]
legalCourse :: CourseData -> Bool
legalCourse course = legal1 course && legal2 course
where
-- legal1 course means the course does not contain any projects like ("David","David",90)
legal1 [] = True
legal1 ((name1,name2,_):moreGroups) = name1 /= name2 && legal1 moreGroups
-- hasPair course name1 name2 means the course has a project done by name1 and name2
-- (in either order)
hasPair [] _ _ = False
hasPair ((a,b,_):moreGroups) name1 name2 =
(a == name1 && b == name2) || (a == name2 && b == name1) || hasPair moreGroups name1 name2
-- legal2 course means the course does not contain two projects done by the same
-- pair of students (regardless of order)
legal2 [] = True
legal2 [_] = True
legal2 ((name1,name2,_):moreProjects) =
not (hasPair moreProjects name1 name2) && legal2 moreProjects
我不理解hasPair
和legal2
,这部分是怎样的
hasPair ((a,b,_):moreGroups) name1 name2 =
(a == name1 && b == name2) || (a == name2 && b == name1) || hasPair moreGroups name1 name2
避免同一对人做项目?
答案 0 :(得分:2)
hasPair
在第一个参数中搜索与其下两个参数匹配的对。
空对列表没有与其他参数匹配的对,无论它们是什么。
hasPair [] _ _ = False
包含学生对(a, b, _)
和更多对moreGroups
的列表将与学生对name1
和name2
匹配,如果...
hasPair ((a,b,_):moreGroups) name1 name2 =
学生a
和b
为name1
和name2
。这可能以任何顺序发生。
(a == name1 && b == name2) || (a == name2 && b == name1) || ...
或者,如果剩余的一个群组是name1
和name2
。
... hasPair moreGroups name1 name2
hasPair
并不确定没有任何小组在做任何两个项目,但在考虑单个项目时,可以使用它来确保&#39 ;没有其他项目由同一组完成。
答案 1 :(得分:1)
hasPair xs name1 name2
检查列表xs
中是否有3个元组,其中前两个元素为name1
和name2
,但不按此顺序排列。 legal2
对每个项目组应用相同的检查,但这样每个项目对只会被检查一次。我认为' hasPair'使用类型签名可以更容易理解函数。在这里(我认为),更清楚地定义了这个功能:
hasPair :: Eq a => [(a, a, b)] -> a -> a -> Bool
hasPair [] _ _ = False
hasPair ((x1, x2, _):xs) y1 y2
| x1 == y1 && x2 == y2 = True
| x1 == y2 && x2 == y1 = True
| otherwise = hasPair xs y1 y2
答案 2 :(得分:0)
import Data.Set (Set,fromList)
data CourseData = CourseData String String Int deriving Show
制作忽略成绩的Eq
和Ord
个实例,并期望已对学生姓名进行排序。
instance Eq CourseData where
(==) (CourseData a b _) (CourseData a' b' _) = a == a' && b == b'
instance Ord CourseData where
compare (CourseData a b _) (CourseData a' b' _) = compare a a' `mappend` compare b b'
无法做出错误的" CourseData
通过对名称进行排序。
mkCourseData :: String -> String -> Int -> CourseData
mkCourseData a b = case compare a b of
-- Make sure the greater element is to the right
GT -> CourseData b a
_ -> CourseData a b
正如您所看到的,这会使Set
CourseData
符合您的规则:
test :: Set CourseData
test = fromList [mkCourseData "a" "b" 1,mkCourseData "b" "a" 2]
这出现在fromList [CourseData "a" "b" 2]
答案 3 :(得分:0)
另一种成分替代
import Data.List(sort,group)
legalCourse = null . filter (>1) . map length . group . sort . map dictOrder
where dictOder (x,y,_) = if (x<y) then (x,y) else (y,x)