Apila los regalos de navidad

21

Alguien apiló apresuradamente los regalos de Navidad, y es un desastre:

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

Al igual que, en serio, ¿cómo se equilibra ese presente superior? Probablemente sea un martillo. Para evitar que esta torre de regalos se desmorone, debes reordenar los regalos para que se apilen bien:

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

Las normas

  • Cada presente consta de una parte superior e inferior de =caracteres, y una o más filas intermedias, que consisten en dos |separados por espacios. El ancho del presente es el mismo en todas sus filas.
  • No hay líneas vacías.
  • Los regalos consecutivos se superpondrán en al menos una columna.
  • Los regalos se deben apilar en orden decreciente de ancho. En caso de empate, el regalo más alto debe ir por debajo del regalo más plano.
  • Los regalos deben centrarse en el presente debajo. Si el presente no se puede colocar exactamente en el centro (porque la diferencia de ancho es impar), puede elegir cualquier posición que esté a medio carácter del centro.
  • Puede asumir o no que la entrada tiene una nueva línea final, pero por favor indique su suposición.
  • Su solución no tiene que funcionar para una entrada vacía, sino que debe poder manejar un único presente.
  • Puede escribir un programa o función, que toma la entrada a través de STDIN o argumento de función y devuelve el resultado o lo imprime en STDOUT.
  • Este es el código de golf, por lo que gana la respuesta más corta (en bytes).
Martin Ender
fuente

Respuestas:

15

CJam, 81 70 bytes

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

¿Entonces tenemos que apilar los regalos de Navidad? Este código lo hace como lo haría una persona real * .

Primero , apilamos todos los regalos contra una pared para moverlos fácilmente hacia arriba y hacia abajo usando este código:

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

luego , identificamos cada presente como un elemento separado usando este código:

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

luego , clasificamos los regalos en función de sus alturas y anchos utilizando este código:

$

Hasta ahora , todos los regalos se han apilado contra una pared para tener una alineación perfecta entre sí. Pero como es Navidad, ¡queremos colocar los regalos alineados centrados como un árbol de Navidad! Este código hace eso:

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

Aquí hay una salida paso a paso del código, por ejemplo, en la pregunta:

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

Pruébalo en línea aquí

* Sin embargo, puede diferir de persona a persona: P

Optimizador
fuente
¡Es increíble que el orden lexicográfico estándar cumpla con los requisitos de clasificación! Buena atrapada.
wchargin
@WChargin sí. ¡Me ahorró una tonelada de bytes!
Optimizador
3

Japt , 18 bytes

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

Pruébalo en línea!

Utilizo una estrategia suficientemente diferente de la otra respuesta de Japt que pensé que valía la pena. Toma entrada y salida como una matriz de líneas

Explicación:

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

No sé exactamente por qué la "ordenación predeterminada" funciona así, pero he probado que la caja más alta de las dos con el mismo ancho está en la parte inferior, independientemente de cuál sea el primero en la entrada.

Kamil Drakari
fuente
1
Imagine que la cadena más corta se rellena a la derecha con un carácter imaginario con un punto de código -1 a la longitud de la más larga.
Erik the Outgolfer
1
Reemplace "=="con '=²para guardar un byte.
Shaggy
2

Rubí, 164

¡Buen desafío! No pude descifrarlo mucho más.

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

Explicación

La entrada Stringse corta en un lugar Arraydonde cada presente es un elemento. Luego, la matriz se ordena por la cantidad de caracteres de tubería y se ordena nuevamente por la cantidad de signos iguales.

Luego elimina todos los espacios en blanco iniciales e imprime cada línea individualmente, centrada por el ancho del regalo más grande.

Se comporta igual con o sin una nueva línea final en la entrada.

Versión legible

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
fuente
1

05AB1E , 23 20 bytes

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

-3 bytes gracias a @ErikTheOutgolfer .

Pruébalo en línea.

Explicación:

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

  • Los regalos de ancho impar están centrados a la izquierda centralizados. Esto se puede cambiar a centrado a la derecha cambiando las minúsculas finales ca mayúsculas C.
  • El inicio |se puede eliminar si se nos permite tomar la entrada como una lista de líneas de cadena.
  • Asume que la entrada no contiene espacios finales para ninguno de los regalos (similar a la entrada en la descripción del desafío); las nuevas líneas finales están bien, ya que las |elimina de todos modos.
Kevin Cruijssen
fuente
1
20 bytes . ðδÛse puede usar en lugar de εðÛ}aquí, ¶'=.øes lo mismo que …=\n=( \nsignifica nueva línea), 0'=.øes lo mismo que …=0=.
Erik the Outgolfer
@EriktheOutgolfer Ah, soy un idiota por usar en lugar de las cadenas literales de 3 caracteres. Y gracias por ðδÛ. En realidad nunca lo usé δantes y no tenía idea de que funcionaba así.
Kevin Cruijssen
1

Adjunto , 91 bytes

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

Pruébalo en línea!

Sin golf

?? 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
fuente
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

Pruébalo en línea!

Xcali
fuente
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)

Pruébalo en línea!

Espera una cadena entre comillas sin arrastrar líneas nuevas como entrada

No es genial, pero es lo mejor que puedo hacer.

Triggernometry
fuente
0

Japt , 23 20 19 bytes

Enfoque similar a la solución de Kevin . El primer byte puede eliminarse si podemos tomar la entrada como una matriz de líneas.

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

Intentalo

·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
Lanudo
fuente
0

Javascript 279 bytes 275 bytes

Soy un novato en el código de golf, y no soy nada como un experto en JavaScript, pero el desafío es interesante y divertido. Me gustaría ver qué trucos usaría un verdadero experto en js.

Supuestos

  • La entrada y la salida son matrices de cadenas.
  • No hay líneas en blanco en ningún lado
  • La altura de un cuadro es <= 99 líneas (¿esto me descalifica)?
  • Las variables de entrada y salida están predefinidas, la salida es inicialmente una matriz vacía

Código

La entrada está adentro g[]. La producción en 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)})});

El código funciona por

  1. construyendo una matriz de objetos, cada objeto representando una caja, con dos miembros: K, una clave de clasificación es (ancho x 100 + altura) y O, una matriz de las cadenas (recortadas) que forman la caja. Al construir la matriz, el código recuerda el ancho del cuadro más ancho.

  2. La matriz de objetos de cuadro se ordena en orden por la clave K. Cuando los cuadros tienen el mismo ancho, la clave garantiza que estén ordenados por alto.

  3. Después de ordenar los cuadros, las cadenas de cada cuadro se insertan en la matriz de salida con espacios iniciales agregados, que colocan el cuadro centralmente sobre el más ancho.

Pruébalo en línea!

JohnRC
fuente