Der betrunkene Bischof


42

In der Kryptografie mit öffentlichem Schlüssel ist ein Fingerabdruck mit öffentlichem Schlüssel eine kurze Folge von Bytes, die zum Identifizieren eines längeren öffentlichen Schlüssels verwendet wird.

Insbesondere in SSH können sie verwendet werden, um zu überprüfen, ob es sich bei einem Server tatsächlich um den Server handelt, mit dem ich voraussichtlich kommunizieren und auf den kein Man-in-the-Middle-Angriff abzielt.

Sie werden in der Regel als hexadezimale Ziffernfolge dargestellt, daher kann es ziemlich langweilig und mühsam sein, sie mit dem erwarteten Fingerabdruck zu vergleichen:

37:e4:6a:2d:48:38:1a:0a:f3:72:6d:d9:17:6b:bd:5e

Zur Vereinfachung hat OpenSSH eine Methode zur Visualisierung von Fingerabdrücken als ASCII-Grafik eingeführt, die wie folgt aussehen würde:

+-----------------+
|                 |
|                 |
|          .      |
|     .   o       |
|o . o . S +      |
|.+ + = . B .     |
|o + + o B o E    |
| o .   + . o     |
|         .o      |
+-----------------+

Damit könnte ich versuchen, mich an die raue Form der ASCII-Grafik zu erinnern, und sie dann (theoretisch) erkennen, wenn sich der Fingerabdruck des Servers ändert und das Bild anders aussieht.

Wie es funktioniert

Entnommen Dirk Loss, Tobias Limmer, Alexander von Gernler. 2009. Der betrunkene Bischof: Eine Analyse des OpenSSH-Algorithmus zur Visualisierung von Fingerabdrücken .

Das Raster hat eine Breite von 17 Zeichen und eine Höhe von 9 Zeichen. Der "Bischof" beginnt in Zeile 4 / Spalte 8 (in der Mitte). Jede Position kann als [x, y] bezeichnet werden, dh [8,4] für die Startposition des Bischofs.

            1111111
  01234567890123456
 +-----------------+
0|                 |
1|                 |
2|                 |
3|                 |
4|        S        |
5|                 |
6|                 |
7|                 |
8|                 |
 +-----------------+

Der Bischof benutzt den Fingerabdruck, um sich zu bewegen. Es liest es byteweise von links nach rechts und vom niedrigstwertigen bis zum höchstwertigen Bit:

Fingerprint      37      :       e4      :       6a      :  ...  :       5e
Bits        00 11 01 11  :  11 10 01 00  :  01 10 10 10  :  ...  :  01 01 11 10
             |  |  |  |      |  |  |  |      |  |  |  |              |  |  |  |
Step         4  3  2  1      8  7  6  5     12 11 10  9             64 63 62 61

Der Bischof wird sich nach folgendem Plan bewegen:

Bits   Direction
-----------------
00     Up/Left
01     Up/Right
10     Down/Left
11     Down/Right

Sonderfälle:

  • Wenn der Bischof in einer Ecke ist und wieder in die Ecke ziehen würde, bewegt er sich überhaupt nicht. Dh: Der Bischof ist bei [0,0]und sein nächster Schritt wäre 00. Er bleibt bei[0,0]
  • Befindet sich der Bischof in einer Ecke oder an einer Wand und würde er in eine der Wände einziehen, bewegt er sich nur horizontal oder vertikal. Dh: Der Bischof ist bei [0,5]und sein nächster Schritt wäre 01. Er kann nicht nach links gehen, also bewegt er sich einfach nach oben [0,4].

Jede Position enthält einen Wert dafür, wie oft der Bischof dieses Feld besucht hat:

Value      | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13| 14| 15| 16|
Character  |   | . | o | + | = | * | B | O | X | @ | % | & | # | / | ^ | S | E |

Die Werte 15 (S) und 16 (E) sind insofern besonders, als sie die Start- und Endposition des Bischofs markieren und den tatsächlichen Wert der jeweiligen Position überschreiben.

Tor

