大早上起来逛微博,看见@西瓜大丸子汤Po的一个逻辑题,遂点开看之...
原文链接:http://nbviewer.ipython.org/url/norvig.com/ipython/Cheryl.ipynb
然后发现这不是TM的猜卡牌的那个题么,某次面试的时候还跪了来着。。接着就魔性大发,试着用JAVA来学习一下
1 package cn.edu.bipt.hcol; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /** 7 * This logic puzzle has been making the rounds: 8 * 9 * Albert and Bernard just became friends with Cheryl, and they want to know 10 * when her birtxhday is. Cheryl gave them a list of 10 possible dates: 11 * 12 * May 15 May 16 May 19 June 17 June 18 July 14 July 16 August 14 August 15 13 * August 17 Cheryl then tells Albert and Bernard separately the month and the 14 * day of the birthday respectively. 15 * 16 * Albert: I don't know when Cheryl's birthday is, but I know that Bernard does 17 * not know too. 18 * 19 * Bernard: At first I don't know when Cheryl's birthday is, but I know now. 20 * 21 * Albert: Then I also know when Cheryl's birthday is. 22 * 23 * So when is Cheryl's birthday? 24 * 25 * @author Colin 26 * 27 */ 28 public class WhenIsCherylsBirthday { 29 30 public static final String DATES[] = { "May 15", "May 16", "May 19", 31 "June 17", "June 18", "July 14", "July 16", "August 14", 32 "August 15", "August 17" }; 33 34 /** 35 * Albert : I don't know when Cheryl's birthday is, but I know that Bernard 36 * does not know too. 37 * 38 * That means: Albert : After Cheryl told me the month of her birthdate, I 39 * didn't know her birthday, I don't know which day Cheryl told Bernard, but 40 * I know that for all of the possible dates, if Bernard is told that day , 41 * he wouldn't know the birthdate. 42 * 43 */ 44 private boolean statement3(String date) { 45 // When Cheryl told the month to Albert 46 // Albert : I know if Bernard doesn't knows Cheryl birthday when Cheryl 47 // told him the day 48 // that means the day is not unique in DATES 49 // that means I know the month and I know the days but Bernard doesn't 50 // konws 51 boolean temper = true; 52 53 List<String> possible_dates = tell(getMonth(date)); 54 55 for (int i = 0; i < possible_dates.size(); i++) { 56 if (know(tell(getDay(possible_dates.get(i))))) { 57 temper = false; 58 break; 59 } 60 } 61 62 return !know(possible_dates) && temper; 63 } 64 65 /** 66 * Bernard: At first I don't know when Cheryl's birthday is, but I know now. 67 * 68 * Bernard: At first time Cheryl told me the day,and i didn't know. Then I 69 * considered just the dates for which Albert's statement3 is true,and now I 70 * know. 71 * 72 * @param date 73 * @return 74 */ 75 private boolean statement4(String date) { 76 List<String> atFirst = tell(getDay(date)); 77 78 List<String> filterItem = new ArrayList<String>(); 79 for (String item : atFirst) { 80 if (statement3(item) == true) 81 filterItem.add(item); 82 } 83 84 return !know(atFirst) && know(filterItem); 85 } 86 87 /** 88 * Albert: Then I also know when Cheryl's birthday is. 89 * 90 * @param date 91 * @return 92 */ 93 private boolean statement5(String date) { 94 List<String> mList = tell(getMonth(date)); 95 96 List<String> filterItem = new ArrayList<String>(); 97 for (String item : mList) { 98 if (true == statement4(item)) 99 filterItem.add(item); 100 } 101 102 return know(filterItem); 103 } 104 105 /** 106 * filter(statement4 , filter(statement3 , DATES)) filter(statement4 , 107 * tell(getMonth(date))) 108 * 109 * @param date 110 * @return 111 */ 112 private boolean statement3to5(String date) { 113 return statement3(date) && statement4(date) && statement5(date); 114 } 115 116 private String getCherylsBirthday(String dates[]) { 117 String birthday = ""; 118 for (String date : dates) { 119 if (true == statement3to5(date)) 120 birthday = date; 121 } 122 return birthday; 123 } 124 125 /** 126 * Cheryl tells a part of birthday to someone; Return a new list of possible 127 * dates that match the part. 128 * 129 * @param part 130 * @param return 131 */ 132 private List<String> tell(String part) { 133 List<String> mList = new ArrayList<String>(); 134 char c = part.charAt(0); 135 136 // 匹配“月” 137 if (c >= 'A' && c <= 'Z') { 138 for (String date : DATES) { 139 if (part.equals(getMonth(date))) { 140 mList.add(date); 141 } 142 } 143 } else {// 匹配“日” 144 for (String date : DATES) { 145 if (part.equals(getDay(date))) { 146 mList.add(date); 147 } 148 } 149 } 150 return mList; 151 } 152 153 /** 154 * A person knows the birthday if they have exactly one possible date 155 * 156 * @return 157 */ 158 private boolean know(List<String> mList) { 159 return mList.size() == 1; 160 } 161 162 /** 163 * 获取data中的“月”的数据 164 * 165 * @param data 166 * getMonth("May 15") 167 * @return May 168 */ 169 private String getMonth(String date) { 170 return date.split(" ")[0]; 171 } 172 173 /** 174 * 获取data中的“日”的数据 175 * 176 * @param data 177 * getMonth("May 15") 178 * @return 15 179 */ 180 private String getDay(String date) { 181 return date.split(" ")[1]; 182 } 183 184 public static void main(String[] args) { 185 WhenIsCherylsBirthday whenIsCherylsBirthday = new WhenIsCherylsBirthday(); 186 187 System.out.println(whenIsCherylsBirthday.getCherylsBirthday(DATES)); 188 } 189 }
顺着原文中的思路和Python代码修改的...话说Python还真是叼炸天啊...all()和filter()这俩函数简直叼...膜拜之...
疑惑:还是不太明白statement3的用处。。