Hexplosive ASCII-Kunst Herausforderung

20

Im Strategiespiel "Hexplode" legen die Spieler abwechselnd Spielsteine auf ein sechseckiges Brett. Sobald die Anzahl der Spielsteine ​​gleich der Anzahl der benachbarten Spielsteine ​​ist, wird dieser Spielstein hexplodiert und alle Spielsteine ​​darauf werden zu den umliegenden Nachbarn bewegt. Sie können das Spiel hier online spielen .

Ich mag dieses Spiel, aber manchmal ist es schwierig, genau zu wissen, wie viele Spielsteine ​​auf einem bestimmten Plättchen liegen. Ich zähle immer die Anzahl der Nachbarn. Es wäre sehr praktisch, wenn ich eine ASCII-Grafik hätte, um mich daran zu erinnern, wie viele Token auf jedem Plättchen liegen.

Sie müssen ein Programm oder eine Funktion schreiben, die eine positive Ganzzahl als Eingabe verwendet und diese ASCII-Darstellung des Hexagons der Größe N erzeugt . Jedes Plättchen ist die Anzahl der Nachbarn, die das Plättchen hat. Da 1 ein seltsamer Eckfall mit null Nachbarn ist, müssen Sie nur Eingaben verarbeiten, die größer als 1 sind.

Sie können diese Zahl in jedem vernünftigen Format verwenden, z. B. STDIN, Funktionsargumente, Befehlszeilenargumente, aus einer Datei usw. Die Ausgabe kann auch in jedem vernünftigen Format erfolgen, z. B. Drucken in STDOUT, Schreiben in eine Datei, Zurückgeben eine Liste von Zeichenfolgen, eine durch Zeilenumbrüche getrennte Zeichenfolge usw.

Hier einige Beispiele für die ersten 5 Eingänge:

2)

 3 3
3 6 3
 3 3


3)

  3 4 3
 4 6 6 4
3 6 6 6 3
 4 6 6 4
  3 4 3


4)

   3 4 4 3
  4 6 6 6 4
 4 6 6 6 6 4
3 6 6 6 6 6 3
 4 6 6 6 6 4
  4 6 6 6 4
   3 4 4 3

5)

    3 4 4 4 3
   4 6 6 6 6 4
  4 6 6 6 6 6 4
 4 6 6 6 6 6 6 4
3 6 6 6 6 6 6 6 3
 4 6 6 6 6 6 6 4
  4 6 6 6 6 6 4
   4 6 6 6 6 4
    3 4 4 4 3

6)

     3 4 4 4 4 3
    4 6 6 6 6 6 4
   4 6 6 6 6 6 6 4
  4 6 6 6 6 6 6 6 4
 4 6 6 6 6 6 6 6 6 4
3 6 6 6 6 6 6 6 6 6 3
 4 6 6 6 6 6 6 6 6 4
  4 6 6 6 6 6 6 6 4
   4 6 6 6 6 6 6 4
    4 6 6 6 6 6 4
     3 4 4 4 4 3

Und das Muster setzt sich auf ähnliche Weise fort. Wie üblich gelten Standardlücken, und die Antwort mit der niedrigsten Byteanzahl wird zum Gewinner gekürt!

Bestenlisten

Hier ist ein Stack-Snippet, um sowohl eine reguläre Rangliste als auch eine Übersicht der Gewinner nach Sprache zu erstellen.

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Wenn Sie mehrere Zahlen in Ihre Kopfzeile aufnehmen möchten (z. B. weil Ihre Punktzahl die Summe von zwei Dateien ist oder wenn Sie die Strafen für Interpreter-Flags separat auflisten möchten), stellen Sie sicher, dass die tatsächliche Punktzahl die letzte Zahl in der Kopfzeile ist:

# Perl, 43 + 2 (-p flag) = 45 bytes

Sie können den Namen der Sprache auch als Link festlegen, der dann im Leaderboard-Snippet angezeigt wird:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

