タワーのバランスは取れますか?


36

前書き

ASCIIタワーと風の力が与えられたら、プログラムまたは関数を作成して、タワーのバランスをとるか、どちらに落ちるかを決定します。

たとえば、最初の塔はバランスが取れていますが、2番目の塔は左に倒れます。

  # #            # #
  ###            ### 
 ###            ### 
 # #            # # 
#####          ##### 
 ###            ### 
 ###              #

これが私の最初の挑戦です。あなたが楽しんでくれることを望みます。

行き方

塔はによって表される連結ブロックで構成され#剛体を形成します。各ブロックは、幅と高さが1単位の正方形で、密度は一定です。タワーに作用する力には、重量と風力があります。すべての力は各ブロックに個別に作用し、ブロックの中心を通過します。

  • その重量により、各ブロックには1つのユニットの下向きの力が作用します。
  • また、風上側に隣接する別のブロックを持たない各ブロックには、風の方向に水平に作用する力があります。この力の大きさは入力として与えられます。
  • 風の方向は、入力のどこかにASCIIフラグで示されます。風がゼロでない場合にのみ、入力にフラグが表示されます。フラグは力に影響しません。

フラグは、下に表示されるとおりになります。

Flag design and corresponding wind direction:

 o~~        ~~o
 |~~        ~~|

--->        <---

明確にするために、タワーは堅固な物体であり、バラバラにならず、地面に取り付けられていません。ただし、プログラムは各ブロックの力を個別に計算して、タワーのバランスが取れているかどうかを判断する必要があります。

  o~~
  |~~
  # #              > > 
  ###              >## 
 ###              >##  
 # #              > >  
#####            >#### 
 ###              >##  
 ###              >##  

Wind force: 1    Wind direction: --->

風は右に吹いて>おり、上の右に示されているブロックを押します。風は穴の内側に作用することに注意してください。

タワーの左下隅に座標があると仮定し(0,0)ます。タワーの左baseの周りの瞬間(0,0)は時計回りに71単位なので、タワーは左に落ちません。(0,3)でのタワーの右基部の周りの瞬間は時計回りに8単位なので、タワーは右に倒れます。

風が左に吹いている場合、それぞれのモーメントは同じポイントで時計回りに2単位、反時計回りに61単位であるため、タワーのバランスが取れます。

入力

  • プログラムまたは関数は、10進数と改行で区切られた文字列の2つの入力を受け取る必要があります。
  • 10進数はゼロより大きくなり、例のように各露出ブロックに風が及ぼす力を表します。
  • 文字列は塔を上から下に表し、スペース、#|o~文字、改行を含む場合があります。オプションで、後続の改行を想定したり、タワーを後続のスペースで埋めて長方形を形成したりできます。
  • #の最下列には少なくとも1つあります。
  • 数字と文字列はどちらの順序でも入力できます。
  • 風力の大きさがゼロ以外の場合、入力のどこかに、地上またはタワーに接続されたフラグがあります。フラグの形式は上記のとおりです。
  • #ブロックは、穴を含んでいてもよい接続された形状を形成することになります。つまり、ブロックが1つしかない場合を除き、すべてのブロックは他のブロックに隣接します。

出力

  • 文字の一つはBL、またはR、タワーのバランスをとるかどうかに応じて、左(反時計回り)に向けて落下し、または右(時計回り)に向けて落下します。
  • 出力には、オプションの末尾の改行が含まれる場合があります。

これはです。標準ルールと抜け穴が適用されます。

B テストケース:

Wind: 1
    ~~o
    ~~|
      # #
      ###
     ###
     # #
    #####
     ###
     ###

Wind: 0
##
# ##
###

Wind: 1.7
o~~
|~~
#
##

Wind: 0.768
      o~~
      |~~
      # #
      ###
     ###
     # #
    #####
     ###
     ###

Wind: 0.1
#
#
#
#
#
# o~~
# |~~

Wind: 0
#

Wind: 0
############

Wind: 144
               o~~
############   |~~

Wind: 0
#######
 ##
 #
 ##

Wind: 0
                ############
           ############
       ############
    ############
   ############
 ############
############

Wind: 41
                 ############
            ############
        ############
     ############
    ############
  ############     ~~o
 ############      ~~|

L テストケース:

Wind: 0
#####
   #


Wind: 42
                 ############
            ############
        ############
     ############
    ############
  ############     ~~o
 ############      ~~|

Wind: 4
########
    ###
 ~~o# ##
 ~~|#  #

Wind: 3
########
    ###
 o~~# ##
 |~~   #

R テストケース:

Wind: 1
      o~~
      |~~
      # #
      ###
     ###
     # #
    #####
     ###
     ###

Wind: 2
o~~
|~~
#

