Вместе все добиваются большего


28

(связано: один , два , три )

Акростих это стиль стихотворения / записи , где начальный символ каждой строки, при чтении по вертикали, а также производит слово или сообщение. Например,

Together
Everyone
Achieves
More

также расшифровывает слово, TEAMкогда первый столбец читается по вертикали.

Акростика - это подмножество мезостыков , где вертикальное слово может быть где угодно в горизонтальных словах. Например, TEAMвышеприведенное можно также записать в виде мезостики следующим образом

   togeTher
everyonE
       Achieves
       More

наряду с несколькими другими вариантами.

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

вход

  • Список слов в любом подходящем формате .
  • Список будет содержать только слова из строчных букв [a-z].
  • Список гарантированно формирует акростих или мезостику (не нужно обрабатывать фиктивные данные).
  • Одно из входных слов образует вертикальное слово, в то время как остальные составляют горизонтальные слова - часть задачи здесь состоит в том, чтобы найти подходящее вертикальное слово, поэтому его нельзя использовать отдельно.

Выход

  • ASCII-арт акростик или мезостик, сформированный из входных слов, записанных в STDOUT или возвращенных в любом разумном формате.
  • Соответствующее вертикальное слово должно быть написано заглавными (как в примерах).
  • Ведущие пространства , чтобы получить вертикальное слово выстраиваться соответствующим образом будут необходимы . Конечные пробелы и начальные / конечные переводы строк являются необязательными. Лишние пробелы также хороши, если слова выровнены правильно.
  • Если возможны как акростик, так и мезостим, выведите только акростик .
  • Если возможно более одного acrostic / mesostic, ваш код может вывести любой или все из них.

правила

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

Примеры

['together', 'team', 'everyone', 'achieves', 'more']
Together
Everyone
Achieves
More

['aaa', 'aaa', 'aaa', 'aaa']
Aaa
Aaa
Aaa
# One output, or multiple (of the same) output is allowed

['aaa', 'aaa', 'aab', 'baa']
Aaa
Aaa
Baa
# This is the only allowed output, since others would be mesostic, which are lower priority

['live', 'every', 'love', 'very', 'ohio']
Live
Ohio
Very
Every
# Note that 'live' couldn't be the vertical word since then it would be a mesostic, which is lower priority output

['cow', 'of', 'fox']
cOw
 Fox
# A shorter mesostic test case

['late', 'ballroom', 'anvil', 'to', 'head']
anviL
   bAllroom
    To
   hEad

Кажется, что в тех случаях, когда производится акростих, список будет в таком порядке?
Утренняя монахиня

У вас может быть более короткий мезостик?
Утренняя монахиня

1
Допускаются ли дополнительные пробелы?
PurkkaKoodari

Это не говорит о том, что входные данные гарантированно будут отсортированы правильно, но, судя по тестовым примерам, они есть. Они?
aross

2
@ Pietu1998 Конечно, все в порядке - главное, чтобы слова были выстроены в очередь. Я отредактирую это разъяснение.
AdmBorkBork

Ответы:



6

Брахилог , 145 байт

p~c[A:B:C],Bl1,A:CcP@pz:cahgB,P:1a~@nw|lL,?:laot:" "rjg:Ljb:sa:?z:cap~c[A:B:C],Bl1,A:Cc@pz:caZ:LmgB,Zl-yM,Z:M:Lz:2az:ca~@nw
bB,?h@u:Bc
b#=,?h@u|h

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

(Занимает полминуты, так что наберитесь терпения.)


1
Похоже, что это потребовало некоторых усилий, чтобы написать :) Очень приятно!
Эминья

@TimmyD Исправлено, спасибо.
Утренняя монахиня

4

JavaScript (ES6), 255 263 269 286

Редактировать 17 байтов, сохраненных как произвольное количество начальных пробелов, разрешено
Edit2, некоторые тасования, 6 байтов сохранены.
Edit3 возвращает список строк вместо одной строки с символами новой строки (комментарий OP к ответу feersum), еще 8 байтов сохранены.

Для каждого слова в списке ввода я использую рекурсивную DFS, чтобы найти все возможные мезостики / акростики. Каждый из них хранится в виде массива со словом и позицией целевой буквы внутри слова. Каждый найденный результат сохраняется в глобальном массиве результатов в позиции 1 (если это акростик) или в 0, если это мезостик.

