Пентомино 6x10 нормализатор раствора


19

Как вы, скорее всего, сейчас знаете, существует 2339 решений головоломки пентомино в сетке 6х10. Существуют разные схемы маркировки для 12 пентомино, две из них показаны на рисунке ниже:

введите описание изображения здесь

Изображение предоставлено: Википедия

Для целей текущей задачи мы скажем, что нормализованное решение пентомино является решением, использующим вторую схему маркировки (по Конвею).

Пример:

O O O O O S S S Z Z
P P R R S S W W Z V
P P P R R W W Z Z V
U U X R T W Y V V V
U X X X T Y Y Y Y Q
U U X T T T Q Q Q Q

Кусок с 5 квадратами в ряд обозначен буквами O, согласно схеме. То же самое верно для всех частей.

Задача:

Учитывая решение пентомино 6x10, в котором кусочки помечены случайным слоем, нормализуйте его так, чтобы все кусочки были помечены в схеме маркировки Конвея. Вы должны распознать фигуры и пометить каждый квадрат конкретной фигуры символом фигуры.

Входные данные:

Решение должно быть нормализовано, в любом удобном для вас формате, например:

  • Многострочная строка

  • Список строк

  • Список списков персонажей

и так далее

Выход:

То же решение (все положения и ориентация кусков сохранены), но каждый кусочек помечен в соответствии со схемой маркировки Конвея. Примечание: выходные данные ДОЛЖНЫ быть напечатаны в виде сетки символов 6x10. Передние и конечные переводы строки и пробелы разрешены. Вы также можете напечатать пробел между символами (но не пустые строки), как в примере выше.

Тестовые случаи:

1. Вход:

6623338888
6222344478
66A234BB70
1AAA94B770
11A99BB700
1199555550

Выход:

UURTTTQQQQ
URRRTVVVSQ
UUXRTVZZSY
PXXXWVZSSY
PPXWWZZSYY
PPWWOOOOOY

2. Вход:

45ookkkk00
455ooogk00
4a55gggdd0
4aaa3gnnd.
4am333ndd.
mmmm3nn...

Выход:

OWSSQQQQPP
OWWSSSRQPP
OTWWRRRUUP
OTTTXRZZUV
OTYXXXZUUV
YYYYXZZVVV

Критерии победы:

Самое короткое решение в байтах на каждом языке выигрывает. Не разочаровывайтесь языками игры в гольф. Пояснения к алгоритмам и реализациям приветствуются.



@KevinCruijssen Спасибо! (Я не проверял на вопросы, связанные с тетромоно)
Гален Иванов

Ответы:


12

APL (Dyalog Classic) , 54 53 50 байтов

⍴⍴{'OXRYTPZQUWSV'[⌊5÷⍨⍋⍋,{×/+⌿↑|(⊢-+/÷≢)⍸⍵}¨⍵=⊂⍵]}

Попробуйте онлайн!

Вычислите инвариант для каждого пентомино на входе: измерьте (∆x, ∆y) от каждого из его квадратов до центра тяжести, возьмите abs (∆x) и abs (∆y), сложите компоненты x и отдельно y компоненты, и умножьте две суммы. Это дает 12 четких результатов. Затем найдите индекс каждого инварианта пентомино в отсортированной коллекции всех инвариантов. Заменить 0 на 'O', 1 на 'X', 2 на 'R'и т. Д.


Спасибо за быстрый ответ и объяснение +1 от меня! Я имел в виду решение, которое должно быть явно напечатано в виде сетки 6х10. Я изменил описание, обновите ваше решение - извините за неудобства.
Гален Иванов

@GalenIvanov но ... это сетка . Мои тесты выдают «ок» вместо вывода результата - может, это слишком запутанно?
нг

Да, меня смутили тесты.
Гален Иванов

3
теперь они печатают результат перед его проверкой
нг

4

Желе , 37 байт

ŒĠZÆmạƊ€ḅı§AỤỤị“æṂ⁾+’Œ?¤+78Ọ,@FQṢƊyⱮY

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

Попробуйте онлайн!

Как?

Я полагаю, что это работает с использованием той же классификации пентамино, что и в решении ngn APL , хотя и немного по-другому (я также не знаю APL, поэтому я не уверен, насколько похож метод за категоризацией).

(Обратите внимание, что “æṂ⁾+’Œ?¤+78Ọэто только один байт “XRPTZWUYSVQO”!)