DJMcMayhem
quelle
1
Verwandte (aber Fragen über den Prozess und nicht die Anzahl der Nachbarn).
Trichoplax
1
Ich bin versucht, Hexagony zu lernen, nur um dieser Herausforderung willen. ;)
Kevin Cruijssen

Antworten:

11

MATL , 39 37 Bytes

4*3-:!G:+o~YRtP*!tPw4LY)vtI5&lZ+47+*c

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erläuterung

Ich kann Faltung wieder benutzen!

Betrachten Sie die Eingabe n = 3. Der Code erstellt zunächst eine Matrix der Größe 4*n-3×, nindem er den Spaltenvektor [1; 2; ...; 9]dem Zeilenvektor [1, 2, 3]mit Rundsendung hinzufügt . Dies bedeutet, dass ein 2D-Array-Array aller paarweisen Additionen berechnet wird:

 2  3  4
 3  4  5
 4  5  6
 5  6  7
 6  7  8
 7  8  9
 8  9 10
 9 10 11
10 11 12

Durch Ersetzen von geraden 1und ungeraden Zahlen 0erhält man ein Schachbrettmuster

1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1

Dies wird zum Erzeugen (eines Teils) des hexagonalen Gitters verwendet. Einsen stellen Punkte im Raster dar, und Nullen stellen Leerzeichen dar.

Die obere rechte Ecke wird entfernt, indem alle Einträge über der Hauptdiagonale der Matrix auf Null gesetzt werden:

1 0 0
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1

Elementweise Multiplikation dieser Matrix mit einer vertikal gespiegelten Version von sich selbst entfernt auch die untere rechte Ecke. Transponieren gibt dann

1 0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 1 0 0

Dies fängt an, wie ein Sechseck auszusehen. Unter Verwendung der Symmetrie wird das Gitter erweitert, um die obere Hälfte zu erzeugen:

0 0 1 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0
1 0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 1 0 0

Jetzt müssen wir jeden Eintrag gleich eins durch die Anzahl der Nachbarn ersetzen. Hierfür verwenden wir die Faltung mit einer 3 × 5-Nachbarschaft (das heißt, der Kernel ist eine 3 × 5-Matrix von Einsen). Das Ergebnis,

2 3 4 5 5 5 4 3 2
4 5 7 7 8 7 7 5 4
4 6 7 8 7 8 7 6 4
4 5 7 7 8 7 7 5 4
2 3 4 5 5 5 4 3 2

hat zwei Probleme (die später behoben werden):

  1. Die Werte wurden für alle Positionen berechnet, während wir sie nur an den Positionen der Positionen im Null-Eins-Raster benötigen.
  2. Für jede dieser Positionen enthält die Nachbarzählung den Punkt selbst, so dass die Abweichung um ist 1.

Der Code addiert nun 47zu jedem berechneten Wert. Dies entspricht dem Subtrahieren 1, um das Problem (2) zu lösen, und dem Addieren 48(ASCII für '0'), wodurch jede Zahl in den Codepunkt des entsprechenden Zeichens konvertiert wird.

Die resultierende Matrix wird dann mit einer Kopie des Null-Eins-Gitters multipliziert. Dies löst das obige Problem (1), indem die Punkte, die nicht Teil des hexagonalen Gitters sind, wieder gleich Null werden:

 0  0 51  0 52  0 51  0  0
 0 52  0 54  0 54  0 52  0
51  0 54  0 54  0 54  0 51
 0 52  0 54  0 54  0 52  0
 0  0 51  0 52  0 51  0  0

Schließlich wird dieses Zahlenfeld in ein Zeichenfeld umgewandelt. Null-Zeichen werden als Leerzeichen angezeigt, was das Endergebnis ergibt:

  3 4 3  
 4 6 6 4 
3 6 6 6 3
 4 6 6 4 
  3 4 3  
Luis Mendo
quelle
15

JavaScript (ES6), 118 bis 117 Byte

n=>[...Array(m=n+--n)].map((_,i,a)=>a.map((_,j)=>(k=j-(i>n?i-n:n-i))<0?``:k&&++j<m?i/2%n?6:4:3+!i%n).join` `).join`\n`