После полного сканирования всех слов я получаю результат на последней позиции в массиве и собираю и возвращаю его представление ascii art.

l=>(l.map((w,i)=>(r=(p,v,i,a)=>(l[i]='.',w[p]?l.map((v,i)=>~(j=v.search(w[p]))&&r(p+1,v,i,a|j,m[p]=[j,v])):l[p+1]?0:s[+!a]=[...m],l[i]=v))(0,w,i,m=[]),s=[]),m=s.pop(),m.map(([j,v])=>' '.repeat((l+0).length-j)+v.slice(0,j)+v[j].toUpperCase()+v.slice(j+1)))

Меньше гольфа

f=l=>(
  l.map((w,i)=>
    // r: recursive DFS function
    // defined here as it uses local w variable
    (r = (p,v,i,a) => (
     l[i] = '.'
     , w[p] 
     ? l.map(
       (v,i) => ~(j=v.search(w[p])) && 
                r(p+1, v, i, a|j, m[p] = [j,v])

     )
     : l[p+1] ? 0 // invalid if there are still unused words
              : s[+!a]=[...m] // a is 0 if acrostic
     , l[i] = v) 
    )(0, w, i, m=[])
  , s=[]),
  m = s.pop(), // get last result
  // m.map(([j]) => o = o<j ? j : o, o=0), // find offset for alignment
  // no need to find the optimal offset as leading blanks are allowed
  m.map(([j,v]) => ' '.repeat((l+0).length-j) 
                   + v.slice(0,j) 
                   + v[j].toUpperCase()
                   + v.slice(j+1)
  )
)

Тест

f=l=>(l.map((w,i)=>(r=(p,v,i,a)=>(l[i]='.',w[p]?l.map((v,i)=>~(j=v.search(w[p]))&&r(p+1,v,i,a|j,m[p]=[j,v])):l[p+1]?0:s[+!a]=[...m],l[i]=v))(0,w,i,m=[]),s=[]),m=s.pop(),m.map(([j,v])=>' '.repeat((l+0).length-j)+v.slice(0,j)+v[j].toUpperCase()+v.slice(j+1)))

console.log=x=>O.textContent+=x+'\n\n'

;[
 ['together', 'team', 'everyone', 'achieves', 'more']
,['aaa', 'aaa', 'aaa', 'aaa']
,['aaa', 'aaa', 'aab', 'baa']
,['live', 'every', 'love', 'very', 'ohio']
,['cow', 'of', 'fox']
,['late', 'ballroom', 'anvil', 'to', 'head']
].forEach(l=>console.log(f(l).join`\n`))
<pre id=O></pre>


3

Perl6, 287 277 269 ​​байт

my @w=$*IN.words;my ($q,$r)=gather for ^@w {my @v=@w.rotate($_);my \d=@v.shift;for @v.permutations {my @o=flat($_ Z d.comb).map:{$^a.index: $^b};take $_,@o if @o>>.defined.all}}.sort(*[1].sum)[0];for @$q Z @$r ->(\a,\b){say " "x($r.max -b)~a.substr(0,b)~a.substr(b).tc}

3

Mathematica 10,0, 139 байт

Безымянная функция, возвращающая список строк:

