罗马军盾


26

沙盒帖子(已删除)

古老的罗马军队在世界范围内非常有名。在这些阵型中,罗马军团以几何形状(通常是矩形)分组,使用盾牌保护侧翼及其上半部分。内部位置的军团士兵将上盾放置在头顶上方,侧面的军团士兵携带2个或多个盾牌:一个用于保护上半部分,一个或多个盾牌用于保护侧面(如果有人在角落里)他有3个盾牌,如果有人一个人有5个盾牌,是的,我知道一个人不可能带5个盾牌,但是他们以某种方式做到了。利用这一阵型,所有罗马军团保护自己,并成为当时最坚强的对手。

历史告诉我们,有一位罗马将军说,最好的编队形状是正方形(行和列的军团人数相同)。问题在于弄清楚他应该分裂多少个编队(和规模),以便:

  • 不要将任何军团排除在编队之外(尽管他承认只有一个军团编队)
  • 减少所需的防护罩数量

这位将军在做一些数学和计算后,得出完成这两个条件的最佳方法是从可能的最大平方开始,然后重复直到没有军团成员离开为止


例:

如果他的军队中有35个军团,

  • 一个5x5的军团正方形(这是可能的最大正方形)。

与其余军团一起(10)

  • 3x3正方形

与其余军团一起(1)

  • 1x1正方形。

最后,它看起来像这样:

   5x5      
* * * * *        3x3            
* * * * *       * * *      1x1  
* * * * *       * * *       *
* * * * *       * * *       
* * * * *               

处于内部位置的军团覆盖了上半身,将盾牌放在头顶上方。他们只需要1盾。

* * * * *                   
* 1 1 1 *       * * *       
* 1 1 1 *       * 1 *       *
* 1 1 1 *       * * *       
* * * * *               

侧翼的军团携带2

* 2 2 2 *                   
2 1 1 1 2       * 2 *       
2 1 1 1 2       2 1 2       *
2 1 1 1 2       * 2 *       
* 2 2 2 *               

如果有人在角落里,他有3个盾牌

3 2 2 2 3               
2 1 1 1 2       3 2 3       
2 1 1 1 2       2 1 2       *
2 1 1 1 2       3 2 3       
3 2 2 2 3               

如果有人独自在编队中,他有5个盾牌

3 2 2 2 3               
2 1 1 1 2       3 2 3       
2 1 1 1 2       2 1 2       5
2 1 1 1 2       3 2 3       
3 2 2 2 3               

这种编队总共需要71个盾牌。


挑战

  • 计算X军团所需的盾牌数量

输入项

  • 军队中的军团人数

输出量

  • 所需的防护罩数量。

测试用例

35 => 71
20 => 44
10 => 26
32 => 72


11
谷歌“携带5个盾牌”的结果是,Amazon.com : Best-selling Nipple Shield Carrying Case, Perfect...所以我想我永远不会真正知道。他们实际上携带5个盾牌吗?或者这是使问题起作用的原因:P?
魔术章鱼缸

1
@MagicOctopusUrn Im相当肯定你知道答案由xD我不认为有人有胆量走出去在战斗中有5个盾牌
路易斯·费利佩·穆尼奥斯耶稣

4
我不认为将军的数学和计算得出正确的结论,那就是反复采取必要的最大平方可以最大程度地减少盾牌。例如,32个军团可以分割成两个4 * 4的正方形(总共64个盾牌),而不是5 * 5 + 2 * 2 + 1 * 1 + 1 * 1 + 1 * 1的正方形(共72个盾牌)。
xnor

6
@xnor在一般情况下,一般将军是不正确的,但是一般将军是将军(尽管我们不应该将其概括)。
pajonk

2
@AJFaraday Asterix和雇佣 badge ?
克里斯·H

Answers:


14

Python 2中60个 50 48字节

def f(s):n=s**.5//1;return s and(n+4)*n+f(s-n*n)

在线尝试!

编码高尔夫球的新手,但是挥杆最好!

方法:

总和n^2 + 4n,其中n每一个最大的广场数字是一笔投入。

编辑1

@Jonathan Frech减少到50个字节!

编辑2

@ovs 切换int(s**.5)s**.5//1节省2个字节



2
我认为n*nn**2为您节省两个字节还短;我不能说更多,因为我不写python ...
Giuseppe


