Empilhe os presentes de Natal

21

Alguém tem empilhado às pressas os presentes de Natal, e é uma bagunça:

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

Sério, como esse top apresenta equilíbrio. Provavelmente é um martelo. Para impedir que essa torre de presentes desmorone, você deve reordenar os presentes para que eles fiquem bem empilhados:

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

As regras

  • Cada presente consiste em uma parte superior e inferior dos =caracteres e uma ou mais linhas do meio, consistindo em duas |separadas por espaços. A largura do presente é a mesma em todas as suas linhas.
  • Não há linhas vazias.
  • Presentes consecutivos se sobrepõem em pelo menos uma coluna.
  • Os presentes devem ser empilhados em ordem decrescente de largura. Em caso de empate, o presente mais alto deve ficar abaixo do presente mais plano.
  • Os presentes devem estar centralizados no presente abaixo. Se o presente não puder ser colocado exatamente no centro (porque a diferença nas larguras é ímpar), você poderá escolher uma posição com meio caractere fora do centro.
  • Você pode ou não presumir que a entrada tenha uma nova linha à direita, mas indique sua suposição.
  • Sua solução não precisa funcionar para uma entrada vazia, mas deve poder manipular um único presente.
  • Você pode escrever um programa ou função, que recebe entrada via STDIN ou argumento de função e retorna o resultado ou o imprime em STDOUT.
  • Isso é código de golfe, então a resposta mais curta (em bytes) vence.
Martin Ender
fonte

Respostas:

15

CJam, 81 70 bytes

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

Então temos que empilhar os presentes de Natal? Esse código faz como uma pessoa real faria * .

Primeiro , empilhamos todos os presentes contra uma parede para movê-los facilmente para cima e para baixo usando este código:

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

então , identificamos cada presente como um item separado usando este código:

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

em seguida , classificamos os presentes com base em suas alturas e larguras usando este código:

$

Até agora , todos os presentes foram empilhados contra uma parede para ter um alinhamento perfeito uns com os outros. Mas como este é o Natal, queremos colocar os presentes alinhados centralizados como uma árvore de Natal! Este código faz isso:

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

Aqui está uma saída passo a passo do código, por exemplo, na pergunta:

"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";
        =======
        |     |
        |     |
        =======
        =======
        |     |
        |     |
        |     |
        =======
     =============
     |           |
     |           |
     |           |
     |           |
     |           |
     |           |
     =============
   =================
   |               |
   |               |
   |               |
   |               |
   =================
  ===================
  |                 |
  |                 |
  |                 |
  ===================
========================
|                      |
========================

Experimente online aqui

* Pode diferir de pessoa para pessoa: P

Optimizer
fonte
É incrível que a ordem lexicográfica padrão cumpra os requisitos de classificação! Boa pegada.
wchargin
@WChargin yeah. Me salvou uma tonelada de bytes!
Optimizer
3

Japonês , 18 bytes

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

Experimente online!

Eu uso uma estratégia suficientemente diferente da outra resposta japonesa que achei que valeria a pena. Toma entrada e saída como uma matriz de linhas

Explicação:

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

Não sei exatamente por que a "classificação padrão" funciona assim, mas testei que a caixa mais alta das duas com a mesma largura está na parte inferior, independentemente da que ocorrer primeiro na entrada.

Kamil Drakari
fonte
11
Imagine que a cadeia mais curta seja preenchida com um caractere imaginário com o ponto de código -1 no comprimento da cadeia mais longa.
Erik the Outgolfer
11
Substitua "=="por '=²para salvar um byte.
Salsicha
2

Ruby, 164

Desafio puro! Não foi possível diminuir muito mais.

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)}}}

Explicação

A entrada Stringé dividida em um Arraylocal em que cada presente é um elemento. Em seguida, a matriz é classificada pelo número de caracteres de pipe e classificada novamente pelo número de sinais de igual.

Em seguida, remove todo o espaço em branco à esquerda e imprime cada linha individualmente, centralizada pela largura do maior presente.

Ele se comporta da mesma forma com ou sem uma nova linha à direita na entrada.

Versão legível

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
britishtea
fonte
1

05AB1E , 23 20 bytes

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

-3 bytes graças a @ErikTheOutgolfer .

Experimente online.

Explicação:

|         # 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)

Notas:

  • Presentes de largura ímpar são centralizados à esquerda. Isso pode ser alterado para focado à direita, alterando as minúsculas cà direita para maiúsculas C.
  • O líder |pode ser eliminado se for permitido levar a entrada como uma lista de linhas de sequência.
  • Assume que a entrada não contém espaços finais para nenhum dos presentes (semelhante à entrada na descrição do desafio); as novas linhas finais são boas, pois as |remove de qualquer maneira.
Kevin Cruijssen
fonte
11
20 bytes . ðδÛpode ser usado em vez de εðÛ}aqui, ¶'=.øé o mesmo que …=\n=( \nsignifica nova linha), 0'=.øé o mesmo que …=0=.
Erik the Outgolfer
@EriktheOutgolfer Ah, eu sou um idiota por usar em vez das strings literais de 3 caracteres .. E obrigado por ðδÛ. Na verdade, nunca usei δantes e não tinha ideia de que funcionava assim.
Kevin Cruijssen
1

Anexo , 91 bytes

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

Experimente online!

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
Conor O'Brien
fonte
0

Perl 5 -n0 , 123 bytes

sub k{pop=~y/=//}say s+^\s*+$"x((k($p[-1])- k$_)/4)+rmge for@p=sort{k($a)- k$b||$a=~y/|//-$b=~y/|//}/\s*(=+[| 
]+\s*\=+)/gs

Experimente online!

Xcali
fonte
0

Python 2 , 221 196 bytes

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)

Experimente online!

Espera uma sequência de caracteres entre aspas sem seguir novas linhas como entrada.

Não é ótimo, mas é o melhor que posso fazer.

Triggernometria
fonte
0

Japonês , 23 20 19 bytes

Abordagem semelhante à solução de Kevin . O primeiro byte pode ser removido se pudermos receber a entrada como uma matriz de linhas.

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

Tente

·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
Shaggy
fonte
0

Javascript 279 bytes 275 bytes

Sou um novato no código de golfe, e não sou como um especialista em javascript, mas o desafio é interessante e divertido. Gostaria de ver quais truques um verdadeiro especialista em js usaria.

Suposições

  • Entrada e saída são matrizes de strings
  • Não há linhas em branco em nenhum lugar
  • A altura de uma caixa é <= 99 linhas (isso me desqualifica)?
  • As variáveis ​​de entrada e saída são predefinidas, sendo a saída inicialmente uma matriz vazia

Código

A entrada é no g[]. Saída em 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)})});

O código funciona por

  1. construindo uma matriz de objetos, cada objeto representando uma caixa, com dois membros: K, uma chave de classificação sendo a (largura x 100 + altura) e O, uma matriz das cadeias (aparadas) que compõem a caixa. Ao criar a matriz, o código lembra a largura da caixa mais larga.

  2. A matriz de objetos de caixa é classificada em ordem pela chave K. Onde as caixas têm a mesma largura, a chave garante que elas sejam classificadas por altura.

  3. Depois de classificar as caixas, as cadeias de caracteres de cada caixa são inseridas na matriz de saída com os espaços à esquerda adicionados, que posicionam a caixa centralmente sobre a mais larga.

Experimente online!

JohnRC
fonte