周边环圈包围的区域


14

给定其周长环为90度转弯的序列,找到单位晶胞区域的面积。

例如,以三格区域为例

XX
X

我们画出谁的周长环

L<S<L
v   ^
S R>L
v ^
L>L

每转标记为左(L),直(S)或右(R)。从R开始,转弯为RLLSLSLL。因此,给定输入RLLSLSLL,我们应该为该区域输出3。

确保输入序列能找出一个循环,该循环将左侧的单个区域包围起来。

  • 路径在起点处开始,面向初始方向,形成一个循环。
  • 循环不会交叉或接触自身。
  • 循环围绕一个区域逆时针旋转。

输入输出

您可以将输入作为一个列表或字符串LSR,或者作为-1, 0, 1左,直,右的数字。输出是一个正整数。漂浮物还可以。

测试用例

输入以两种格式给出,后面分别是它们的输出。

RLLSLSLL
LLLL
SLLSLL
LSRRSLLSSLSSLSSL
SSSSSLSSSSSLSSSSSLSSSSSL

[1, -1, -1, 0, -1, 0, -1, -1]
[-1, -1, -1, -1]
[0, -1, -1, 0, -1, -1]
[-1, 0, 1, 1, 0, -1, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1]
[0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1]

3
1
2
7
36

Answers:


10

Brain-Flak,112字节

(([]){[{}]<{({}()){{}<>([{}]<([{}])>)(<>)}<>(({}[({})])[({}{})])<>}{}<>>({}<({}())>)<>([])}{})({()<({}()())>}{})

在线尝试!

该程序使用格林定理计算面积

当前位置以取决于所面对方向的格式存储在正确的堆栈中。

Direction  top  second
north       -x       y
west        -y      -x
south        x      -y
east         y       x

在所有情况下,堆栈上的第二个值将增加1,并且该区域的线积分减小到堆栈顶部上的值的一半。为了补偿,该程序的末尾将运行总数除以-2。

# For each number in input
(([]){[{}]

  # Evaluate turn-handling to zero
  <

    # If turn:
    {

      # If right turn:
      ({}()){{}

        # Negate both values on other stack (reverse direction)
        <>([{}]<([{}])>)

      (<>)}

      # Swap the two stack elements and negate the new top of stack
      # This performs a left turn.
      <>(({}[({})])[({}{})])<>

    }{}

  <>>

  # Evaluate as top of stack and...
  ({}<

    # increment the number below it
    ({}())

  >)<>

([])}{})

# Divide total by -2
({()<({}()())>}{})

7

APL(Dyalog Classic)30 28 19字节

-2感谢@Adám

(+/9∘○×11○+\)0j1*+\

在线尝试!

使用复杂数字的技巧来计算坐标

面积为½Σ(x i -x i + 1)(y i + y i + 1)或等效Σ(x i -x i + 1)y i,因为线仅是水平或垂直


通过转换为tradfn正文来保存。
亚当

@Adám对,我希望去坐火车,却以某种方式忘了这么做……
ngn

@Adám啊!我找到火车了:)
ngn

6

JavaScript(ES6),52 50字节

@Neil节省了2个字节

需要第二种输入格式。

a=>a.map(k=>r+=(2-(a=a+k&3))%2*(y+=~-a%2),r=y=0)|r

在线尝试!

怎么样?

此描述适用于以前的版本xy从此被反转。

这是基于已经由@ngn提及的公式A =Σ(X - X i + 1的)Y ,其也可以写成Σdx ÿ 其中DX 要么是-1,0或1。

我们从r = y = 0开始

我们跟踪的电流方向的一个

          | a = 0 | a = 1 | a = 2 | a = 3
----------+-------+-------+-------+-------
direction | East  | South | West  | North
       dx |  +1   |   0   |  -1   |   0     <--  -(~-a % 2)
       dy |   0   |  +1   |   0   |  -1     <--  (2 - a) % 2

用进行更新a = a + k & 3,其中k是输入数组的当前元素。

