To pytanie jest oparte na wieżach z układaniem liczb (znanych również jako Wieżowce), w które można grać online . Twoim celem jest rozwiązanie zagadki i ustalenie wskazówek - liczby wież widocznych wzdłuż każdego rzędu i kolumny. To jest kod golfowy, więc wygrywa najmniej bajtów.
Jak działa Towers
Rozwiązaniem puzzle Towers to kwadrat łaciński - n*n
siatka, w której każdy wiersz i kolumna zawiera permutacji liczb 1
dzięki n
. Przykładem n=5
jest:
4 3 5 2 1
5 4 1 3 2
1 5 2 4 3
2 1 3 5 4
3 2 4 1 5
Każdy wiersz i kolumna jest oznaczony wskazówką na każdym końcu, na przykład:
2 3 1 4 5
v v v v v
2 > 4 3 5 2 1 < 3
1 > 5 4 1 3 2 < 4
2 > 1 5 2 4 3 < 3
3 > 2 1 3 5 4 < 2
3 > 3 2 4 1 5 < 1
^ ^ ^ ^ ^
2 2 2 2 1
Każda wskazówka jest liczbą od 1
do, n
która mówi, ile wież „widzisz” patrząc wzdłuż rzędu / kolumny z tego kierunku, jeśli liczby są traktowane jak wieże o tej wysokości. Każda wieża blokuje za nią krótsze wieże. Innymi słowy, wieże, które można zobaczyć, są wyższe niż jakakolwiek wieża przed nimi.
Na przykład spójrzmy na pierwszy wiersz.
2 > 4 3 5 2 1 < 3
Ma wskazówkę 2
z lewej, ponieważ możesz zobaczyć 4
i 5
. W 4
blokuje 3
od wzroku i 5
blokuje wszystko. Z prawej strony widać 3
wieże: 1
, 2
, i 5
.
Wymagania programu
Napisz program lub funkcję, która pobiera siatkę liczb i wyników lub drukuje wskazówki, postępując zgodnie z ruchem wskazówek zegara od lewego górnego rogu.
Wkład
n*n
Łacińsko-kwadrat z 2<=n<=9
.
Format jest elastyczny. Możesz użyć dowolnej struktury danych, która reprezentuje siatkę lub listę zawierającą cyfry lub znaki cyfrowe. Może być wymagany separator między wierszami lub brak separatora. Niektóre możliwości to lista, lista list, macierz, ciąg znaków oddzielony tokenami
43521 54132 15243 21354 32415,
lub ciąg bez spacji.
Nie jesteś podany n
jako część danych wejściowych.
Wydajność
Wróć lub wydrukuj wskazówki, zaczynając od lewego górnego rogu i postępując zgodnie z ruchem wskazówek zegara. Więc najpierw górne wskazówki czytają w prawo, następnie prawe wskazówki czytają w dół, następnie dolne wskazówki czytają w lewo, lewe wskazówki czytają w górę.
Tak byłoby 23145 34321 12222 33212
w poprzednim przykładzie
2 3 1 4 5
v v v v v
2 > 4 3 5 2 1 < 3
1 > 5 4 1 3 2 < 4
2 > 1 5 2 4 3 < 3
3 > 2 1 3 5 4 < 2
3 > 3 2 4 1 5 < 1
^ ^ ^ ^ ^
2 2 2 2 1
Podobnie jak w przypadku danych wejściowych, możesz użyć listy, łańcucha lub dowolnej uporządkowanej struktury. Cztery „grupy” można rozdzielić lub nie, w strukturze zagnieżdżonej lub płaskiej. Ale format musi być taki sam dla każdej grupy.
Przykładowe przypadki testowe:
(Twój format wejścia / wyjścia nie musi być taki sam jak te.)
>> [[1 2] [2 1]]
[2 1]
[1 2]
[2 1]
[1 2]
>> [[3 1 2] [2 3 1] [1 2 3]]
[1 2 2]
[2 2 1]
[1 2 3]
[3 2 1]
>> [[4 3 5 2 1] [5 4 1 3 2] [1 5 2 4 3] [2 1 3 5 4] [3 2 4 1 5]]
[2 3 1 4 5]
[3 4 3 2 1]
[1 2 2 2 2]
[3 3 2 1 2]
>> [[2 6 4 1 3 7 5 8 9] [7 2 9 6 8 3 1 4 5] [5 9 7 4 6 1 8 2 3] [6 1 8 5 7 2 9 3 4] [1 5 3 9 2 6 4 7 8] [3 7 5 2 4 8 6 9 1] [8 3 1 7 9 4 2 5 6] [9 4 2 8 1 5 3 6 7] [4 8 6 3 5 9 7 1 2]]
[4 2 2 3 3 3 3 2 1]
[1 3 3 2 2 2 2 3 3]
[4 3 2 1 2 3 3 2 2]
[3 1 2 4 3 3 2 2 5]
Dla Twojej wygody, oto te same przypadki testowe w formacie płaskiego łańcucha.
>> 1221
21
12
21
12
>> 312231123
122
221
123
321
>> 4352154132152432135432415
23145
34321
12222
33212
>> 264137589729683145597461823618572934153926478375248691831794256942815367486359712
422333321
133222233
432123322
312433225
≢¨∪¨↓⌈\(⍉⍪⌽⍪⍉∘⌽∘⊖⍪⊖)
Python 2, 115 bajtów
Tam dzieje się okropnie dużo przerzucanych list.
Pobiera dane wejściowe jako listę zagnieżdżoną (np. Połączenie z
T([[4,3,5,2,1],[5,4,1,3,2],[1,5,2,4,3],[2,1,3,5,4],[3,2,4,1,5]])
). Dane wyjściowe to pojedyncza płaska lista.Nie golfowany:
Alternatywa 115:
Nie mam pojęcia, dlaczego to działa ze zrozumieniem listy, ale rzuca się
NameError
na określone rozumienie ...Trochę za długo, ale jeśli ktoś jest zainteresowany - tak, można sprowadzić to do lambda!
Pyth , 25 bajtów
Obowiązkowy port Pyth.
Wprowadź listę za pomocą STDIN, np
[[4, 3, 5, 2, 1], [5, 4, 1, 3, 2], [1, 5, 2, 4, 3], [2, 1, 3, 5, 4], [3, 2, 4, 1, 5]]
.Wypróbuj online ... powiedziałbym, ale niestety ze względów bezpieczeństwa tłumacz online nie pozwala na użycie eval w nawiasach zagnieżdżonych.
JcQ5V4=J_CJ~Yml{meS<dhkUd_J)Y
Zamiast tego wypróbuj kod obejścia i wprowadź jako spłaszczoną listę, np[4, 3, 5, 2, 1, 5, 4, 1, 3, 2, 1, 5, 2, 4, 3, 2, 1, 3, 5, 4, 3, 2, 4, 1, 5]
.(Dzięki @isaacg, który pomógł rozegrać kilka bajtów)
źródło
<
i>
są jednostronnymi operatorami krojenia , więc:d0hk
można je zmienić<dhk
.U
na danych wejściowych kolekcji jest taki sam jakUl
, więcUld
można je zmienićUd
.CJam,
2927 bajtówDane wejściowe jak
Dane wyjściowe jak
Jak to działa
Podstawową ideą jest, aby kod działał wzdłuż wierszy i obracał siatkę 4 razy w lewo. Aby policzyć wieże, podnoszę każdą wieżę, o ile nie robi to „różnicy wizualnej” (tj. Nie zmieniaj jej, jeśli jest widoczna, ani nie podciągaj jej na tę samą wysokość wieży przed it), a następnie liczę różne wysokości.
źródło
APL, 44
Testowane tutaj.
źródło
J, 35 znaków
Przykład:
Wypróbuj tutaj.
źródło
Haskell, 113
źródło
Mathematica,
230,120,116,113110 bajtówStosowanie:
źródło
a[[y]][[x]]
jesta[[y,x]]
. I używanieArray
może być krótsze niżTable
.JavaScript,
335264256213Ocena w konsoli JavaScript przeglądarki (użyłem Firefoksa 34.0, wydaje się, że nie działa w Chrome 39?) Testuj z:
Oto obecne wcielenie nieoznakowanego kodu - coraz trudniej jest go śledzić:
Celowo nie spojrzałem na żadną z innych odpowiedzi, chciałem sprawdzić, czy sam mogę coś wymyślić. Moje podejście polegało na spłaszczeniu tablic wejściowych do tablicy jednowymiarowej i wstępnym obliczeniu przesunięć do wierszy ze wszystkich czterech kierunków. Następnie użyłem Shift w prawo, aby sprawdzić, czy następna wieża była fałszywa, a jeśli tak, to zwiększ licznik dla każdego rzędu.
Mam nadzieję, że istnieje wiele sposobów, aby to poprawić, być może nie dokonaj wstępnego obliczenia przesunięć, ale raczej zastosuj pewnego rodzaju przepełnienie / modulo na tablicy wejściowej 1D? I może połącz moje pętle, stań się bardziej funkcjonalny, deduplikuj.
Wszelkie sugestie będą mile widziane!
Aktualizacja nr 1 : Postęp, mamy technologię! Byłem w stanie pozbyć się wstępnie obliczonych przesunięć i wykonać je zgodnie z połączonymi ze sobą operatorami trójskładnikowymi. Był także w stanie pozbyć się mojej instrukcji if i przekonwertować pętle for na while.
Aktualizacja nr 2 : Jest to dość frustrujące; dla mnie nie ma pizzy. Pomyślałem, że przejście na funkcjonalność i użycie rekurencji zmniejszy liczbę bajtów, ale moje pierwsze próby zakończyły się powiększeniem nawet o 100 znaków! W desperacji zdecydowałem się na użycie funkcji strzałek z tłuszczu ES6, aby naprawdę je spowolnić. Potem zabrałem się do zastępowania operatorów logicznych operacjami arytmetycznymi i usuwania parenów, średników i spacji, gdzie tylko mogłem. Zrezygnowałem nawet z deklarowania moich zmiennych i zanieczyściłem globalną przestrzeń nazw moimi lokalnymi symbolami. Brudny, brudny. Po całym tym wysiłku pobiłem swój wynik aktualizacji nr 1 aż o 8 znaków, aż do 256. Blargh!
Gdybym zastosował te same bezwzględne optymalizacje i sztuczki ES6 do mojej funkcji aktualizacji nr 1, pobiłbym ten wynik o milę. Mogę zrobić aktualizację nr 3 tylko po to, żeby zobaczyć, jak by to wyglądało.
Aktualizacja nr 3 : Okazało się, że podejście rekurencyjne z grubą strzałą miało o wiele więcej życia, po prostu musiałem bezpośrednio pracować z dwuwymiarowym wejściem zamiast spłaszczać go i lepiej wykorzystywać zakresy zamknięcia. Dwa razy przepisałem obliczenia przesunięcia tablicy wewnętrznej i uzyskałem ten sam wynik, więc to podejście może być bliskie wyczerpania!
źródło
Tylko Java
352350325 bajtów ...Dane wejściowe jak
43521 54132 15243 21354 32415
Dane wyjściowe takie jak:
23145343211222233212
Zębaty:
Wszelkie wskazówki będą mile widziane!
źródło
for
pętlamifor(;i<n;i++)
sięfor(;++i<n;)
i zainicjowaći
celu-1
. Następnie używaj ich do robienia różnych rzeczy. Możesz zrobić to samo z drugą pętlą.a[i].charAt(j)-'0'
zamiast jawnej analizy. Nie wymaga to również ograniczników wejściowych (sprawia, że format wejściowy bardziej przypomina format wyjściowy).for
pętlach zawsze można włożyć coś użytecznego do części „przyrostu pętli”. To sprawia, że kod jest bardziej niejasny i usuwa jeden średnik. Na przykład:for(j=n;j-->0;System.out.print(c))
.Python 2 - 204 bajty
To prawdopodobnie bardzo kiepski golf. Myślałem, że problem jest interesujący, więc postanowiłem go rozwiązać, nie patrząc na czyjeś rozwiązanie. Kiedy piszę to zdanie, muszę jeszcze spojrzeć na odpowiedzi na to pytanie. Nie zdziwiłbym się, gdyby ktoś inny zrobił już krótszy program w języku Python;)
Przykład we / wy
Opcjonalnie możesz włączyć białe znaki na wejściu. Prawie wszędzie, szczerze mówiąc. Tak długo, jak to możliwe
eval()
, będzie działać.Wyjaśnienie
Jedyną interesującą częścią tego programu jest pierwsza linia. Definiuje funkcję,
f(l)
która mówi, ile wież można zobaczyć z rzędu, a reszta programu po prostu stosuje tę funkcję do każdej możliwej pozycji.Po wywołaniu znajduje długość
l
i zapisuje ją w zmiennejn
. Następnie tworzy nową zmiennąk
z tym dość potwornym zrozumieniem listy:Nie jest tak źle, kiedy się psujesz. Ponieważ
n==len(l)
wszystko przedif
sprawiedliwymi reprezentujel
. Jednak za pomocąif
możemy usunąć niektóre elementy z listy. Tworzymy listę z([0]+list(l))
, która jest po prostu „l
z0
dodanym na początku” (zignoruj wywołanie dolist()
, to tylko tam, ponieważ czasamil
jest generator i musimy upewnić się, że faktycznie jest to lista).l[c]
jest umieszczany na końcowej liście, tylko jeśli jest większy niż([0]+list(l))[c]
. To robi dwie rzeczy:l[c]
staje sięc+1
. Skutecznie porównujemy każdy element z elementem po jego lewej stronie. Jeśli jest większy, jest widoczny. W przeciwnym razie jest ukryty i usunięty z listy.[0]+
nonsens i tylko w stosunkul[c]
dol[c-1]
Python by porównać pierwszej wieży do ostatniego (można indeks do listy od końca z-1
,-2
itp), więc jeżeli ostatnia wieża była wyższa niż po pierwsze otrzymalibyśmy zły wynik.Kiedy wszystko jest powiedziane i zrobione,
l
zawiera pewną liczbę wież ik
zawiera każdą z nich, która nie jest krótsza niż jej bezpośredni sąsiad po lewej stronie. Jeśli żaden z nich nie był (np. Zaf([1,2,3,4,5])
), tol == k
. Wiemy, że nie ma już nic do zrobienia i powrotun
(długość listy). Jeślil != k
to oznacza, że przynajmniej jedna z wież została tym razem usunięta i może być więcej do zrobienia. Więc wracamyf(k)
. Boże, kocham rekursję. Co ciekawe,f
zawsze powtarza się o jeden poziom głębiej niż jest to absolutnie „konieczne”. Po wygenerowaniu listy, która zostanie zwrócona, funkcja nie może na początku tego wiedzieć.Kiedy zacząłem pisać to wyjaśnienie, ten program miał 223 bajty. Podczas wyjaśniania rzeczy zdałem sobie sprawę, że istnieją sposoby na uratowanie postaci, więc cieszę się, że to napisałem! Największym przykładem jest to, że
f(l)
pierwotnie została zaimplementowana jako nieskończona pętla, która została przerwana, kiedy obliczenia zostały wykonane, zanim zdałem sobie sprawę, że rekurencja zadziała. To po prostu pokazuje, że pierwsze rozwiązanie, o którym myślisz, nie zawsze będzie najlepsze. :)źródło
Matlab,
(123)(119)używane w ten sposób:
C #, do 354 ...
Zastosowano inne podejście niż TheBestOne.
źródło
\n
zamiast znaków nowej linii, po prostu zastąpiłem je spacjami, więc kod działa od razu, gdy ktoś go kopiuje. I pozwoliłem sobie usunąć ostatniend
(który zamyka funkcję, co nie jest konieczne), który zapisuje dodatkowe 4 znaki, mam nadzieję, że było ok =)end
,