When Is Cheryl's Birthday

大早上起来逛微博,看见@西瓜大丸子汤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的用处。。

原文地址:https://www.cnblogs.com/H-Col/p/4463303.html