Google Foobar Challenge Level 2 “Hey-I-Already-Did-That” [closed]

拥有回忆 提交于 2020-07-15 09:26:30

问题


I need help with solving the second level of Google's Foobar challenge.


Commander Lambda uses an automated algorithm to assign minions randomly to tasks, in order to keep her minions on their toes. But you've noticed a flaw in the algorithm - it eventually loops back on itself, so that instead of assigning new minions as it iterates, it gets stuck in a cycle of values so that the same minions end up doing the same tasks over and over again. You think proving this to Commander Lambda will help you make a case for your next promotion.

You have worked out that the algorithm has the following process:

1) Start with a random minion ID n, which is a nonnegative integer of length k in base b
2) Define x and y as integers of length k. x has the digits of n in descending order, and y has the digits of n in ascending order
3) Define z = x - y. Add leading zeros to z to maintain length k if necessary
4) Assign n = z to get the next minion ID, and go back to step 2

For example, given minion ID n = 1211, k = 4, b = 10, then x = 2111, y = 1112 and z = 2111 - 1112 = 0999. Then the next minion ID will be n = 0999 and the algorithm iterates again: x = 9990, y = 0999 and z = 9990 - 0999 = 8991, and so on.

Depending on the values of n, k (derived from n), and b, at some point the algorithm reaches a cycle, such as by reaching a constant value. For example, starting with n = 210022, k = 6, b = 3, the algorithm will reach the cycle of values [210111, 122221, 102212] and it will stay in this cycle no matter how many times it continues iterating. Starting with n = 1211, the routine will reach the integer 6174, and since 7641 - 1467 is 6174, it will stay as that value no matter how many times it iterates.

Given a minion ID as a string n representing a nonnegative integer of length k in base b, where 2 <= k <= 9 and 2 <= b <= 10, write a function solution(n, b) which returns the length of the ending cycle of the algorithm above starting with n. For instance, in the example above, solution(210022, 3) would return 3, since iterating on 102212 would return to 210111 when done in base 3. If the algorithm reaches a constant, such as 0, then the length is 1.

Test Cases:
Solution.solution("1211", 10) returns 1
Solution.solution("210022", 3) returns 3

Here is my code:

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;
    }

It only works for three out of the ten test cases


回答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)


来源:https://stackoverflow.com/questions/61907902/google-foobar-challenge-level-2-hey-i-already-did-that

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!