2d uzayda bir nesneyi izleme


11

Açıklama

Bu zorluğun görevi, belirli bir nesneyi nxn boşluğunda izleyen bir program veya işlev tasarlamaktır .

I / O

Programınıza herhangi bir şekilde alınabilecek 3 giriş verilecektir :

nuçağın tarafının büyüklüğü olacak. (yani, n=5 , uçağınız 5x5 ). Her nzaman tek bir tamsayı olacağını varsayabilirsiniz .

sbir çift (x,y) koordinatı olarak verilen nesnenin başlangıç ​​konumu olacaktır .

Dsıralı çiftlerin bir vektörü olacaktır. D = [ ( d 0 , t 0 ) , ( d 1 , t 1 ) ,D biçimini izleyecektir . . . , ( D , n , t , n ) ] , burada d k her zaman olacaktır bir bölgesinin kardinal ve primer intercardinal tarifini, ve t k 'keneler' sayısı için bir tamsayı olacaktır.D=[(d0,t0),(d1,t1),...,(dn,tn)]dk'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'tk

Bu girdiler göz önüne alındığında, programınız düzlemdeki nesnenin bir izlemesinin çıktısını almalıdır.

kurallar

Çıktı gerekir uçağın sınırlarını içermektedir. Örneğin:

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

boş bir 5x5 düzlemine örnek olacaktır . Yukarıdaki ve yan taraftaki sayılar yalnızca referans amaçlıdır ve yazdırılması gerekmez.

Boşluk olmadığı (veya boşluk olduğu sürece) sınırlar için hangi karakter (ler) i kullanabilirsiniz. Seçtiğiniz karakterler tam düzlemi tanımlamalıdır, yani aralarında boşluk olamaz.

Kabul edilebilir bazı uçaklar şunları içerir:

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

Kabul edilemez uçaklar şunları içerir:

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

İzlenecek nesne, uçakta yalnızca 1 yer kapladığı ve sınır karakterlerinden farklı olduğu sürece seçtiğiniz karakter olabilir.

İzlenen nesnenin izlemesi, uçakta yalnızca 1 yer kapladığı ve nesneden farklı olduğu sürece, seçtiğiniz karakterler de olabilir.

D' deki her eleman (dk,tk) için , nesne t boşluklarını d'ye doğru hareket ettirmeli ve arkasında bir iz bırakmalıdır.Dtd

Nesne bir sınıra ulaşırsa yansıtılır. Nesnede hala hareket varsa, yansıtıldığı yönde hareket etmeye devam eder.

Referans olarak, bu talimatlar birbirine yansır:

N-S → üst veya alt sınır karşılandığında;

EW → bir yanal sınır karşılandığında;

Son çıktı mümkün olan en yeni izleri içerecektir, yani nesne zaten izin olduğu bir alanda iz bırakacaksa, daha yeni iz karakteri eskisinin üzerine yazacaktır.

Her zamanki gibi standart boşluklar varsayılan olarak yasaklanmıştır .

puanlama:

Bu bir mücadelesi.

Örnekler:

Giriş: n=5 , s=(0,0) , D=[('N-W',2),('S',2),('E',1)]

Çalışmak:

t=0

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

t=2

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

t=4

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

t=5 olacak.

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