Wind: 0.001
                 ############
            ############
        ############
     ############
    ############
  ############     o~~
 ############      |~~

Wind: 145
               o~~
############   |~~

Wind: 1
#
#
#
#
#
# o~~
# |~~

Wind: 0.26
#######
 ##
 #   o~~
 ##  |~~

参照ソリューション(JavaScript)

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

function balanced(tower, wind) {
    var rows = tower.split('\n').reverse(); // Reverse so row index matches height of row.
    var height = rows.length;
    var leftEdge = rows[0].indexOf('#'); // Find bottom left corner of tower.
    var rightEdge = rows[0].lastIndexOf('#') + 1; // Find bottom right corner of tower.
    var leftMoment = 0, rightMoment = 0; // Moments around the bottoms corners of tower.
    wind *= tower.indexOf('~o')>-1 ? -1 : 1; // Find direction of the wind.

    // Sum the moments for each block in the tower.
    for (var i = height - 1; i >= 0; i--) {
        rows[i].split('').map(function(ch, index, arr) {
            if (ch=='#') {
                // If there's not a block toward the windward side of the current one.
                if ((wind < 0 && arr[index-1] != '#') || (wind > 0 && arr[index+1]!='#')) {
                    // Add moments from wind.
                    leftMoment += (i+0.5)*-wind;
                    rightMoment += (i+0.5)*-wind; 
                }

                leftMoment += leftEdge - (index + 0.5);
                rightMoment += rightEdge - (index + 0.5);
            }
        }, 0);
    }
    if (leftMoment > 0) return 'L';
    else if (rightMoment < 0) return 'R';
    else return 'B';
}

リーダーボード

これは、通常のリーダーボードと言語ごとの勝者の概要の両方を生成するスタックスニペットです。

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、見出しから回答を開始してください。

# Language Name, N bytes

N提出物のサイズはどこですか。スコアを改善する場合、古いスコアを打つことで見出しに残すことができます。例えば:

# Ruby, <s>104</s> <s>101</s> 96 bytes

ヘッダーに複数の数字を含める場合(たとえば、スコアが2つのファイルの合計であるか、インタープリターフラグペナルティーを個別にリストする場合)、実際のスコアがヘッダーの最後の数字であることを確認します。

# Perl, 43 + 2 (-p flag) = 45 bytes

言語名をリンクにして、リーダーボードスニペットに表示することもできます。

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


17
PPCGへようこそ。これは見事に書かれた最初の挑戦です!:)
ドアノブ

回答:


2

JavaScript(ES6)、239バイト

私は参照実装を徹底的に調べました。私は、ループのために変更することでバイトを保存することができましたmap、使用した&&||声明し、使用している場合、短絡に,1文でフィットすべてに、オペレータが機能的に明示的な戻りを回避するために。

(a,b)=>((c=a.split`
`.reverse(),d=c[f=g=0].indexOf`#`,e=c[0].lastIndexOf`#`+1),a.match`o~`&&(b*=-1),c.map((h,i)=>h.replace(/#/g,(j,k,l)=>(b>0&l[k-1]!='#'|b<0&l[k+1]!='#'&&(f+=(i+=0.5)*b,g+=i*b),f+=d-k-0.5,g+=e-k-0.5))),f>0?'L':g<0?'R':'B')

これ以上ゴルフすることはまだ可能かもしれません。提案を歓迎します。


ナイーブソリューションよりもはるかに優れた+1
コナーオブライエン

1

JavaScriptのES6、297の 293バイト

基本的に、指定された実装の圧縮バージョン。

b=(n,e)=>{r=n.split`
`.reverse(),t=r.length,a=r[0].indexOf`#`,f=r[i=l=0].lastIndexOf`#`+1;e*=n.indexOf`~o`>-1?-1:1;for(d=t-1;d>=0;d--)r[d].split``.map((n,r,t)=>{(j="#")==n&&((0>e&&j!=t[r-1]||e>0&&j!=t[r+1])&&(i+=(d+.5)*-e,l+=(d+.5)*-e),i+=a-(r+.5),l+=f-(r+.5))},0);return i>0?"L":0>l?"R":"B"}

半展開:

b = (n, e) => {
    r = n.split `
`.reverse(), t = r.length, a = r[0].indexOf `#`, f = r[i = l = 0].lastIndexOf `#` + 1;
    e *= n.indexOf `~o` > -1 ? -1 : 1;
    for (d = t - 1; d >= 0; d--) r[d].split ``.map((n, r, t) => {
        (j = "#") == n && ((0 > e && j != t[r - 1] || e > 0 && j != t[r + 1]) && (i += (d + .5) * -e, l += (d + .5) * -e), i += a - (r + .5), l += f - (r + .5))
    }, 0);
    return i > 0 ? "L" : 0 > l ? "R" : "B"
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.