To pytanie dotyczy abelowych piaskowców . Przeczytaj poprzednie wyzwanie i obejrzyj wideo z numerami, aby dowiedzieć się więcej.
Abelowa kupa piasku o rozmiarze n na n jest siatką zawierającą liczbę 0, 1, 2 i 3 (reprezentującą liczbę ziaren piasku). Dodanie dwóch stosów piasków polega na dodaniu elementu po elemencie, a następnie obaleniu dowolnego elementu, który przekracza 3. Kolejność, w jakiej się przewrócisz, nie ma znaczenia, wynik końcowy jest taki sam. Kiedy komórka przewraca się, jej liczba zmniejsza się o 4, a każdy z jej bezpośrednich sąsiadów wzrasta o 1. Może to spowodować reakcję łańcuchową. Jeśli komórka znajduje się na krawędzi siatki, wszelkie ziarna spadające z siatki podczas obalania znikają.
Na przykład dodaję dwa stosy piasku 3 na 3 (co daje dość ekstremalną reakcję łańcuchową):
3 3 3 1 2 1 4 5 4 4 6 4 6 2 6 6 3 6 2 5 2 4 1 4 4 2 4 0 4 0 2 0 2 2 1 2
3 3 3 + 2 1 2 = 5 4 5 -> 6 0 6 -> 2 4 2 -> 3 0 3 -> 5 0 5 -> 1 4 1 -> 2 0 2 -> 4 0 4 -> 0 4 0 -> 1 0 1
3 3 3 1 2 1 4 5 4 4 6 4 6 2 6 6 3 6 2 5 2 4 1 4 4 2 4 0 4 0 2 0 2 2 1 2
W tym wyzwaniu interesuje nas podzbiór wszystkich możliwych stosów piasków n na n . Ten podzbiór zawiera dowolny stos piasków, który można uzyskać, dodając dowolny stos sandpile do all-3s n przez n sandpile. Na przykład tuż powyżej widzieliśmy, że 212 | 101 | 212
jest w podzbiorze, ponieważ otrzymaliśmy to, dodając coś do stosu wszystkich 3.
Teraz ten podzbiór ma interesujący element: element tożsamości . Jeśli weźmiesz ten element i dodasz go do dowolnego innego elementu w podzbiorze , suma nie ulegnie zmianie. Innymi słowy, ten stos piasku działa jak zero tego podzbioru. Tak się składa, że 212 | 101 | 212
jest to element zerowy dla podzbioru 3 na 3. Na przykład:
2 2 2 2 1 2 4 3 4 0 5 0 2 1 2 2 2 2
2 2 2 + 1 0 1 = 3 2 3 -> 5 2 5 -> 1 6 1 -> 2 2 2
2 2 2 2 1 2 4 3 4 0 5 0 2 1 2 2 2 2
Teraz jest to twoje wyzwanie: biorąc n , znajdź element tożsamości podzbioru siatki n na n . Wydrukuj go, przypisując każdemu z nich unikalny kolor z wystarczającym kontrastem 0, 1, 2, 3
i wysyłając obraz n na n. Twój kod musi być w stanie wyprodukować skrzynkę 50 na 50 w niecałą minutę na rozsądnym nowoczesnym komputerze.
Na przykład element tożsamości 500 na 500:
Oto niebieski = 3, zielony = 2, czerwony = 1, biały = 0. Ale nie musisz używać tego schematu kolorów w swojej odpowiedzi.
Odpowiedzi:
Oktawa,
120113 bajtówPodziękowania dla JungHwana Min za udostępnienie linku do dokumentu referencyjnego w jego odpowiedzi Mathematica.
Dzięki Stewie Griffin zaoszczędziłem 7 bajtów
[any(any(x)) -> nnz(x)]
Tutaj używane są dwie funkcje:
1
f
.: dla stabilizacji macierzy2. Anonimowa funkcja, która przyjmuje
n
dane wejściowe i pokazuje macierz tożsamości.Wypróbuj na rextesterze! do generowania matrycy 50 * 50
Czas, który upłynął do obliczania macierzy:
0.0844409 seconds
.Wyjaśnienie:
Zastanów się nad funkcją
f
stabilizującą matrycę, a poszukiwanie tożsamości jest prostef(ones(n)*6 - f(ones(n)*6)
.że
ones(n)*6
oznacza macierz n * 6.więc dla
n=3
:Wynik będzie
f(M-f(M))
Dla funkcji stabilizacji splot 2D używany do przyspieszenia zadania; W każdej iteracji tworzymy macierz binarną
b
o tym samym rozmiarze matrycy wejściowej i ustawiamy ją na 1, jeśli odpowiadający jej element ma> 3. Następnie stosujemy 2D splot macierzy binarnej za pomocą następującej maskireprezentujących czterech bezpośrednich sąsiadów.
Wynik splotu jest dodawany do matrycy i odejmowany czterokrotnie matryca binarna.
Pętla była kontynuowana, aż wszystkie elementy macierzy osiągnęły <= 3
Wersja bez golfa :
źródło
Mathematica,
177157135133 bajtówPodejmuje liczbę
n
. Dane wyjściowe to sandpile tożsamości. 0 to czarny, 1 to jasnoszary, 2 to purpurowy, a 3 to niebiesko-szary.Niestety Mathematica nie ma wbudowanego do tego ...
Wykorzystuje algorytm określony w pracy Scotta Corry'ego i Davida Perkinsona .
Moje 9-letniemu laptopowi zajmuje 91,7 sekundy, aby obliczyć sandpile tożsamości 50x50. Jestem przekonany, że rozsądny nowoczesny komputer stacjonarny jest o ponad 50% szybszy. (Na końcu mam też znacznie szybszy kod).
Wyjaśnienie
Zdefiniuj funkcję
f
(dane wejściowe to macierz piasku): funkcja, która ...... powtarza
BlockMap
operację, dopóki dane wyjściowe się nie zmienią.BlockMap
operacja: ...... wypełnij tablicę wejściową jedną warstwą 0 ...
... podziel go na matryce 3x3, z przesunięciem 1 ...
... i dla każdej partycji dodaj liczbę ziaren piasku zrzuconych na środkową komórkę i wartość środkowej komórki mod 4.
tzn. wyjście
f
jest ustabilizowaną wersją wejścia.Zdefiniuj
k
jako tablica n na n 6s.Oblicz f (k - f (k)).
Zastosuj kolory do wyniku.
Szybsza wersja (142 bajty)
Ten sam kod, ale zamiast tego używa wbudowanej rotacji listy
BlockMap
. Oblicza n = 50 w 4,0 sekundy na moim laptopie.źródło
Python 3 + Numpy + PIL,
385370364 bajtówPobiera dane wejściowe na STDIN. Wysyła obraz w skali szarości do
i.png
. Czarny odpowiada 0, ciemnoszary do 1, jasnoszary do 2, a biały do 0.Wykorzystuje formułę
I = R(S - R(S))
, gdzieI
jest elementem tożsamości,S
macierzą wypełnioną szóstkami iR
jest funkcją redukcji.Prawdopodobnie mógłbym zaoszczędzić trochę bajtów, przechodząc do Python 2 i wykonując to
from numpy import*
, ale (1) nie mam Numpy zainstalowanego na Pythonie 2 i (2) program się nie kończyłfrom numpy import*
.Nie golfowany:
źródło
scipy
lubmatplotlib
wyświetlić dane zamiast generować obraz bezpośrednio za pomocą PIL.