Стек рождественские подарки


21

Кто-то поспешно складывал рождественские подарки, и это довольно беспорядок:

           ========================
           |                      |
           ========================
     =============
     |           |
     |           |
     |           |
     |           |
     |           |
     |           |
     =============
        =======
        |     |
        |     |
        |     |
        =======
  ===================
  |                 |
  |                 |
  |                 |
  ===================
=================
|               |
|               |
|               |
|               |
=================
   =======
   |     |
   |     |
   =======

Как, если серьезно, как эта вершина представляет даже баланс. Это, вероятно, молоток. Чтобы эта башня подарков не рухнула, вы должны переупорядочить подарки так, чтобы они красиво складывались:

        =======
        |     |
        |     |
        =======
        =======
        |     |
        |     |
        |     |
        =======
     =============
     |           |
     |           |
     |           |
     |           |
     |           |
     |           |
     =============
   =================
   |               |
   |               |
   |               |
   |               |
   =================
  ===================
  |                 |
  |                 |
  |                 |
  ===================
========================
|                      |
========================

Правила

  • Каждый подарок состоит из верха и низа =символов и одного или нескольких средних рядов, состоящих из двух |разделенных пробелами. Ширина подарка одинакова во всех его рядах.
  • Там нет пустых строк.
  • Последовательные подарки будут перекрываться как минимум в одном столбце.
  • Подарки должны быть сложены в порядке уменьшения ширины. В случае галстука, более высокий подарок должен идти ниже более плоского подарка.
  • Подарки должны быть сосредоточены на настоящем внизу. Если подарок не может быть размещен точно в центре (потому что разница в ширине нечетна), вы можете выбрать любую позицию, которая находится на половину символа от центра.
  • Вы можете или не можете предполагать, что ввод содержит один завершающий символ новой строки, но, пожалуйста, изложите свое предположение.
  • Ваше решение не должно работать для пустого ввода, но должно быть в состоянии обработать один подарок.
  • Вы можете написать программу или функцию, которая принимает входные данные через STDIN или аргумент функции и возвращает результат или печатает его в STDOUT.
  • Это код гольф, поэтому самый короткий ответ (в байтах) выигрывает.

Ответы:


15

CJam, 81 70 байт

