Moderate 猜测序列hit或是pseudo-hit @CareerCup

本文详细介绍了MasterMind游戏的算法实现过程,通过一种高效的方法计算玩家猜测与正确答案之间的匹配程度,包括直接命中(hit)和颜色匹配(pseudo-hit)的数量。文章提供了完整的Java代码示例,并对比了一种次优解法。

思路不难,关键是如何写出结构清晰的代码,另外注意到的就是用到的frequencies数组来使得复杂度由暴力的O(n2)到O(n)



package Moderate;

import java.util.Random;


/**
 * The Game of Master Mind is played as follows:

The computer has four slots containing balls that are red (R ), yellow (Y), green (G) or blue (B). For example, the computer might have RGGB (e.g., Slot #1 is red, Slots #2 and #3 are green, Slot #4 is blue).

You, the user, are trying to guess the solution. You might, for example, guess YRGB.When you guess the correct color for the correct slot, you get a “hit”. If you guess a color that exists but is in the wrong slot, you get a “pseudo-hit”. For example, the guess YRGB has 2 hits and one pseudo hit.

For each guess, you are told the number of hits and pseudo-hits. Write a method that, given a guess and a solution, returns the number of hits and pseudo hits.

译文:

Master Mind游戏规则如下:

4个槽,里面放4个球,球的颜色有4种,红(R ),黄(Y),绿(G),蓝(B)。比如, 给出一个排列RGGB,表示第一个槽放红色球,第二和第三个槽放绿色球,第四个槽放蓝色球。

你要去猜这个排列。比如你可能猜排列是:YRGB。当你猜的颜色是正确的,位置也是正确的, 你就得到一个hit,比如上面第3和第4个槽猜的和真实排列一样(都是GB),所以得到2个hit。 如果你猜的颜色在真实排列中是存在的,但位置没猜对,你就得到一个pseudo-hit。比如, 上面的R,猜对了颜色,但位置没对,得到一个pseudo-hit。

对于你的每次猜测,你会得到两个数:hits和pseudo-hits。写一个函数, 输入一个真实排列和一个猜测,返回hits和pseudo-hits。
 *
 */
public class S17_5 {

	public static class Result {
        public int hits;
        public int pseudoHits;
        
        public Result(int h, int p) {
            hits = h;
            pseudoHits = p;
        }
        
        public Result() {
        }
        
        public String toString() {
            return "(" + hits + ", " + pseudoHits + ")";
        }
	};

	public static int code(char c) {
        switch (c) {
        case 'B':
                return 0;
        case 'G':
                return 1;
        case 'R':
                return 2;
        case 'Y':
                return 3;
        default:
                return -1;
        }
	}

	public static int MAX_COLORS = 4;

	public static Result estimate(String guess, String solution) {
        if (guess.length() != solution.length()) return null;
        Result res = new Result();
        int[] frequencies = new int[MAX_COLORS];
            
        /* Compute hits and built frequency table */
        for (int i = 0; i < guess.length(); i++) {
            if (guess.charAt(i) == solution.charAt(i)) {
                res.hits++;
            } else {
                /* Only increment the frequency table (which will be used for pseudo-hits) if
                 * it's not a hit. If it's a hit, the slot has already been "used." */
                int code = code(solution.charAt(i));
                if (code >= 0) {
                	frequencies[code]++;		// 把答案的分布存在frequencies数组中
                }
            }
        }
        
        /* Compute pseudo-hits */
        for (int i = 0; i < guess.length(); i++) {
            int code = code(guess.charAt(i));
            if (code >= 0 && frequencies[code] > 0 && guess.charAt(i) != solution.charAt(i)) {
                res.pseudoHits++;
                frequencies[code]--;
            }
        }
        return res;
	}

/************************** TEST CODE **********************************/

	public static char letterFromCode(int k) {
        switch (k) {
        case 0:
                return 'B';
        case 1:
                return 'G';
        case 2:
                return 'R';
        case 3:
                return 'Y';
        default:
                return '0';
        }                
	}

	public static Result estimateBad(String g, String s) {
        char[] guess = g.toCharArray();
        char[] solution = s.toCharArray();
        int hits = 0;
        for (int i = 0; i < guess.length; i++) {
            if (guess[i] == solution[i]) {
                hits++;
                solution[i] = '0';
                guess[i] = '0';
            }
        }
        
        int pseudohits = 0;
        
        for (int i = 0; i < guess.length; i++) {
            if (guess[i] != '0') {
                for (int j = 0; j < solution.length; j++) {
                    if (solution[j] != '0') {
                        if (solution[j] == guess[i]) {
                            pseudohits++;
                            solution[j] = '0';
                            break;
                        }
                    }
                }
            }
        }
        
        return new Result(hits, pseudohits);
	}
	
