Küçük Bir Gezgin


34

Sen bir kaşifsin, bilinmeyen bir dünyayı haritalıyorsun. Geminiz rüzgârla taşınır. Nereye gittiğini kim bilir?

Her gün spyglass'ınızda kuzey, güney, doğu ve batı gibi özellikler görüyorsunuz. Her zaman kardinal yönlere karşılık gelen dört özellik görürsünüz. Spyglass'ınız ASCII sembollerini şöyle bildirir:

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

Semboller sırasıyla (kuzey, güney, doğu, batı).

Bu semboller: ~= deniz, .= sahil, ^= dağ, *= ağaç, #= geçersiz (gözlem yok, bu, dünyanın sınırlarını gördüğünüzde veya manzara sis tarafından gizlendiğinde gerçekleşir). Spyglass'ınız her yönde tam olarak bir ünite görüyor.

Her gece ne kadar uzağa gittiğinizi görmek için yıldızlara bakıyorsunuz. Yıldızlara bakmak, şöyle bir ascii sembolü bildirir:

n, s, e,w

sırasıyla Kuzey, Güney, Doğu ve Batı'ya karşılık gelmektedir. Her gece tam olarak bir üniteyi kuzeye, güneye, doğuya veya batıya taşırsınız. Yani siz, kaşif olarak sonsuz bir sembol akışı alacaksınız:

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

Göreviniz dünyanın 2B haritasını çıkarmak ( ?haritanın bilinmeyen kısımları, kuzey yukarı, doğu doğru):

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

Basitlik adına haritanın sol alt köşesinden başladığınızı varsayalım. Tüm haritaların 8x8 olduğunu varsayalım.

İşte basit bir 3x3 örneği. Haritanın şöyle göründüğünü varsayın:

~.~
~^~
~.~

Aşağıdaki girişle: ~#.#n~~^#s

Bu çıktıyı alacaksınız:

~??
~^?
~.?

Daha fazla örnek giriş ve çıkış:

giriş ~#~#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.#~~

çıktı

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

Giriş:

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

Çıktı:

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

7
Programlama Bulmacaları ve Kod Golf'üne Hoş Geldiniz! Bu güzel bir ilk meydan okumadır. Yine de birkaç şey bana net değil: Çıktıdaki tüm semboller boşlukla mı ayrılmış olmalı? Örnek çıktıda durum böyle görünüyor, ancak açıkça hiçbir yerde ifade edilmedi. Ayrıca, yıldız yönleri hangi amaca hizmet ediyor? Sembollerin nereye gideceğini kontrol ettiklerini düşündüm, ama örnekleri takip ederek sol alttan başlayarak durum böyle görünmüyordu. Bunu açıklayabilir misiniz?
Alex A.

Çıktı boşlukla ayrılmış olmak zorunda değildir, bu benim açımdan bir hata. "#" "Gözlem yok" u temsil eder. Haritanın sınırlarında olduğunuzda ortaya çıkarlar, ancak rastgele de olabilirler.
user52676

4
Mükemmel. Alex'in dediği gibi, bu büyük bir ilk zorluk. Gelecekte sizden daha fazla görmeyi umuyorum! :) (FYI, Sandbox gelecekteki zorluklar hakkında geri bildirim almak için harika bir yer.)
El'endia Starman

1
İlk örneğin (girişin olduğu yer ~#~#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) yanlış olduğundan şüpheleniyorum ve çıktının söylediği ??yere sahip olması gerekir?.
Sızan Rahibe

3
Bu büyülü bir hava gemisi ;)
user52676

Yanıtlar:


8

MATL , 68 59 58 bayt

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

Çevrimiçi deneyin!

açıklama

Harita yığının altında tutulur ve yavaş yavaş doldurulur. Gezginin şu anki konumu J panosunda saklanır.

Harita matris koordinatlarını kullanıyor, bu yüzden (1,1) sol üst. Ek olarak, sütun ana doğrusal endekslemesi kullanılır. Bu, haritayı temsil eden 8 x 8 matrisin elemanlarına tek bir indeks ile aşağıdaki şekilde erişildiği anlamına gelir :

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