Erstellen Sie ein Programm, das einen alphanumerischen Fingerabdruck als Eingabe verwendet und dessen ASCII-Grafikdarstellung wie in den Beispielen gezeigt erstellt.

Beispiele

Input:
16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48

Output:
+-----------------+
|        .        |
|       + .       |
|      . B .      |
|     o * +       |
|    X * S        |
|   + O o . .     |
|    .   E . o    |
|       . . o     |
|        . .      |
+-----------------+

Input:
b6:dd:b7:1f:bc:25:31:d3:12:f4:92:1c:0b:93:5f:4b

Output:
+-----------------+
|            o.o  |
|            .= E.|
|             .B.o|
|              .= |
|        S     = .|
|       . o .  .= |
|        . . . oo.|
|             . o+|
|              .o.|
+-----------------+

Input:
05:1e:1e:c1:ac:b9:d1:1c:6a:60:ce:0f:77:6c:78:47

Output:
+-----------------+
|       o=.       |
|    o  o++E      |
|   + . Ooo.      |
|    + O B..      |
|     = *S.       |
|      o          |
|                 |
|                 |
|                 |
+-----------------+

Regeln

  • Das ist . Der Code mit den wenigsten Bytes gewinnt.
  • Sie können keine vorhandene Bibliothek verwenden, die das Bild erzeugt.
  • Verwenden Sie die Sprache, die Sie bevorzugen!
  • Ihre Einreichung muss ein vollständiges Programm sein

3
Können wir davon ausgehen, dass keine Zelle mehr als 14 Mal besucht wird?
Martin Ender

2
Es gibt einige Eckfälle mit minimaler Abdeckung, die dazu führen würden, dass einige Felder mehr als 14 Mal besucht werden. 33:33:33:...:33, cc:cc:cc:...:ccwären Beispiele dafür. Der Fingerabdruck ist normalerweise ein MD5-Hash, daher ist es sehr unwahrscheinlich, dass Sie ein solches Ergebnis erhalten. Ich habe keine verlässlichen Quellen gefunden, um mit diesen umzugehen. Deshalb
Padarom

Antworten:


2

Pyth, 125 Bytes

Jj*17\-"++"JVc9XXsm@"^ .o+=*BOX@%&#/"hdrS+*U9U17K.u.e@S[0b*8hk)1.b+tNyYNYsm_c4.[08jxsM^.HM16 2d2cz\:,4 8 8ieK17\E76\SjN"||")J

Probieren Sie es online aus: Demo oder Test-Suite

Ich habe vor ein paar Tagen geschrieben, aber nicht gepostet, weil ich nicht wirklich glücklich darüber war.

Erläuterung:

Die Grundidee ist die folgende. Ich fange mit dem Paar an (4, 8). Bei jedem Zug (m1,m2)gehe ich vom (x, y)zum (x-1+2*m1, y-1+2*m2). Um sicher zu gehen, dass diese Koordinaten gehen nicht außerhalb der Grenzen, werde ich einige Listen machen, sortieren sie und senden Sie das mittlere Element: (sorted(0,8,newx)[1], sorted(0,16,newy)[1]).

Ich verfolge alle Positionen. Zu dieser Liste von Positionen füge ich eine Liste aller möglichen Positionen hinzu, sortiere sie und codiere sie in Lauflängen. Das gibt mir eine Nummer für jede Position. Mit dieser Nummer kann ich das Coorect-Zeichen auswählen und am Ende die Zeichen der Start- und Endposition überschreiben.


9

Dyalog APL (178)

{⎕ML←3⋄F←9 17⍴0⋄5 9{(⍺⌷F)+←1⋄×⍴⍵:(1 1⌈9 17⌊⍺-1 1-2×↑⍵)∇1↓⍵⋄(⍺⌷F)←16⋄F[5;9]←15⋄K⍪(M,' .o+=*BOX@%&#/^SE'[1+F],M←'|')⍪K←'+','+',⍨17⍴'-'}⊃,/{↓⊖4 2⍴⍉(4/2)⊤¯1+⍵⍳⍨⎕D,'abcdef'}¨⍵⊂⍨':'≠⍵}

