Bereich, der von einer Begrenzungsschleife umschlossen ist

14

Ermitteln Sie die Fläche eines Bereichs von Einheitszellen anhand der Umfangsschleife als Folge von 90-Grad-Umdrehungen.

Nehmen Sie zum Beispiel den Bereich mit drei Zellen

XX
X

deren Umfangsschleife zeichnen wir

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

Jede Abbiegung ist als links (L), gerade (S) oder rechts (R) markiert. Ausgehend vom R sind die Abbiegungen RLLSLSLL. Bei einer gegebenen Eingabe RLLSLSLLsollten wir also 3 für den Bereich ausgeben.

Die Eingangssequenz zeichnet garantiert eine Schleife auf, die eine einzelne Region auf der linken Seite umschließt.

  • Der Pfad endet wieder am Startpunkt und zeigt in die ursprüngliche Richtung. Er bildet eine Schleife.
  • Die Schleife kreuzt oder berührt sich nicht.
  • Die Schleife dreht sich gegen den Uhrzeigersinn um eine Region.

I / O

Sie können Eingaben als Liste oder Zeichenfolge LSRoder als Zahlen -1, 0, 1für links, gerade, rechts vornehmen. Die Ausgabe ist eine positive Ganzzahl. Schwimmer sind in Ordnung.

Testfälle

Die Eingaben werden in beiden Formaten angegeben, gefolgt von den jeweiligen Ausgaben.

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
xnor
quelle

Antworten:

10

Brain-Flak , 112 Bytes

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

Probieren Sie es online!

Dieses Programm verwendet den Satz von Green , um die Fläche zu berechnen

Die aktuelle Position wird in einem Format auf dem rechten Stapel gespeichert, das von der Ausrichtung abhängt.

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

In allen Fällen wird der zweite Wert auf dem Stapel um 1 erhöht, und das Linienintegral für die Fläche wird um die Hälfte des Werts auf dem Stapel verringert. Zum Ausgleich dividiert das Programmende die laufende Summe durch -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
({()<({}()())>}{})
Nitrodon
quelle
7

APL (Dyalog Classic) , 30 28 19 Bytes

-2 danke an @ Adám

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

Probieren Sie es online!

verwendet Tricks mit komplexen Zahlen , um die Koordinaten zu berechnen

der Bereich ist ½Σ (x i -X i + 1 ) (y i + y i + 1 ) oder in äquivalenter Weise Σ (x i -X i + 1 ) y i wie die Linien sind nur horizontale oder vertikale

ngn
quelle
Speichern in, indem Sie in einen tradfn body konvertieren.
Adám
@ Adám richtig, ich hatte auf einen Zug gehofft und irgendwie vergessen, das zu tun ...
ngn
@ Adám ah! Ich fand den Zug :)
ngn
6

JavaScript (ES6), 52 bis 50 Byte

2 Bytes dank @Neil gespeichert

Erwartet das zweite Eingabeformat.

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

Probieren Sie es online!

Wie?

Diese Beschreibung gilt für die Vorgängerversion : x und y wurden inzwischen invertiert.

Dies basiert auf der bereits von @ngn erwähnten Formel : A = Σ (x i - x i + 1 ) y i , die auch als alsodx i y i mit dx i geschrieben werden kann entweder -1, 0 oder 1 ist.

Wir beginnen mit r = y = 0 .

Wir verfolgen die aktuelle Richtung in einem :

          | 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

Es wird aktualisiert mit a = a + k & 3, wo k das aktuelle Element des Eingabearrays ist.

Da a anfänglich das Eingabearray enthält, wird a + k bei der ersten Iteration zu NaN und dann zu 0 gezwungen wenn das bitweise UND angewendet wird. Das bedeutet, dass der erste Richtungswechsel ignoriert wird und wir immer nach Osten fahren. Es spielt keine Rolle, da die Fläche gleich bleibt, unabhängig von der Ausrichtung der endgültigen Form.

