Explorer เล็ก ๆ


34

คุณเป็นนักสำรวจทำแผนที่โลกที่ไม่รู้จัก เรือของคุณถูกลมพัด มันจะไปไหนใครจะไปรู้?

ในแต่ละวันในกล้องสอดแนมของคุณคุณจะเห็นคุณสมบัติทางเหนือ, ใต้, ตะวันออกและตะวันตก คุณมักจะเห็นสี่คุณสมบัติดังกล่าวซึ่งสอดคล้องกับทิศทางสำคัญ ๆ กล้องสอดแนมของคุณรายงานสัญลักษณ์ ASCII ดังนี้:

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

สัญลักษณ์อยู่ในลำดับ (เหนือ, ใต้, ตะวันออก, ตะวันตก)

นี่คือสัญลักษณ์: ~= ทะเล, .= ชายฝั่ง, ^= ภูเขา, *= ต้นไม้, #= ไม่ถูกต้อง (ไม่สังเกตสิ่งนี้จะเกิดขึ้นทุกครั้งที่คุณเห็นขอบโลกหรือภูมิประเทศถูกบดบังด้วยหมอก) กล้องส่องทางไกลของคุณมองเห็นหนึ่งหน่วยในทุกทิศทาง

ในแต่ละคืนคุณจะมองดูดวงดาวเพื่อดูว่าคุณเดินทางไปไกลแค่ไหน เมื่อมองดูดวงดาวจะรายงานสัญลักษณ์ ASCII ดังนี้:

n, s, e,w

สอดคล้องกับภาคเหนือภาคใต้ภาคตะวันออกและตะวันตกตามลำดับ คุณจะย้ายยูนิตหนึ่งไปทางทิศเหนือทิศใต้ทิศตะวันออกหรือทิศตะวันตกทุกคืน ดังนั้นคุณในฐานะนักสำรวจจะได้รับสัญลักษณ์มากมาย:

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

งานของคุณคือส่งออกแผนที่ 2D ของโลก (ซึ่ง?เป็นส่วนที่ไม่รู้จักของแผนที่ทิศเหนือขึ้นไปทางตะวันออกอยู่ทางขวา):

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

เพื่อความเรียบง่ายสมมติว่าคุณเริ่มที่มุมล่างซ้ายของแผนที่ สมมติว่าแผนที่ทั้งหมดเป็น 8x8

นี่คือตัวอย่างง่ายๆ 3x3 สมมติว่าแผนที่มีลักษณะดังนี้:

~.~
~^~
~.~

ด้วยอินพุตต่อไปนี้: ~#.#n~~^#s

คุณจะได้รับผลลัพธ์นี้:

~??
~^?
~.?

ตัวอย่างอินพุตและเอาต์พุตเพิ่มเติม:

อินพุต ~#~#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.#~~

เอาท์พุต

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

การป้อนข้อมูล:

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

เอาท์พุท:

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

7
ยินดีต้อนรับสู่ Programming Puzzles & Code Golf! นี่เป็นความท้าทายครั้งแรกที่ดี มีสองอย่างที่ไม่ชัดเจนสำหรับฉัน: สัญลักษณ์ทั้งหมดในผลลัพธ์จะต้องมีการเว้นวรรคหรือไม่ ดูเหมือนว่าจะเป็นกรณีในผลลัพธ์ตัวอย่าง แต่ไม่ได้ระบุไว้อย่างชัดเจนที่ใดก็ได้ นอกจากนี้ทิศทางของดวงดาวมีจุดประสงค์อะไร? ฉันคิดว่าบางทีพวกเขาอาจควบคุมสัญลักษณ์ที่ไปบนแผนที่ แต่ทำตามตัวอย่างและเริ่มต้นที่ด้านล่างซ้ายดูเหมือนจะไม่เป็นเช่นนั้น คุณอธิบายรายละเอียดเกี่ยวกับเรื่องนั้นได้ไหม?
Alex A.

