クリスマスギフトを積み重ねる


21

誰かが急いでクリスマスプレゼントを積み上げており、それは非常に混乱しています。

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

真剣に、そのトップがどのようにバランスを示しているのか。おそらくハンマーです。このプレゼントの塔が崩れるのを防ぐには、プレゼントを並べ替えて、うまくスタックするようにします。

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

ルール

  • 各プレゼントは、=文字の上と下、および|スペースで区切られた2つで構成される1つ以上の中間行で構成されます。現在の幅は、すべての行で同じです。
  • 空行はありません。
  • 連続するプレゼントは、少なくとも1つの列で重複します。
  • プレゼントは、幅の狭い順に積み重ねられます。同点の場合、背の高いプレゼントは平らなプレゼントの下に行く必要があります。
  • プレゼントは、その下のプレゼントを中心とする必要があります。(幅の違いが奇数であるため)プレゼントを正確に中央に配置できない場合は、中央から文字の半分だけ離れた位置を選択できます。
  • 入力の末尾に改行が1つあると仮定する場合もしない場合もありますが、仮定を述べてください。
  • ソリューションは空の入力に対して機能する必要はありませんが、単一のプレゼントを処理できる必要があります。
  • 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 14

@WCharginええ。大量のバイトを節約してくれました!
オプティマイザー14

3

Japt、18バイト

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

オンラインでお試しください!

私は、他のJaptの回答とは十分に異なる戦略を使用しており、独自の回答の価値があると考えました。入力と出力を行の配列として受け取ります

説明:

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

「デフォルトの並べ替え」がそのように機能する理由は正確にはわかりませんが、入力のどちらが先かに関わらず、同じ幅の2つの高い方のボックスが下部にあることをテストしました。


1
短い文字列に、コードポイント-1の長い文字の長さまでの仮想文字が右詰めされることを想像してください。
エリックアウトゴルファー

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

説明

入力StringArray、各存在が要素であるところに切り分けられます。次に、配列はパイプ文字の数でソートれ、等号の数で再度ソートれます。

次に、先頭の空白をすべて削除し、存在する最大の幅を中心に各行を個別に印刷します。

入力の末尾に改行があってもなくても同じように動作します。

読みやすいバージョン

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

05AB1E23 20 バイト

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

@ErikTheOutgolferのおかげで-3バイト。

オンラインでお試しください。

説明:

|         # 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=\n0'=.ø…=0=
エリックアウトゴルファー

@EriktheOutgolferああ、私は文字通りの3文字の文字列の代わりに使うのがばかですðδÛ。実際にはこれまで使用したことδはなく、そのように機能することも考えていませんでした。
ケビンCruijssen

1

アタッシュ、91バイト

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

オンラインでお試しください!

非ゴルフ

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

パイソン2221の 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

Japt23 20 19 バイト

Kevinのソリューションに対する同様のアプローチ。入力を行の配列として取得できる場合は、最初のバイトを削除できます。

·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. オブジェクトの配列を作成します。各オブジェクトは2つのメンバーを持つ1つのボックスを表します。Kは(幅x 100 +高さ)であるソートキー、Oはボックスを構成する(トリミングされた)文字列の配列です。配列の構築中、コードは最も幅の広いボックスの幅を記憶します。

  2. ボックスオブジェクトの配列は、キーKの順にソートされます。ボックスの幅が同じ場合、キーにより、高さでソートされます。

  3. ボックスを並べ替えた後、各ボックスの文字列が先頭のスペースが追加された出力配列にプッシュされ、最も広いボックスの中央にボックスが配置されます。

オンラインでお試しください!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.