Traccia un oggetto nello spazio 2d


11

Descrizione

Il compito di questa sfida è ideare un programma o una funzione che tenga traccia di un determinato oggetto in uno spazio .n×n

I / O

Al tuo programma verranno dati 3 ingressi, che possono essere presi in modo sensato :

nsarà la dimensione del lato dell'aereo. (quindi, per , il tuo aereo sarà ). Puoi presumere che sarà sempre un numero intero dispari.n=55×5n

ssarà la posizione iniziale dell'oggetto, data come una coppia di coordinate .(x,y)

Dsarà un vettore di coppie ordinate. Dseguirà il formato , dove sarà sempre uno dei , per le direzioni cardinale e primaria intercardinale, e sarà un numero intero per il numero di "tick".D=[(d0,t0),(d1,t1),...,(dn,tn)]dk'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'tk

Dati questi input, il tuo programma deve produrre un tracciamento dell'oggetto sul piano.

Regole

L'output deve contenere i limiti del piano. Per esempio:

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

sarebbe un esempio di un piano vuoto . I numeri sopra e a lato sono solo di riferimento e non devono essere stampati.5×5

Puoi usare qualunque personaggio (i) per i confini, purché non sia uno spazio bianco (o il rendering come uno spazio bianco). I personaggi scelti devono delineare l'intero piano, il che significa che non possono esserci spazi vuoti tra di loro.

Alcuni aerei accettabili includono:

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

Gli aerei non accettabili includono:

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

L'oggetto da tracciare può essere qualsiasi personaggio tu scelga, purché occupi solo 1 spazio sul piano ed è diverso dai caratteri di confine.

La traccia dell'oggetto tracciato può anche essere qualsiasi personaggio tu scelga, purché occupino solo 1 spazio sul piano e siano diversi dall'oggetto.

Per ogni elemento in , l'oggetto deve spostare spazi verso e lasciare una traccia dietro.(dk,tk)Dtd

Se l'oggetto colpirà un limite, verrà riflesso. Se all'oggetto rimangono ancora delle mosse, continuerà a muoversi nella direzione in cui è stato riflesso.

Per riferimento, queste direzioni si riflettono reciprocamente:

NS → quando viene raggiunto il limite superiore o inferiore;

EW → quando viene raggiunto un limite laterale;

L'output finale conterrà le tracce più recenti possibili, ovvero se l'oggetto lascerebbe una traccia in uno spazio in cui è già presente una traccia, il carattere di traccia più recente sovrascriverà il più vecchio.

Come al solito, le scappatoie standard sono vietate per impostazione predefinita .

punteggio:

Questa è una sfida di .

Esempi:

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

Risolvendolo:

t=0

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

t=2

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

t=4

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

t=5 , che sarà l'output.

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