Dies ist eine Funktion, die die Zeichenfolge als rechtes Argument verwendet und eine Zeichenmatrix mit der ASCII-Grafikdarstellung zurückgibt, z.

      F←{⎕ML←3⋄F←9 17⍴0⋄5 9{(⍺⌷F)+←1⋄×⍴⍵:(1 1⌈9 17⌊⍺-1 1-2×↑⍵)∇1↓⍵⋄(⍺⌷F)←16⋄F[5;9]←15⋄K⍪(M,' .o+=*BOX@%&#/^SE'[1+F],M←'|')⍪K←'+','+',⍨17⍴'-'}⊃,/{↓⊖4 2⍴⍉(4/2)⊤¯1+⍵⍳⍨⎕D,'abcdef'}¨⍵⊂⍨':'≠⍵}


      F '16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48'
+-----------------+
|        .        |
|       + .       |
|      . B .      |
|     o * +       |
|    X * S        |
|   + O o . .     |
|    .   E . o    |
|       . . o     |
|        . .      |
+-----------------+
      F 'b6:dd:b7:1f:bc:25:31:d3:12:f4:92:1c:0b:93:5f:4b'
+-----------------+
|            o.o  |
|            .= E.|
|             .B.o|
|              .= |
|        S     = .|
|       . o .  .= |
|        . . . oo.|
|             . o+|
|              .o.|
+-----------------+

