Một thám hiểm nhỏ


34

Bạn là một nhà thám hiểm, lập bản đồ một thế giới chưa biết. Tàu của bạn được thực hiện trên gió. Nó đi đâu, ai biết?

Mỗi ngày, trong chiếc kính của bạn, bạn sẽ thấy các đặc điểm ở phía bắc, nam, đông và tây. Bạn luôn thấy bốn tính năng như vậy, tương ứng với các hướng hồng y. Kính gián điệp của bạn báo cáo các biểu tượng ASCII như thế này:

~~.*, ~~~~, ~.^^,~#~#

Các biểu tượng theo thứ tự (bắc, nam, đông, tây).

Đây là các biểu tượng: ~= biển, .= bờ biển, ^= núi, *= cây, #= không hợp lệ (không quan sát, điều này xảy ra bất cứ khi nào bạn nhìn thấy rìa của thế giới hoặc cảnh quan bị che khuất bởi sương mù). Kính gián điệp của bạn nhìn thấy chính xác một đơn vị theo mọi hướng.

Mỗi đêm, bạn nhìn lên các vì sao để xem bạn đã đi được bao xa. Nhìn vào các ngôi sao báo cáo một biểu tượng ascii như thế này:

n, s, e,w

tương ứng với Bắc, Nam, Đông và Tây, tương ứng. Bạn luôn di chuyển chính xác một đơn vị về phía bắc, nam, đông hoặc tây mỗi đêm. Vì vậy, bạn, với tư cách là nhà thám hiểm sẽ nhận được vô số biểu tượng:

~~.*n~~~~s~~.*s~.**

Nhiệm vụ của bạn là xuất bản đồ 2D về thế giới (nơi ?không xác định được bản đồ, hướng bắc lên, hướng đông là phải):

?~~~??????
?~~~??????
?~~~.^^.??
?~~.***.~~
~~.*^^*.~~
~~~..~~~~~
~~~~~~~~~~
~~~~~~~~~~

Để đơn giản, giả sử bạn bắt đầu ở góc dưới bên trái của bản đồ. Giả sử tất cả các bản đồ là 8x8.

Dưới đây là một ví dụ 3x3 đơn giản. Giả sử bản đồ trông như thế này:

~.~
~^~
~.~

Với đầu vào sau: ~#.#n~~^#s

Bạn sẽ nhận được đầu ra này:

~??
~^?
~.?

Ví dụ đầu vào và đầu ra:

đầu vào ~#~#n~~~#n~~~#n~~~#n~~~#n~~.#n~~.#n#~~#e#.~~e#.~~e#.~~e#.~~e#~~~e#~~~e#~#~s~~#~s~~#~s~~#~s~~#.s~~#~s~~#~s~##~w~#~~w.#~~w^#~~w.#~~

đầu ra

~~~~~~~~ 
~....~~~ 
~.????~~ 
~~????~~ 
~~????.~ 
~~????~~ 
~~?.^.~~ 
~~~~~~~~

Đầu vào:

~#~#e~#~~e~#~~e.#~~e^#~~n.~..n~^~.n~.~~n.~~.n.~~*n~.~.n#.~~w#.~~w#.~~s~*..s..*.s*~.~s.~~~s

Đầu ra:

?~~~~~?? 
?....~?? 
?.**.~?? 
?~..~~?? 
?~~~~~?? 
?~~..~?? 
~~~.^.?? 
~~~~~~?? 

7
Chào mừng bạn đến với Câu đố lập trình & Code Golf! Đây là một thử thách đầu tiên tốt đẹp. Một vài điều không rõ ràng đối với tôi: Phải tất cả các biểu tượng trong đầu ra được phân tách không gian? Đó có vẻ là trường hợp trong đầu ra ví dụ nhưng nó không được nêu rõ ràng ở bất cứ đâu. Ngoài ra, mục đích của các hướng sao phục vụ là gì? Tôi nghĩ có lẽ họ đã kiểm soát các biểu tượng đi đâu trên bản đồ, nhưng theo các ví dụ và bắt đầu ở phía dưới bên trái, điều đó dường như không phải là trường hợp. bạn có thể giải thích về điều đó không?
Alex A.

Đầu ra không phải là không gian riêng biệt, đó là một lỗi về phía tôi. "#" Đại diện cho "không quan sát". Chúng xảy ra bất cứ khi nào bạn ở trên ranh giới của bản đồ, nhưng cũng có thể xảy ra ngẫu nhiên.
dùng52676

4
Xuất sắc. Như Alex đã nói, đây là một thử thách đầu tiên tuyệt vời. Tôi hy vọng sẽ nhìn thấy nhiều hơn từ bạn trong tương lai! :) (FYI, Sandbox là một nơi tuyệt vời để nhận phản hồi về những thách thức trong tương lai.)
El'endia Starman