Sort[{q=Max[p=Min/@Position@@@({z={##2},#})],Array[" "&,q-#2]<>ToUpperCase~MapAt~##&@@@({z,p})}&@@@Permutations@Characters@#][[1,2]]&

Пример использования:

В [144]: = f = Sort [{q = Max [p = Min / @ Position @@@ ({z = {## 2}, #} ​​)], Array ["" &, q- # 2 ] ToUpperCase ~ MapAt ~ ## & @@@ ({г, р} )} & @@@ Перестановки @ Символы @ #] [[1,2]] &;

В [145]: = f @ {"late", "ballroom", "anvil", "to", "head"} // Столбец

 ... несколько страниц предупреждений ... 

Out [145] = туалетная комната
            наковальня
            к
           голова

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


Конечно, функции могут возвращать многострочные строки в виде списка строк.
AdmBorkBork

2

Haskell, 214 206 204 202 байта

import Data.List
z=zipWith
h i j t|(u,v:w)<-splitAt j t=([1..sum i-j]>>" ")++u++toEnum(fromEnum v-32):w
f x=uncurry(z=<<h)$sort[(head<$>z elemIndices w l,l)|w:l<-permutations x,(True<$w)==z elem w l]!!0

Возвращает список строк с пробелами, например, f ["late","ballroom","anvil","to","head"]-> [" baLlroom"," Anvil"," To"," hEad"]или более удобный для отображения:

*Main> mapM_ putStrLn $ f ["late", "ballroom", "anvil", "to", "head"]
 baLlroom
   Anvil
   To
  hEad

fвыбирает слова, которые написаны по горизонтали вместе со списком смещений. hвставляет каждое слово в соответствии с соответствующим смещением и вставляет заглавную букву. В деталях:

                permutations x       -- for each permutation of the input list x
         w:l<-                       -- bind w to the first word and l to the rest
             (True<$w)==z elem w l   -- keep it if the list of other words
                                     -- containing the next letter of w
                                     -- equals (length w) times True, i.e. we have
                                     -- as many matching letters as letters in w.
                                     -- This rules out combinations shortcut by zipWith

                                     -- for all the remaining w and l make a pair
         head<$>z elemIndices w l    -- the first element of the list of list of
                                     -- indices where the letter appears in the word 
                                l    -- and l itself
   sort                              -- sort the pairs (all 0 indices, i.e. acrostics
                                     -- go first)
                               !!0   -- pick the first
                                     -- now we have a pair like
                                     -- ([2,0,0,1],["ballroom","anvil","to","head"])
 uncurry(z=<<h)                      -- loop over (index,word) and 
                                     -- provide the third parameter for h 



 h i j t                             -- h takes the list of indices and
                                     -- an index j and a word t
       (u,v:w)<-splitAt j t          -- split the word at the index and bind
                                     --   u: part before the split
                                     --   v: letter at the split
                                     --   w: part after the split
         [1..sum i-j]>>" "           -- the spaces to pad
           ++ u                      -- followed by u
           ++ toEnum(fromEnum v-32)  -- and uppercase v
           :                         -- and w 

2

Python, 249 байт

Вероятно, все еще очень пригодный для игры в гольф

from itertools import*;e=enumerate;lambda l:[[[' ']*(max(j for k,(j,c)in o[1:])-i)+l[k][:i]+[c.upper()]+l[k][i+1:]for k,(i,c)in o[1:]]for p in product(*[list(e(w))for w in l])for o in permutations(list(e(p)))if[c for k,(i,c)in o[1:]]==l[o[0][0]]][0]

Принимает и возвращает список списка символов.
- например, " bAllroom"это[' ',' ',' ','b','A','l','l','r','o','o','m']

Только когда-либо возвращает первый результат и проверяет в таком порядке, что все акростики проверяются в первую очередь.

Посмотреть все контрольные примеры, напечатанные в формате дисплея на ideone


Вот более читаемая функциональная форма, которая делает то же самое (за исключением того, что она возвращает первый результат немедленно, а не оценивает и затем возвращает первый результат):

from itertools import*
def f(l):
    for p in product(*[list(enumerate(w)) for w in l]):
        for o in permutations(list(enumerate(p))):
            if [c for k,(i,c) in o[1:]] == l[o[0][0]]:
                return [ [' '] * (max(j for k,(j,c) in o[1:]) - i)
                       + l[k][:i]
                       + [c.upper()]
                       + l[k][i+1:]
                       for k, (i, c) in o[1:]
                       ]

1

Perl 6, 177 байт

->\a{for first({.[0] eq[~] .[1]»[1]},map |*,[Z] map {.[0]X [X] map {.comb[(^$_,$_,$_^..* for ^.chars)]},.[1..*]},a.permutations)[1] ->$/ {say [~] " "x a.comb-$0,|$0,$1.uc,|$2}}

Решение для перебора.

Как это работает

-> \a {
    for first({.[0] eq[~] .[1]»[1]},          # For the first valid candidate
            map |*, [Z]                       # among the transposed
            map {                             # lists of candidates
                .[0] X [X] map {
                    .comb[(^$_,$_,$_^..* for ^.chars)]
                }, .[1..*]
            },
            a.permutations                    # for all permutations of the input:
        )[1] ->$/ {
        say [~] " "x a.comb-$0,|$0,$1.uc,|$2  # Print the candidate as ASCII art.
    }
}

Каждый кандидат выглядит так:

"of", (("c"),"o",("w")), ((),"f",("o","x"))

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.