Verfolgen Sie ein Objekt im 2D-Raum

11

Beschreibung

Die Aufgabe dieser Herausforderung besteht darin, ein Programm oder eine Funktion zu entwickeln, die ein bestimmtes Objekt in einem n×n Raum verfolgt.

I / O.

Ihr Programm erhält 3 Eingaben, die auf jede sinnvolle Weise vorgenommen werden können :

nwird die Größe der Flugzeugseite sein. (Für n=5 ist Ihre Ebene also 5×5 ). Sie können davon ausgehen, dass nes sich immer um eine ungerade Ganzzahl handelt.

swird die Startposition des Objekts sein, angegeben als ein Paar von (x,y) Koordinaten.

Dwird ein Vektor von geordneten Paaren sein. Dfolgt dem Format D=[(d0,t0),(d1,t1),...,(dn,tn)] , wobei dk immer eine von 'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'für die kardinale und primäre interkardinale Richtung ist und tk eine ganze Zahl für die Anzahl von 'Ticks' ist.

Angesichts dieser Eingaben muss Ihr Programm eine Verfolgung des Objekts in der Ebene ausgeben.

Regeln

Die Ausgabe muss die Grenzen der Ebene enthalten. Z.B:

- 21012 +
+ ┌─────┐
2│ │
1│ │
0│ │
1│ │
2│ │
-└─────┘

wäre ein Beispiel für eine leere 5×5 Ebene. Die Zahlen oben und seitlich dienen nur als Referenz und müssen nicht gedruckt werden.

Sie können beliebige Zeichen für die Grenzen verwenden, sofern es sich nicht um Leerzeichen handelt (oder als Leerzeichen gerendert werden). Die von Ihnen ausgewählten Zeichen müssen die gesamte Ebene abgrenzen, sodass zwischen ihnen keine Lücken bestehen dürfen.

Einige akzeptable Flugzeuge umfassen:

┌──┐ .... ---- + - +
│ │. . | | | |
│ │. . | | | |
└──┘; ....; ----; + - +

Nicht akzeptable Flugzeuge umfassen:

      .... .... ++++. .
            . . + +. .
            . + +. .
    ;; ....; ....; + +; . .

Das zu verfolgende Objekt kann ein beliebiges Zeichen sein, solange es nur 1 Feld in der Ebene einnimmt und sich von den Begrenzungszeichen unterscheidet.

Die Spur des verfolgten Objekts kann auch ein beliebiges Zeichen sein, sofern diese nur 1 Feld in der Ebene belegen und sich vom Objekt unterscheiden.

Für jedes Element (dk,tk) in D muss das Objekt t Leerzeichen in Richtung d und eine Spur hinterlassen.

Wenn das Objekt eine Grenze treffen würde, wird es reflektiert. Wenn das Objekt noch Bewegungen hat, bewegt es sich weiter in die Richtung, in die es reflektiert wurde.

Als Referenz spiegeln sich diese Richtungen zueinander wider:

NS → wenn die obere oder untere Grenze erreicht ist;

EW → wenn eine seitliche Grenze erreicht ist;

Die endgültige Ausgabe enthält die neuesten möglichen Spuren. Wenn das Objekt eine Spur in einem Bereich hinterlassen würde, in dem bereits eine Spur vorhanden ist, überschreibt das neuere Spurenzeichen das ältere.

Standardschlupflöcher sind wie üblich standardmäßig verboten .

Wertung:

Dies ist eine Herausforderung.

Beispiele:

n=5s=(0,0)D=[(NW,2),(S,2),(E,1)]

Arbeiten Sie es aus:

t=0

    0
 ┌─────┐
 │ │
 │ │
0│ ○ │
 │ │
 │ │
 └─────┘

t=2

    0
 ┌─────┐
 │ ○ │
 │ \ │
0│ \ │
 │ │
 │ │
 └─────┘

t=4

    0
 ┌─────┐
 │∧ │
 │ | \ │
0│ ○ \ │
 │ │
 │ │
 └─────┘

t=5

    0
 ┌─────┐
 │∧ │
 │ | \ │