1
Tôi nghi ngờ ví dụ đầu tiên (nơi đầu vào là ~#~#n~~~#n~~~#n~~~#n~~~#n~~.#n~~.#n#~~#e#.~~e#.~~e#.~~e#.~~e#~~~e#~~~e#~#~s~~#~s~~#~s~~#~s~~#.s~~#~s~~#~s~##~w~#~~w.#~~w^#~~wsai) và đầu ra nên có ??nơi nó nói?.
Leaky Nun

3
Đó là một con tàu không khí kỳ diệu ;)
user52676

Câu trả lời:


8

MATL , 68 59 58 byte

'?'7XJQtX"'s'jh5e"@2#1)t35>)-1l8t_4$h9M)b'nsew'=8M*sJ+XJ+(

Hãy thử trực tuyến!

Giải trình

Bản đồ được giữ ở dưới cùng của ngăn xếp và dần dần được lấp đầy. Vị trí hiện tại của trình thám hiểm được lưu trữ trong clipboard J.

Bản đồ sử dụng tọa độ ma trận, vì vậy (1,1) ở phía trên bên trái. Ngoài ra, lập chỉ mục tuyến tính chính cột được sử dụng. Điều này có nghĩa là các phần tử của ma trận 8 × 8 đại diện cho bản đồ được truy cập với một chỉ mục như sau:

1  9 17 25 33 41 49 57
2 10 18 26 34 42 50 58
3 11 19 27 35 43 51 59
4 12 20 28 36 44 52 60
5 13 21 29 37 45 53 61
6 14 22 30 38 46 54 62
7 15 23 31 39 47 55 63
8 16 24 32 40 48 56 64

Vì vậy, ví dụ phần tử (3,2) của ma trận là phần tử có chỉ số tuyến tính 11. Chuyển động về phía Bắc, Nam, Đông và Tây tương ứng với việc thêm -1, 1, 8 hoặc -8 vào chỉ số tuyến tính. Mảng [-1 1 8 -8] dùng để mã hóa hai thứ khác nhau:

  • Các chuyển vị có thể của các nhà thám hiểm.
  • Các vị trí tương đối của các tính năng được phát hiện với các điệp viên. Những vị trí này liên quan đến vị trí hiện tại của nhà thám hiểm.

Chuỗi đầu vào được sắp xếp thành các khối 5ký tự. Vì đoạn đầu tiên bị thiếu ký tự đầu tiên (biểu thị chuyển động), nên một ký tự đầu tiên sđược đưa vào tùy ý để làm cho tất cả các khối có cùng kích thước. Để bù đắp cho điều này, nhà thám hiểm bắt đầu ở vị trí 7, không phải 8, do đó, sự dịch chuyển ban đầu về phía Nam (thêm 1 vào chỉ số tuyến tính) để chúng ở vị trí 8.

Các đoạn gồm 5 ký tự được xử lý trong một vòng lặp. Ký tự đầu tiên cập nhật vị trí và 4 ký tự còn lại, nếu khác #, được ghi vào các mục đầy đủ của ma trận thể hiện bản đồ.

