Pijany Biskup

42

W kryptografii klucza publicznego odcisk palca klucza publicznego to krótka sekwencja bajtów używana do identyfikacji dłuższego klucza publicznego.

W szczególności w SSH można ich użyć do sprawdzenia, czy serwer jest w rzeczywistości serwerem, z którym mam się komunikować i że nie jestem atakowany przez man-in-the-middle.

Zazwyczaj są one przedstawiane jako ciąg cyfr szesnastkowych, więc porównywanie go z odciskiem palca, którego bym się spodziewał, może być nudne i żmudne:

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

Aby to trochę ułatwić, OpenSSH wprowadził metodę wizualizacji odcisków palców jako sztuki ASCII, która wyglądałaby następująco:

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

Dzięki temu mogłem spróbować zapamiętać szorstki kształt sztuki ASCII, a następnie (teoretycznie) rozpoznać ją, gdy zmienił się odcisk palca serwera i obraz wygląda inaczej.

Jak to działa

Zaczerpnięte z Dirk Loss, Tobias Limmer, Alexander von Gernler. 2009. Pijany biskup: Analiza algorytmu wizualizacji odcisków palców OpenSSH .

Siatka ma szerokość 17 znaków i wysokość 9 znaków. „Biskup” zaczyna się w rzędzie 4 / kolumnie 8 (środek). Każda pozycja może być oznaczona jako [x, y], tj. [8,4] dla pozycji początkowej biskupa.

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

Biskup używa odcisku palca, aby się poruszać. Odczytuje bajty od lewej do prawej i od najmniej znaczącego do najbardziej znaczącego:

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

Biskup wykona następujący plan:

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

Przypadki specjalne:

  • Jeśli biskup znajduje się w kącie i ponownie się w nie ruszy, w ogóle się nie rusza. tj .: Biskup jest w, [0,0]a jego następnym krokiem będzie 00. On pozostaje w[0,0]
  • Jeśli biskup jest w rogu lub pod ścianą i porusza się do jednej ze ścian, porusza się tylko poziomo lub pionowo. tj .: Biskup jest w, [0,5]a jego następnym krokiem będzie 01. Nie może iść w lewo, więc po prostu przesuwa się w górę, do [0,4].

Każda pozycja zawiera wartość tego, jak często biskup odwiedzał to pole:

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 |

Wartości 15 (S) i 16 (E) są wyjątkowe, ponieważ oznaczają odpowiednio pozycję początkową i końcową biskupa i zastępują rzeczywistą wartość pozycji szacunku.

Cel

Utwórz program, który pobiera alfanumeryczny odcisk palca jako dane wejściowe i tworzy reprezentację graficzną ASCII, jak pokazano w przykładach.

Przykłady

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          |
|                 |
|                 |
|                 |
+-----------------+

Zasady

  • To jest . Kod w najmniejszej liczbie bajtów wygrywa.
  • Można nie korzystać z istniejącej biblioteki, która wytwarza obraz.
  • Używaj dowolnego preferowanego języka!
  • Twoje zgłoszenie musi być kompletnym programem
Padarom
źródło
3
Czy możemy założyć, że żadna komórka nie będzie odwiedzana więcej niż 14 razy?
Martin Ender
2
Istnieje kilka narożnych przypadków minimalnego zasięgu, które spowodowałyby, że kilka pól byłoby odwiedzanych ponad 14 razy. 33:33:33:...:33, cc:cc:cc:...:ccbyłyby tego przykłady. Odcisk palca jest zwykle skrótem MD5, więc bardzo mało prawdopodobne jest uzyskanie takiego wyniku. Nie znalazłem żadnych wiarygodnych źródeł, jak sobie z nimi radzić, więc na razie powiem: Załóżmy, że żadna komórka nie będzie odwiedzana więcej niż 14 razy.
Padarom,

Odpowiedzi:

2

Pyth, 125 bajtów

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

Wypróbuj online: wersja demonstracyjna lub pakiet testowy

Napisałem kilka dni temu, ale nie opublikowałem tego, ponieważ nie byłem z tego powodu szczęśliwy.

Wyjaśnienie:

Podstawowa idea jest następująca. Zaczynam od pary (4, 8). W każdym ruchu (m1,m2)przechodzę od (x, y)do (x-1+2*m1, y-1+2*m2). Aby upewnić się, że te współrzędne nie chodzą poza granicami, zrobię jakieś listy, sortować je i powrócić element środkowy: (sorted(0,8,newx)[1], sorted(0,16,newy)[1]).

Śledzę wszystkie pozycje. Do tej listy pozycji dodaję listę wszystkich możliwych pozycji, sortuję je i koduję według długości. Co daje mi numer dla każdej pozycji. Za pomocą tego numeru mogę wybrać znak „coorect”, a na końcu zastąpić znaki pozycji początkowej i końcowej.

Jakube
źródło
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'}¨⍵⊂⍨':'≠⍵}

Jest to funkcja, która przyjmuje ciąg jako prawidłowy argument i zwraca macierz znaków zawierającą reprezentację graficzną ASCII, np .:

      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.|
+-----------------+