0│└ ○ \ │
 │ │
 │ │
 └─────┘

(Die Nullen dienen nur als Referenz und müssen nicht in der endgültigen Ausgabe enthalten sein.)


n=9s=(3,1)D=[(N,2),(SW,8),(SE,3),(NE,8)]

t=10

      0     
 ┌─────────┐
 │ │
 │ │
 │ │
 │ ∧ │
0│ / | │
 │ ○ / | │
 │⟨ / │
 │ \ / │
 │ ∨ │
 └─────────┘

SWNWNWNE

t=21

      0     
 ┌─────────┐
 │ ○ │
 │ \ │
 │ \ │
 │ \ │
0│ / | ⟩│
 │ ∧ / / │
 │⟨ \ / / │
 │ \ \ / │
 │ ∨ ∨ │
 └─────────┘

Testfälle:

n=5s=(0,0)D=[(NW,2),(S,2),(E,1)]

Ausgabe:

    0
 ┌─────┐
 │∧ │
 │ | \ │
0│└ ○ \ │
 │ │
 │ │
 └─────┘


Eingabe: n=9 , s=(3,1) , D=[(N,2),(SW,8),(SE,3),(NE,8)]

Ausgabe:

      0     
 ┌─────────┐
 │ ○ │
 │ \ │
 │ \ │
 │ \ │
0│ / | ⟩│
 │ ∧ / / │
 │⟨ \ / / │
 │ \ \ / │
 │ ∨ ∨ │
 └─────────┘


Eingabe: n=3 , s=(1,1) , D=[(N,5),(W,5)]

Ausgabe:

   0
 ┌───┐
 │ | │
0│- ○ ┐│
 │ | │
 └───┘


Eingabe: n=11 , s=(3,5) , D=[(NW,8),(E,5),(SE,3),(SW,5),(N,6),(NE,10)]

Ausgabe:

       0
 ┌───────────┐
 │ ∧ │
 │ / \ │
 │┌ - / - \ \ │
 │ \ | / \ \ │
 │ \ | \ \ │
0│ | / ⟩│
 │ | \ / / │
 │ | / ○ │
 │ | / \ │
 │ ∨ \ │
 │ \ │
 └───────────┘
J. Sallé
quelle
Ich habe vergessen zu erwähnen, dass diese Herausforderung im Sandkasten lag .
J. Sallé
Können wir nehmen 'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW' eine 0-indizierte (oder 1-indizierte) Ganzzahl verwenden? So [('NW',2),('S',2),('E',1)]wird [[7,2],[4,2],[2,1]]zum Beispiel.
Kevin Cruijssen
@ KevinCruijssen sicher, kein Problem. Stellen Sie einfach sicher, dass Sie in der Antwort darauf hinweisen.
J. Sallé
1
@Arnauld ja, du darfst ein einzelnes Trace-Zeichen verwenden. Ich habe mehr als einen verwendet, um die Testfälle einfacher zu visualisieren, aber es ist nicht erforderlich. Stellen Sie einfach sicher, dass sich das Ablaufverfolgungszeichen vom Zeichen des zu verfolgenden Objekts unterscheidet.
J. Sallé
1
@Arnauld " Das zu verfolgende Objekt kann ein beliebiges Zeichen sein, das Sie auswählen, solange es nur 1 Feld in der Ebene einnimmt und sich von den Begrenzungszeichen unterscheidet. Die Spur des verfolgten Objekts kann auch ein beliebiges beliebiges Zeichen sein da sie nur 1 Feld im Flugzeug einnehmen und sich vom Objekt unterscheiden. "
Kevin Cruijssen

Antworten:

9

JavaScript (ES6), 228 Byte

Nimmt Eingabe als (n,x,y,[[dir,len],[dir,len],...])07

Gibt eine Zeichenfolge mit 0für eine Grenze, 1für eine Ablaufverfolgung und 3für die Endposition aus.