Dann aktualisieren wir y mity += (2 - a) % 2 .

Schließlich berechnen wir -dx mit ~-a % 2und subtrahieren y * -dx von r , was - am Ende des Prozesses - unser Endergebnis ist.

Arnauld
quelle
1
a=>a.map(k=>r+=(2-(a=a+k&3))%2*(y+=~-a%2),r=y=0)|rSpart 2 Bytes.
Neil
4

Python 2 , 64 Bytes

f=lambda c,d=1,x=0:c>[]and f(c[1:],d*1j**c[0],x+d.real)-x*d.imag

Probieren Sie es online!

Berechnet ∑xΔy mit komplexen Zahlen.

Lynn
quelle
3

Haskell , 71 70 69 Bytes

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

Erklärung: Der Satz von Green gibt die Formel für die Fläche an: A = ½∑ (x k + 1 + x k ) (y k + 1 -y k ), die sich zu A = ½∑ Δx = 0 2x k Δy + ½∑ vereinfacht & Delta; y = 0 (x k + 1 + x k ) * 0 = ΣxΔy wenn Drehungen um 90 Grad entlang der Achsen sind. Wir haben den folgenden Pseudocode für eine rekursive Turn-Globbing-Funktion, die die x-Position und -Richtung verfolgt:

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

wobei die neue Richtung ΔA und Δx aus den folgenden Tabellen ersichtlich ist. Wir können eine sinusförmige Periodizität der Länge 4 sowohl in & Dgr; A als auch in & Dgr; x entlang der diagonalen Achse sehen dir+turn, die unter Verwendung von sinanstelle von modularer Arithmetik implementiert wird .

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

Probieren Sie es online!

Angs
quelle
2

Wolfram Language (Mathematica) , 36-30 Bytes

Area@Polygon@AnglePath[.5Pi#]&

Wenn Sie eine ältere Version von Mathematica (~ v10) haben, müssen Sie Most@vor AnglePath, um das Schließen des Polygons zu vermeiden. (Danke an @ user202729 für die Tipps).

Original: Online ausprobieren!

aktualisiert: Probieren Sie es online!

Kelly Lowder
quelle
#.5Pischeint zu funktionieren.
user202729
Es sieht so aus, als könnte man das auch fallen lassen Most.
User202729
2

Jelly , 15 11 Bytes

Vielen Dank an @xnor für den Hinweis auf einen nutzlosen Schritt und das Speichern von 2 Bytes.
Vielen Dank an @dylnan für das Speichern eines weiteren Bytes

Erwartet das zweite Eingabeformat. Gibt einen float zurück.

+\ı*Ḟ_\×ƊĊS

Probieren Sie es online! oder führen Sie alle Testfälle aus

Kommentiert

+\ı*Ḟ_\×ƊĊ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
Arnauld
quelle
Sind nur die mindestens 2 signifikanten Bits erforderlich?
xnor
+\ı*Ḟ_\×ƊĊSspeichert ein Byte
dylnan
@xnor und dylnan Danke, dass du mir geholfen hast, diese Einsendung zu machen. Und extra danke an xnor für das Kopfgeld!
Arnauld
2

Python 2 , 62 Bytes

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

Probieren Sie es online!

Ähnlich wie bei Lynns Lösung , jedoch mit einer komplexen Arithmetik, um die richtige Komponente der komplexen Zahl auf einmal zu extrahieren.

xnor
quelle
0

Pyth , 14 Bytes

_smec^.j)sd2.:

Testsuite

_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

Dies drückt den Bereich als die Summe -1/2 * g(sum(l))aller zusammenhängenden Unterlisten lüber die Eingabe aus, in gdie modular indiziert wird [0,1,0,-1]. Der Code implementiert gals g(x)=imag(1j**x). Es kann eine kürzere Methode mit direkter modularer Indizierung, Verwendung sinoder einer Arithmetikfunktion geben x%4.

xnor
quelle