(0'lar sadece referans içindir ve nihai çıktıda olmaları gerekmez.)


Giriş: n=9 , s=(3,-1) , D=[('N-',2),('SW',8),('SE',3),('N-E',8)]

Dikkat edin, t=10 olduğunda :

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

Nesne yansıtılmıştır iki : bir kez ulaşıldığında alt doğru giderken düzleminin SW bu yansıtır, N-W ; daha sonra bir kez daha ulaşan sol kanadın düzleminde ve N-W yansıtmaktadır N-E .

Son çıktı t=21 gelir :

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

Test senaryoları:

Giriş: n=5 , s=(0,0) , D=[('N-W',2),('S',2),('E',1)]

Çıktı:

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


Giriş: n=9 , s=(3,-1) , D=[('N-',2),('SW',8),('SE',3),('N-E',8)]

Çıktı:

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


Giriş: n=3 , s=(1,1) , D=[('N-',5),('W',5)]

Çıktı:

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


Giriş: n=11 , s=(3,-5) , D=[('N-W',8),('E',5),('SE',3),('SW',5),('N-',6),('N-E',10)]

Çıktı:

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

Bu zorluğun korumalı olduğunu belirtmeyi unuttum .
J. Sallé

'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'Bunun yerine 0 dizinli (veya 1 dizinli) bir tamsayı olarak alabilir miyiz ? Yani [('NW',2),('S',2),('E',1)]olur [[7,2],[4,2],[2,1]]örneğin.
Kevin Cruijssen

@KevinCruijssen emin, sorun değil. Sadece cevabı belirttiğinizden emin olun.
J. Sallé

1
@ Evet, tek bir izleme karakteri kullanmanıza izin verilir. Birden fazla kullandım, bu yüzden test senaryolarını görselleştirmek daha kolay olurdu, ancak gerekli değil. İzleme karakterinin, izlenmekte olan nesnenin karakterinden farklı olduğundan emin olun.
J. Sallé

1
@Arnauld "İzlenecek nesne, uçakta yalnızca 1 boşluk kapladığı ve sınır karakterlerinden farklı olduğu sürece seçtiğiniz karakter olabilir. İzlenen nesnenin izlemesi, seçtiğiniz karakterler de olabilir. çünkü uçakta sadece 1 yer kaplarlar ve nesneden farklıdırlar. "
Kevin Cruijssen

Yanıtlar:


9

JavaScript (ES6), 228 bayt

Girişi (n,x,y,[[dir,len],[dir,len],...])yönlerin saat yönünün tersine kodlandığı yere alır07

İle bir dize çıktılar 0Bir sınır, 1bir iz ve 3son konum için .

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

Çevrimiçi deneyin!

Nasıl?

Başlatma ve 'tuval' (yani bir karakter matrisi) içine çizim yapmak JavaScript'te biraz sıkıcı ve uzundur.

Bu kod farklı bir strateji kullanıyor: Çıktıyı bir 2D dizide saklamak yerine, karakterden, soldan sağa ve yukarıdan aşağıya bir dize karakteri oluşturur. Her yinelemede:

  • Bir çıktı 0 bir sınır üzerinde iseniz.
  • Aksi takdirde, tam yolu simüle eder ve mevcut konumumuzu geçip geçmediğini görürüz. Biz de çıktı1 ya 3öyle ya da başka bir boşluk varsa.
  • Doğru sınıra ulaşırsak bir satır besleme ekleriz.

Sonuçta, bu en kısa yaklaşım olmayabilir, ama denemeye değer olduğunu düşündüm.


9

Java 10, 350 343 340 336 bayt

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

Dtarifi 0 endeksli tamsayılardır 2B tamsayı dizidir: N=0, NE=1, E=2, SE=3, S=4, SW=5, W=6, NW=7. Başlangıç x,ykoordinatları iki ayrı parametre olacaktır sve S. Çıktı bir karakter matrisidir.
O kullanır #, sınır olarak *iz olarak ve Obitiş pozisyonu için (ancak her üç Unicode aralığındaki herhangi bir ASCII karakter olabilir[33,99] istediğiniz olsaydın aynı bayt sayım için).

Çevrimiçi deneyin.

@Ceilingcat sayesinde -4 bayt .
Hareketleri basitleştirerek ve hangi yönde biraz daha seyahat ettiğimizi kesinlikle daha iyi golf oynayabilir.

Açıklama:

(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:74-ive 8-iyön değişikliklerinin çoğu için aşağıdakilerin golf edilmiş bir versiyonudur :

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

Kömür , 74 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. N, x, y, d formatında girdi alır; burada d, yönün sayısal bir kodlama 0 = güney saat yönünde 7 = güney doğu olduğu bir [mesafe, yön] çift dizisi dizisidir. Açıklama:

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

nİç kısmı orijin merkezli olan bir kutu girin ve çizin.

JN±N

Girin ve atlayın xve y(ancak Kömürün yy ekseni arttığı için olumsuzlayın ).

FA«

İçindeki girişlerin üzerine gelin d.

≔⊟ιζ

Başlangıç ​​yönünü çıkartın.

F⊟ι«

İstenilen mesafe için tekrarlayın.

≔ζδ

Yönü kaydedin.

↷δ¶

Bu yönde deneysel bir hareket yapın.

F›⊗↔ⅈθ≦±ζ

Bu kenarlardan çıkarsa, yönü yatay olarak çevirin.

F›⊗↔ⅉθ≦⁻⁴ζ

Bu yukarıdan veya aşağıdan çıkarsa, yönü dikey olarak çevirin.

≧﹪⁸ζ

Yön modülü 8'i azaltın (Pivot komutları yalnızca 0 ila 7 arasındaki değerleri kabul eder).

↷⁴¶↶⁴

Deneysel hareketi geri alın.

↶δ↷ζ*¶

Doğru yöne bakıp bir iz yazdırın ve taşıyın.

↶ζPo

Varsayılan yöne dönün ve nesneyi geçerli konuma yazdırın.


2

JavaScript, 206 bayt

Girdileri, yönlerin bit maskesi kullanılarak kodlandığı (n, x, y, [[dir, len], [dir, len], ...]) olarak alır:

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

İle bir dize çıktılar

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

Sınırlar için farklı değerler bir sonraki yönü değerlendirmek için kullanılır

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

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

ÖLÇEK

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) , 352323 bayt

Tavan kedisi sayesinde 29 bayt düştü.

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

Çevrimiçi deneyin!

Program girişi komut satırı argümanları olarak alır (gibi a.out 10 1 1 3 5 0 4 7 2):

  • ilk argüman alan büyüklüğü,
  • (x,y) aktörün ,
  • (d,t)dEt

açıklama

// 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
İzlenen nesnenin izlemesi, yalnızca uçakta 1 boşluk kapladığı ve nesneden farklı olduğu sürece, izlenen nesnenin izlemesi de seçtiğiniz karakterler olabileceğinden , kodunuzun son konumda nesne çıktısının eksik olduğuna inanıyorum . Bunun dışında bana iyi geliyor.
J. Sallé

Hata! Bunu tamamen özledim, J.Sallé'yi fark ettiğiniz için teşekkürler. Neyse ki düzeltme programı daha uzun hale getirmedi.
Max Yekhlakov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.