(n,x,y,a)=>(g=X=>Y>n?'':(Y%n&&X%n&&a.map(([d,l],i)=>(M=H=>(h-X|v-Y||(k|=a[i+!l]?1:3),l--&&M(H=(h+H)%n?H:-H,h+=H,v+=V=(v+V)%n?V:-V)))(~-(D='12221')[d],V=~-D[d+2&7]),h=x+n/2,v=n/2-y,k=' ')&&k)+(X<n?'':`
`)+g(X++<n?X:!++Y))(Y=!++n)

Probieren Sie es online aus!

Wie?

Das Initialisieren und Zeichnen in eine 'Leinwand' (dh eine Matrix von Zeichen) ist in JavaScript etwas mühsam und langwierig.

Dieser Code verwendet eine andere Strategie: Anstatt die Ausgabe in einem 2D-Array zu speichern, wird eine Zeichenfolge zeichenweise von links nach rechts und von oben nach unten erstellt. Bei jeder Iteration:

  • Wir geben a aus, 0wenn wir eine Grenze überschreiten.
  • Andernfalls simulieren wir den vollständigen Pfad und prüfen, ob er unsere aktuelle Position überschreitet. Wir geben entweder 1oder 3wenn ja, oder ein anderes Leerzeichen aus.
  • Wir fügen einen Zeilenvorschub hinzu, wenn wir die richtige Grenze erreicht haben.

Alles in allem ist dies vielleicht nicht der kürzeste Ansatz, aber ich dachte, es lohnt sich, es zu versuchen.

Arnauld
quelle
9

Java 10, 350 343 340 336 Bytes

(n,s,S,D)->{int N=n+2,x=N/2+s,y=N/2-S,i=N*N;var r=new char[N][N];for(;i-->0;)r[i/N][i%N]=i/N*(i%N)<1|i/N>n|i%N>n?'#':32;r[y][x]=42;for(var d:D)for(i=d[0];d[1]-->0;r[y+=i%7<2?1/y*2-1:i>2&i<6?y<n?1:-1:0][x+=i>0&i<4?x<n?1:-1:i>4?1/x*2-1:0]=42)i=y<2&i<2|y>=n&i>2&i<5?4-i:x<2&i>4|x>=n&i>0&i<4?8-i:y<2&i>6?5:y<n|i!=5?i:7;r[y][x]=79;return r;}

Dist ein 2D-Integer-Array, bei dem die Richtungen 0-indizierte Ganzzahlen sind : N=0, NE=1, E=2, SE=3, S=4, SW=5, W=6, NW=7. Die x,yStartkoordinaten sind zwei separate Parameter sund S. Die Ausgabe ist eine Zeichenmatrix.
Es verwendet #als Grenze, *als Spur undO für die Endposition verwendet (es können jedoch alle drei ASCII-Zeichen im Unicode-Bereich [33,99]für dieselbe Byteanzahl sein, wenn Sie möchten).

Probieren Sie es online aus.

-4 Bytes dank @ceilingcat .
Kann definitiv noch mehr Golf gespielt werden, indem man die Bewegungen vereinfacht und in welche Richtung wir noch mehr reisen.

Erläuterung:

(n,s,S,D)->{           // Method with `n`,`s,S`,`D` parameters & char-matrix return-type
  int N=n+2,           //  Set `N` to `n+2`, since we use it multiple times
      x=N/2+s,         //  Calculate the starting `x` coordinate
      y=N/2-S,         //  Calculate the starting `y` coordinate
      i=N*N;           //  Index integer
  var r=new char[N][N];//  Result char-matrix of size `N` by `N`
  for(;i-->0;)         //  Loop `i` in the range (`N**2`, 0]
    r[i/N][i%N]=       //    Set the cell at position `i` divmod-`N` to:
      i/N*(i%N)<1|i/N>n|i%N>n?
                       //     If we're at a border:
       '#'             //      Set the current cell to '#'
      :                //     Else:
       32;             //      Set the current cell to ' ' (a space) instead
  r[y][x]=42;          //  Then set the starting position `x,y` to a '*'
  for(var d:D)         //  Loop over the `D` input:
    for(i=d[0];        //   Set `i` to the current direction
        d[1]-->0       //   Inner loop the current `d` amount of times
        ;              //     After every iteration:
         r[y+=         //      Change `y` based on the current direction
            i%7<2?     //       If the current direction is N, NE, or NW
             1/y*2-1   //        If we're at the top border:
                       //         Go one row down
                       //        Else
                       //         Go one row up
            :i>2&i<6?  //       Else-if the current direction is S, SE, or SW
             y<n?      //        If we're at the bottom border
              1        //         Go one row up
             :         //        Else
              -1       //         Go one row down
            :          //       Else (directions E or W)
             0]        //        Stay in the same row
          [x+=         //      Change `x` based on the current direction
            i>0&i<4?   //       If the current direction is E, NE, or SE
             x<n?      //        If we're NOT at the right border
              1        //         Go one column to the right
             :         //        Else:
              -1       //         Go one column to the left
            :i>4?      //       Else-if the current direction is W, NW, or SW
             1/x*2-1   //        If we're NOT at the left border:
                       //         Go one column to the left
                       //        Else:
                       //         Go one column to the right
            :          //       Else (directions N or S)
             0]        //        Stay in the same column
               =42)    //      And fill this new `x,y` cell with a '*'
      i=               //    Determine the new direction
        y<2&i<2|y>=n&i>2&i<5?4-i:x<2&i>4|x>=n&i>0&i<4?8-i:y<2&i>6?5:y<n|i!=5?i:7;
                       //     (See loose explanation below)
  r[y][x]=79;          //  And finally set the last `x,y` cell to 'O'
  return r;}           //  And return the result-matrix

y<2&i<2|y>=n&i>2&i<5?4-i:x<2&i>4|x>=n&i>0&i<4?8-i:y<2&i>6?5:y<n|i!=5?i:7ist eine Golfversion davon unten unter Verwendung 4-iund 8-ifür die meisten Richtungsänderungen:

y<2?     // If we're at the top border
 i==0?   //  If the current direction is N
  4      //   Change it to direction S
 :i==1?  //  Else-if the current direction is NE
  3      //   Change it to SE
 :i==7?  //  Else-if the current direction is NW
  5      //   Change it to SW
 :       //  Else
  i      //   Leave the direction the same
:x<2?    // Else-if we're at the left border
 i==7?   //  If the current direction is NW
  1      //   Change it to NE
 :i==6?  //  Else-if the current direction is W
  2      //   Change it to E
 :i==5?  //  Else-if the current direction is SW
  3      //   Change it to SE
 :       //  Else
  i      //   Leave the direction the same
:y>=n?   // Else-if we're at the bottom border
 i==3?   //  If the current direction is SE
  1      //   Change it to NE
 :i==4?  //  Else-if the current direction is S
  0      //   Change it to N
 :i==5?  //  Else-if the current direction is SW
  7      //   Change it to NW
 :       //  Else
  i      //   Leave the direction the same
:x>=n?   // Else-if we're at the right border
 i==1?   //  If the current direction is NE
  7      //   Change it to NW
 :i==2?  //  Else-if the current direction is E
  6      //   Change it to W
 :i==3?  //  Else-if the current direction is SE
  5      //   Change it to SW
 :       //  Else
  i      //   Leave the direction the same
:        // Else
 i       //  Leave the direction the same
Kevin Cruijssen
quelle
3

Holzkohle , 74 Bytes

NθJ⊘⊕θ⊘⊕θUR±⊕⊕θJN±NFA«≔⊟ιζF⊟ι«≔ζδ↷δ¶F›⊗↔ⅈθ≦±ζF›⊗↔ⅉθ≦⁻⁴ζ≧﹪⁸ζ↷⁴¶↶⁴↶δ↷ζ*¶↶ζPo

Probieren Sie es online aus! Der Link führt zur ausführlichen Version des Codes. Nimmt Eingaben im Format n, x, y, d vor, wobei d ein Array von Arrays von [Entfernung, Richtung] -Paaren ist, wobei die Richtung eine numerische Codierung von 0 = Süd im Uhrzeigersinn bis 7 = Südost ist. Erläuterung:

NθJ⊘⊕θ⊘⊕θUR±⊕⊕θ

Geben Sie nein Feld ein und zeichnen Sie es, dessen Inneres die Größe hat, die auf dem Ursprung zentriert ist.