Wyjaśnienie:

  • ⎕ML←3: ustaw ⎕MLna 3. To sprawia, że ​​jest bardziej przydatny do dzielenia ciągów.

  • F←9 17⍴0: utwórz macierz zer 17 na 9. Freprezentuje ile razy każda pozycja została odwiedzona.

  • ⍵⊂⍨':'≠⍵: podział na :postacie.

  • {... : dla każdej grupy:
    • ¯1+⍵⍳⍨⎕D,'abcdef': znajdź indeks każdego znaku w ciągu '01234567890abcdef'. Odejmij 1, ponieważ APL jest domyślnie indeksowany jako 1.
    • (4/2)⊤: przekonwertuj wartości na ich reprezentacje 4-bitowe (powinna być teraz matryca 2 na 4).
    • ↓⊖4 2⍴⍉: obróć matrycę, użyj elementów, aby zamiast tego wypełnić matrycę 2 na 4, wykonaj lustrzane odbicie matrycy w poziomie, a następnie pobierz każdą linię osobno. To daje nam 4 2-bitowe wartości, których potrzebujemy.
  • ⊃,/: połącz wynikowe listy razem, podając listę 2-bitowych kroków.
  • 5 9{... }: biorąc pod uwagę listę kroków i zaczynając od pozycji [9,5]:
    • (⍺⌷F)+←1: zwiększ aktualną pozycję w F.
    • ×⍴⍵:: jeśli lista kroków nie jest pusta:
      • ↑⍵: zrób pierwszy krok z listy
      • ⍺-1 1-2×: pobierz deltę dla tego kroku i odejmij ją od bieżącej pozycji
      • 1 1⌈9 17⌊: ogranicz ruch w obrębie pola
      • (... )∇1↓⍵: kontynuuj z nową pozycją i resztą kroków
    • Jeśli jest pusty:
      • (⍺⌷F)←16: ustaw Fna 16 w pozycji końcowej
      • F[5;9]←15: ustaw Fna 15 w pozycji początkowej
      • ' .o+=*BOX@%&#/^SE'[1+F]: zamapuj każdą pozycję na odpowiedni znak
      • K⍪(M,... ,M←'|')⍪K←'+','+',⍨17⍴'-': zawiń wynik w wiersze
marinus
źródło
8

Perl, 300 + 1 (-n) = 301 bajtów

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'

Ta odpowiedź jest obrzydliwa, ale jest też pierwsza dla tej układanki, więc na razie wystarczy.

-nwziąć wiersz danych wejściowych STDIN i wypełnić $_.

# 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
Eric Wastl
źródło
7

R, 465 459 410 393 382 357 bajtów

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

Z wcięciami i znakami nowej linii:

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

Stosowanie:

> 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      |
+-----------------+
plannapus
źródło
Nie możesz zagrać w golfa w funkcję macierzy, definiując ją raz jako „m”? To samo dla „funkcji”?
CousinCocaine
Myślę, że nie potrzebujesz „sep =” w funkcji „cat”
CousinCocaine
domyślną wartością sep jest spacja, więc muszę ją przesłonić, ale rzeczywiście mógłbym uzyskać alias matrix.
plannapus
Dodatkowo, o ile mi wiadomo, nie można pseudonimu function.
plannapus
5

Oktawa, 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]

Wyjaśnienie:

%// 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]

Przykładowy przebieg:

>> 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.|
+-----------------+
zlewka
źródł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

Wypróbuj online.

Pyth nie jest zbyt dobry w wyzwaniach związanych z iteracją. Spodziewam się, że CJam łatwo to pokona.

PurkkaKoodari
źródło
3

JavaScript (ES6) 249 208

Edytuj Dodano brakującą ramkę

Przetestuj poniższy fragment kodu w dowolnej przeglądarce zgodnej z EcmaScript 6

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>

edc65
źródło
Twój kod do gry w golfa powinien być w stanie również drukować ramki. Obecnie tylko twój przypadek testowy drukuje górną i dolną ramkę w forEach, nadal brakuje pionowych ramek.
Padarom,
@Padarom Nie zrozumiałem twojego komentarza „bądź rozsądny”, myśląc, że nie poprosiłem o
granicę
Miałem na myśli rozsądny wybór metody wejścia i wyjścia. Przepraszam, jeśli to było mylące,
zredaguję
3

Python, 381 328

-51 dzięki @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)

Nieco golfa dla wyjaśnienia:

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)

Ten bałagan na linii:

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

Jest funkcjonalnie równoważny z tym:

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

ale zawiera wszystkie warunki warunkowe w tym skrócie golfowym: (false_value,true_value)[condition] Mam nadzieję, że reszta jest dość oczywista

Testy

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          |
|                 |
|                 |
|                 |
+-----------------+
```
senox13
źródło
Witam i witam w PPCG. Możesz golfować swój kod, używając jednoliterowych nazw zmiennych i umieszczając pojedynczą linię dla pętli w jednej linii. (1,0)[p%17==16]jest +(p%17!=16), a może nawet p%17!=16.
Jonathan Frech
Ponadto istnieje niepotrzebna przestrzeń ] for.
Jonathan Frech
Myślę, że fppowinno być f.
Jonathan Frech
330 bajtów .
Jonathan Frech
2
Dlaczego użyłem ~16? Odrobina zaciemnienia nigdy nie zaszkodzi twojemu golfowi!
Jonathan Frech
2

Rubinowy 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'
'}

Wypróbuj online: http://ideone.com/QOHAnM

Czytelna wersja (ta, od której zacząłem grać w golfa) znajduje się tutaj: http://ideone.com/XR64km

Cristian Lupascu
źródło
2

C - 488

Musi istnieć sposób na zmniejszenie tego ...

#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;}
Jerry Jeremiasz
źródło
0

Rdza - 509 bajtów

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

Duży, ale ... prawie zbliżony do C. Jak zwykle zużytych jest wiele bajtów ze względu na to, że Rust nie rzuca się w siebie automatycznie. Ale prawdopodobnie jest też miejsce na ulepszenia ... prawdopodobnie przydałoby się kilka pomysłów innych rozwiązań.

wersja bez gry jest na Rust Playground online

Don Bright
źródło