เอาท์พุทไม่จำเป็นต้องแยกพื้นที่ออกไปนั่นเป็นข้อผิดพลาดในส่วนของฉัน "#" หมายถึง "ไม่สังเกต" มันเกิดขึ้นทุกครั้งที่คุณอยู่บนขอบเขตของแผนที่ แต่อาจเกิดขึ้นแบบสุ่ม
user52676

4
ยอดเยี่ยม อเล็กซ์กล่าวว่านี่เป็นความท้าทายครั้งแรกที่ยอดเยี่ยม ฉันหวังว่าจะได้เห็นคุณมากขึ้นในอนาคต! :) (FYI, Sandboxเป็นสถานที่ที่ดีในการรับข้อเสนอแนะเกี่ยวกับความท้าทายในอนาคต)
El'endia Starman

1
ฉันสงสัยว่าตัวอย่างแรก (ที่อินพุต~#~#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) ผิดและผลลัพธ์ควรมี??ที่กล่าวว่า?.
Leun Nun

3
มันเป็นเรืออากาศมหัศจรรย์;)
52676

คำตอบ:


8

MATL , 68 59 58 ไบต์

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

ลองออนไลน์!

คำอธิบาย

แผนที่จะถูกเก็บไว้ที่ด้านล่างของสแต็คและเต็มไปเรื่อย ๆ ตำแหน่งปัจจุบันของ explorer ถูกเก็บไว้ในคลิปบอร์ด J

แผนที่ใช้พิกัดเมทริกซ์ดังนั้น (1,1) จึงเป็นมุมบนซ้าย นอกจากนี้ยังมีการใช้การจัดทำดัชนีเชิงเส้นแบบคอลัมน์ ซึ่งหมายความว่าองค์ประกอบของเมทริกซ์ 8 × 8 ที่เป็นตัวแทนของแผนที่สามารถเข้าถึงได้ด้วยดัชนีเดียวดังนี้

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

ตัวอย่างเช่นองค์ประกอบ (3,2) ของเมทริกซ์คือองค์ประกอบที่มีดัชนีเชิงเส้น 11 การเคลื่อนที่ไปทางเหนือ, ใต้, ตะวันออกและตะวันตกตามลำดับสอดคล้องกับการเพิ่ม -1, 1, 8 หรือ -8 ไปยังดัชนีเชิงเส้น อาร์เรย์ [-1 1 8 -8] ทำหน้าที่เข้ารหัสสองสิ่งที่แตกต่าง:

  • displacements ที่เป็นไปได้ของ explorer
  • ตำแหน่งสัมพัทธ์ของฟีเจอร์ที่ตรวจพบด้วยกล้องส่องทางไกล ตำแหน่งเหล่านี้สัมพันธ์กับตำแหน่งปัจจุบันของ explorer

สตริงอินพุตถูกจัดเรียงเป็นกลุ่มของ5อักขระ เนื่องจากชิ้นแรกหายไปอักขระแรก (สิ่งที่บ่งบอกถึงการเคลื่อนไหว) เริ่มต้นsรวมอยู่โดยพลการเพื่อให้ชิ้นทั้งหมดมีขนาดเดียวกัน เพื่อชดเชยสิ่งนี้นักสำรวจเริ่มต้นที่ตำแหน่ง 7 ไม่ใช่ 8 ดังนั้นการกระจัดเริ่มต้นไปทางทิศใต้ (เพิ่ม 1 ในดัชนีเชิงเส้น) ทำให้พวกมันอยู่ที่ตำแหน่ง 8

ชิ้นของ 5 ตัวถูกประมวลผลในวง อักขระตัวแรกจะอัพเดตตำแหน่งและส่วนที่เหลืออีก 4 ถ้าแตกต่างกัน#จะถูกเขียนลงในรายการที่เพียงพอของเมทริกซ์ที่แสดงถึงแผนที่

'?'          % 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

นั่นเป็นเคล็ดลับที่ฉลาด! ฉันจะทดสอบโปรแกรมของคุณเทียบกับแผนที่ไม่กี่แผนที่เพื่อดูว่าเป็นไปตามที่ฉันคาดหวังหรือไม่
user52676

