Минимальные Boggle-подобные договоренности

14

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

Слово MISSISSIPPIможет быть организовано с использованием только 6 кубов. Вот одна из возможных договоренностей:

 S
MIS
 PP

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

Удивительно, но более длинная фраза вроде AMANAPLANACANALPANAMAтакже требует только 6 кубов:

MAN
PLC

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

Вызов

Напишите программу, которая принимает строку и упорядочивает ее в стиле Boggle так , чтобы использовалось минимальное количество кубов . (Размеры результирующей сетки и количество пустых ячеек не имеют значения.)

Предположим, у вас есть неограниченное количество кубов для каждого печатаемого символа ASCII, кроме пробела (шестнадцатеричные коды от 21 до 7E), поскольку он используется в качестве пустой ячейки сетки. Будут введены только печатаемые строки ASCII (без пробелов).

Ввод должен быть взят из стандартного ввода или командной строки. Вывод должен идти в стандартный вывод (или ближайший вариант).

Лидирующие или завершающие символы новой строки и пробелы в выводе хороши (но, надеюсь, не слишком много).

По мере увеличения длины строки пространство поиска увеличивается экспоненциально, но вам не нужно пытаться сделать ваш алгоритм эффективным (хотя это было бы неплохо :)). Это код-гольф, поэтому выигрывает самое короткое решение в байтах .

пример

Если бы входные данные были Oklahoma!(минимум 8 символов), все они были бы действительными выходными данными, потому что у всех было ровно 8 заполненных ячеек сетки, и они следовали (пересмотренному) шаблону чтения Boggle:

Oklaho
   !m

или

  !
Oamo
klh

или

   lkO   
  !amo              
    h    

и т.п.

Кальвин Хобби
источник
4
Это звучит как сложная проблема оптимизации. Я думаю, что это сделало бы хороший вызов кода.
Мартин Эндер
1
Я не могу редактировать, потому что есть ожидающее редактирование от пользователя с низким повторением, но у Миссисипи есть два двойных с.
Питер Тейлор
Как насчет чувствительности к регистру?
гордый haskeller
1
@proudhaskeller Я уверен, что ввод нечувствителен к регистру, потому что: 1) ввод - это любой печатный ASCII 2) OP не упомянул иначе 3) Пример с Оклахомой не был бы минимальным, если ввод был без учета регистра.
Мартин Эндер
@ MartinBüttner Я думаю , что вы имели в виду случай , чувствительный
Ypnypn

Ответы:

5

Python 342 355 398

R=(-1,0,1)
A=[];b={}
def s(w,x,y):
 if w: # not at the end of the word yet?
  for I in R: # search adjacent squares
   for j in R:
    if I|j: # skip the square we are on
     i=I+x;j+=y;c=b.get((i,j)) # get square in board
     if c==w[0]:s(w[1:],i,j) # square is what we are looking for?
     elif not c:b[i,j]=w[0];s(w[1:],i,j);del b[i,j] # we can set square?
 else:A.append(dict(b)) # all solutions
s(raw_input(),9,9) # run the search
A=min(A,key=len) # A is now the shortest solution
C=sum(map(list,A),[]) # put all board coords together
C=range(min(C),max(C)+1) # find the board biggest square bound
for r in C:print"".join(A.get((c,r)," ") for c in C)

Отступ на четыре пробела на самом деле является символом табуляции.

AMANAPLANACANALPANAMA:

MC 
NA 
PL

MISSISSIPPI:

S  
SI 
PPM

Oklahoma!:

oh    
 ma   
 ! l  
    k 
     O

Llanfairpwllgwyngyllявляется летальной ;)

Будет
источник
Выглядит хорошо сейчас, просто очень медленно: /
Увлечения Кэлвина
1
Вы можете немного сократить его, удалив import sysи заменив sys.argv[1]на raw_input().
Увлечения Кэлвина
@ Calvin'sHobbies ТНХ снова, аккуратный кончик :) Чтобы получить ранний выход , вы можете просто изменить , elifчтобы elif not c and (not A or len(b)<len(A[-1])):и он работает намного быстрее
Воля
1
если "Oklahoma!"все в порядке, вы можете просто использовать input()вместо raw_input().
FryAmTheEggman