Алгоритм поиска улиц и однотипных в руке - PullRequest
12 голосов
/ 11 ноября 2010

Это на самом деле вопрос, основанный на маджонге, но фон на основе Romme или даже покера также будет легко понять.

В маджонге 14 плиток (плитки похожи на карты в покере) расположены так, чтобы4 комплекта и пара.Улица («123») всегда использует ровно 3 плитки, не больше и не меньше.Набор того же вида («111») состоит из ровно 3 плиток.Это приводит к сумме 3 * 4 + 2 = 14 плиток.

Существуют различные исключения, такие как Кан или Тринадцать сирот, которые здесь не актуальны.Цвета и диапазоны значений (1-9) также не важны для алгоритма.

Я пытаюсь определить, можно ли расположить руку так, как описано выше.По определенным причинам он должен иметь возможность работать не только с 14, но и с любым количеством плиток.(Следующим шагом было бы найти, сколько плиток нужно обменять, чтобы иметь возможность завершить раздачу.)

Примеры:

11122233344455 - достаточно просто, 4 сета и пара.
12345555678999 - 123, 456, 789, 555, 99
11223378888999 - 123, 123, 789, 888, 99
11223344556789 - недопустимая рука

Моя текущая и еще не реализованная идея заключается в следующем: для каждой плитки попробуйте составить: а) улицу, б) набор, в) пару.Если ничего не работает (или будет> 1 пара), вернитесь к предыдущей итерации и попробуйте следующую опцию, или, если это самый высокий уровень, не пройдите.Иначе, удалите использованные плитки из списка оставшихся плиток и продолжите следующую итерацию.

Я считаю, что этот подход работает и также будет достаточно быстрым (производительность - «хороший бонус»), но яинтересует ваше мнение по этому поводу.Можете ли вы придумать альтернативные решения?Это или что-то подобное уже существует?

(не домашнее задание, Я учусь играть в маджонг. )

Ответы [ 3 ]

15 голосов
/ 11 ноября 2010

Сумма значений на улице и в наборе может быть разделена на 3:

  • n + n + n = 3n
  • (n-1) + n+ (n + 1) = 3n

Итак, если вы сложите все числа в решенной раздаче, вы получите число вида 3N + 2M, где M - значение плиткив паре.Остаток от деления на три (total % 3) для каждого значения M:

total % 3 = 0  -> M = {3,6,9}
total % 3 = 1  -> M = {2,5,8}
total % 3 = 2  -> M = {1,4,7}

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

Как только вы это получите, начните с самого низкого значения.Если с этим значением меньше трех плиток, это означает, что они обязательно являются первым элементом улицы, поэтому удалите эту улицу (если вы не можете этого сделать, потому что плитки n + 1 или n + 2 отсутствуют, это означает, что руканедопустимо) и перейдите к следующему наименьшему значению.

Если есть хотя бы три плитки с наименьшим значением, удалите их как набор (если вы спросите "что, если они были частью улицы?"«учтите, что если бы они были, то есть также три фрагмента n + 1 и три фрагмента n + 2, которые также можно превратить в наборы), и продолжим.

Если вы дойдете до пустой руки, эта рука действительна.

Например, для вашей недействительной руки итоговая сумма равна 60, что означает M = {3,6,9}:

Remove the 3: 112244556789
 - Start with 1: there are less than three, so remove a street
   -> impossible: 123 needs a 3

Remove the 6: impossible, there is only one

Remove the 9: impossible, there is only one

В вашем втором примере 12345555678999 сумма равна78, что означает M = {3,6,9}:

Remove the 3: impossible, there is only one

Remove the 6: impossible, there is only one

Remove the 9: 123455556789
 - Start with 1: there is only one, so remove a street
   -> 455556789
 - Start with 4: there is only one, so remove a street
   -> 555789
 - Start with 5: there are three, so remove a set
   -> 789
 - Start with 7: there is only one, so remove a street
   -> empty : hand is valid, removals were [99] [123] [456] [555] [789]

Ваш третий пример 11223378888999 также имеет в общей сложности 78, что вызывает возврат:

Remove the 3: 11227888899
 - Start with 1: there are less than three, so remove a street
   -> impossible: 123 needs a 3

Remove the 6: impossible, there are none

Remove the 9: 112233788889
 - Start with 1: there are less than three, so remove streets
   -> 788889
 - Start with 7: there is only one, so remove a street
   -> 888
 - Start with 8: there are three, so remove a set
   -> empty, hand is valid, removals were : [99] [123] [123] [789] [888]
2 голосов
/ 31 октября 2012

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

Пусть b обозначает бамбук, c обозначает символ и d обозначает точку, попробуйте эту руку:

b2,b3,b4,b5,b6,b7,c4,c4,c4,d4,d4,d6,d7,d8

d4,d4 should serve as the pair, and c4,c4,c4 should serve as the run-of-3 set.

Но так как 3 плитки "c4" появляются перед плитками 2 d4, первые 2 плитки c4 будут выбраны в качестве пары, оставляя сироту c4 и 2 d4s, и эти 3 плитки выиграли 't сформировать правильный набор.

В этом случае вам нужно будет «вернуть» плитки 2 c4 обратно в руку (и держать руку отсортированной) и найти следующую плитку, которая соответствует критериям (значение == 4).Для этого вам нужно заставить код «помнить», что он пробовал c4, поэтому на следующей итерации он должен пропустить c4 и искать другие фрагменты со значением == 4. Код будет немного запутанным, но выполнимым.

1 голос
/ 11 ноября 2010

Я бы разбил его на 2 шага.

  1. Выясни возможные комбинации.Я думаю, что с этими числами возможна исчерпывающая проверка.Результатом этого шага является список комбинаций, где каждая комбинация имеет тип (набор, улица или пара) и шаблон с использованными картами (может быть растровым изображением).
  2. С предыдущей информацией,определить возможные коллекции комбинаций.Это где растровое изображение пригодится.Используя побитовые операторы, вы могли видеть наложения в использовании одной и той же плитки для разных комбинаторов.

Вы также можете выполнить шаг 1.5, где вы просто проверяете, достаточно ли доступно каждого типа.На этом шаге и шаге 2 вы сможете создать общий алгоритм.Первый шаг будет одинаковым для всех чисел плиток и возможных комбинаций быстро.

...