塔会平衡吗?


36

介绍

给定一个ASCII塔和风的作用力,编写一个程序或函数来确定塔是否平衡或以哪种方式掉落。

例如,第一座塔平衡了,但是第二座向左倒了。

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

这是我的第一个挑战。我希望你喜欢它。

方向

塔由相连的砖块组成,#并构成一个刚性物体。每个块是一个正方形,其宽度和高度为一个单位,并且具有恒定的密度。塔上有两种作用力,即重量和风力。所有力分别作用在每个块上,并穿过块的中心。

  • 由于其重量,每个块都具有一个作用在其上的向下力。
  • 而且,在其迎风侧上没有与其相邻的另一个块的每个块具有在其上沿风向水平作用的力。该力的大小作为输入给出。
  • 风的方向由输入中某处的ASCII标志指示。当且仅当风不为零时,输入中才会有一个标志。该标志不影响任何力量。

该标志将与下面显示的完全一样。

Flag design and corresponding wind direction:

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

--->        <---

为了澄清起见,该塔是坚固的物体,不会破碎,也不会附着在地面上。但是,您的程序应分别计算每个砌块的力,以确定塔架是否平衡。

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

Wind force: 1    Wind direction: --->

风向右吹,将推动右上方显示的方块>。请注意,风作用在孔的内部。

假设塔的左下角具有坐标(0,0)。围绕塔左基座的力矩(0,0)为顺时针71个单位,因此塔不会向左掉落。绕塔右基座在(0,3)处的力矩为顺时针8个单位,因此塔将向右下落。

如果风向左吹,在相同的点,各自的力矩分别为顺时针2个单位和逆时针61个单位,因此塔将保持平衡。

输入值

  • 您的程序或函数必须接受两个输入,一个十进制数字和一个换行符分隔的字符串。
  • 十进制数将大于零,并且如示例中所示,代表风在每个裸露块上施加的力。
  • 该字符串将从上到下代表塔,并且可以包含空格,#|o~字符和换行符。您可以选择使用尾随换行符和/或用尾随空格填充塔以形成矩形。
  • #的底部至少有一个。
  • 您可以按任何顺序输入数字和字符串。
  • 如果风力的大小不为零,则输入中的某个位置将有一个标志,该标志位于地面上或连接至塔架。该标志将具有上面显示的确切形式。
  • #块将形成可包含孔连接的形状。换句话说,所有块都将与另一个块相邻,除非只有一个块。

输出量

  • 字符B,,L或之一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';
}

排行榜

这是一个堆栈片段,用于按语言生成常规排行榜和获胜者概述。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

# Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以通过打败旧分数保持标题。例如:

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

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

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

您还可以将语言名称设置为链接,然后该链接将显示在页首横幅代码段中:

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


17
欢迎来到PPCG;这是写得很好的第一个挑战!:)
门把手

Answers:


2

JavaScript(ES6),239个字节

我参考了参考实现。通过将for循环更改为map,使用&&||短路if语句,并使用,运算符将所有内容放入一个语句中,从而避免在函数中显式返回,我能够节省字节。

(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比我的天真解决方案好得多
Conor O'Brien

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"
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.