Ein winziger Entdecker


34

Du bist ein Entdecker, der eine unbekannte Welt abbildet. Ihr Schiff wird vom Wind getragen. Wo geht es hin, wer weiß?

Jeden Tag sehen Sie in Ihrem Fernglas Merkmale im Norden, Süden, Osten und Westen. Sie sehen immer vier solche Merkmale, die den Hauptrichtungen entsprechen. Ihr Fernglas meldet ASCII-Symbole wie folgt:

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

Die Symbole sind in der Reihenfolge (Nord, Süd, Ost, West).

Dies sind die Symbole: ~= Meer, .= Küste, ^= Berg, *= Baum, #= ungültig (keine Beobachtung, wenn Sie den Rand der Welt sehen oder die Landschaft durch Nebel verdeckt ist). Ihr Fernglas sieht in jede Richtung genau eine Einheit.

Jede Nacht siehst du zu den Sternen hoch, um zu sehen, wie weit du gereist bist. Wenn Sie die Sterne betrachten, sehen Sie ein ASCII-Symbol wie das folgende:

n, s, e,w

entsprechend Nord, Süd, Ost und West. Sie bewegen sich jede Nacht genau eine Einheit nach Norden, Süden, Osten oder Westen. Als Entdecker erhalten Sie also einen endlosen Strom von Symbolen:

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

Ihre Aufgabe ist es, eine 2D-Karte der Welt auszugeben (wo ?unbekannte Teile der Karte sind, Norden ist oben, Osten ist rechts):

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

Der Einfachheit halber nehmen wir an, dass Sie in der unteren linken Ecke der Karte beginnen. Angenommen, alle Karten sind 8x8.

Hier ist ein einfaches 3x3 Beispiel. Angenommen, die Karte sieht folgendermaßen aus:

~.~
~^~
~.~

Mit folgender Eingabe: ~#.#n~~^#s

Sie erhalten diese Ausgabe:

~??
~^?
~.?

Weitere Beispiele für Ein- und Ausgänge:

Eingang ~#~#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.#~~

Ausgabe

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

Eingang:

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

Ausgabe:

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

7
Willkommen bei Programming Puzzles & Code Golf! Dies ist eine schöne erste Herausforderung. Ein paar Dinge sind mir jedoch unklar: Müssen alle Symbole in der Ausgabe durch Leerzeichen getrennt sein? Dies scheint in der Beispielausgabe der Fall zu sein, wird aber nirgendwo explizit angegeben. Welchen Zweck erfüllen die Sternrichtungen? Ich dachte, sie hätten vielleicht kontrolliert, wohin die Symbole auf der Karte gehen, aber wenn man den Beispielen folgt und unten links anfängt, scheint das nicht der Fall zu sein. Können Sie das näher erläutern?
Alex A.

Die Ausgabe muss nicht durch Leerzeichen getrennt sein, das ist ein Fehler von meiner Seite. Das "#" steht für "keine Beobachtung". Sie treten immer dann auf, wenn Sie sich an der Kartengrenze befinden, können aber auch zufällig auftreten.
user52676