	public static String randomString() {
        int length = 4;
        char[] str = new char[length];
        Random generator = new Random();
        
        for (int i = 0; i < length; i++) {
            int v = generator.nextInt(4);
            char c = letterFromCode(v);
            str[i] = c;
        }
        
        return String.valueOf(str);
	}
	
	public static boolean test(String guess, String solution) {
        Result res1 = estimate(guess, solution);
        Result res2 = estimateBad(guess, solution);
        if (res1.hits == res2.hits && res1.pseudoHits == res2.pseudoHits) {
            return true;
        } else {
            System.out.println("FAIL: (" + guess + ", " + solution + "): " + res1.toString() + " | " + res2.toString());
            return false;
        }
	}
	
	public static boolean testRandom() {
        String guess = randomString();
        String solution = randomString();
        return test(guess, solution);
	}
	
	public static boolean test(int count) {
        for (int i = 0; i < count; i++) {
            if (!testRandom()) {
                    return true;
            }
        }
        return false;
	}
	
	/********************** END TEST CODE ************************/
	
	
	public static void main(String[] args) {
		test(1000);
	}
}


[root@yfw jsxc]# npm install --no-bin-links npm WARN acorn-import-phases@1.0.4 requires a peer of acorn@^8.14.0 but none is installed. You must install peer dependencies yourself. npm WARN getscreenmedia@5.1.2 requires a peer of webrtc-adapter@^6.0.0 but none is installed. You must install peer dependencies yourself. npm WARN xmpp-jid@1.3.0 requires a peer of node-stringprep@^0.8.0 but none is installed. You must install peer dependencies yourself. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @parcel/watcher-android-arm64@2.5.1 (node_modules/@parcel/watcher-android-arm64): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @parcel/watcher-android-arm64@2.5.1: wanted {"os":"android","arch":"arm64"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @parcel/watcher-darwin-arm64@2.5.1 (node_modules/@parcel/watcher-darwin-arm64): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @parcel/watcher-darwin-arm64@2.5.1: wanted {"os":"darwin","arch":"arm64"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @parcel/watcher-darwin-x64@2.5.1 (node_modules/@parcel/watcher-darwin-x64): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @parcel/watcher-darwin-x64@2.5.1: wanted {"os":"darwin","arch":"x64"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @parcel/watcher-freebsd-x64@2.5.1 (node_modules/@parcel/watcher-freebsd-x64): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @parcel/watcher-freebsd-x64@2.5.1: wanted {"os":"freebsd","arch":"x64"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @parcel/watcher-linux-arm-glibc@2.5.1 (node_modules/@parcel/watcher-linux-arm-glibc): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @parcel/watcher-linux-arm-glibc@2.5.1: wanted {"os":"linux","arch":"arm"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @parcel/watcher-linux-arm-musl@2.5.1 (node_modules/@parcel/watcher-linux-arm-musl): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @parcel/watcher-linux-arm-musl@2.5.1: wanted {"os":"linux","arch":"arm"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @parcel/watcher-linux-arm64-glibc@2.5.1 (node_modules/@parcel/watcher-linux-arm64-glibc): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @parcel/watcher-linux-arm64-glibc@2.5.1: wanted {"os":"linux","arch":"arm64"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @parcel/watcher-linux-arm64-musl@2.5.1 (node_modules/@parcel/watcher-linux-arm64-musl): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @parcel/watcher-linux-arm64-musl@2.5.1: wanted {"os":"linux","arch":"arm64"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @parcel/watcher-win32-arm64@2.5.1 (node_modules/@parcel/watcher-win32-arm64): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @parcel/watcher-win32-arm64@2.5.1: wanted {"os":"win32","arch":"arm64"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @parcel/watcher-win32-ia32@2.5.1 (node_modules/@parcel/watcher-win32-ia32): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @parcel/watcher-win32-ia32@2.5.1: wanted {"os":"win32","arch":"ia32"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @parcel/watcher-win32-x64@2.5.1 (node_modules/@parcel/watcher-win32-x64): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @parcel/watcher-win32-x64@2.5.1: wanted {"os":"win32","arch":"x64"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.3 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules/webpack-dev-server/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) audited 1644 packages in 8.908s 266 packages are looking for funding run `npm fund` for details found 64 vulnerabilities (2 low, 28 moderate, 28 high, 6 critical) run `npm audit fix` to fix them, or `npm audit` for details [root@yfw jsxc]#
11-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值