2
int(s**.5)可以缩短为s**.5//1
ovs '18

2
@mypetlion确实如此。//在两个Python的2楼师和3 3**.5//1的计算结果为1.0两个版本。
ovs '18

11

R51 50字节

f=function(x,y=x^.5%/%1)"if"(x,y^2+4*y+f(x-y^2),0)

在线尝试!

yy2+4yxx

证明:

y(y2)2y2(y2)2y=1y2+4y5y=1y


y24y

1
@ToddSewell肯定的,那就是阿尔诺的解释,这更优雅,但这是我走近它,所以我坚持它的方式!幸运的是,这不是证明问题。
朱塞佩

10

JavaScript(ES7),34个字节

f=n=>n&&(w=n**.5|0)*w+w*4+f(n-w*w)

在线尝试!

怎么样?

w=nsw

sw=w2+4w

w=3

(323212323)=(s3=21)(111111111)+(3²=9)(111000000)+(001001001)+(000000111)+(100100100)(4×3=12)

该公式对于,因为。w=1s1=5



4

朱莉娅0.6,36字节

!n=(s=isqrt(n))*s+4s+(n>0&&!(n-s*s))

在线尝试!

使用与@Giuseppe的R答案相同的方法,尽管我到达那里的方法所涉及的思考较少,而只是视觉检查:1s的内部正方形的尺寸为 ×,因此具有盾牌。围绕着它,有4堵名士兵的墙,每堵士兵有2个盾牌-因此增加了盾牌。最后,四个角有四个3,因此增加了12个盾牌。n2+4n(n2)(n2)(n2)2n24(n2)2

(n2)2+4(n2)2+43=n2+44n+8n16+12=n2+4n

取消高尔夫:

!n = begin       # Assign to ! operator to save bytes on function parantheses
  s = isqrt(n)   # Integer square root: the largest integer m such that m*m <= n
  s * s +
    4 * s +
      (n > 0 &&  # evaluates to false = 0 when n = 0, otherwise recurses
        !(n - s * s))
end

(也可以使用n>0?(s=isqrt(n))*s+4s+f(n-s*s):0,以35个字节来完成此操作,但我为Julia 0.7编写了此代码,是为了避免出现新的弃用警告(要求空格为?:)。)


屏蔽计数的另一种过于复杂的解释,请参阅我对@Giuseppe答案的评论。
托德·塞维尔

2
@ToddSewell是的,面积+周长是一种更优雅的观察方式。我没有那样做,与Giuseppe相似,我的目的是描述我的方法,而不是给出公式的最新证据。
sundar-恢复莫妮卡


3

Brachylog,26个字节

0|⟧^₂ᵐ∋N&;N-ℕ↰R∧N√ȧ×₄;N,R+

在线尝试!

0           % The output is 0 if input is 0
|           % Otherwise,
⟧           % Form decreasing range from input I to 0
^₂ᵐ         % Get the squares of each of those numbers
∋N          % There is a number N in that list
&;N-ℕ       % With I - N being a natural number >= 0 i.e. N <= I
            % Since we formed a decreasing range, this will find the largest such number
↰           % Call this predicate recursively with that difference I - N as the input
R           % Let the result of that be R
∧N√ȧ        % Get the positive square root of N
×₄          % Multiply by 4
;N,R+       % Add N and R to that
            % The result is the (implicit) output

2

视网膜0.8.2,28字节

.+
$*
(\G1|11\1)+
$&11$1$1
.

在线尝试!链接包括测试用例。说明:

.+
$*

转换为十进制。

(\G1|11\1)+

匹配奇数。第一次通过该组\1还不存在,因此只能\G1匹配,匹配1。后续匹配不匹配,\G1因为\G仅匹配开始时匹配,因此我们必须匹配11\1比2大2的匹配。上一场比赛。我们尽可能地匹配奇数,因此总的匹配数是一个平方数,而最后一次捕获的次数小于其边的两倍。

$&11$1$1

在每场比赛中都添加侧挡板。$&是并且是,同时,我们需要。n2$12n1n2+4n=n2+2+2(2n1)

.

求和并转换为十进制。


2

05AB1E,17 个字节