'?'          % push '?'. The map will initially be filled with this
7XJ          % push 7: initial position of the explorer. Copy into clipboard J
Qt           % add 1. Duplicate
X"           % 8x8 matrix containing '?'
'n'jh        % take input string. Prepend 'n'
5e           % reshape into a 5-column matrix
"            % for each column (chunk)
  @          %   push current chunk
  2#1)       %   split chunk into its first char and an array with the other 4
  t35>       %   duplicate. Logical index of chars different than #
  )          %   apply that index to keep characters different than #
  -1l8t_4$h  %   array [-1 1 8 -8]
  9M         %   push logical index again
  )          %   apply that index to keep only relevant relative positions
  b          %   bubble up in stack: move first char of chunk to top
  'nsew'=    %   logical index that tells if that char is 'n', 's', 'e' or 'w'
  8M         %   push array [-1 1 8 -8] again
  *          %   multiply element-wise. Only one of the four results will be nonzero
  s          %   sum of the array. Gives displacement of the explorer
  J+         %   push position of the explorer and add to compute new position
  XJ         %   update position in clipboard J
  +          %   add updated position of explorer to relative positions of features
  (          %   write those fearttures into the indexed entries of the map
             % end for each. Implicitly display

Đó là một mẹo thông minh! Tôi sẽ kiểm tra chương trình của bạn dựa trên một vài bản đồ để xem nó có làm những gì tôi mong đợi không.
dùng52676

3

C, 210 208 207 byte

Cái này sử dụng printf và scanf để đọc đầu vào và một mảng tuyến tính thay vì x, y; vì vậy tôi cảm thấy nó đủ khác biệt so với millibyte .

Chơi gôn

 main(p){char*i,*j,m[80];for(p=73,i=m+p;p--;m[p]=63);for(p=8;scanf("%5s",i)>0;p+=*j=='n'?8:*j=='s'?-8:*j=='e'?1:-1)for(j=i;j-i<4;j++)if(*j^35)m[p+"qajh"[j-i]-'i']=*j;for(p=72;m[p]=0,p-=8;)printf("%s\n",m+p);}

Hơi vô dụng:

main(p){
    char*i,*j,m[80];
    for(p=73,i=m+p;p--;m[p]=63);                   // fill with ?
    for(p=8;scanf("%5s",i)>0;
            p+=*j=='n'?8:*j=='s'?-8:*j=='e'?1:-1)  // read 5-at-a-time
        for(j=i;j-i<4;j++)
            if(*j^35)m[p+"qajh"[j-i]-'i']=*j;      // update map positions
    for(p=72;m[p]=0,p-=8;)printf("%s\n",m+p);      // output line-by-line
}

Đại diện:

  // board: (vertically reversed when printed)
    0  1  2  3  4  5  6  7
    8  9  10 ...
    16 18 19 ...
    ...
    56 57 58 59 60 61 62 63

  // offsets and offset order, or why "qajh": 
    s2      -8       a
  w4  e3  -1 0+1   h i j
    n1      +8       q   <- offset by +'i'

Ngoài ra, bạn bắt đầu ở vị trí 8 vì điều này sẽ loại bỏ một char hoặc quá vòng lặp in.


2

Fortran, 263 251 247 235 234 216 byte

Phiên bản 1D (tương tự như phiên bản của Don Muesli):

#define R read(*,'(a)',advance='no',eor=1)c
#define F(x)R;if(c/='#')a(x+i)=c
program t
character::a(64)='?',c
integer::k(4)=[8,-8,1,-1],i=57
do
F(-8)
F(8)
F(1)
F(-1)
R
i=i+k(index('snew',c))
enddo
1 print'(8a)',a
end

Phiên bản 2D:

#define R read(*,'(a)',advance='no',eor=1)c
#define F(x,y)R;if(c/='#')a(x+m,y+l)=c
#define G(x,y)j=index(x,c);if(j==2)j=-1;y=y+j
program t
character::a(8,8)='?',c
l=8;m=1
do
F(,-1)
F(,1)
F(1,)
F(-1,)
R
G('sn',l)
G('ew',m)
enddo
1 print'(8a)',a
end

Để bật biểu mẫu miễn phí và xử lý trước, tệp cần có phần mở rộng .F90, vd explorer.F90. Đầu vào được đọc từ STDIN:

echo "~#~#e~#~~e~#~~e.#~~e^#~~n.~..n~^~.n~.~~n.~~.n.~~*n~.~.n#.~~w#.~~w#.~~s~*..s..*.s*~.~s.~~~s" | ./a.out 
?~~~~~??
?....~??
?.**.~??
?~..~~??
?~~~~~??
??~..~??
~~~.^.??
~~~~~~??

Vậy Fortran cũng có lập chỉ mục tuyến tính?
Luis Mendo

@DonMuesli Không, không thực sự. Tôi đang hoạt động trên mảng 1D trực tiếp. Để in mảng các ký tự tôi đang sử dụng thực tế là mảng được lưu trữ liên tục trong bộ nhớ.
Alexander Vogt

2

C, 265 226 224 byte

a[8][8];x;y;i;main(c){for(;c=getchar(),c+1;y+=(c=='n')-(c=='s'),x+=(c=='e')-(c=='w'))for(i=5;--i;c=getchar())i&&c-35&&(a[x+(i==2)-(i==1)][y-(i==3)+(i==4)]=c);for(y=8;y--;putchar(10))for(x=0;x<8;)putchar((i=a[x++][y])?i:63);}

Bản đồ là 8x8, tôi đã không nhận thấy điều đó trước đây. Và đây là giải pháp 265 byte hoạt động cho các bản đồ có kích thước thay đổi:

a[99][99];c;x;X;y;i;k;p;main(Y){for(;c=getchar(),c+1;y+=(c=='n')-(c=='s'),x+=(c=='e')-(c=='w'))for(i=5;--i;c=getchar())i&&c-35&&(a[k=x+(i==2)-(i==1),X=X<k?k:X,k][p=y-(i==3)+(i==4),Y=Y<p?p:Y,p]=c);for(y=Y+1;y--;putchar(10))for(x=0;x<=X;)putchar((i=a[x++][y])?i:63);}

Không nên a[8][8]là đủ?
Alexander Vogt

@Alexander Vogt - Ồ, đúng rồi! Cảm ơn bạn, điều đó làm giảm thêm hai byte.
mIllIbyte

Tôi thực sự thích cách bạn tính toán tăng / giảm cho x và y. So sánh mã C của chúng tôi, tĩnh int a[8][8]giúp bạn khởi tạo bản đồ miễn phí và sử dụng char m[64]giúp tôi giảm giá lớn cho đầu ra bản đồ. Tuy nhiên, số lượng thực sự rất gần
tucuxi

Nếu bạn đảo ngược ewthể hiện bản đồ của mình, thì bạn có thể sử dụng for(x=8;x--;)putchar((i=a[x][y])?i:63)để cạo hai byte trên đầu ra.
tuc lửa

Không c=getchar(),c+1tương đương với getchar(),c++hoặc có một số mánh khóe liên quan?
Jonathan Frech

2

Ruby, 169 147 byte

Chương trình đầy đủ. Lấy chuỗi đầu vào từ STDIN (có thể bạn cần phải nối nó từ một tệp để ngăn chặn bất kỳ dòng mới nào làm rối tung mọi thứ) và đưa bản đồ kết quả sang STDOUT.

Cắt một tấn bằng cách đặt tất cả các chuỗi thành một và sau đó tách chúng sau.

m=??*64
d=0
x=56
gets.each_char{|c|d<4?(w=x+(d>2?-1:d>1?1:d<1?-8:d<2?8:0)
m[w]=c if c>?$):x+=c>?v?-1:c<?f?1:c>?q?8:-8
d+=1;d%=5}
puts m.scan /.{8}/

Ung dung:

m = ?? * 64                 # 64 "?" symbols
                            # y axis counts downwards; 0-7 is top row
d = 0                       # Keep track of which direction we're looking
x = 56                      # Position, bottom left corner (0,7)
gets.each_char do |c|       # For each character from first line of STDIN
    if d < 4                # Looking in a direction
        if    d > 2         # d == 3; looking west
            w = x - 1
        elsif d > 1         # d == 2; looking east
            w = x + 1
        elsif d < 1         # d == 0; looking north
            w = x - 8
        else                # d == 1; looking south
            w = x + 8
        end
        m[w] = c if c > ?$  # Only '#' gets rejected by this step
    else                    # Moving in a direction
        if    c > ?v        # c == 'w'
            x -= 1
        elsif c < ?f        # c == 'e'
            x += 1
        elsif c > ?q        # c == 's'
            x += 8
        else                # c == 'n'
            x -= 8
        end
    end
    d = (d + 1) % 5         # Look in the next direction
end
puts m.scan /.{8}/          # Split map into rows of 8

1

Lua, 354 byte ( thử trực tuyến )

Chơi gôn

n=(...)r={}y=8x=1q="?"for i=1,8 do r[i]={q,q,q,q,q,q,q,q}end for u in n:gsub("#",q):gmatch(".....")do a,b,c,d,e=u:match("(.)(.)(.)(.)(.)")if a~=q then r[y-1][x]=a end if b~=q then r[y+1][x]=b end if c~=q then r[y][x+1]=c end if d~=q then r[y][x-1]=d end y=y+(("n s"):find(e)or 2)-2x=x+(("w e"):find(e)or 2)-2 end for i=1,8 do print(table.concat(r[i]))end

Hơi vô dụng:

n = "~#~#e~#~~e~#~~e.#~~e^#~~n.~..n~^~.n~.~~n.~~.n.~~*n~.~.n#.~~w#.~~w#.~~s~*..s..*.s*~.~s.~~~s"

r={} y=8 x=1 q="?"
for i=1,8 do r[i]={q,q,q,q,q,q,q,q} end
for u in n:gsub("#",q):gmatch(".....") do
  a,b,c,d,e=u:match("(.)(.)(.)(.)(.)")
  if a~=q then r[y-1][x]=a end
  if b~=q then r[y+1][x]=b end
  if c~=q then r[y][x+1]=c end
  if d~=q then r[y][x-1]=d end
  y=y+(("n s"):find(e)or 2)-2
  x=x+(("w e"):find(e)or 2)-2
end
for i=1,8 do print(table.concat(r[i])) end

Không thể x=x+(("w e"):find(e)or 2)-2 endđược x=x-2+(("w e"):find(e)or 2)end?
Jonathan Frech

1

Kotlin, 242 byte

{val m=Array(8){Array(8){'?'}}
var d=7
var i=0
for(c in it)(mapOf('n' to{d--},'s' to{d++},'w' to{d-=8},'e' to{d+=8},'#' to{i++})[c]?:{m[d%8+listOf(-1,1,0,0)[i%4]][d/8+listOf(0,0,1,-1)[i%4]]=c
i++})()
m.forEach{for(c in it)print(c);println()}}

Các dòng mới có thể được thay thế bằng dấu chấm phẩy nếu muốn.

Thử ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.