'"qN/{__Sm0=#>}%N*"=
="/"=\"\"="*'"++~]$_W='=/,f{1$'=/,m4/\N/\f{S*\N}}

Значит, мы должны складывать рождественские подарки? Этот код делает это так, как это делал бы реальный человек * .

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

'"qN/{__Sm0=#>}%N*

затем мы идентифицируем каждый подарок как отдельный предмет, используя этот код:

"=
="/"=\"\"="*'"++~]

Затем мы сортируем подарки на основе их высоты и ширины, используя этот код:

$

До сих пор все подарки были сложены у стены, чтобы идеально совмещаться друг с другом. Но так как это Рождество, мы хотим разместить подарки по центру, как рождественская елка! Этот код делает это:

_W=Af{1$Am4/\N/\f{S*\N}}

Вот пошаговый вывод кода, например, в вопросе:

"Step 1 - Stack the presents against a wall";
========================
|                      |
========================
=============
|           |
|           |
|           |
|           |
|           |
|           |
=============
=======
|     |
|     |
|     |
=======
===================
|                 |
|                 |
|                 |
===================
=================
|               |
|               |
|               |
|               |
=================
=======
|     |
|     |
=======

"Step 2 - Identify the presents as a collection of presents";
["========================
|                      |
========================" "=============
|           |
|           |
|           |
|           |
|           |
|           |
=============" "=======
|     |
|     |
|     |
=======" "===================
|                 |
|                 |
|                 |
===================" "=================
|               |
|               |
|               |
|               |
=================" "=======
|     |
|     |
======="]

"Step 3 - Sort on height & width, with presents stacked against a wall to help sort them";
=======
|     |
|     |
=======
=======
|     |
|     |
|     |
=======
=============
|           |
|           |
|           |
|           |
|           |
|           |
=============
=================
|               |
|               |
|               |
|               |
=================
===================
|                 |
|                 |
|                 |
===================
========================
|                      |
========================

"Final step - stack them like a Christmas Tree";
        =======
        |     |
        |     |
        =======
        =======
        |     |
        |     |
        |     |
        =======
     =============
     |           |
     |           |
     |           |
     |           |
     |           |
     |           |
     =============
   =================
   |               |
   |               |
   |               |
   |               |
   =================
  ===================
  |                 |
  |                 |
  |                 |
  ===================
========================
|                      |
========================

Попробуйте онлайн здесь

* Может отличаться от человека к человеку, хотя: P


Удивительно, что стандартный лексикографический порядок соответствует требованиям сортировки! Хорошо поймал.
wchargin

@ Чаргин да. Спас меня тонна байтов!
Оптимизатор

3

Japt , 18 байт

mx óÈíY b'=²Ãn c û

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

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

Объяснение:

mx                    #Trim leading whitespace from each line
   ó        Ã         #Split the array between lines where:
    ÈíY               # The lines interleaved (e.g. "abc","def" => "adbecf")
        b'=²          # starts with "=="
             n        #Default sorting for "array of arrays of strings"
               c      #Flatten to a single array of lines
                 û    #Pad each line so they are centered

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


1
Представьте себе, что более короткая строка дополняется справа мнимым символом с кодовой точкой от -1 до длины более длинной.
Эрик Outgolfer

1
Заменить "=="на, '=²чтобы сохранить байт.
Лохматый

2

Руби, 164

Аккуратный вызов! Не мог получить это намного дальше.

f=->x{y=x.scan(/\s+=+[\s|]+\s+=+/).sort_by{|p|-p.count(?|)}.sort_by{|p|p.count ?=}
y.map{|p|p.gsub(/^\s+/,'').each_line{|l|puts l.strip.center(y[-1].count(?=)/2)}}}

объяснение

Входные данные Stringразделены на Arrayэлементы, где каждый подарок является элементом. Затем массив сортируется по количеству символов канала и снова сортируется по количеству знаков равенства.

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

Он ведет себя одинаково с завершающим переводом строки на входе или без него.

Читаемая версия

f = lambda do |x|
  y = x.scan(/\s+=+[\s|]+\s+=+/)
       .sort_by { |p| -p.count("|") }
       .sort_by { |p|  p.count("=") }

  y.map do |p|
    p.gsub(/^\s+/,'').each_line do |l|
      puts l.strip.center(y.last.count("=") / 2 )
    end
  end
end

1

05AB1E , 23 20 байт

|ðδÛ»…=
=…=0=:0¡{».c

-3 байта благодаря @ErikTheOutgolfer .

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

Объяснение:

|         # Take the input split by newlines
 ðδÛ      # Remove leading spaces from each line
    »     # And join everything back together again with a newline delimiter
…=
=         # Push string "=\n="
 …=0=     # Push string "=0="
     :    # Replace all "=\n=" with "=0="
0¡        # Now split on "0"
          # (We now have our list of presents without any leading spaces)
  {       # Sort this list (with default string-wise sorting)
   »      # Join the list of presents by newlines
    .c    # Left-focused centralize the string (and output implicitly)

Заметки:

  • Подарки нечетной ширины централизованы слева. Это можно изменить на правую, изменив нижний регистр cв верхнем C.
  • Ведущий |может быть отброшен, если нам разрешено принимать входные данные в виде списка строк.
  • Предполагается, что входные данные не содержат завершающих пробелов ни для одного из подарков (аналогично входным данным в описании вызова); последние символы перевода в порядке, так как в |любом случае удаляют их.

1
20 байтов . ðδÛможет использоваться вместо εðÛ}здесь, так ¶'=.øже, как …=\n=( \nозначает перевод строки), так 0'=.øже, как …=0=.
Эрик Outgolfer

@EriktheOutgolfer Ах, я идиот для использования вместо буквенных 3-х символьных строк ... И спасибо за ðδÛ. На самом деле никогда не использовал δраньше и понятия не имел, что это работает так.
Кевин Круйссен

1

Атташе , 91 байт

Join&lf@{Center&#(_@-1@0)@>_}@{SortBy[&{#_'#__},Strip@>Lines=>Split[_,/"(?<==)\\s+(?==)"]]}

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

Ungolfed

?? returns [length of first entry, number of entries]
revDim := &{#_'#__}

?? regex
SPLIT_ON_BARRIERS := /"(?<==)\\s+(?==)"

splitPresents[str] := (
    chopped .= Split[str, SPLIT_ON_BARRIERS];;
    normalized .= Strip @> Lines => chopped
)

orderPresents[presents] :=
    SortBy[revDim, presents]

fixPresents[ordered] := (
    ?? number of columns of bottom-most present
    pad_size .= Size[Last[ordered][0]];;
    ?? center each line of each present
    Center&pad_size @> _
)

joinNewlines := Join&lf

stackPresents := joinNewlines@fixPresents@orderPresents@splitPresents


0

Python 2 , 221 196 байт

s,a,b,i=[c.strip()for c in input().split("\n")]+["="],[],[],0
exec"a+=[s[i].center(max(map(len,s)))]\nif s[i][0]==s[i+1][0]=='=':b+=[a];a=[]\ni+=1;"*(len(s)-1)
for c in sorted(b):print"\n".join(c)

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

Ожидает заключенную в кавычки строку без завершающих строк в качестве входных данных.

Не здорово, но это лучшее, что я могу сделать.


0

Japt , 23 20 19 байт

Подобный подход к решению Кевина . Первый байт может быть удален, если мы можем принять входные данные как массив строк.

·mx ·r¥¬·È·Ãq, n ·û

Попытайся

·mx ·r¥¬·È·Ãq, n ·û     :Implicit input of string
·                       :Split on newlines
 m                      :Map
  x                     :  Trim
    ·                   :Join with newlines
     r                  :Global replace
      ¥                 :  Shortcut for the == operator. Passing an operator as the first argument of a method in Japt implicitly converts it to a string
       ¬                :  Split
        ·               :  Join with newlines, giving the string "=\n=" to be replaced
         È              :  Pass each match through a function
          ·             :    Split on newlines. As we're working within a string, the resulting array gets cast to a string (i.e., "=\n=" -> ["=","="] -> "=,="
           Ã            :End replace
            q,          :Split on ","
               n        :Sort
                 ·      :Join with newlines
                  û     :Centre pad each line with spaces to the length of the longest

0

JavaScript 279 байт 275 байт

Я новичок в код-гольфе, а не эксперт в javascript, но задача интересная и веселая. Я хотел бы посмотреть, какие хитрости использовал бы настоящий специалист по js.

Предположения

  • Вход и выход - это массивы строк
  • Нигде нет пустых строк
  • Высота ящика <= 99 строк (это дисквалифицирует меня)?
  • Входные и выходные переменные предопределены, выходом изначально является пустой массив

Код

Вход находится в g[]. Выход в m[].

a=[];s='';b=0;c=0;o=[];g.forEach((t,x)=>{t=t.trim(),c=Math.max(c,t.length);o.push(t);if(s==''){s=t;b=x}else{if(t==s){a.push({"K":s.length*100+x-b,"O":o});s='';o=[]}}});a.sort((p,q)=>{return p.K-q.K});a.forEach((t)=>{t.O.forEach((q)=>{m.push(" ".repeat((c-q.length)/2)+q)})});

Код работает

  1. построение массива объектов, каждый из которых представляет один блок, с двумя членами: K, ключ сортировки (ширина x 100 + высота) и O, массив (обрезанных) строк, составляющих блок. При построении массива код запоминает ширину самого широкого поля.

  2. Массив блоков-блоков сортируется в порядке по ключу K. Если блоки имеют одинаковую ширину, ключ обеспечивает их сортировку по высоте.

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

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

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