寻找谢丽尔生日的算法
这个例子考察了Julia编程语言中逻辑任务"Cheryl's birthday"的实现。
导言
谢丽尔的生日是2015年提出的一个流行的逻辑问题。 在其中,两个朋友,阿尔伯特和伯纳德,试图根据一组有限的日期和逻辑陈述来确定谢丽尔的生日。 问题的解决方案是基于对人物所拥有的信息的分析和对不可能的选择的一致消除。
设置任务:
艾伯特和伯纳德刚认识谢丽尔。 他们想知道她的生日是什么时候。 谢丽尔为他们提供了十个可能的日期:5月15日,5月16日,5月19日,6月17日,6月18日,7月14日,7月16日,8月14日,8月15日和8月17日。
| 五月 | 15 | 16 | 19 | |||
| 六月 | 17 | 18 | ||||
| 七月份 | 14 | 16 | ||||
| 八月份 | 14 | 15 | 17 | 
谢丽尔然后告诉阿尔伯特她出生的月份,伯纳德的日子。 之后,进行了对话。
*阿尔伯特:我不知道谢丽尔的生日是什么时候,但我知道伯纳德也不知道。
*伯纳德:起初,我不知道谢丽尔的生日是什么时候,但我现在知道。
*阿尔伯特:现在我也知道谢丽尔的生日是什么时候。
谢丽尔的生日是什么时候?
主要部分
源数据和辅助功能
我们以[日,月]的格式设置谢丽尔生日的可能日期。
const dates = [[15, "Мая"], [16, "Мая"], [19, "Мая"], [17, "Июня"], [18, "Июня"],
    [14, "Июля"], [16, "Июля"], [14, "Августа"], [15, "Августа"], [17, "Августа"]]
定义查找唯一日期的函数。
唯一的一天是列表中只出现一次的一天。
uniqueday(parr) = filter(x -> count(y -> y[1] == x[1], parr) == 1, parr)
逻辑分析的第一步:用独特的日子去除月份
在第一步中,我们排除那些有独特日子的月份。
这是因为阿尔伯特说他知道伯纳德无法知道确切的日期。
因此,生日不能在一个月内包含一个独特的日子。
const f1 = filter(m -> !(m[2] in [d[2] for d in uniqueday(dates)]), dates)
第二步:在剩余数据中搜索唯一天数
现在我们再次寻找独特的日子,但在剩余的日期列表中(f1).
这一步对应于伯纳德的假设,现在可以确定日期。
const f2 = uniqueday(f1)
第三步:找到最终日期
在最后一步,我们只留下那些日期。,
这是在唯一可能的日期的月份。
这与阿尔伯特的结论相对应,现在也可以确定日期。
const bday = filter(x -> count(m -> m[2] == x[2], f2) == 1, f2)[]
我们输出响应。
println("День рождения Шерил $(bday[1]) $(bday[2]).")
结论
在这个例子中,我们详细介绍了Julia语言中逻辑任务"Cheryl's birthday"的实现。 通过顺序过滤数据并做出逻辑假设,我们能够确定生日的确切日期。 这个例子展示了Julia语言在解决逻辑编程和数据分析问题方面的力量和简洁性。
该示例是使用[Rosetta代码]的材料开发的(https://rosettacode.org/wiki/Cheryl's_birthday )