【问题标题】:Google Foobar Challenge Level 2 "Hey-I-Already-Did-That" [closed]Google Foobar 挑战 2 级“嘿,我已经做到了”[关闭]
【发布时间】:2025-12-20 07:15:12
【问题描述】:

我需要帮助来解决 Google 的 Foobar 挑战的第二级。


指挥官 Lambda 使用自动算法将奴才随机分配给任务,以使她的奴才保持警觉。但是你已经注意到算法中的一个缺陷——它最终会循环回到自身,因此它不会在迭代时分配新的 minions,而是陷入一个值循环,因此相同的 minions 最终会重复执行相同的任务并且再次。您认为向指挥官 Lambda 证明这一点将有助于您为下一次晋升提供依据。

你已经算出算法有如下过程:

1) 从一个随机的 minion ID n 开始,它是一个长度为 k 的非负整数,以 b 为底
2) 将 x 和 y 定义为长度为 k 的整数。 x 的 n 位按降序排列,y 的 n 位按升序排列
3) 定义 z = x - y。如有必要,向 z 添加前导零以保持长度 k
4) 赋值n = z 得到下一个minion ID,返回步骤2

例如,给定 minion ID n = 1211, k = 4, b = 10, 那么 x = 2111, y = 1112 and z = 2111 - 1112 = 0999. 那么下一个 minion ID 将是 n = 0999 并且算法再次迭代:x = 9990、y = 0999 和 z = 9990 - 0999 = 8991,依此类推。

根据 n、k(从 n 派生)和 b 的值,算法在某些时候会达到一个循环,例如通过达到一个常数值。例如,从 n = 210022, k = 6, b = 3 开始,算法将到达值的循环 [210111, 122221, 102212],无论它继续迭代多少次,它都将停留在这个循环中。从 n = 1211 开始,例程将到达整数 6174,并且由于 7641 - 1467 是 6174,因此无论迭代多少次,它都将保持该值。

给定一个 minion ID 作为字符串 n,表示长度为 k 的非负整数,以 b 为底,其中 2

测试用例:
Solution.solution("1211", 10) 返回 1
Solution.solution("210022", 3) 返回 3

这是我的代码:

import java.util.ArrayList;
import java.util.Arrays;

public class Solution {

    public static int solution(String n, int b) {
        int k = n.length();
        String m = n;
        ArrayList<String> minionID = new ArrayList<>();

        while (!minionID.contains(m)) {
            minionID.add(m);
            char[] s = m.toCharArray();
            Arrays.sort(s);
            int y = Integer.parseInt(toString(s));
            int x = Integer.parseInt(reverseString(s));
            if (b == 10) {
                int intM = x - y;
                m = Integer.toString(intM);
            } else {
                int intM10 = ((int) Integer.parseInt(toBase10(x,b))) - ((int) Integer.parseInt(toBase10(y, b)));
                m = toBaseN(intM10, b);
            }

            m = addLeadingZeros(k, m);
        }
        System.out.println(minionID);
        return minionID.size() - minionID.indexOf(m);
    }

    private static String toBaseN (int intBase10, int b) {
        int residual = intBase10;
        ArrayList<String> digitsBaseN = new ArrayList<>();

        while (residual >= b) {
            int r = residual % b;
            digitsBaseN.add(Integer.toString(residual));
            residual = (residual - r) / b;
        }
        digitsBaseN.add(Integer.toString(residual));

        StringBuilder reverseDigits = new StringBuilder();
        for (int i = digitsBaseN.size() -1; i >= 0; i--) {
            reverseDigits.append(digitsBaseN.get(i));
        }
        return reverseDigits.toString();
    }

    private static String toBase10 (int intBaseN, int b) {
        int[] xArr = new int[Integer.toString(intBaseN).length()];
        int count = 0;
        for (int i = xArr.length - 1; i >= 0; i--) {
            xArr[count] = Integer.toString(intBaseN).charAt(i) - '0';
            count++;
        }

        int yBase10 = 0;

        for(int i = 0; i < xArr.length; i++) {
            yBase10 += xArr[i] * (Math.pow(b, i));
        }
        return Integer.toString(yBase10);
    }

    public static String toString(char[] arr) {
        StringBuilder newString = new StringBuilder();
        for (char c : arr) {
            newString.append(c);
        }
        if (newString.toString().contains("-")) {
            newString.deleteCharAt(0);
        }
        return newString.toString();
    }

    public static String reverseString(char[] arr) {
        StringBuilder newString = new StringBuilder();
        for (int i = arr.length - 1; i >= 0; i--) {
            newString.append(arr[i]);
        }
        if (newString.toString().contains("-")) {
            newString.deleteCharAt(newString.length()-1);
        }
        return newString.toString();
    }

    public static String addLeadingZeros(int k, String z) {
        if (k > z.length()) {
            String zeros = "";
            for (int i = 0; i < (k - z.length()); i++) {
                zeros += "0";
            }
            zeros += z;
            return zeros;
        }
        return z;
    }

它只适用于十个测试用例中的三个

【问题讨论】:

  • 输入n有什么限制,可以有多少位?
  • 它没有告诉我长度的输入限制
  • 失败的测试用例报告了哪些类型的错误?
  • NumberFormatExceptionError 对于“基数”不是 10 的情况。

标签: java algorithm base


【解决方案1】:
def answer(n, b):

    k = len(n)
    m = n
    mini_id = []
    while m not in mini_id:
        mini_id.append(m)
        s = sorted(m)
        x_descend = ''.join(s[::-1])
        y_ascend = ''.join(s)        
        if b == 10:
            int_m = int(x_descend) - int(y_ascend)
            m = str(int_m)
        else:
            int_m_10 = int(to_base_10(x_descend, b)) - int(to_base_10(y_ascend, b))
            m = to_base_n(str(int_m_10), b)

        m =  (k - len(m)) * '0' + m
    return len(mini_id) - mini_id.index(m)

【讨论】:

    最近更新 更多