|
| 1 | +/** |
| 2 | + * You are playing the following Bulls and Cows game with your friend: |
| 3 | + * You write down a number and ask your friend to guess what the number is. |
| 4 | + * Each time your friend makes a guess, you provide a hint that indicates |
| 5 | + * how many digits in said guess match your secret number exactly in both digit |
| 6 | + * and position (called "bulls") and how many digits match the secret number |
| 7 | + * but locate in the wrong position (called "cows"). Your friend will use |
| 8 | + * successive guesses and hints to eventually derive the secret number. |
| 9 | + * |
| 10 | + * Bulls and Cows https://en.wikipedia.org/wiki/Bulls_and_Cows |
| 11 | + * |
| 12 | + * For example: |
| 13 | + * |
| 14 | + * Secret number: "1807" |
| 15 | + * Friend's guess: "7810" |
| 16 | + * |
| 17 | + * Hint: 1 bull and 3 cows. (The bull is 8, the cows are 0, 1 and 7.) |
| 18 | + * Write a function to return a hint according to the secret number and |
| 19 | + * friend's guess, use A to indicate the bulls and B to indicate the cows. |
| 20 | + * In the above example, your function should return "1A3B". |
| 21 | + * |
| 22 | + * Please note that both secret number and friend's guess may contain duplicate digits, for example: |
| 23 | + * |
| 24 | + * Secret number: "1123" |
| 25 | + * Friend's guess: "0111" |
| 26 | + * |
| 27 | + * In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a |
| 28 | + * cow, and your function should return "1A1B". |
| 29 | + * |
| 30 | + * You may assume that the secret number and your friend's guess only contain |
| 31 | + * digits, and their lengths are always equal. |
| 32 | + */ |
| 33 | + |
| 34 | + |
| 35 | +public class BullsAndCows299 { |
| 36 | + public String getHint(String secret, String guess) { |
| 37 | + |
| 38 | + Map<Character, Integer> secrets = new HashMap<>(); |
| 39 | + Map<Character, Integer> guesses = new HashMap<>(); |
| 40 | + |
| 41 | + Map<String, Integer> counts = new HashMap<>(); |
| 42 | + counts.put("bull", 0); |
| 43 | + counts.put("cows", 0); |
| 44 | + |
| 45 | + List<Integer> left = new ArrayList<>(); |
| 46 | + |
| 47 | + for (int i=0; i<guess.length(); i++) { |
| 48 | + Character c1 = secret.charAt(i); |
| 49 | + Character c2 = guess.charAt(i); |
| 50 | + |
| 51 | + if (c1.equals(c2)) { |
| 52 | + counts.put("bull", counts.get("bull")+1); |
| 53 | + } else { |
| 54 | + secrets.put(c1, secrets.getOrDefault(c1, 0)+1); |
| 55 | + guesses.put(c2, guesses.getOrDefault(c2, 0)+1); |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + for (Map.Entry<Character, Integer> e: guesses.entrySet()) { |
| 60 | + if (secrets.containsKey(e.getKey())) { |
| 61 | + counts.put("cows", counts.get("cows") + Math.min(secrets.get(e.getKey()), e.getValue())); |
| 62 | + } |
| 63 | + } |
| 64 | + |
| 65 | + return String.format("%dA%dB", counts.get("bull"), counts.get("cows")); |
| 66 | + } |
| 67 | + |
| 68 | + |
| 69 | + public String getHint2(String secret, String guess) { |
| 70 | + |
| 71 | + Map<Character, Integer> secrets = new HashMap<>(); |
| 72 | + Map<Character, Integer> guesses = new HashMap<>(); |
| 73 | + |
| 74 | + Map<String, Integer> counts = new HashMap<>(); |
| 75 | + counts.put("bull", 0); |
| 76 | + counts.put("cows", 0); |
| 77 | + |
| 78 | + for (int i=0; i<guess.length(); i++) { |
| 79 | + Character c1 = secret.charAt(i); |
| 80 | + Character c2 = guess.charAt(i); |
| 81 | + |
| 82 | + if (c1.equals(c2)) { |
| 83 | + counts.put("bull", counts.get("bull")+1); |
| 84 | + } else { |
| 85 | + if (secrets.containsKey(c2) && secrets.get(c2) > 0) { |
| 86 | + secrets.put(c2, secrets.get(c2)-1); |
| 87 | + counts.put("cows", counts.get("cows")+1); |
| 88 | + } else { |
| 89 | + guesses.put(c2, guesses.getOrDefault(c2, 0)+1); |
| 90 | + } |
| 91 | + if (guesses.containsKey(c1) && guesses.get(c1) > 0) { |
| 92 | + guesses.put(c1, guesses.get(c1)-1); |
| 93 | + counts.put("cows", counts.get("cows")+1); |
| 94 | + } else { |
| 95 | + secrets.put(c1, secrets.getOrDefault(c1, 0)+1); |
| 96 | + } |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + return String.format("%dA%dB", counts.get("bull"), counts.get("cows")); |
| 101 | + } |
| 102 | + |
| 103 | + /** |
| 104 | + * https://discuss.leetcode.com/topic/28463/one-pass-java-solution |
| 105 | + */ |
| 106 | + public String getHint3(String secret, String guess) { |
| 107 | + int bulls = 0; |
| 108 | + int cows = 0; |
| 109 | + int[] numbers = new int[10]; |
| 110 | + for (int i = 0; i<secret.length(); i++) { |
| 111 | + if (secret.charAt(i) == guess.charAt(i)) bulls++; |
| 112 | + else { |
| 113 | + if (numbers[secret.charAt(i)-'0']++ < 0) cows++; |
| 114 | + if (numbers[guess.charAt(i)-'0']-- > 0) cows++; |
| 115 | + } |
| 116 | + } |
| 117 | + return bulls + "A" + cows + "B"; |
| 118 | + } |
| 119 | + |
| 120 | +} |
0 commit comments