3

C, 210 208 207 ไบต์

อันนี้ใช้ printf และ scanf เพื่ออ่านอินพุตและอาเรย์เชิงเส้นแทน x, y; ดังนั้นฉันจึงรู้สึกว่ามันแตกต่างจากมิลลิบิทมากพอ

แข็งแรงเล่นกอล์ฟ:

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

ค่อนข้าง-ungolfed:

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
}

ตัวแทน:

  // 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'

นอกจากนี้คุณเริ่มต้นที่ตำแหน่งที่ 8 เนื่องจากเป็นการลบอักขระหรือออกจากลูปการพิมพ์


2

Fortran, 263 251 247 235 234 216 ไบต์

รุ่น 1D (คล้ายกับ 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

รุ่น 2 มิติ:

#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

ในการใช้งานรูปแบบฟรีและการประมวลผลก่อนไฟล์ความต้องการส่วนขยายเช่น.F90 explorer.F90อินพุตถูกอ่านจาก STDIN:

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

ดังนั้นฟอร์แทรนจึงมีการจัดทำดัชนีเชิงเส้นเช่นกัน
Luis Mendo

@ DonMuesli ไม่ไม่จริง ฉันทำงานกับอาร์เรย์ 1D โดยตรง สำหรับการพิมพ์อาเรย์ของตัวละครฉันใช้ความจริงที่ว่าอาเรย์นั้นถูกเก็บไว้อย่างต่อเนื่องในหน่วยความจำ
Alexander Vogt

2

C, 265 226 224 ไบต์

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

แผนที่คือ 8x8 ฉันไม่เคยสังเกตมาก่อน และนี่คือโซลูชัน 265 ไบต์ที่ทำงานกับแผนที่ที่มีขนาดตัวแปร:

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

ไม่ควรa[8][8]จะเพียงพอหรือไม่
Alexander Vogt

@Alexander Vogt - โอ้ใช่! ขอบคุณที่ลดขนาดให้เหลืออีกสองไบต์
mIllIbyte

ฉันชอบวิธีที่คุณคำนวณการเพิ่ม / ลดลงถึง x และ y การเปรียบเทียบโค้ด C ของเราคงที่int a[8][8]ช่วยให้คุณเริ่มต้นแผนที่ได้ฟรีและการใช้ถ่านm[64]ทำให้ฉันได้รับส่วนลดมากสำหรับแผนที่เอาท์พุท แม้ว่าจะนับได้ใกล้เคียงจริงๆ
tucuxi

หากคุณย้อนกลับeและwในการนำเสนอแผนที่ของคุณคุณสามารถใช้for(x=8;x--;)putchar((i=a[x][y])?i:63)สองไบต์สำหรับการโกน
tucuxi

คือc=getchar(),c+1ไม่ได้เทียบเท่ากับgetchar(),c++หรือมีกลอุบายบางเกี่ยวข้อง?
Jonathan Frech

2

ทับทิม, 169 147 ไบต์

โปรแกรมเต็มรูปแบบ ใช้เวลาในสตริงอินพุตจาก STDIN (คุณอาจต้องไพพ์มันจากไฟล์เพื่อป้องกันการขึ้นบรรทัดใหม่จากสิ่งที่ยุ่งเหยิงขึ้นมา) และเอาท์พุทแผนที่ผลลัพธ์ไปยัง STDOUT

ตัดทอนโดยใส่สายทั้งหมดเป็นหนึ่งแล้วแยกพวกเขาในภายหลัง

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}/

Ungolfed:

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 ไบต์ ( ลองออนไลน์ )

แข็งแรงเล่นกอล์ฟ:

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

ungolfed เล็กน้อย:

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

x=x+(("w e"):find(e)or 2)-2 endไม่สามารถเป็นได้x=x-2+(("w e"):find(e)or 2)end?
Jonathan Frech

1

Kotlin ขนาด 242 ไบต์

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

บรรทัดใหม่สามารถถูกแทนที่ด้วยเครื่องหมายอัฒภาคหากต้องการ

ลองที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.