微小的探索者


34

您是一位探险家,正在绘制一个未知的世界。你的船在风中航行。哪里知道,谁知道?

每天,在望远镜中,您都会看到北,南,东和西的特征。您始终会看到四个与基本方向相对应的功能。您的望远镜会报告如下ASCII符号:

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

这些符号按顺序排列(北,南,东,西)。

这些符号是:~=海洋,.=海岸,^=山脉,*=树木,#=无效(无观测,只要您看到世界的边缘或地貌被雾遮盖,就会发生这种情况)。您的望远镜在各个方向上只能看到一个单位。

每天晚上,您抬头仰望星星,以了解您旅行了多远。看着星星会报告这样的ascii符号:

nsew

分别对应于北部,南部,东部和西部。每天晚上,您总是只向北,南,东或西移动一个单位。因此,作为浏览器的您将收到无穷无尽的符号流:

~~.*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
欢迎来到编程难题和代码高尔夫球!这是一个不错的第一个挑战。不过,有两点我不清楚:输出中的所有符号都必须用空格隔开吗?在示例输出中似乎是这种情况,但未在任何地方明确声明。另外,星空指示有什么目的?我以为他们可以控制符号在地图上的位置,但是按照示例并从左下角开始,似乎并非如此。您能详细说明一下吗?
Alex A.

输出不必用空格分开,这是我的错误。“#”代表“没有观察到”。只要您在地图边界上,它们就会发生,但也可能是随机发生的。
2016年

4
优秀。正如亚历克斯所说,这是一个巨大的第一个挑战。希望以后能有更多机会!:)(仅供参考,沙盒是获得有关未来挑战的反馈的好地方。)
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)是错误的,并且输出应该??在那里说?.
漏尼姑

3
这是一艘神奇的飞船;)
user52676

Answers:


8

MATL68 59 58字节

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

在线尝试!

说明

该地图保存在堆栈的底部,并逐渐填充。资源管理器的当前位置存储在剪贴板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]用于编码两种不同的事物:

  • 资源管理器可能的位移。
  • 用望远镜检测到的特征的相对位置。这些位置相对于资源管理器的当前位置。

输入字符串按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 '16

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

有点无聊:

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

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

要启用自由格式和预处理,文件需要扩展名.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 
?~~~~~??
?....~??
?.**.~??
?~..~~??
?~~~~~??
??~..~??
~~~.^.??
~~~~~~??

那么Fortran是否也具有线性索引?
Luis Mendo

@DonMuesli不,不是。我直接在1D数组上进行操作。为了打印字符数组,我使用了数组连续存储在内存中的事实。
亚历山大·沃格特

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]不够吗?
亚历山大·沃格特

@亚历山大·沃格特-哦,对!谢谢,减少了两个字节。
mIllbyte

我真的很喜欢您如何计算x和y的增量/减量。比较我们的C代码,静态为int a[8][8]您提供免费的地图初始化,而使用char为m[64]我提供了地图输出的大幅折扣。不过,计数非常接近
tucuxi

如果反转ew以地图表示形式,则可以用于for(x=8;x--;)putchar((i=a[x][y])?i:63)在输出上剃除两个字节。
tucuxi

c=getchar(),c+1不是等同于getchar(),c++或者是有一些涉及挂羊头卖狗肉?
乔纳森·

2

Ruby,169147字节

完整程序。从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}/

取消高尔夫:

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

稍微松了一下:

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
乔纳森·弗雷希

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

如果需要,可以用分号替换换行符。

在这里尝试

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.