Есть ли быстрый способ сравнить 3 троичных числа в соответствии с простым набором правил? - PullRequest
2 голосов
/ 20 мая 2019

Учитывая 3 троичных (базовых 3) числа равной длины (их можно дополнить нулями слева), существует ли быстрый и простой способ сравнить каждое значение места (или столбец) так, чтобы каждый столбец состоял из 3 разные цифры или 3 одинаковых номера.

Например:

Good pairs:     || Bad pairs:
________________||________________ 
101 | 000 | 012 || 111 | 012 | 002 
212 | 111 | 112 || 122 | 120 | 022
020 | 222 | 212 || 120 | 202 | 102

Что я пробовал до сих пор

Мое лучшее решение в настоящее время состоит в том, чтобы сложить 3 числа, но добавить их как десятичные числа вместо (так, чтобы первая хорошая пара стала бы 333 вместо 1110). Затем я проверяю каждое отдельное число и проверяю, делится ли оно на 3.

Сначала я проверял, делилось ли все число на 3, но на многих числах это не получалось.

00
10
11
--
21 % 3 == 0 

Как вы можете видеть, просто деление на 3 не является достаточно хорошей проверкой, поскольку вы можете быстро заметить, что столбцы фактически не соответствуют установленным мною правилам. Вот метод, который я написал, который проверяет его правильно, как я объяснил:

//The 3 numbers are originally decimal numbers
private static boolean ternary(int a, int b, int c)
{
    //Convert each number to a ternary number, add them and assign the result to a string
    //This is the best base conversion code I was able to find using native java
    String ternary = Integer.toString(Integer.parseInt(Integer.toString(a, 3))
                + Integer.parseInt(Integer.toString(b, 3)) 
                + Integer.parseInt(Integer.toString(c, 3)));

    //For each digit in the number, check if it is divisible by 3. If not, return false
    for (int i = 0; i < ternary.length(); i++)
        if (Integer.parseInt(ternary.charAt(i) + "") % 3 != 0)
            return false;
    //If all the numbers passed the test, return true
    return true;
}

Я также возился с добавлением чисел как десятичных и преобразованием результата в троичное число и попыткой проверить свойства безрезультатно. У меня есть второй метод, который действует как выше, но без использования строк. Вместо этого он делит число на 10000, 1000 и т. Д., Поскольку вы не можете сделать .charAt () для числа.

Настоящий Q

Моя интуиция подсказывает мне, что должен быть гораздо более простой способ сделать это, но я еще не открыл его. Я потратил слишком много времени, пытаясь придумать элегантное решение, но я застрял. Это может быть больше математическим вопросом, чем вопросом программирования, но я думаю, что кто-то здесь мог бы указать мне правильное направление. Спасибо:)

1 Ответ

1 голос
/ 20 мая 2019

По сути, у вас есть матрица 3x3, в которой каждый столбец должен иметь сумму 0 (все элементы в столбце 0), 3 (все элементы в столбце 1 или элементы в столбце являются перестановками 0, 1 и 2) или 6 (все элементы в столбце 2).

Поскольку столбцы должныСуммируя либо 0, 3, либо 6, мы можем просто проверить, что сумма делится на 3.

Код для проверки будет следующим:

private static boolean ternary(int a, int b, int c) {
    for (int i = 0; i < 3; i++) {
        if ((a % 3 + b % 3 + c % 3) % 3 != 0) {
            return false;
        }

        a /= 3;
        b /= 3;
        c /= 3;
    }

    return true;
}

Поскольку a, b и c вводятся как десятичные числа (основание-10), мы можем использовать n % 3 (для каждого значения), чтобы получить наименее значимые троичные цифры, и вернуть false если их сумма не делится на 3.

Однако затем нам нужно разделить каждое значение на 3, чтобы эффективно сбросить наименьшую значащую троичную цифру.


Это также личные предпочтения, но звонки на a /= 3, b /= 3 и c /= 3 можно переместить с шагом часть цикла for:

private static boolean ternary(int a, int b, int c) {
    for (int i = 0; i < 3; i++, a /= 3, b /= 3, c /= 3) {
        if ((a % 3 + b % 3 + c % 3) % 3 != 0) {
            return false;
        }
    }

    return true;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...