Susun Hadiah Natal

21

Seseorang dengan terburu-buru menumpuk hadiah Natal, dan itu cukup berantakan:

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

Seperti, serius, bagaimana top itu menyajikan keseimbangan. Mungkin palu. Untuk mencegah menara hadiah ini runtuh, Anda harus menyusun ulang hadiah agar tertumpuk dengan baik:

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

Aturan

  • Setiap hadiah terdiri dari karakter atas dan bawah =, dan satu atau lebih baris tengah, yang terdiri dari dua |dipisahkan oleh spasi. Lebar hadiah sama di semua barisnya.
  • Tidak ada garis kosong.
  • Hadiah berurutan akan tumpang tindih dalam setidaknya satu kolom.
  • Hadiah harus ditumpuk agar mengurangi lebar. Jika ada dasi, hadiah yang lebih tinggi harus di bawah hadiah yang lebih rata.
  • Hadiah harus dipusatkan pada saat ini di bawah. Jika hadiah tidak dapat ditempatkan tepat di tengah (karena perbedaan lebar ganjil), Anda dapat memilih posisi yang setengah karakter dari tengah.
  • Anda mungkin atau mungkin tidak berasumsi bahwa input memiliki satu baris baru, tetapi tolong sebutkan asumsi Anda.
  • Solusi Anda tidak harus berfungsi untuk input kosong, tetapi harus dapat menangani satu hadiah.
  • Anda dapat menulis sebuah program atau fungsi, yang mengambil input melalui STDIN atau argumen fungsi dan mengembalikan hasilnya atau mencetaknya ke STDOUT.
  • Ini adalah kode golf, jadi jawaban tersingkat (dalam byte) menang.
Martin Ender
sumber

Jawaban:

15

CJam, 81 70 byte

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

Jadi kita harus menumpuk hadiah Natal? Kode ini melakukannya seperti yang dilakukan orang yang sebenarnya * .

Pertama , kami menumpuk semua hadiah di dinding untuk memindahkannya dengan mudah menggunakan kode ini:

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

kemudian , kami mengidentifikasi setiap hadiah sebagai item terpisah menggunakan kode ini:

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

lalu , kami mengurutkan hadiah berdasarkan ketinggian dan lebar menggunakan kode ini:

$

Sampai sekarang , semua hadiah telah ditumpuk di dinding agar memiliki keselarasan yang sempurna satu sama lain. Tetapi karena ini adalah Natal, kami ingin menempatkan hadiah yang sejajar seperti pohon Natal! Kode ini melakukan itu:

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

Berikut ini adalah langkah demi langkah keluaran kode misalnya dalam pertanyaan:

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

Cobalah online di sini

* Mungkin berbeda dari orang ke orang: P

Pengoptimal
sumber
Itu luar biasa bahwa urutan leksikografis standar terjadi untuk memenuhi persyaratan penyortiran! Tangkapan bagus.
wchargin
@WChargin ya. Menghemat saya banyak byte!
Pengoptimal
3

Japt , 18 byte

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

Cobalah online!

Saya menggunakan strategi yang cukup berbeda dari jawaban Japt lain yang saya pikir layak untuk dijawab sendiri. Mengambil input dan output sebagai array garis

Penjelasan:

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

Saya tidak tahu persis mengapa "sort default" berfungsi seperti itu, tetapi saya telah menguji bahwa kotak yang lebih tinggi dari keduanya dengan lebar yang sama ada di bagian bawah terlepas dari mana yang lebih dulu ada di input.

Kamil Drakari
sumber
1
Bayangkan bahwa string yang lebih pendek akan diisi dengan kanan dengan karakter imajiner dengan titik kode -1 dengan panjang yang lebih panjang.
Erik the Outgolfer
1
Ganti "=="dengan '=²untuk menyimpan byte.
Shaggy
2

Ruby, 164

Tantangan rapi! Tidak bisa menurunkannya lebih jauh.

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

Penjelasan

Input Stringdicincang menjadi di Arraymana setiap hadiah adalah elemen. Kemudian array diurutkan berdasarkan jumlah karakter pipa dan diurutkan lagi dengan jumlah tanda yang sama.

Itu kemudian menghapus semua spasi putih terkemuka dan mencetak setiap baris secara individual, dipusatkan dengan lebar hadiah terbesar.

Berperilaku sama dengan atau tanpa baris baru di input.

Versi yang mudah dibaca

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

05AB1E , 23 20 byte

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

-3 byte terima kasih kepada @ErikTheOutgolfer .

Cobalah online.

Penjelasan:

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

Catatan:

  • Hadiah aneh-lebar adalah fokus kiri terpusat. Ini dapat diubah menjadi fokus kanan dengan mengubah trailing huruf kecil cmenjadi huruf besar C.
  • Pelopor |dapat dijatuhkan jika kita diizinkan untuk mengambil input sebagai daftar garis-string.
  • Asumsikan input tidak mengandung spasi tambahan untuk hadiah apa pun (sama seperti input dalam deskripsi tantangan); mengikuti baris baru baik-baik saja, karena bagaimanapun juga |menghapusnya.
Kevin Cruijssen
sumber
1
20 byte . ðδÛdapat digunakan alih-alih di εðÛ}sini, ¶'=.øsama dengan …=\n=( \nberarti baris baru),0'=.ø sama dengan …=0=.
Erik the Outgolfer
@EriktheOutgolfer Ah, saya idiot untuk menggunakan bukannya string 3-char literal .. Dan terima kasih untuk ðδÛ. Sebenarnya tidak pernah digunakan δsebelumnya dan tidak tahu itu berfungsi seperti itu.
Kevin Cruijssen
1

Atase , 91 byte

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

Cobalah online!

Tidak disatukan

?? 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
sumber
0

Perl 5 -n0 , 123 byte

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

Cobalah online!

Xcali
sumber
0

Python 2 , 221 196 byte

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)

Cobalah online!

Mengharapkan string yang dikutip tanpa tertinggal baris baru sebagai input.

Tidak hebat, tapi itu yang terbaik yang bisa saya lakukan.

Triggernometri
sumber
0

Japt , 23 20 19 byte

Pendekatan yang mirip dengan solusi Kevin . Bita pertama dapat dihapus jika kita dapat mengambil input sebagai array baris.

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

Cobalah

·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
sumber
0

Javascript 279 byte 275 byte

Saya seorang pemula untuk kode-golf, dan tidak seperti ahli dalam javascript tetapi tantangannya menarik dan menyenangkan. Saya ingin melihat trik apa yang akan digunakan oleh seorang ahli js.

Asumsi

  • Input dan output adalah array string
  • Tidak ada garis kosong di mana pun
  • Tinggi kotak adalah <= 99 garis (apakah ini mendiskualifikasi saya)?
  • Variabel input dan output sudah ditentukan sebelumnya, output awalnya berupa array kosong

Kode

Input di g[]. Output dalam 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)})});

Kode ini berfungsi oleh

  1. membangun array objek, masing-masing objek mewakili satu kotak, dengan dua anggota: K, kunci pengurutan adalah (lebar x 100 + tinggi) dan O, array dari string (dipangkas) yang membentuk kotak. Saat membangun array kode mengingat lebar kotak terlebar.

  2. Array objek kotak diurutkan ke dalam urutan dengan tombol K. Dimana kotak memiliki lebar yang sama, kunci memastikan mereka diurutkan berdasarkan ketinggian.

  3. Setelah menyortir kotak, string untuk setiap kotak didorong ke dalam array keluaran dengan spasi tambahan ditambahkan, yang menempatkan kotak secara terpusat di atas yang terlebar.

Cobalah online!

JohnRC
sumber