ŒĠZÆmạƊ€ḅı§AỤỤị“æṂ⁾+’Œ?¤+78Ọ,@FQṢƊyⱮY - Main Link: list of lists of characters L
ŒĠ                                    - group multidimensional indices by value
      Ɗ€                              - last three links as a monad for €ach i.e. f(x):
  Z                                   -   transpose x
   Æm                                 -   mean (vectorises) (i.e. the average of the coordinates)
     ạ                                -   absolute difference with x (vectorises) (i.e. [dx, dy])
         ı                            - square root of -1 (i)
        ḅ                             - convert from base (vectorises) (i.e a list of (i*dx+dy)s)
          §                           - sum each
           A                          - absolute value (i.e. norm of the complex number)
            Ụ                         - grade up (sort indices by value)
             Ụ                        - grade up (...getting the order from the result of A back,
                                      -              but now with one through to 12)
                       ¤              - nilad followed by links as a nilad:
               “æṂ⁾+’                 -   base 250 literal = 370660794
                     Œ?               -   permutation@lex-index = [10,4,2,6,12,9,7,11,5,8,3,1]
              ị                       - index into
                        +78           - add seventy-eight
                           Ọ          - cast to characters (character(1+78)='O', etc...)
                                 Ɗ    - last three links as a monad (i.e. f(L)):
                              F       -   flatten
                               Q      -   de-duplicate
                                Ṣ     -    sort
                            ,@        - pair (with sw@pped @rguments) (giving a list of 2 lists)
                                   Ɱ  - Ɱap across L with:
                                  y   -   translate i.e. swap the letters as per the the pair)
                                    Y - join with new lines
                                      - implicit print

2

Wolfram Language (Mathematica) , 103 байта

""<>Riffle[(t=#)/.Thread[SortBy[Union@@t,Tr@Kurtosis@Position[t,#]&]->Characters@"UPSWZVRTQXYO"],"\n"]&

Вводит в виде списка списков символов.

Попробуйте онлайн!

Основная идея здесь заключается в том, что для каждого символа на входе мы находим координаты, где он происходит, берем эксцесс и суммируем его координаты. Это дает нам инвариант для каждого куска.

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

В любом случае, кроме странного инварианта, это решение аналогично другим: мы сортируем символы и части по каждому инварианту, а затем заменяем каждый символ соответствующим символом "UPSWZVRTQXYO": частей, отсортированных по сумме эксцессов.

Наконец, ""<>Riffle[...,"\n"]это код для печати в виде сетки.


+1 за знание операции, о которой я даже не слышал, и полезного использования
Black Owl Kai

Моя первая попытка найти решение имела Sort@Varianceместо Tr@Kurtosis, и, вероятно, больше людей слышали о дисперсии. Но Tr@Varianceне работает, потому что несколько пентомино (таких как P и X) имеют одинаковую сумму x-дисперсии и y-дисперсии. Поэтому я просмотрел документацию Mathematica на предмет чего-то более необычного.
Миша Лавров

2

Python 2 , 191 байт

def y(o):print"".join(['XPRTWZUYSVQO\n'[[w for v,w in sorted([sum(abs(u-sum(t)/5)for t in[[complex(r%11,r/11)for r,q in enumerate(o)if q==p]]for u in t),p]for p in o)].index(x)/5]for x in o])

Попробуйте онлайн!

Принимает многострочную строку с завершающим переводом строки и выполняет шесть вложенных списков.

Безголовая версия

def pentomino_normalizer(input_string):
    # input_string is a multi-line string with a trailing newline

    results = []  # For saving the results of the for loop
    for current_char in input_string:
        # current_char = p in the golfed version

        # The python data type complex stores a real and a imaginary value and
        # is used for storing the x and y coordinates.
        # In the end, the positions list contains a complex number for every
        # occurence of current_char in the string
        # positions_list = t in the golfed version
        positions_list = [complex(i % 11, i / 11) for i, c
                          in enumerate(input_string) if c == current_char]
        # average_pos is the midpoint of all occurences of current_char, 
        # to get rid of translations
        average_pos = sum(positions_list)/5
        # Calculates a value for each tile that is invariant under 
        # translations and rotations,
        # simply the sum of all the distances between the midpoint
        # and the positions
        invariant = sum(abs(pos - average_pos) for pos in positions_list)

        # Saves the invariant value to a list
        results.append(invariant, current_char)

    # This new list contains the characters occuring in the string, sorted
    # by the invariant value. Because this was done with each char in the 
    # input string, this lists contains every value five times and also 
    # contains six newlines
    # at the end of the list
    sorted_results = [w for v, w in sorted(results)]

    # This code snippet maps each char from the input string to its according
    # output and prints to stdout
    chars = ['XPRTWZUYSVQO\n'[sorted_results.index(c)/5] for c in input_string]
    print "".join(chars)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.