4
Ausgezeichnet. Wie Alex sagte, ist dies eine großartige erste Herausforderung. Ich hoffe, in Zukunft mehr von dir zu sehen! :) (Zu
Ihrer Information

1
Ich vermute, das erste Beispiel (wo die Eingabe ist ~#~#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) ist falsch, und die Ausgabe sollte haben, ??wo es heißt?.
Leaky Nun

3
Es ist ein magisches Luftschiff ;)
User52676

Antworten:


8

MATL , 68 59 58 Bytes

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

Probieren Sie es online!

Erläuterung

Die Karte wird unten im Stapel aufbewahrt und nach und nach gefüllt. Die aktuelle Position des Explorers wird in der Zwischenablage J gespeichert.

Die Karte verwendet Matrixkoordinaten, also ist (1,1) oben links. Darüber hinaus wird eine lineare Indexierung mit Spaltenschwerpunkt verwendet. Dies bedeutet, dass auf die Elemente der 8 × 8-Matrix, die die Karte darstellen, mit einem einzelnen Index wie folgt zugegriffen wird :

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

So ist beispielsweise das Element (3,2) der Matrix das Element mit dem linearen Index 11. Die Bewegung nach Norden, Süden, Osten und Westen entspricht einer Addition von -1, 1, 8 oder -8 zum linearen Index. Das Array [-1 1 8 -8] dient dazu, zwei verschiedene Dinge zu kodieren:

  • Die möglichen Verschiebungen des Explorers.
  • Die relativen Positionen der mit dem Fernglas erkannten Merkmale. Diese Positionen beziehen sich auf die aktuelle Position des Explorers.

Die Eingabezeichenfolge ist in 5Zeichenblöcke unterteilt. Da dem ersten Block das erste Zeichen (das, was Bewegung anzeigt) fehlt, swird willkürlich eine Initiale eingefügt, um alle Blöcke gleich groß zu machen. Um dies zu kompensieren, beginnt der Explorer an Position 7 und nicht an Position 8, sodass die anfängliche Verschiebung nach Süden (Addition von 1 zum linearen Index) ihn an Position 8 lässt.

Die Stücke von 5 Zeichen werden in einer Schleife verarbeitet. Das erste Zeichen aktualisiert die Position und die verbleibenden 4 werden, sofern sie nicht identisch #sind, in die entsprechenden Einträge der Matrix geschrieben, die die Karte darstellt.

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

Das ist ein kluger Trick! Ich werde Ihr Programm anhand einiger Karten testen, um festzustellen, ob es das tut, was ich erwarte.
user52676

3

C 210, 208, 207 Bytes

Dieser verwendet printf und scanf zum Lesen der Eingabe und ein linearisiertes Array anstelle von x, y; Ich glaube, es ist genug anders als bei Millibyte .

Golf gespielt:

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

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

Darstellung:

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

Sie beginnen auch bei Position 8, da hierdurch ein Zeichen aus der Druckschleife entfernt wird.


2

Fortran, 263 251 247 235 234 216 Bytes

1D-Version (ähnlich der von 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 Version:

#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

Um freie Form und Vorverarbeitung zu ermöglichen, benötigt die Datei die Erweiterung .F90, z explorer.F90. Die Eingabe wird von STDIN gelesen:

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

Hat Fortran also auch eine lineare Indizierung?
Luis Mendo

@ DonMuesli Nein, nicht wirklich. Ich arbeite direkt auf einem 1D-Array. Zum Drucken des Array von Zeichen verwende ich die Tatsache, dass das Array zusammenhängend im Speicher gespeichert ist.
Alexander Vogt

2

C 265 226 224 Bytes

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

Die Map ist 8x8, das habe ich vorher nicht bemerkt. Und hier ist die 265-Byte-Lösung, die für Karten mit variablen Abmessungen funktioniert:

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

Sollte nicht a[8][8]ausreichen?
Alexander Vogt

@ Alexander Vogt - Oh, richtig! Danke, das reduziert zwei weitere Bytes.
MIllIbyte

Ich mag es wirklich, wie Sie Inkremente / Dekremente zu x und y berechnen. Wenn Sie unseren C-Code vergleichen, erhalten Sie mit static eine int a[8][8]kostenlose Karteninitialisierung, und mit char m[64]bekomme ich große Rabatte für die Kartenausgabe. Wirklich enge Zählungen, obwohl
Tucuxi

Wenn Sie eund win Ihrer Kartendarstellung umkehren , können Sie for(x=8;x--;)putchar((i=a[x][y])?i:63)zwei Bytes bei der Ausgabe sparen.
Tucuxi

Ist das c=getchar(),c+1nicht gleichbedeutend mit getchar(),c++oder handelt es sich um einen Trick?
Jonathan Frech

2

Ruby, 169 147 Bytes

Volles Programm. Übernimmt die Eingabezeichenfolge von STDIN (Sie müssen sie wahrscheinlich aus einer Datei einlesen, um zu verhindern, dass nachfolgende Zeilenumbrüche die Dinge durcheinander bringen) und gibt die resultierende Zuordnung an STDOUT aus.

Eine Tonne gekürzt, indem alle Saiten zu einer zusammengefügt und später aufgeteilt wurden.

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 Bytes ( online testen )

Golf gespielt:

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

Leicht 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

Kann x=x+(("w e"):find(e)or 2)-2 endnicht sein x=x-2+(("w e"):find(e)or 2)end?
Jonathan Frech

1

Kotlin, 242 Bytes

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

Die Zeilenumbrüche können auf Wunsch durch Semikolons ersetzt werden.

Versuch es hier

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.