Wobei \nein buchstäbliches Newline-Zeichen darstellt. Erklärung: Angenommen n=4. Wir beginnen mit dem folgenden durch Leerzeichen getrennten Ziffernquadrat:

0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

Die ersten |n-i| 0s werden gelöscht, aber die Leerzeichen bleiben:

   0 0 0 0
  0 0 0 0 0
 0 0 0 0 0 0
0 0 0 0 0 0 0
 0 0 0 0 0 0
  0 0 0 0 0
   0 0 0 0

Sofortiges Sechseck! Es reicht dann aus, den entsprechenden Wert zu berechnen, 0indem Sie prüfen, ob wir uns in der ersten oder letzten Zeile und / oder Spalte befinden. Bearbeiten: 1 Byte dank @Arnauld gespeichert.

Neil
quelle
Unter Verwendung einiger Ihrer Formeln kam ich mit for / console.log () zu einer 107-Byte-Version:n=>{for(i=n+--n;i--;)console.log(' '.repeat(l=i>n?i-n:n-i)+(j=3+!l%n)+` ${l-n?6:4}`.repeat(2*n-l-1)+' '+j)}
Arnauld
@Arnauld Das gefällt mir 3+!i%n!
Neil
7

Python 2, 125 123 Bytes

def h(n):m=n-1;t=[' '*(m-r)+' '.join(('46'[r>0]*(r+m-1)).join('34'[r%m>0]*2))for r in range(n)];print'\n'.join(t+t[-2::-1])

Tests sind auf ideone

Läuft durch die oberen bis mittleren Reihen und for r in range(n)baut Fäden:
- Zwei Ecken oder zwei Kanten '34'[r%m>0]*2;
- Füllen von ihnen mit wiederholtem Beitritt '6'oder '4', '46'[r>0]*(r+m-1);
- Verbinden der Ecken und Kanten mit ' ';
- Leerzeichen voranstellen ' '*(m-r);

Dann druckt dies und es ist Spiegelbild in der mittleren Reihe durch neue Linien verbunden, print'\n'.join(t+t[-2::-1])

Jonathan Allan
quelle
4

Python 2, 96 Bytes

n=input();m=n-1
while n+m:n-=1;j=abs(n);c='34'[0<j<m];print' '*j+c+' '+'46  '[j<m::2]*(2*m+~j)+c

Das sieht ziemlich chaotisch und etwas golfen aus ...

Sp3000
quelle
3

Java, 375 363 361 339 329 317 293 Bytes

interface J{static void main(String[]r){int i=0,k,h=Integer.decode(r[0]),a=1,l,n=0;for(;i++<h*2-1;n+=a){if(n==h-1)a=-1;String s="";for(k=0;k<n+h;k++,s+=" ")s+=n==0?k==0||k==n+h-1?3:4:k!=0&&k!=n+h-1?6:n==h-1?3:4;l=(h*4-3-s.trim().length())/2;System.out.printf((l==0?"%":"%"+l)+"s%s\n","",s);}}}

Ungolfed

interface J {
    static void main(String[] r) {
        int i = 0, k, h = Integer.decode(r[0]), a = 1, l, n = 0;
        for (; i++ < h * 2 - 1; n += a) {
            if (n == h - 1) {
                a = -1;
            }
            String s = "";
            for (k = 0; k < n + h; k++, s += " ") {
                s += n == 0 ? k == 0 || k == n + h - 1 ? 3 : 4 : k != 0 && k != n + h - 1 ? 6 : n == h - 1 ? 3 : 4;
            }
            l = (h * 4 - 3 - s.trim().length()) / 2;
            System.out.printf((l == 0 ? "%" : "%" + l) + "s%s\n", "", s);
        }
    }
}

Verwendung :

$ java J 5
    3 4 4 4 3     
   4 6 6 6 6 4    
  4 6 6 6 6 6 4   
 4 6 6 6 6 6 6 4  