因为a最初包含输入数组,所以a + k在第一次迭代时被强制为NaN,然后在应用按位AND时被强制为0。这意味着实际上第一个方向更改被忽略了,我们总是开始向东行驶。没关系,因为无论最终形状的方向如何,面积都保持不变。

然后,我们更新ÿy += (2 - a) % 2

最后,我们使用-dx进行计算,~-a % 2并从r中减去y * -dx,这是我们的最终结果。


1
a=>a.map(k=>r+=(2-(a=a+k&3))%2*(y+=~-a%2),r=y=0)|r节省2个字节。
尼尔


3

Haskell71 70 69字节

a 0 0
a x d(t:r)|k<-t+d=x*g k+a(x+g(k-1))k r
a _ _ _=0
g a=sin$a*pi/2

说明:格林定理给出了面积的公式:A =½Σ(X K + 1 + X ķ)(Y K + 1 -y ķ),其简化为A =½Σ ΔX= 0ķ ΔY+½Σ 当沿轴旋转90度时,Δy= 0(x k + 1 + x k)* 0 = ∑xΔy。对于递归转向球函数,我们具有以下伪代码,该函数跟踪x的位置和方向:

A x dir (turn:turns) = ΔA + A (xx) (dir+turn) turns

从下表中可以看到新方向ΔA和Δx。我们可以看到,沿对角轴在ΔA和Δx中长度均为4的正弦周期dir+turn,这是通过使用sin模块化算法来实现的。

  ↔|L S R ΔA| L  S  R  Δx| L  S  R 
         -x  0  x      0 -1  0  
          0  x  0     -1  0  1
          x  0 -x      0  1  0
          0 -x  0      1  0 -1

在线尝试!



2

果冻15 11字节

感谢@xnor指出了一个无用的步骤,节省了2个字节
感谢@dylnan节省了另一个字节

需要第二种输入格式。返回一个浮点数。

+\ı*Ḟ_\×ƊĊS

在线尝试!运行所有测试用例

已评论

+\ı*Ḟ_\×ƊĊS  - main link, taking the input list   e.g. [1, -1, -1, 0, -1, 0, -1, -1]
+\           - cumulative sum                     -->  [1, 0, -1, -1, -2, -2, -3, -4]
  ı*         - compute 1j ** d,                   -->  [(0+1j), (1+0j), (0-1j), (0-1j),
               which gives a list of (-dy + dx*j)       (-1+0j), (-1+0j), (0+1j), (1+0j)]
         Ċ   - isolate the imaginary part (dx)    -->  [1, 0, -1, -1, 0, 0, 1, 0] (floats)
        Ɗ    - invoke the last 3 links as a monad
    Ḟ        - isolate the real part (-dy)        -->  [0, 1, 0, 0, -1, -1, 0, 1] (floats)
     _\      - negated cumulative sum (gives y)   -->  [0, -1, -1, -1, 0, 1, 1, 0]
       ×     - compute dx * y                     -->  [0, 0, 1, 1, 0, 0, 1, 0]
          S  - sum                                -->  3

是否仅需要保留至少2个有效位?
xnor

+\ı*Ḟ_\×ƊĊS保存一个字节
dylnan '18

@xnor和dylnan谢谢您帮助我打高尔夫球。还要感谢xnor的赏金!
阿诺尔德



0

Pyth,14个字节

_smec^.j)sd2.:

测试套件

_smec^.j)sd2.:
              Q     implicit input
            .:      take all non-empty contiguous sublists
  m                map this operation onto each one:
   ec^.j)sd2
         s           the sum of the sublist
     ^.j)            raise it to the complex unit 1j to that power
    c      2         halve it
   e                take the imaginary part
_s                take the negated sum of the result

这将面积表示为输入-1/2 * g(sum(l))上所有连续子列表的总和,在l其中进行g模块化索引[0,1,0,-1]。该代码实现gg(x)=imag(1j**x)。可能有一种较短的方法,可以使用直接模索引,在上使用sin或算术函数x%4

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.