Hexplosive ASCII-art challenge

20

W grze strategicznej „Hexplode” gracze na zmianę umieszczają żetony na sześciokątnej planszy. Gdy liczba żetonów jest równa liczbie sąsiadujących kafelków, kafle te są heksodami i przenoszą wszystkie zebrane na nim żetony do otaczających sąsiadów. Możesz zagrać w grę online tutaj .

Podoba mi się ta gra, ale czasami trudno jest dokładnie wiedzieć, ile żetonów trafia na konkretny kafelek; Zawsze liczę liczbę sąsiadów. Byłoby bardzo wygodne, gdybym miał grafikę ASCII, która pomogłaby mi zapamiętać, ile tokenów trafia na każdy kafelek.

Musisz napisać program lub funkcję, która pobiera dodatnia jako wejście i tworzy tę reprezentację ASCII sześciokąta o rozmiarze N . Każdy kafelek będzie liczbą sąsiadów, którą ma kafelek. Ponieważ 1 to dziwny przypadek narożny z zerowymi sąsiadami, musisz obsługiwać tylko dane wejściowe większe niż 1.

Możesz wziąć tę liczbę w dowolnym rozsądnym formacie, takim jak STDIN, argumenty funkcji, argumenty wiersza polecenia, z pliku itp. Dane wyjściowe mogą być również w dowolnym rozsądnym formacie, takim jak drukowanie do STDOUT, zapisywanie do pliku, zwracanie lista ciągów, ciąg oddzielony znakiem nowej linii itp.

Oto przykładowe dane wyjściowe dla pierwszych 5 danych wejściowych:

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

I wzór trwa w podobny sposób. Jak zwykle obowiązują standardowe luki, a zwycięzca otrzyma odpowiedź o najniższej liczbie bajtów!

Liderów

Oto fragment kodu, który pozwala wygenerować zarówno zwykłą tabelę wyników, jak i przegląd zwycięzców według języka.

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

# Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:

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

Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie tabeli wyników:

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

DJMcMayhem
źródło
1
Powiązane (ale pytające o proces, a nie o liczbę sąsiadów).
trichoplax
1
Kusi mnie, aby nauczyć się heksagonii tylko ze względu na to wyzwanie. ;)
Kevin Cruijssen

Odpowiedzi:

11

MATL , 39 37 bajtów

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

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie

Znowu używam splotu!

Rozważ wejście n = 3. Kod najpierw buduje macierz wielkości 4*n-3× n, dodając wektor kolumny [1; 2; ...; 9]do wektora wiersza [1, 2, 3]z rozgłoszeniem. Oznacza to obliczenie tablicy tablic 2D wszystkich dodatków parami:

 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

Zastąpienie liczb 1parzystych i nieparzystych przez 0daje wzór szachownicy

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

Zostanie to wykorzystane do wygenerowania (części) siatki heksagonalnej. Jedne będą reprezentować punkty na siatce, a zera będą reprezentować spacje.

Prawy górny róg usuwa się przez wyzerowanie wszystkich wpisów powyżej głównej „przekątnej” matrycy:

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

Mnożenie elementu macierzy przez jej odwróconą pionowo wersję usuwa również prawy dolny róg. Transpozycja następnie daje

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

To zaczyna wyglądać jak sześciokąt. Używając symetrii, siatka jest przedłużana w celu uzyskania górnej połowy:

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

Teraz musimy zastąpić każdy wpis równy jeden przez liczbę sąsiadów. W tym celu używamy splotu z otoczeniem 3 × 5 (tj. Jądro jest macierzą 3 × 5 z nich). Wynik,

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

ma dwa problemy (które zostaną rozwiązane później):

  1. Wartości zostały obliczone dla wszystkich pozycji, podczas gdy potrzebujemy ich tylko w pozycjach tych w siatce zero-jedynkowej.
  2. Dla każdej z tych pozycji liczba sąsiadów obejmuje sam punkt, więc jest wyłączony o 1.

Kod dodaje teraz 47do każdej obliczonej wartości. Odpowiada to odejmowaniu w 1celu rozwiązania problemu (2) i dodawaniu 48(ASCII dla '0'), co konwertuje każdą liczbę do punktu kodowego odpowiadającego jej znaku.

Otrzymana macierz jest następnie mnożona przez kopię siatki zerowej. Rozwiązuje to problem (1) powyżej, dzięki czemu punkty, które nie są częścią sześciokątnej siatki, znów są równe zero:

 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

Wreszcie ta tablica liczb jest rzutowana na tablicę znaków. Zera znaków są wyświetlane jako spacja, co daje końcowy wynik:

  3 4 3  
 4 6 6 4 
3 6 6 6 3
 4 6 6 4 
  3 4 3  
Luis Mendo
źródło
15