JN±N

Eingabe und Sprung zu xund y(aber negieren, yda die y-Achse von Charcoal nach unten zunimmt).

FA«

Schleife über die Einträge in d.

≔⊟ιζ

Extrahieren Sie die Anfangsrichtung.

F⊟ι«

Wiederholen Sie dies für den gewünschten Abstand.

≔ζδ

Speichern Sie die Richtung.

↷δ¶

Machen Sie einen experimentellen Schritt in diese Richtung.

F›⊗↔ⅈθ≦±ζ

Wenn dies von den Seiten abweicht, drehen Sie die Richtung horizontal.

F›⊗↔ⅉθ≦⁻⁴ζ

Wenn dies oben oder unten geschieht, drehen Sie die Richtung vertikal.

≧﹪⁸ζ

Reduzieren Sie die Richtung Modulo 8 (die Pivot-Befehle akzeptieren nur Werte von 0 bis 7).

↷⁴¶↶⁴

Machen Sie den experimentellen Zug rückgängig.

↶δ↷ζ*¶

Zeigen Sie in die richtige Richtung, drucken Sie eine Spur und bewegen Sie sich.

↶ζPo

Gehen Sie zurück in die Standardrichtung und drucken Sie das Objekt an der aktuellen Position.

Neil
quelle
2

JavaScript, 206 Bytes

Nimmt die Eingabe als (n, x, y, [[dir, len], [dir, len], ...]) auf, wobei Richtungen mit Bitmasken codiert werden:

S : 1  
N : 2   
E : 4  
W : 8  
SE: 5 (1|4)  
SW: 9 (1|8)
NE: 6 (2|4)
NW:10 (2|8)

Gibt einen String mit aus

- 1 for top and bottom boundary
- 4 for left and right boundary 
- 5 for corners 
- 0 for trace
- 8 for the final position.

Die verschiedenen Werte für Grenzen werden verwendet, um die nächste Richtung zu bewerten

(n,x,y,d)=>(Q=[e=`
5`+'1'[R='repeat'](n)+5,o=n+3,-o,c=[...e+(`
4`+' '[R](n)+4)[R](n)+e],1,1+o,1-o,,-1,o-1,~o],p=1-o*(~n/2+y)-~n/2+x,c[d.map(([q,s])=>{for(a=q;s--;p+=Q[a^=c[p+Q[a]]*3])c[p]=0}),p]=8,c.join``)

Weniger Golf gespielt

F=(n,x,y,d) => (
  o = n+3, // vertical offset, accounting for boundaries and newline
  // Q = offsets for different directions, bitmask indexed 
  Q = [,  // 0000 no direction
     o,   // 0001 S
     -o,  // 0010 N
     ,    // 0011 NS - invalid
     1 ,  // 0100 E
     1+o, // 0101 SE
     1-o, // 0110 NE
     ,    // 0111 NSE - invalid
     -1,  // 1000 W
     o-1, // 1001 SW
    -o-1],// 1010 NW

  e = `\n5`+'1'.repeat(n)+5, // top and bottom boundary
  c = [...e + (`\n4` + ' '.repeat(n) + 4).repeat(n) + e], // canvas
  p = 1 - o*(~n/2+y) - ~n/2 + x, // start position
  d.map( ([q,s]) => { // repeat for each element in 'd'
    a = q; // starting offset pointer - will change when bounce
    while( s-- )
    {
      c[p] = 0; // trace
      b = c[p + Q[a]] // boundary value or 0 (space count 0)
      a ^= b * 3 // xor with 0 if no bounce, else 3 or 12 or 15
      p += Q[q]  // advance position
    }
  })
  c[p] = 8, // set end position
  c.join``
)

PRÜFUNG

var F=
(n,x,y,d)=>(Q=[e=`
5`+'1'[R='repeat'](n)+5,o=n+3,-o,c=[...e+(`
4`+' '[R](n)+4)[R](n)+e],1,1+o,1-o,,-1,o-1,~o],p=1-o*(~n/2+y)-~n/2+x,c[d.map(([q,s])=>{for(a=q;s--;p+=Q[a^=c[p+Q[a]]*3])c[p]=0}),p]=8,c.join``)