Örneğin, matrisin elemanı (3,2) doğrusal endeks 11'e sahip elemandır. Kuzey, Güney, Doğu ve Batı'ya doğru hareket sırasıyla doğrusal endekse -1, 1, 8 veya -8 eklemeye karşılık gelir. [-1 1 8 -8] dizisi iki farklı şeyi kodlamaya hizmet eder:

  • Kaşifin olası yer değiştirmeleri.
  • Spyglass ile tespit edilen özelliklerin göreceli konumları. Bu pozisyonlar kaşifin o andaki konumuna göredir.

Giriş dizesi, parçalarına düzenlenmiştir. 5 karakter . İlk öbek, ilk karakteri (hareketi gösteren) eksik olduğundan, ilks olduğundan, bütün öbekleri aynı boyutta yapmak için keyfi olarak dahil edilir. Bunu telafi etmek için, kaşif 8'de değil, 7 pozisyonunda başlar, böylece güneye ilk yer değiştirmesi (doğrusal endekse 1 ekleyin) onları 8 pozisyonunda bırakır.

5 karakterden oluşan parçalar bir döngüde işlenir. İlk karakter pozisyonu günceller ve kalan 4 #ise haritayı temsil eden matrisin yeterli girişlerine yazılır.

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

Bu akıllıca bir numara! Beklediğiniz şeyi yapıp yapmadığını görmek için programınızı birkaç harita üzerinde test edeceğim.
user52676

3

C, 210 208 207 bayt

Bu, girişi okumak için printf ve scanf ve x, y yerine doğrusallaştırılmış bir dizi kullanır; bu yüzden milibayttan yeterince farklı olduğunu hissediyorum .

golfed:

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

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

Temsil:

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

Ayrıca, 8. pozisyondan başlarsınız, çünkü bu baskı döngüsünün üstünü çizer veya keser.


2

Fortran, 263 251 247 235 234 216 bayt

1D versiyonu (Don Muesli'ninkine benzer):

#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 versiyon:

#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

Serbest form ve ön işleme olanak sağlamak için, dosyanın uzantıya ihtiyacı vardır .F90, örn explorer.F90. Giriş STDIN'den okunur:

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

Öyleyse Fortran'ın ayrıca doğrusal indekslemesi var mı?
Luis Mendo

@DonMuesli Hayır, gerçekten değil. Doğrudan bir 1D dizisi üzerinde çalışıyorum. Karakter dizisini yazdırmak için dizinin bitişik olarak bellekte depolanması gerçeğini kullanıyorum.
Alexander Vogt

2

C, 265 226 224 bayt

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

Harita 8x8, daha önce farketmedim. Ve işte değişken boyutlara sahip haritalar için çalışan 265 baytlık çözüm:

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]Yeterli olmamalı mı ?
Alexander Vogt

@Alexander Vogt - Ah, doğru! Teşekkürler, bu iki baytı daha azaltır.
iLillIbyte

X ve y değerlerine yapılan artış / azalışları hesaplama şeklinizi gerçekten çok seviyorum. C kodumuzu karşılaştırmakla birlikte, statik int a[8][8]ücretsiz harita başlatma işlemini başlatır ve char kullanımı m[64]harita çıktısı için bana büyük indirimler sağlar. Gerçekten çok yakın sayılır, olsa
tucuxi

Tersine çevirirseniz eve wharita gösteriminizde, for(x=8;x--;)putchar((i=a[x][y])?i:63)çıktıdaki iki baytı tıraş etmek için kullanabilirsiniz .
tucuxi

c=getchar(),c+1değil eşdeğer getchar(),c++veya ilgili bazı hile var mı?
Jonathan Frech

2

Yakut, 169 147 bayt

Tam program Giriş dizgisini STDIN'den alır (takip eden yeni satırların işleri karıştırmasını önlemek için büyük olasılıkla bir dosyaya aktarmanız gerekir) ve sonuçta ortaya çıkan haritayı STDOUT'a çıkarır.

Tüm telleri bir araya getirip daha sonra bölerek bir tonu kesin.

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 bayt ( çevrimiçi dene )

golfed:

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

Biraz 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

Can x=x+(("w e"):find(e)or 2)-2 endolmaz x=x-2+(("w e"):find(e)or 2)end?
Jonathan Frech

1

Kotlin, 242 bayt

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

İstenirse newlines noktalı virgül ile değiştirilebilir.

Burada dene

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.