JavaScript (ES6), 118 117 bajtów

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`

Gdzie \nreprezentuje dosłowny znak nowej linii. Objaśnienie: Załóżmy n=4. Zaczynamy od następującego oddzielonego spacjami kwadratu cyfrowego:

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

Pierwsze |n-i| 0s są usuwane, ale spacje pozostają:

   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

Natychmiastowy sześciokąt! Wystarczy wtedy obliczyć odpowiednią wartość zamiast każdej 0, sprawdzając, czy jesteśmy w pierwszym czy ostatnim wierszu i / lub kolumnie. Edycja: Zapisano 1 bajt dzięki @Arnauld.

Neil
źródło
Korzystając z części twojej formuły, doszedłem do 107-bajtowej wersji for / console.log ():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 Lubię to 3+!i%n!
Neil
7

Python 2, 125 123 bajtów

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

Testy są na ideone

Biegnie od góry do środkowych rzędów, for r in range(n)konstruując struny:
- tworząc dwa rogi lub dwie krawędzie '34'[r%m>0]*2;
- wypełnianie przez połączenie ich z powtarzającym się '6'lub '4', '46'[r>0]*(r+m-1);
- łączenie narożników i krawędzi z ' ';
- prepending ze spacjami ' '*(m-r);

Następnie drukuje to i jego odbicie w środkowym rzędzie połączone nowymi liniami, print'\n'.join(t+t[-2::-1])

Jonathan Allan
źródło
4

Python 2, 96 bajtów

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

Wygląda to dość niechlujnie i nieco golfowo ...

Sp3000
źródło
3

Java, 375 363 361 339 329 317 293 bajtów

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

Nie golfił

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

Zastosowanie :

$ 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

Jestem pewien, że ten strasznie zagnieżdżony blok „jeśli-inaczej” można przepisać na mniejszy, ale w tej chwili nie mogę go rozgryźć. Wszelkie sugestie są mile widziane :-)

Aktualizacja

  • Postępował zgodnie z sugestią Kevina Cruijssena i zastosował dekodowanie zamiast parsowania.
  • Ponownie przepisałem niektóre ifs za pomocą operatora trójskładnikowego.
  • Więcej operatorów trójskładnikowych.
  • Potrójne operatory moarowe! Myślę, że stworzyłem potwora!
  • Ponownie przepisaj blok if-else dotyczący drukowania.
Master_ex
źródło
1
Nie przyjrzałem się dokładnie metodzie, której używasz, ale kilka małych wskazówek golfowych dla twojego obecnego kodu: Integer.parseIntmożna grać w golfa Integer.decode. l=(h*4-3-s.trim().length())/2;if(l==0)można grać w golfa if((l=(h*4-3-s.trim().length())/2)==0). Również całkowicie dopuszczalne jest po prostu opublikowanie metody bez klasy (chyba że pytanie stanowi inaczej), więc void f(int i){...use i...}zamiast interface J{static void main(String[]r){...i=Integer.decode(r[0])...use i...}tego powinno to zaoszczędzić sporo bajtów. Kiedy będę miał więcej czasu, będę szukać dalej.
Kevin Cruijssen
@KevinCruijssen: Dziękujemy za sugestie. l=(h*4-3-s.trim().length())/2;if(l==0)jest faktycznie tej samej długości z if((l=(h*4-3-s.trim().length())/2)==0).
Master_ex
2

05AB1E , 44 bajty

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

Wyjaśnienie

Ponieważ góra i dół sześciokąta są odbijane, musimy tylko wygenerować górną część.
Tak więc dla wejścia X musimy wygenerować X wierszy. Tak właśnie działa główna pętla.

F                                        }

Następnie wykonujemy środkową część rzędów.
To 4 dla pierwszego rzędu i 6 dla reszty (ponieważ robimy tylko górną część).
Łączymy tę liczbę ze spacją, ponieważ wzorzec będzie wymagał odstępów między liczbami.

N_i4ë6}ð«

Następnie powtarzamy ten ciąg X-2 + N razy, gdzie N to bieżący wiersz indeksowany 0 i wstawiamy spację po lewej stronie.

¹ÍN+×ðì

Potem nadszedł czas na zakręty. Będą to 3 dla pierwszego i ostatniego rzędu i 4 dla środkowych rzędów.

N_N¹<Q~i3ë4}.ø

Teraz musimy upewnić się, że rzędy są prawidłowo ustawione, dodając spacje z przodu każdego rzędu. Liczba dodanych spacji będzie X-1-N .

¹<N-ð×ì

Teraz, gdy mamy już górną część siatki, dodajemy wiersze do listy, tworzymy odwróconą kopię i usuwamy pierwszy element z tej kopii (ponieważ potrzebujemy tylko środkowego wiersza tylko raz), a następnie łączymy te dwie listy razem i wydrukować.

)¦«»

Wypróbuj online!

Dodatkowe rozwiązanie, również 44 bajty:

ÍÅ10.øvN_i4ë6}ð«¹ÍN+×ðìyi4ë3}.ø¹<N-ð×ì})¦«»
Emigna
źródło
2

Rubinowy, 87 bajtów

Funkcja anonimowa przyjmuje n jako argument i zwraca tablicę ciągów.

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

Niegolfowany w programie testowym

Wejście przez stdin. Zapisuje cały kształt na standardowe wyjście. Dość oczywiste.

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
źródło
1

V , 60 bajtów

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

Wypróbuj online!

To naprawdę za długo. Oto zrzut heksowy, ponieważ zawiera znaki niedrukowalne:

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
źródło
1

Rakieta, 487 bajtów

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

Testowanie:

(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

Wersja szczegółowa:

(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
źródło