Erläuterung:

  • ⎕ML←3: eingestellt ⎕MLauf 3. Dies ist nützlicher zum Teilen von Strings.

  • F←9 17⍴0: Erstelle eine 17 x 9-Matrix aus Nullen. Fstellt dar, wie oft jede Position besucht wurde.

  • ⍵⊂⍨':'≠⍵: auf :Zeichen aufgeteilt.

  • {... : für jede Gruppe:
    • ¯1+⍵⍳⍨⎕D,'abcdef': Finden Sie den Index jedes Zeichens in der Zeichenfolge '01234567890abcdef'. Subtrahieren Sie 1, da APL standardmäßig 1-indiziert ist.
    • (4/2)⊤: wandle die Werte in ihre 4-Bit-Darstellungen um (es sollte jetzt eine 2-mal-4-Matrix geben).
    • ↓⊖4 2⍴⍉: Drehen Sie die Matrix, verwenden Sie die Elemente, um stattdessen eine 2-mal-4-Matrix zu füllen, spiegeln Sie diese Matrix horizontal und erhalten Sie dann jede Zeile separat. Dies gibt uns die 4 2-Bit-Werte, die wir benötigen.
  • ⊃,/: Fügen Sie die resultierenden Listen zu einer Liste von 2-Bit-Schritten zusammen.
  • 5 9{... }: mit der Liste der Schritte und beginnend an Position [9,5]:
    • (⍺⌷F)+←1: Erhöht die aktuelle Position in F.
    • ×⍴⍵:: wenn die Liste der Schritte nicht leer ist:
      • ↑⍵: Machen Sie den ersten Schritt aus der Liste
      • ⍺-1 1-2×: Hole das Delta für diesen Schritt und subtrahiere es von der aktuellen Position
      • 1 1⌈9 17⌊: Bewegung auf das Feld beschränken
      • (... )∇1↓⍵: Fahren Sie mit der neuen Position und den restlichen Schritten fort
    • Wenn es ist leer:
      • (⍺⌷F)←16: Fan der Endposition auf 16 stellen
      • F[5;9]←15: FAn der Startposition auf 15 stellen
      • ' .o+=*BOX@%&#/^SE'[1+F]: Ordne jede Position dem entsprechenden Zeichen zu
      • K⍪(M,... ,M←'|')⍪K←'+','+',⍨17⍴'-': Wickle das Ergebnis in Zeilen um

8

Perl, 300 + 1 (-n) = 301 Bytes

perl -ne 'sub b{$b=$_[0]+$_[1];$_[0]=$b<0?0:$b>$_[2]?$_[2]:$b}$v=pack"(H2)*",/\w\w/g;($x,$y)=(8,4);$a[b($y,($_&2)-1,8)*17+b($x,($_&1)*2-1,16)]++for map{vec$v,$_,2}0..63;@a[76,$y*17+$x]=(15,16);$c=" .o+=*BOX@%&#/^SE";print$d="+".("-"x17)."+\n",(map{+"|",(map{substr$c,$_,1}@a[$_*17..($_+1)*17-1]),"|\n"}0..8),$d'

Diese Antwort ist widerlich, aber es ist auch die erste für dieses Rätsel.

-num eine Eingabezeile auf STDIN zu nehmen und zu füllen $_.

# b($v, -1 or 1, max) modifies $v within 0..max
sub b{$b=$_[0]+$_[1];$_[0]=$b<0?0:$b>$_[2]?$_[2]:$b}

# turn $_ into a binary string
$v=pack"(H2)*",/\w\w/g;

# initialize cursor
($x,$y)=(8,4);

# find an element of single-dimensional buffer @a
$a[
    # y += (bitpair & 2) - 1, within 8
    b($y,($_&2)-1,8) * 17
    # x += (bitpair & 1) * 2 - 1, within 17
  + b($x,($_&1)*2-1,16)
# and increment it
]++
# for each bit pair (in the right order!)
  for map{vec$v,$_,2}0..63;

# overwrite the starting and ending positions
@a[76,$y*17+$x]=(15,16);

# ascii art lookup table
$c=" .o+=*BOX@%&#/^SE";

# output
print
  # the top row, saving it for later
  $d="+".("-"x17)."+\n",
  # each of the eight middle rows
  (map{+
    # converting each character in @a in this row as appropriate
    "|",(map{substr$c,$_,1}@a[$_*17..($_+1)*17-1]),"|\n"
  }0..8),
  # the bottom row
  $d

7

R, 465 459 410 393 382 357 Bytes

f=function(a){s=strsplit;C=matrix(as.integer(sapply(strtoi(el(s(a,":")),16),intToBits)[1:8,]),2);C[!C]=-1;n=c(17,9);R=array(0,n);w=c(9,5);for(i in 1:64){w=w+C[,i];w[w<1]=1;w[w>n]=n[w>n];x=w[1];y=w[2];R[x,y]=R[x,y]+1};R[]=el(s(" .o+=*BOX@%&#/^",""))[R+1];R[9,5]="S";R[x,y]="E";z="+-----------------+\n";cat(z);for(i in 1:9)cat("|",R[,i],"|\n",sep="");cat(z)}

Mit Einrückungen und Zeilenumbrüchen:

f=function(a){
    s=strsplit
    C=matrix(as.integer(sapply(strtoi(el(s(a,":")),16),intToBits)[1:8,]),2)
    C[!C]=-1
    n=c(17,9)
    R=array(0,n)
    w=c(9,5)
    for(i in 1:64){
        w=w+C[,i]
        w[w<1]=1
        w[w>n]=n[w>n]
        x=w[1]
        y=w[2]
        R[x,y]=R[x,y]+1
    }
    R[]=el(s(" .o+=*BOX@%&#/^",""))[R+1]
    R[9,5]="S"
    R[x,y]="E"
    z="+-----------------+\n"
    cat(z)
    for(i in 1:9)cat("|",R[,i],"|\n",sep="")
    cat(z)
}

Verwendungszweck:

> f("16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48")
+-----------------+
|        .        |
|       + .       |
|      . B .      |
|     o * +       |
|    X * S        |
|   + O o . .     |
|    .   E . o    |
|       . . o     |
|        . .      |
+-----------------+
> f("37:e4:6a:2d:48:38:1a:0a:f3:72:6d:d9:17:6b:bd:5e")
+-----------------+
|                 |
|                 |
|          .      |
|     .   o       |
|o . o . S +      |
|.+ + = . B .     |
|o + + o B o E    |
| o .   + . o     |
|         .o      |
+-----------------+

Können Sie die 'Matrix'-Funktion nicht Golf spielen, indem Sie sie einmal als' m 'definieren? Gleiches für 'Funktion'?
CousinCocaine

Ich denke, Sie brauchen nicht "sep =" in der "Katze" -Funktion
CousinCocaine

Der Standard für Sep ist ein Leerzeichen, daher muss ich es überschreiben, aber in der Tat könnte ich eine Alias-Matrix verwenden.
Plannapus

Außerdem, soweit ich weiß, kann man nicht alias function.
Plannapus

5

Oktave, 277

d=reshape(rot90(dec2bin(hex2dec(strsplit(input('','s'),':'))))>'0',2,[])*2-1;p=[9;5];for m=1:64 p=[max(min(p(:,1)+d(:,m),[17;9]),1) p];end;A=' .o+=*BOX@%&#/^SE';F=A(sparse(p(2,:),p(1,:),1,9,17)+1);F(5,9)='S';F(p(2,1),p(1,1))='E';[a='+-----------------+';b=['|||||||||']' F b;a]

Erläuterung:

%// convert the input to binary and rearrange it to be
%//   an array of vectors: [x_displacement; y_displacement]
d=reshape(rot90(dec2bin(hex2dec(strsplit(input('','s'),':'))))>'0',2,[])*2-1;

%// start position array with vector for the start position
p=[9;5];
%// for each move, add displacement, clamping to valid values
for m=1:64 p=[max(min(p(:,1)+d(:,m),[17;9]),1) p];end;

%// alphabet for our fingerprint
A=' .o+=*BOX@%&#/^SE';

%// create a sparse matrix, accumulating values for duplicate
%// positions, and replace counts with symbols
F=A(sparse(p(2,:),p(1,:),1,9,17)+1);

%// correct the start and end symbols and construct the final output
F(5,9)='S';F(p(2,1),p(1,1))='E';
[a='+-----------------+';b=['|||||||||']' F b;a]

Probelauf:

>> bish
b6:dd:b7:1f:bc:25:31:d3:12:f4:92:1c:0b:93:5f:4b
ans =

+-----------------+
|            o.o  |
|            .= E.|
|             .B.o|
|              .= |
|        S     = .|
|       . o .  .= |
|        . . . oo.|
|             . o+|
|              .o.|
+-----------------+

3

Pyth, 145 143 140

Jm*17]09A,4K8FYcz\:V4AmhtS[0^2d+@,HGdtyv@+_.BiY16*7\0+-4dyN),3 4 X@JGHh@@JGH; X@J4K15 X@JGH16
=Y++\+*17\-\+VJ++\|s@L" .o+=*BOX@%&#/^SE"N\|)Y

Probieren Sie es online aus.

Pyth kann mit Iterationen nicht wirklich gut umgehen. Ich erwarte, dass CJam es leicht schlägt.


3

JavaScript (ES6) 249 208

Bearbeiten Fehlender Rand hinzugefügt

Testen Sie das folgende Snippet in einem beliebigen EcmaScript 6-kompatiblen Browser

B=f=>f.replace(/\w+/g,b=>{for(b=`0x1${b}`;b-1;b>>=2)++g[p=(q=(p=(q=p+~-(b&2)*18)>0&q<162?q:p)+b%2*2-1)%18?q:p]},p=81,z=`+${'-'.repeat(17)}+`,g=Array(162).fill(0))&&g.map((v,q)=>q?q-81?q-p?q%18?' .o+=*BOX@%&#/^'[v]:`|
|`:'E':'S':z+`
|`).join``+`|
`+z

// TEST
console.log=x=>O.innerHTML+=x+'\n'

;['37:e4:6a:2d:48:38:1a:0a:f3:72:6d:d9:17:6b:bd:5e'
,'16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48'
,'b6:dd:b7:1f:bc:25:31:d3:12:f4:92:1c:0b:93:5f:4b'
,'05:1e:1e:c1:ac:b9:d1:1c:6a:60:ce:0f:77:6c:78:47'  
].forEach(t=>console.log(t+'\n'+B(t)+'\n'))


// Less golfed

BB=f=>(
  p = 81,
  g = Array(162).fill(0),
  f.replace(/\w+/g, b => {
    for(b = `0x1${b}`;b != 1; b >>= 2)
      q = p+~-(b&2)*18,
      p = q>0&q<162?q:p,
      p = (q=p+b%2*2-1)%18?q:p,
      ++g[p]
  }),
  g.map((v,q) => q-81?q-p?q%18?' .o+=*BOX@%&#/^'[v]:'\n':'E':'S')
  .join``
)
pre { font-family: menlo,consolas; font-size:13px }
<pre id=O></pre>


Ihr Golfcode selbst sollte in der Lage sein, auch die Ränder zu drucken. Derzeit druckt nur Ihr Testfall die oberen und unteren Ränder in forEach, die vertikalen Ränder fehlen noch.
Padarom

@Padarom Ich habe Ihren "vernünftig sein" Kommentar falsch verstanden und dachte, dass die Grenze nicht angefordert wurde
edc65

Ich wollte vernünftig sein, welche Methode der Eingabe und Ausgabe Sie verwenden. Ich entschuldige mich, wenn das irreführend war, ich werde es
korrigieren

3

Python, 381 328

-51 danke an @JonathanFrech

def h(f):
 s=[f'{int(o,16)>>s&3:02b}'for o in f.split(':')for s in(0,2,4,6)];r=[0]*153;p=76;w=17
 for d in s:r[p]+=1;p+=(-(p%w!=0),p%w!=16)[int(d[1])]+(-w*(p//w!=0),w*(p//w!=8))[int(d[0])]
 r[76]=15;r[p]=16;b='+'+'-'*w+'+';print(b);i=0
 while i<153:print(f"|{''.join(' .o+=*BOX@%&#/^SE'[c]for c in r[i:i+w])}|");i+=w
 print(b)

Zur Erklärung etwas ungolfed:

def h_(f):
 #Alias 17 because it gets used enough times for this to save bytes
 w=17

 #Input parsing
 s=[f'{int(o,16)>>s&3:02b}'for o in f.split(':')for s in(0,2,4,6)]

 #Room setup
 r=[0]*153
 p=76

 #Apply movements
 for d in s:
  r[p]+=1
  p+=(-(p%w!=0),p%w!=16)[int(d[1])]+(-w*(p//w!=0),w*(p//w!=8))[int(d[0])]
 r[76]=15 #Set start position
 r[p]=16 #Set end position

 #Display result
 b='+'+'-'*w+'+'
 print(b)
 i=0
 while i<153:
  print(f"|{''.join(' .o+=*BOX@%&#/^SE'[c]for c in r[i:i+w])}|")
  i+=w
 print(b)

Dieses Durcheinander einer Linie:

r[p]+=1;p+=(-(p%w!=0),p%w!=16)[int(d[1])]+(-w*(p//w!=0),w*(p//w!=8))[int(d[0])]

Ist funktional äquivalent dazu:

if int(d[0]): #Down, Y+
  if p//17!=8:
    p+=17
else: #Up, Y-
  if p//17!=0:
    p-=17
​
if int(d[1]): #Right, X+
  if p%17!=16:
    p+=1
else: #Left, X-
  if p%17!=0:
    p-=1

Aber in dieser Art von Golf-Abkürzung (false_value,true_value)[condition] nisten alle Bedingungen: Der Rest ist hoffentlich ziemlich selbsterklärend

Tests

h('16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48')
+-----------------+
|        .        |
|       + .       |
|      . B .      |
|     o * +       |
|    X * S        |
|   + O o . .     |
|    .   E . o    |
|       . . o     |
|        . .      |
+-----------------+

h("b6:dd:b7:1f:bc:25:31:d3:12:f4:92:1c:0b:93:5f:4b")
+-----------------+
|            o.o  |
|            .= E.|
|             .B.o|
|              .= |
|        S     = .|
|       . o .  .= |
|        . . . oo.|
|             . o+|
|              .o.|
+-----------------+

h("05:1e:1e:c1:ac:b9:d1:1c:6a:60:ce:0f:77:6c:78:47")
+-----------------+
|       o=.       |
|    o  o++E      |
|   + . Ooo.      |
|    + O B..      |
|     = *S.       |
|      o          |
|                 |
|                 |
|                 |
+-----------------+
```

Hallo und willkommen bei PPCG. Sie können Ihren Code mit einbuchstabigen Variablennamen und einer einzeiligen for-Schleife in eine Zeile einteilen. (1,0)[p%17==16]ist +(p%17!=16), oder möglicherweise sogar p%17!=16.
Jonathan Frech

Darüber hinaus gibt es einen überflüssigen Raum in ] for.
Jonathan Frech

Ich denke fpsollte sein f.
Jonathan Frech


2
Warum habe ich verwendet ~16? Ein bisschen Verschleierung kann Ihrem Golf niemals schaden!
Jonathan Frech

2

Rubin 288

->k{w=17
r=[z=?++?-*w+?+]
(0...w*9).each_slice(w).map{|o|r<<?|+o.map{|x|c=76
q=0
k.split(?:).flat_map{|b|(0..7).map{|i|b.to_i(16)[i]}}.each_slice(2){|h,v|v<1?(c>w&&c-=w):c<w*8&&c+=w
c+=h<1?c%w>0?-1:0:c%w<16?1:0
c==x&&q+=1}
x==76?'S':c==x ?'E':' .o+=*BOX@%&#/^'[q]}.join+?|}
(r+[z]).join'
'}

Probieren Sie es online aus: http://ideone.com/QOHAnM

Die lesbare Version (von der ich angefangen habe zu golfen) ist hier: http://ideone.com/XR64km


2

C - 488

Es muss einen Weg geben, dies kleiner zu machen ....

#include<stdio.h>
#define H ++p;h[i]|=(*p-(*p>58?87:48))<<
#define B ((h[j]>>n*2)&3)
#define L puts("+-----------------+")
#define F(m,s)for(m=0;m<s;m++)
int h[16],m[17][9],i,j,n,x=8,y=4;main(w,v)char**v;{char*p=v[1]-1,c[17]={32,46,111,43,61,42,66,79,88,64,37,38,35,47,94,83,69};for(;*p;p++,i++){H 4;H 0;}F(j,16)F(n,4){if(B&1)x+=!(x==16);else x-=!(x==0);if(B&2)y+=!(y==8);else y-=!(y==0);m[x][y]++;}m[8][4]=15;m[x][y]=16;L;F(i,9){printf("|");F(j,17)printf("%c",c[m[j][i]]);puts("|");}L;}

0

Rust - 509 Bytes

fn b(s:&str)->String{let(mut v,mut b)=([[0;11];20],[9,5]);v[19]=[19;11];for i in 0..16{let mut c=usize::from_str_radix(&s[i*3..i*3+2],16).unwrap();for k in 0..4{for j in 0..2{v[j*18][i%9+1]=18;v[i+k][j*10]=[17,3][(i+k+17)%18/17];b[j]=match(if c&(j+1)==j+1{b[j]+1}else{b[j]-1},j,){(0,_)=>1,(18,0)=>17,(10,1)=>9,x@_=>x.0 as usize,}}v[b[0]][b[1]]+=1;c>>=2;}}v[9][5]=15;v[b[0]][b[1]]=16;(0..220).fold("\n".to_string(),|s,i|{format!("{}{}",s," .o+=*BOX@%&#/^SE-|\n".chars().nth(v[i%20][i/20] as usize).unwrap())})}

Groß, aber ... fast in der Nähe von C. Wie üblich sind viele Bytes verbraucht, da Rust Typen nicht automatisch ineinandergreift. Aber es gibt wahrscheinlich auch Verbesserungspotential .... könnte wahrscheinlich einige Ideen von anderen Lösungen gebrauchen.

Die ungolfed version ist auf dem Rust Playground online

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.