(Gli 0 sono solo per riferimento e non devono essere nell'output finale.)


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

t=10

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

SWNWNWNE

t=21

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

Casi test:

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

Produzione:

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


Input: n=9 , S=(3,-1) , D=[('N',2),('SW',8),('SE',3),('NE',8)]

Produzione:

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


Input: n=3 , S=(1,1) , D=[('N',5),('W',5)]

Produzione:

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


Input: n=11 , S=(3,-5) , D=[('NW',8),('E',5),('SE',3),('SW',5),('N',6),('NE',10)]

Produzione:

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

Ho dimenticato di dire che questa sfida è stata sandbox .
J. Sallé,

Possiamo invece prendere 'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'come numero intero indicizzato 0 (o 1 indicizzato)? Così [('NW',2),('S',2),('E',1)]diventa [[7,2],[4,2],[2,1]]ad esempio.
Kevin Cruijssen,

@KevinCruijssen certo, nessun problema. Assicurati solo di indicarlo nella risposta.
J. Sallé,

1
@Arnauld sì, ti è permesso usare un singolo carattere traccia. Ne ho usato più di uno, quindi sarebbe più semplice visualizzare i casi di test, ma non è necessario. Assicurati solo che il carattere di traccia sia diverso dal carattere dell'oggetto da tracciare.
J. Sallé,

1
@Arnauld " L'oggetto da tracciare può essere qualsiasi personaggio tu scelga, purché occupi solo 1 spazio sul piano ed è diverso dai caratteri di confine. La traccia dell'oggetto tracciato può anche essere qualunque personaggio tu scelga, purché poiché occupano solo 1 spazio sull'aereo e sono diversi dall'oggetto. "
Kevin Cruijssen,

Risposte:


9

JavaScript (ES6), 228 byte

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

Emette una stringa con 0per un limite, 1per una traccia e 3per la posizione finale.

(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)

Provalo online!

Come?

Inizializzare e disegnare in una 'tela' (cioè una matrice di caratteri) è un po 'noioso e lungo in JavaScript.

Questo codice utilizza una strategia diversa: invece di archiviare l'output in un array 2D, crea una stringa carattere per carattere, da sinistra a destra e dall'alto verso il basso. Ad ogni iterazione:

  • Emettiamo un 0se superiamo un limite.
  • Altrimenti, simuliamo l'intero percorso e vediamo se sta attraversando la nostra posizione attuale. Produciamo 1o 3se lo fa, oppure uno spazio in caso contrario.
  • Aggiungiamo un avanzamento di riga se abbiamo raggiunto il limite giusto.

Tutto sommato, questo potrebbe non essere l'approccio più breve, ma ho pensato che valesse la pena provarlo.


9

Java 10, 350 343 340 336 byte

(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;}

Dè un numero intero 2D-array in cui le indicazioni sono interi 0-indicizzati: N=0, NE=1, E=2, SE=3, S=4, SW=5, W=6, NW=7. Le x,ycoordinate di partenza saranno due parametri separati se S. L'output è una matrice di caratteri.
Utilizza #come bordo, *come traccia e Oper la posizione finale (ma possono essere tutti e tre i caratteri ASCII nell'intervallo unicode [33,99]per lo stesso conteggio byte se lo si desidera).

Provalo online.

-4 byte grazie a @ceilingcat .
Puoi sicuramente giocare a golf un po 'di più semplificando i movimenti e in quale direzione stiamo viaggiando un po' di più.

Spiegazione:

(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:7è una versione giocata di questo sotto usando 4-ie 8-iper la maggior parte dei cambi di direzione:

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

3

Carbone , 74 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Prende l'input nel formato n, x, y, d dove d è una matrice di matrici di coppie [distanza, direzione] in cui la direzione è una codifica numerica da 0 = sud in senso orario a 7 = sud est. Spiegazione:

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

Inserisci ne disegna una scatola il cui interno è quella dimensione centrata sull'origine.

JN±N

Inserisci e salta a xe y(ma nega yperché l'asse y del carbone sta diminuendo).

FA«

Scorri le voci in d.

≔⊟ιζ

Estrarre la direzione iniziale.

F⊟ι«

Ripetere l'operazione per la distanza desiderata.

≔ζδ

Salva la direzione.

↷δ¶

Fai una mossa sperimentale in quella direzione.

F›⊗↔ⅈθ≦±ζ

Se questo si sposta dai lati, capovolgere la direzione in senso orizzontale.

F›⊗↔ⅉθ≦⁻⁴ζ

Se questo va fuori dalla parte superiore o inferiore, capovolgere la direzione verticalmente.

≧﹪⁸ζ

Ridurre la direzione modulo 8 (i comandi Pivot accettano solo valori da 0 a 7).

↷⁴¶↶⁴

Annulla la mossa sperimentale.

↶δ↷ζ*¶

Rivolgere la direzione corretta, quindi stampare una traccia e spostarsi.

↶ζPo

Tornare indietro nella direzione predefinita e stampare l'oggetto nella posizione corrente.


2

JavaScript, 206 byte

Prende l'input come (n, x, y, [[dir, len], [dir, len], ...]) dove le direzioni sono codificate usando le maschere di bit:

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

Emette una stringa con

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

I diversi valori per i confini vengono utilizzati per valutare la direzione successiva

(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``)

Meno golf

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``
)

TEST

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>


2

C (gcc) , 352 323 byte

Golfato di 29 byte grazie al plafoniera.

#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);}

Provalo online!

Il programma accetta input come argomenti della riga di comando (come a.out 10 1 1 3 5 0 4 7 2):

  • il primo argomento è la dimensione del campo,
  • (X,y)
  • (d,t)dEt

Spiegazione

// 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 #
           );
}

1
Credo che al tuo codice manchi l'output dell'oggetto nella posizione finale, poiché la traccia dell'oggetto tracciato può anche essere qualsiasi carattere tu scelga, purché occupino solo 1 spazio sul piano e siano diversi dall'oggetto . A parte questo, mi sta bene.
J. Sallé,

Oops, mi sono perso del tutto, grazie per aver notato J.Sallé. Fortunatamente la correzione non ha allungato il programma.
Max Yekhlakov,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.