var out=x=>O.textContent+=x

var test=(n,x,y,d)=>{
  var dd = d.map(([d,s])=>[,'S','N',,'E','SE','NE',,'W','SW','NW'][d]+' '+s)
  out([n,x,y]+' ['+dd+']')
  out(F(n,x,y,d))
  out('\n\n')
}

test(5,0,0,[[10,2],[1,2],[4,1]])
test(9,3,-1,[[2,2],[9,8],[5,3],[6,8]])
test(11,3,-5,[[10,8],[4,5],[5,2],[9,5],[2,6],[6,10]])
<pre id=O></pre>

edc65
quelle
2

C (gcc) , 352 323 Bytes

Dank Deckenkatze 29 Bytes runtergegolfen.

#define G(x,a)x+=a=x<2|x>m-3?-a:a
#define A(p)atoi(v[p])
m,r,c,x,y,s,a,b;main(q,v)int**v;{m=A(1)+2;int f[r=m*m];for(x=A(2)+m/2;r--;f[r]=32);for(y=A(s=3)+m/2;++s<q;)for(a=cos(A(s)*.8)*2,b=sin(A(s)*.8)*2,c=A(++s);c--;G(y,b),f[y*m+x]=42)G(x,a);for(f[y*m+x]=64;++r<m;puts(""))for(c=0;c<m;c++)putchar(c%~-m&&r%~-m?f[r*m+c]:35);}

Probieren Sie es online aus!

Das Programm nimmt Eingaben als Befehlszeilenargumente (wie a.out 10 1 1 3 5 0 4 7 2):

  • Das erste Argument ist die Feldgröße.
  • (x,y)
  • (d,t)dEt

Erläuterung

// Update the coordinate AND simultaneously modify the direction (if needed)
#define G (x, a) x += a = x < 2 || x >= m - 2 ? -a : a

// Get the numeric value of an argument
#define A (p) atoi (v[p])

// variables
m, // width and height of the array with field data
r, c, // helpers
x, y, // current coordinates of the actor
s, // helper
a, b; // current direction of the movement

main (q, v) char **v;
{
    // array size is field size + 2 (for borders)
    m = A (1) + 2;

    // allocate the array
    int f[r = m * m];

    // fill the array with spaces,
    for
    (
        // but first get x of the actor
        x = A (2) + m / 2;

        r--;

        f[r] = 32
    );

    // trace: iterate over remaining commandline argument pairs
    for
    (
        // but first get y of the actor
        y = A (s = 3) + m / 2;

        ++s < q; // loop until no args left
    )
        // for each such pair
        for
        (
            a = cos (A (s) * .8) * 2,  // get the x-increment
            b = sin (A (s) * .8) * 2, // get the y-increment
            c = A (++s);  // then get the number of steps

            c--;

            // after each step:
            G (y, b), // update y and maybe the y-direction
            f[y * m + x] = 42 // draw the trail
        )
            G (x, a); // update x and maybe the x-direction

   // output
   for
   (
       f[x * m + y] = 64; // put a @ to the current position of the actor
       ++r < m; // r == -1 at the beginning of the loop so preincrement

       puts("") // terminate each row with newline
   )
       // iterate over columns in the row
       for (c = 0; c < m; c++)
           putchar
           (
               c % ~ -m && r % ~ -m ? // if it is not a border cell,
               f[r * m + c] // output the character from the array
               : 35 // otherwise output the #
           );
}
Max Yekhlakov
quelle
1
Ich glaube, Ihrem Code fehlt die Objektausgabe an der Endposition, da die Spur des verfolgten Objekts auch beliebige Zeichen sein kann, solange sie nur 1 Feld in der Ebene einnehmen und sich vom Objekt unterscheiden . Davon abgesehen sieht es für mich gut aus.
J. Sallé
Hoppla, das habe ich total vermisst, danke, dass du J.Sallé bemerkt hast. Glücklicherweise hat die Korrektur das Programm nicht länger gemacht.
Max Yekhlakov