3 6 6 6 6 6 6 6 3 
 4 6 6 6 6 6 6 4  
  4 6 6 6 6 6 4   
   4 6 6 6 6 4    
    3 4 4 4 3

Ich bin sicher, dass der schreckliche verschachtelte if-else-Block kleiner geschrieben werden kann, aber ich kann es im Moment nicht herausfinden. Anregungen sind willkommen :-)

Aktualisieren

  • Folgen Sie dem Vorschlag von Kevin Cruijssen und verwenden Sie decode anstelle von parseInt.
  • Schrieb einige ifs mit dem ternären Operator um.
  • Weitere ternäre Operatoren.
  • Moar ternäre Operatoren! Ich glaube ich habe ein Monster erschaffen!
  • Schrieb den if-else-Block bezüglich des Drucks um.
Master_ex
quelle
1
Ich habe mir die Methode, die Sie selbst Integer.parseIntanwenden, nicht so genau angesehen, aber ein paar kleine Golftipps für Ihren aktuellen Code: Kann zum Golfen verwendet werden Integer.decode. l=(h*4-3-s.trim().length())/2;if(l==0)kann golfen werden if((l=(h*4-3-s.trim().length())/2)==0). Es ist auch völlig akzeptabel, nur eine Methode ohne Klasse zu veröffentlichen (sofern in der Frage nichts anderes angegeben ist), sodass Sie void f(int i){...use i...}stattdessen auch interface J{static void main(String[]r){...i=Integer.decode(r[0])...use i...}einige Bytes einsparen sollten. Wenn ich mehr Zeit habe, schaue ich weiter.
Kevin Cruijssen
@ KevinCruijssen: Vielen Dank für Ihre Vorschläge. l=(h*4-3-s.trim().length())/2;if(l==0)ist eigentlich gleich lang mit if((l=(h*4-3-s.trim().length())/2)==0).
Master_ex
2

05AB1E , 44 Bytes

FN_i4ë6}ð«¹ÍN+×ðìN_N¹<Q~i3ë4}.ø¹<N-ð×ì})¦«»

Erläuterung

Da die Ober- und Unterseite des Sechsecks gespiegelt sind, müssen wir nur den oberen Teil erzeugen.
Für eine Eingabe von X müssen wir also X- Zeilen generieren . Das macht die Hauptschleife.

F                                        }

Dann machen wir den mittleren Teil der Zeilen.
Dies ist 4 für die erste Reihe und 6 für den Rest (da wir nur den oberen Teil machen).
Wir verketten diese Zahl mit einem Leerzeichen, da das Muster einen Abstand zwischen den Zahlen erfordert.

N_i4ë6}ð«

Dann wiederholen wir diese Zeichenfolge X-2 + N- mal, wobei N die aktuelle Zeile mit dem Index 0 ist, und stellen links ein Leerzeichen voran.

¹ÍN+×ðì

Danach ist es Zeit für die Ecken. Sie sind 3 für die erste und letzte Reihe und 4 für die mittlere Reihe.

N_N¹<Q~i3ë4}.ø

Jetzt müssen wir sicherstellen, dass die Zeilen richtig ausgerichtet sind, indem wir vor jeder Zeile Leerzeichen einfügen. Die Anzahl der hinzugefügten Leerzeichen ist X-1-N .

¹<N-ð×ì

Nachdem der obere Teil des Rasters fertig ist, fügen wir die Zeilen zu einer Liste hinzu, erstellen eine umgekehrte Kopie und entfernen das erste Element aus dieser Kopie (da wir die mittlere Zeile nur einmal benötigen). Führen Sie dann diese beiden Listen zusammen und drucken.

)¦«»

Probieren Sie es online!

Zusätzliche Lösung, auch 44 Bytes:

ÍÅ10.øvN_i4ë6}ð«¹ÍN+×ðìyi4ë3}.ø¹<N-ð×ì})¦«»
Emigna
quelle
2

Ruby, 87 Bytes

