Area tertutup oleh perimeter loop


14

Temukan luas wilayah sel satuan yang diberi perimeter loop sebagai urutan putaran 90 derajat.

Misalnya, ambil wilayah tiga sel

XX
X

loop perimeter yang kita gambar

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

Setiap belokan ditandai sebagai kiri (L), lurus (S), atau kanan (R). Mulai dari R, belokannya RLLSLSLL. Jadi, diberi input RLLSLSLL, kita harus mengeluarkan 3 untuk area tersebut.

Urutan input dijamin untuk melacak lingkaran yang menyertakan satu wilayah di sebelah kirinya.

  • Jalur berakhir kembali pada titik awal, menghadap ke arah awal, membentuk lingkaran.
  • Loop tidak bersilangan atau menyentuh dirinya sendiri.
  • Loop berputar berlawanan arah jarum jam di sekitar suatu wilayah.

I / O

Anda dapat mengambil input sebagai daftar atau rangkaian karakter LSR, atau sebagai angka -1, 0, 1untuk kiri, lurus, kanan. Output adalah bilangan bulat positif. Mengapung tidak masalah.

Uji kasus

Input diberikan dalam kedua format diikuti oleh output masing-masing.

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

Jawaban:


10

Brain-Flak , 112 byte

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

Cobalah online!

Program ini menggunakan teorema Green untuk menghitung area

Lokasi saat ini disimpan di tumpukan kanan, dalam format yang tergantung pada arah yang dihadapi.

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

Dalam semua kasus, nilai kedua pada tumpukan akan meningkat sebesar 1, dan garis integral untuk area tersebut berkurang setengah nilai di atas tumpukan. Untuk mengkompensasi, akhir program membagi total berjalan dengan -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 byte

-2 Terima kasih kepada @ Adám

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

Cobalah online!

menggunakan trik dengan bilangan kompleks untuk menghitung koordinat

luasnya ½Σ (x i -x i + 1 ) (y i + y i + 1 ) atau setara Σ (x i -x i + 1 ) y i karena garis-garisnya hanya horisontal atau vertikal


Simpan ke dengan mengonversi ke tubuh tradfn.
Adám

@ Adám benar, saya berharap untuk kereta dan entah bagaimana lupa untuk melakukan itu ...
ngn

@ Adah ah! Saya menemukan kereta :)
ngn

6

JavaScript (ES6), 52 50 byte

Disimpan 2 byte berkat @Neil

Mengharapkan format input kedua.

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

Cobalah online!

Bagaimana?

Deskripsi ini berlaku untuk versi sebelumnya : x dan y sejak itu telah terbalik.

Ini didasarkan pada rumus yang telah disebutkan oleh @ngn : A = Σ (x i - x i + 1 ) y i , yang juga dapat ditulis sebagai Σdx i y i di mana dx i bernilai -1, 0 atau 1.

Kita mulai dengan r = y = 0 .

Kami terus melacak dari arah arus di sebuah :

          | 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

Itu diperbarui dengan a = a + k & 3, di mana k adalah elemen saat ini dari array input.

Karena suatu awalnya berisi array input, a + k adalah dipaksa untuk NaN pada iterasi pertama dan kemudian ke 0 ketika bitwise DAN diterapkan. Ini berarti bahwa perubahan arah pertama sebenarnya diabaikan dan kami selalu mulai menuju ke Timur. Tidak masalah karena area tetap sama, tidak peduli orientasi bentuk akhir.

Kemudian, kami memperbarui y dengan y += (2 - a) % 2.

Akhirnya, kita menghitung -dx dengan ~-a % 2dan mengurangi y * -dx dari r , yang - pada akhir proses - adalah hasil akhir kita.


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


3

Haskell , 71 70 69 byte

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

Penjelasan: Teorema Green memberikan rumus untuk area: A = ½ € (x k + 1 + x k ) (y k + 1 -y k ), yang disederhanakan menjadi A = ½ € Δx = 0 2x k Δy + ½ € Δy = 0 ( xk + 1 + x k ) * 0 = ∑xΔy saat belokan 90 derajat di sepanjang sumbu. Kami memiliki pseudocode berikut untuk fungsi turn-globbing rekursif yang melacak posisi dan arah x:

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

di mana arah baru, ΔA dan Δx dapat dilihat dari tabel berikut. Kita dapat melihat periodisitas sinusoidal dengan panjang empat di ΔA dan Δx di sepanjang sumbu diagonal dir+turn, yang diimplementasikan menggunakan sinalih-alih aritmatika modular.

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

Cobalah online!



2

Jelly , 15 11 byte

Terima kasih kepada @xnor karena menunjukkan langkah yang tidak berguna, menghemat 2 byte
Terima kasih kepada @dylnan karena telah menyimpan byte lain

Mengharapkan format input kedua. Mengembalikan float.

+\ı*Ḟ_\×ƊĊS

Cobalah online! atau jalankan semua test case

Berkomentar

+\ı*Ḟ_\×ƊĊ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

Apakah hanya menyimpan 2 bit penting saja yang diperlukan?
xnor

+\ı*Ḟ_\×ƊĊSmenghemat satu byte
dylnan

@ xnor dan dylnan Terima kasih telah membantu saya bermain golf kiriman ini. Dan terima kasih ekstra kepada xnor untuk hadiahnya!
Arnauld

2

Python 2 , 62 byte

f=lambda l,p=0,s=1:l>[]and(p/s).imag/2+f(l[1:],p+s,s*1j**l[0])

Cobalah online!

Mirip dengan solusi Lynn , tetapi menggunakan beberapa aritmatika kompleks untuk mengekstrak komponen yang tepat dari bilangan kompleks dalam sekali jalan.



0

Pyth , 14 byte

_smec^.j)sd2.:

Suite uji

_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

Ini menyatakan area sebagai jumlah dari -1/2 * g(sum(l))semua daftar yang berdekatan latas input, di mana gpengindeksan modular menjadi [0,1,0,-1]. Kode diimplementasikan gsebagai g(x)=imag(1j**x). Mungkin ada metode yang lebih pendek dengan pengindeksan modular langsung, menggunakan sin, atau fungsi aritmatika aktif x%4.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.