*** Wykres ameoba **** jest rodzajem drzewa, którego wszystkie węzły mają wartości od 0 do niektórych nieujemnych liczb całkowitych N, a każdy konkretny węzeł o wartości x <N łączy się z x + 1 odrębnymi węzłami o wartościach x + 1.
Wykres Ameoba dla N = 3: (oznaczono A 3 )
Zauważ, że 2 nie mogą współdzielić żadnego z 3; dokładnie trzy 3 muszą „należeć” do każdej 2.
Wyzwanie
Twoim zadaniem jest indukcyjne „powiększenie” tych wykresów ameoba w dwuwymiarowej siatce poprzez chciwe minimalizowanie odległości Manhattanu między węzłami:
- Sprawa podstawowa: 0 to po prostu wykres
0
. - Indukcyjny krok: n + 1 jest wytwarzany przez iteracyjne umieszczenie nowej N + 1 o wartości węzłów, tak blisko jak to możliwe, N wartości węzłów w Istniejące N struktury. (Może być tak blisko, jak to możliwe, ponieważ najbliższe miejsca mogą już być wypełnione).
W przypadku etapu indukcyjnego ogólna procedura, którą należy wykonać, to:
for each existing node P with value N:
for each new N+1 valued node Q you need to connect to P: //this loops N+1 times
find the set of vacant spots that are minimally distant from P //by Manhattan distance
place Q in any of these vacant spots
(Inna procedura z nierozróżnialnym wyjściem jest w porządku.)
Przykład wzrostu dla A 4 :
A0 is always the same:
0
For A1 I happen to put the 1 to the right of the 0 (it has to go on one of the 4 open sides):
01
For A2 I happen to put the two 2's above and to the right of the 1:
2
012
For A3 I find that one of the six 3's I must place cannot be directly next to a 2, so I put in one of the next closest places:
3
323
0123
33 <-- this 3 is distance two away from its 2
The process continues in A4. Note that I'm iterating over each 3 and placing four 4's next to it or as close as possible, then moving to the next 3 (the order of 3's does not matter):
444
443444
4323444
4012344
44334
4444
44
Always keep in mind that nodes cannot be "shared".
Program
Program, który piszesz, musi przyjmować liczbę od 0 do 8 (włącznie) i generować prawidłowy wykres ameoba, używając opisanego powyżej wzorca wzrostu indukcyjnego.
To, co dzieje się po 8, nie ma znaczenia.
(A 8 zawiera 46234 węzły, które go popychają. Wszystko poza A 8 byłoby za daleko. Podziękowania dla Martina Büttnera za zauważenie tego.)
Dane wejściowe powinny pochodzić ze stdin lub wiersza poleceń, a dane wyjściowe powinny przejść do stdout lub pliku.
Przykłady (wzięte bezpośrednio z góry)
Input: 0
Output:
0
Input: 1
Output:
01
Input: 2
Output:
2
012
Input: 3
Output:
3
323
0123
33
Input: 4
Output:
444
443444
4323444
4012344
44334
4444
44
* Ten typ wykresów może już mieć nazwę. Przyznaję, że właśnie je wymyśliłem. ;)
Odpowiedzi:
Mathematica,
353288285275 bajtówNie golfowany:
Oto przykładowy wynik dla
n = 5
:Wejście
8
zajmuje około 4,5 minuty.Aby szybko rozbić mój algorytm:
Używam dwóch tabel przeglądowych
f
ig
. Pierwszy to tylko rzadka mapa zawierająca niepuste komórki. Ta ostatnia jest listą zawierającą wszystkie pary współrzędnych dla każdej wartości komórki (myślę, że nawet nie muszę tutaj śledzić starych). Iteruję przez współrzędne,g
aby rozszerzyć każdą komórkę od ostatniej iteracji. Aby to zrobić, iteruję po odległościach Manhattanu, tworząc wszystkie możliwe wektory dla każdej odległości i sprawdzając, czy wynikowa komórka jest nadal pusta (w którym to przypadku ją wypełniam). Powtarzaj aż do utworzenia wystarczającej liczby nowych komórek.Kiedy skończę, znajduję współrzędną minimalną i maksymalną
g
i tworzę odpowiednią siatkę, która jest wypełniana przez wyszukiwanie komórekf
. Reszta to po prostu łączenie wszystkiego w jeden ciąg znaków z podziałem linii.źródło
C -
309 305 301275 bajtówMeh, za długo ... gdyby tylko ktoś mógł wpisać
#D
lub coś zamiast#define
, wtedy C byłby naprawdę świetny. Oczywiście-D
flagi kompilatora są możliwe, ale wydaje mi się, że to oszustwo, aby mieć znaki inne niż te w pliku źródłowym.Instrukcje biegowe:
Bądź ostrożny! Pierwszy klawisz, który naciśniesz po uruchomieniu programu, stanowi wejście. Po wprowadzeniu znaku innego niż „0” do „8”, kto wie, co się stanie.
Wersja bez golfa (ale już myśli o przyszłości golfa):
Edycja: Zdałem sobie sprawę, że ponieważ przeniosłem deklaracje poza main (), tablic nie można już przypisywać do stosu, więc mogę swobodnie korzystać z pamięci w rozrzutny sposób, bez ryzyka przepełnienia.
źródło
Rubin - 296
Nieco golfa.
źródło
APL (Dyalog) (121)
Charakterystyka wydajności: to O (n!). W moim systemie do n = 5 jest natychmiastowe; n = 6 zajmuje sekundę, n = 7 zajmuje minutę, a n = 8 zajmuje godzinę.
Wersja bez golfa
Test:
Wyjaśnienie:
{
...}⎕
: przeczytaj wiersz z klawiatury, oceń go i przekaż wynik funkcji.0::0
: jeśli inny kod zgłosi błąd, zwróć pojedynczy0
. Wynika to z faktu, że matematyka kończy się niepowodzeniem podczas próby obliczenia rozmiaru wykresu z 0 węzłami, co zdarza się, gdy dane wyjściowe powinny być0
. (Poprzednia wersja miała⍵=0:0
(jeśli dane wejściowe są0
zwracane, w0
przeciwnym razie wykonaj wykres), ale0::0
(po prostu spróbuj i zwróć,0
jeśli się nie powiedzie) jest krótsza.)M←⌈4×.5*⍨3÷⍨+/!⍳⍵
: zakładając, że wyjście jest grubym okręgiem (działa), zsumuj silnię od1
do⍵
(= obszar wyjścia), podziel przez 3 (wystarczająco blisko do pi), weź pierwiastek kwadratowy (dając promień wyjścia), pomnóż przez 4, i weź sufit. Daje to podwójną średnicę koła, więc wyjście pasuje do wolnego miejsca. Przechowuj to wM
.V←,⍳⍴Z←' '⍴⍨2/M
: utwórz macierz M-M-M spacji i zapisz jąZ
. To zatrzyma wynik. Przechowuj listę współrzędnych wszystkich elementów wV
.Z[G;G←⌈M÷2]←'0'
: ustaw środkowy elementZ
na0
.Z⊢{
...}¨⍳⍵
: powrótZ
po zastosowaniu następującej funkcji do liczb1
do⍵
:⍵∘{
...}V/,Z=⍕⍵-1
: dla każdego elementuZ
o wartości poprzedniego węzła:⍵∘{
...}⍺/⍺
: dla bieżącego węzła, N razy,⊃F[⍋+/¨|(F←V/⍨,Z=' ')-⊂⍺]
: uzyskaj wolną przestrzeń najbliżej bieżącego węzła,(
...⌷Z)←⍕⍵
: i ustaw tę przestrzeńZ
na wartość bieżącego węzła.źródło