Распаковка таблицы коэффициентов экспоненты умножает упакованное значение обратно в исходные значения

У меня есть эта карточная игра в покер, где возможные 13 рангов карт хранятся как [от 0 до 12]. Каждая рука, содержащая 5 карт, имеет 13 возможных рангов.

Конечным значением является идентификатор, начинающийся с показателя степени 13⁵ (в степени 5).

Который хранит, какая это выигрышная рука. Затем оставшиеся 5 степеней числа 13 используются для хранения каждой из 5 карт.

Также не говоря уже о том, что не все 5 карт хранятся постоянно, это только для выигрыша старшей карты, для которого требуется 4 кикера.

Мой вопрос заключается в том, чтобы использовать только окончательное значение, как я смогу распаковать каждую карту и какая это была выигрышная рука.

/** The ranking factors (powers of 13, the number of ranks). */
private static final int[] RANKING_FACTORS = {371293, 28561, 2197, 169, 13, 1};

rankings[0] = HIGHCARD WIN [0]
rankings[1] = 12; //Ace
rankings[2] = 6; //Eight
rankings[3] = 9; //Jack
rankings[4] = 1; //Three
rankings[5] = 3; //Five

// Calculate value.
for (int i = 0; i < NO_OF_RANKINGS; i++) {
    value += rankings[i] * RANKING_FACTORS[i];
}

(0*371293) + (12*28561) + (6*2197) + (9*169) + (1*13) + (3*1) = 357451

Попытка распаковать значения из этого значения 357451. Начал пытаться понять математику здесь.

if 357451 < 371293                        rankings[0] = 0

(357451 / 28561) = 12                     rankings[1] = 12
(357451 / 2197) / ((13*2)+1) = 6          rankings[2] = 6
(357451 / 169)  / ((13*18)+1) = 9         rankings[3] = 9
//Alright it seems that 18 is from answers (12+6) probably because I haven't subtracted them or something.
//So next one should be (12+6+9)= 27, but it's 2115
(357451 / 13)  / ((13*2115)+1) = 1        rankings[4] = 1
(357451 / 1) / ((13*9165)+1) = 3          rankings[5] = 3

Я думаю, что понял это, но я не понимаю значения. Вероятно, также работает только для этого случая, сломается в любом другом случае.

Не знаю, откуда генерируются значения 2, 18, 2115, 9165, вероятно, из какой-то чепухи, которую я придумал.

Как мне сделать это правильно? Я не думаю, что мог бы использовать сдвиг, так как это не побитовое.

Значит, так делается?

(357451 / 371293)          = 0
(357451 / 28561)           = 12
(357451 % 28561) / 2197    = 6
(357451 % 2197) / 169      = 9

(357451 % 169) / 13        = 1
(357451 % 13)              = 3

person SSpoke    schedule 01.03.2014    source источник


Ответы (1)


Вы правы в этой части..

(357451 / 28561) = 12                     rankings[1] = 12

Но это нехорошо...

(357451 / 2197) / ((13*2)+1) = 6          rankings[2] = 6

Вам нужно взять результат 12 и умножить его обратно на 28561, а затем вычесть это из 357451, чтобы увидеть, что осталось. В данном случае это 14719.

Теперь вы можете продолжать использовать это число вместо 357451. Итак, 14719/2197 = 6.

Продолжайте этот шаблон (14719 - (2197 * 6)), пока не получите свои 5 чисел.

(357451 % 28561) также даст вам остаток, если вы хотите сделать это таким образом.

Мой "декодирующий" код...

private static final int[] RANKING_FACTORS = {4826809, 371293, 28561, 2197, 169, 13, 1};

@Test
public void testDecode() {
    long value = 357451;
    int[] rankings = new int[6];
    //System.out.println(Math.max(0,value-RANKING_FACTORS[0]));
    for (int i=0; i < rankings.length; i++) {
        rankings[i] = (int)(value / RANKING_FACTORS[i]);
        value %= RANKING_FACTORS[i];
        System.out.println(rankings[i]);
    }
}
person Ted Bigham    schedule 01.03.2014
comment
Вот так: (357451 / 28561) = 12 (357451 % 28561) / 2197 = 6 (357451 % 2197) / 169 = 9 (357451 % 169) / 13 = 1 (357451 % 13) = 3 Как проверить первое значение без оператора if? - person SSpoke; 01.03.2014
comment
Итак, вы также делаете 357451/371293, чтобы получить первое значение 0? - person SSpoke; 02.03.2014
comment
Предполагая, что вы просто добавляете дополнительное значение в верхнюю часть числа, вы можете использовать ratings[0]=Math.max(0,value-RANKING_FACTORS[0]) - person Ted Bigham; 02.03.2014
comment
Ты прав. Не могли бы вы просто добавить еще одну запись в RANKING_FACTORS[0] до 13^6? Если ваш идентификатор не имеет более 13 значений, он будет работать. Какой диапазон значений вы туда вставляете? - person Ted Bigham; 02.03.2014
comment
Я, наверное, мог бы, но зачем мне это делать? идентификатор от [0 до 9] флеш-рояль - это 9, поэтому все это помещается с дополнительным пространством - person SSpoke; 02.03.2014
comment
Префект, тогда вы можете просто добавить 4826809 в свой массив и использовать существующую логику. Я опубликую свой тестовый код. - person Ted Bigham; 02.03.2014
comment
Спасибо за вашу помощь, ваш тестовый код выглядит очень эффективным. - person SSpoke; 02.03.2014