Die anonyme Funktion verwendet n als Argument und gibt ein Array von Zeichenfolgen zurück.

->n{(1-n..n-=1).map{|i|j=i.abs
" "*j+(e=j%n>0?"4 ":"3 ")+["6 ","4 "][j/n]*(2*n-1-j)+e}}

Ungolfed im Testprogramm

Eingabe über stdin. Schreibt die gesamte Form auf stdout. Ziemlich selbsterklärend.

f=->n{
  (1-n..n-=1).map{|i|            #reduce n by 1 and iterate i from -n to n
    j=i.abs;                     #absolute magnitude of i
    " "*j+                       #j spaces +
    (e=j%n>0?"4 ":"3 ")+         #start the string with 3 or 4 +
    ["6 ","4 "][j/n]*(2*n-1-j)+  #2*n-1-j 6's or 4`s as appropriate +
    e                            #end the string with another 3 or 4
  }
}

puts f[gets.to_i]
Level River St
quelle
1

V , 60 Bytes

Àé x@aA4 xr3^.òhYpXa 6^òkyHç^/:m0
Pç 3.*6/^r4$.
òÍ6 4./6

Probieren Sie es online!

Das ist wirklich viel zu lang. Hier ist ein Hexdump, da dieser nicht druckbare Zeichen enthält:

0000000: c0e9 2078 4061 4134 201b 7872 335e 2ef2  .. x@aA4 .xr3^..
0000010: 6859 7058 6120 361b 5ef2 6b79 48e7 5e2f  hYpXa 6.^.kyH.^/
0000020: 3a6d 300a 50e7 2033 2e2a 362f 5e72 3424  :m0.P. 3.*6/^r4$
0000030: 2e0a f2cd 3620 9334 852e 2f36            ....6 .4../6
DJMcMayhem
quelle
1

Schläger, 487 Bytes

(λ(n c e o)(let((sp(append(range(- n 1)-1 -1)(reverse(range(- n 1)0 -1))))
(mm(append(range(- n 2)(-(+ n(- n 1))2))(range(-(+ n(- n 1))2)(-(- n 1)2)-1)))
(r""))(for((i sp)(j mm))(define str"")(for((ss i))(set! str(string-append str" ")))
(set! str(string-append str(if(or(= i 0)(= i(- n 1))(= i(* 2(- n 1))))c e)" "))
(for((jj j))(set! str(string-append str(if(= j(- n 2))e o)" ")))(set! r(if(or(= i 0)
(= i(- n 1))(= i(* 2(- n 1))))c e))(set! str(string-append str r))(displayln str))))

Testen:

(f 4 "3" "4" "6") 

   3 4 4 3
  4 6 6 6 4
 4 6 6 6 6 4
3 6 6 6 6 6 3
 4 6 6 6 6 4
  4 6 6 6 4
   3 4 4 3

(f 5 "o" "*" "-") 

    o * * * o
   * - - - - *
  * - - - - - *
 * - - - - - - *
o - - - - - - - o
 * - - - - - - *
  * - - - - - *
   * - - - - *
    o * * * o

Ausführliche Version:

(define(f1 n c e o)
  (let ((sp(append(range(sub1 n) -1 -1)
                  (reverse(range(sub1 n) 0 -1))))
        (mm(append(range(- n 2)(-(+ n(sub1 n)) 2))
                  (range(-(+ n(sub1 n)) 2)(-(sub1 n)2) -1) ))
        (r ""))
    (for((i sp)(j mm))
      (define str "")
      (for((ss i))(set! str(string-append str " ")))
      (set! str(string-append str
                              (if(or(= i 0)(= i(sub1 n))
                                    (= i(* 2(sub1 n)))) c e)
                              " "))
      (for((jj j))
        (set! str(string-append str
                                (if(= j(- n 2)) e o)
                                " ")))
      (set! r(if(or(= i 0)
                   (= i(sub1 n))
                   (= i(* 2(sub1 n)))) c e))
      (set! str(string-append str r))
      (displayln str))))
rnso
quelle