Ding

When Is Cheryl's Birthday

大早上起来逛微博,看见@西瓜大丸子汤Po的一个逻辑题,遂点开看之…

原文链接:http://nbviewer.ipython.org/url/norvig.com/ipython/Cheryl.ipynb

然后发现这不是TM的猜卡牌的那个题么,某次面试的时候还跪了来着。。接着就魔性大发,试着用JAVA来学习一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
package cn.edu.bipt.hcol;
import java.util.ArrayList;
import java.util.List;
/**
* This logic puzzle has been making the rounds:
*
* Albert and Bernard just became friends with Cheryl, and they want to know
* when her birtxhday is. Cheryl gave them a list of 10 possible dates:
*
* May 15 May 16 May 19 June 17 June 18 July 14 July 16 August 14 August 15
* August 17 Cheryl then tells Albert and Bernard separately the month and the
* day of the birthday respectively.
*
* Albert: I don't know when Cheryl's birthday is, but I know that Bernard does
* not know too.
*
* Bernard: At first I don't know when Cheryl's birthday is, but I know now.
*
* Albert: Then I also know when Cheryl's birthday is.
*
* So when is Cheryl's birthday?
*
* @author Colin
*
*/
public class WhenIsCherylsBirthday {
public static final String DATES[] = { "May 15", "May 16", "May 19",
"June 17", "June 18", "July 14", "July 16", "August 14",
"August 15", "August 17" };
/**
* Albert : I don't know when Cheryl's birthday is, but I know that Bernard
* does not know too.
*
* That means: Albert : After Cheryl told me the month of her birthdate, I
* didn't know her birthday, I don't know which day Cheryl told Bernard, but
* I know that for all of the possible dates, if Bernard is told that day ,
* he wouldn't know the birthdate.
*
*/
private boolean statement3(String date) {
// When Cheryl told the month to Albert
// Albert : I know if Bernard doesn't knows Cheryl birthday when Cheryl
// told him the day
// that means the day is not unique in DATES
// that means I know the month and I know the days but Bernard doesn't
// konws
boolean temper = true;
List<String> possible_dates = tell(getMonth(date));
for (int i = 0; i < possible_dates.size(); i++) {
if (know(tell(getDay(possible_dates.get(i))))) {
temper = false;
break;
}
}
return !know(possible_dates) && temper;
}
/**
* Bernard: At first I don't know when Cheryl's birthday is, but I know now.
*
* Bernard: At first time Cheryl told me the day,and i didn't know. Then I
* considered just the dates for which Albert's statement3 is true,and now I
* know.
*
* @param date
* @return
*/
private boolean statement4(String date) {
List<String> atFirst = tell(getDay(date));
List<String> filterItem = new ArrayList<String>();
for (String item : atFirst) {
if (statement3(item) == true)
filterItem.add(item);
}
return !know(atFirst) && know(filterItem);
}
/**
* Albert: Then I also know when Cheryl's birthday is.
*
* @param date
* @return
*/
private boolean statement5(String date) {
List<String> mList = tell(getMonth(date));
List<String> filterItem = new ArrayList<String>();
for (String item : mList) {
if (true == statement4(item))
filterItem.add(item);
}
return know(filterItem);
}
/**
* filter(statement4 , filter(statement3 , DATES)) filter(statement4 ,
* tell(getMonth(date)))
*
* @param date
* @return
*/
private boolean statement3to5(String date) {
return statement3(date) && statement4(date) && statement5(date);
}
private String getCherylsBirthday(String dates[]) {
String birthday = "";
for (String date : dates) {
if (true == statement3to5(date))
birthday = date;
}
return birthday;
}
/**
* Cheryl tells a part of birthday to someone; Return a new list of possible
* dates that match the part.
*
* @param part
* @param return
*/
private List<String> tell(String part) {
List<String> mList = new ArrayList<String>();
char c = part.charAt(0);
// 匹配“月”
if (c >= 'A' && c <= 'Z') {
for (String date : DATES) {
if (part.equals(getMonth(date))) {
mList.add(date);
}
}
} else {// 匹配“日”
for (String date : DATES) {
if (part.equals(getDay(date))) {
mList.add(date);
}
}
}
return mList;
}
/**
* A person knows the birthday if they have exactly one possible date
*
* @return
*/
private boolean know(List<String> mList) {
return mList.size() == 1;
}
/**
* 获取data中的“月”的数据
*
* @param data
* getMonth("May 15")
* @return May
*/
private String getMonth(String date) {
return date.split(" ")[0];
}
/**
* 获取data中的“日”的数据
*
* @param data
* getMonth("May 15")
* @return 15
*/
private String getDay(String date) {
return date.split(" ")[1];
}
public static void main(String[] args) {
WhenIsCherylsBirthday whenIsCherylsBirthday = new WhenIsCherylsBirthday();
System.out.println(whenIsCherylsBirthday.getCherylsBirthday(DATES));
}
}

顺着原文中的思路和Python代码修改的…话说Python还真是叼炸天啊…all()和filter()这俩函数简直叼…膜拜之…

疑惑:还是不太明白statement3的用处。。

你的认可是我最大的动力!