[Ð_#tïÐns4*+Šn-}O

在线尝试验证所有测试用例

解决方法,因为ΔDtïÐns4*+Šn-}O15个字节)似乎不起作用。. 在调试模式下联机尝试以了解我的意思。我希望它从[45,'35',25]到下一个迭代[45,10]之后到,但是显然它清除了除最后一个值以外的堆栈,并变成,最后导致0。。不确定这是预期的行为还是错误。 (编辑:这是故意的,请参阅底部。)-Δ[10]

说明:

还使用,其中是像大多数其他答案一样的循环宽度。ww2+4ww

[        }     # Start an infinite loop:
 Ð             #  Triplicate the value at the top of the stack
  _#           #  If the top is 0: break the infinite loop
 t             #  Take the square-root of the value
               #   i.e. 35 → 5.916...
  ï            #  Remove any digits by casting it to an integer, so we have our width
               #   i.e. 5.916... → 5
   Ð           #  Triplicate that width
    n          #  Take the square of it
               #   i.e. 5 → 25
     s         #  Swap so the width is at the top again
      4*       #  Multiply the width by 4
               #   i.e. 5 → 20
        +      #  And sum them together
               #   i.e. 25 + 20 → 45
 Š             #  Triple-swap so the calculated value for the current width
               #  is now at the back of the stack
               #   i.e. [35,5,45] → [45,35,5]
  n            #  Take the square of the width again
               #   5 → 25
   -           #  Subtract the square of the width from the value for the next iteration
               #   i.e. 35 - 25 → 10
          O    # Take the sum of the stack
               #   i.e. [45,21,5,0,0] → 71

编辑:显然我上面描述的行为Δ是预期的。这是@ Mr.Xcoder提供的两个17字节替代方案,它们Δ通过将值放入global_array(带有^),然后再取回它们(带有¯)来使用:

ΔЈtïnα}¯¥ÄDt··+O

在线尝试验证所有测试用例

ΔЈtïnα}¯¥ÄtD4+*O

在线尝试验证所有测试用例






1

PHP,67字节

<?for($n=$argv[1];$w=(int)sqrt($n);$n-=$w**2)$a+=$w**2+$w*4;echo$a;

要运行它:

php -n <filename> <n>

例:

php -n roman_army_shields.php 35

在线尝试!


使用-R选项,此版本为60字节

for(;$w=(int)sqrt($argn);$argn-=$w**2)$a+=$w**2+$w*4;echo$a;

例:

echo 35 | php -nR "for(;$w=(int)sqrt($argn);$argn-=$w**2)$a+=$w**2+$w*4;echo$a;"

(在Linux上,替换"'


注意:这是使用Arnauld的答案公式,我找不到比这短的任何东西。


1

Pyth,19个字节

递归函数,应使用调用y(请参阅链接)。

L&b+*Ks@b2+4Ky-b^K2

在这里尝试!

Pyth,21个字节

修订历史很有趣,但是如果您想要一个更快的版本,请确保访问它:)

sm*d+4deeDsI#I#@RL2./

在这里尝试!

说明

sm*d+4deeDsI#I#@RL2./完整程序,我们将其称为输入Q。
                   ./ Q的整数分区产生所有正数的组合
                          加起来等于Q的整数。
               @ RL2取每个分区的所有整数的平方根。
             I#仅将不变的分区保留在下面:
          sI#丢弃所有非整数。这基本上只能保持
                          完全由完美正方形组成的分区,但是
                          与其拥有正方形,不如说它们有根。
       eeD获取具有最高最大值的分区(例如P)。
 m对于P中的每个d ...
  * d + 4d ...产量d *(d + 4)= d ^ 2 + 4d,所有答案中使用的公式。
■对映射结果求和并隐式输出。

1

迅速4111个99 84 78字节

func f(_ x:Int)->Int{var y=x;while y*y>x{y-=1};return x>0 ?(y+4)*y+f(x-y*y):0}

在线尝试!

手动实现整数平方根时的感觉比内置的短得多。

脱胎换骨和解释

// Define a function f that takes an integer, x, and returns another integer
// "_" is used here to make the parameter anonymous (f(x:...) -> f(...))
func f(_ x: Int) -> Int {

    // Assign a variable y to the value of x

    var y = x

    // While y squared is higher than x, decrement y.

    while y * y > x {
        y -= 1
    }

    // If x > 0, return (y + 4) * y + f(x - y * y), else 0.

    return x > 0 ? (y + 4) * y + f(x - y * y) : 0
}
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.