tło
Chcę kupić działkę i zbudować na niej mój dom. Mój dom powinien być prostokątny i tak duży, jak to możliwe; jednak dostępne działki mają wiele skalistych obszarów, na których nie mogę zbudować, i mam problem z dopasowaniem potencjalnego domu na działkach. Chcę, żebyś napisał program, który analizuje dla mnie wykresy.
Wejście i wyjście
Twoje dane wejściowe to prostokątna tablica 2D bitów o wielkości co najmniej 1 × 1, w dowolnym rozsądnym formacie. Tablica przedstawia działkę; 1
s są „dobrymi” obszarami, w których mógłbym zbudować mój dom, i 0
s są „kamienistymi” obszarami, w których domu nie można zbudować.
Twój wynik powinien być maksymalnym obszarem pełnego prostokąta 1
sw tablicy wejściowej. Reprezentuje powierzchnię największego domu, jaki mogłem zbudować na działce. Zauważ, że jeśli 1
na wejściu nie ma żadnych znaków, to wynikiem jest 0
.
Przykład
Rozważ dane wejściowe
101
011
111
Największy prostokąt 1
s to prostokąt 2 × 2 w prawym dolnym rogu. Oznacza to, że poprawne wyjście to 4
.
Zasady i punktacja
Możesz napisać pełny program lub funkcję. Wygrywa najniższa liczba bajtów, a standardowe luki są niedozwolone.
Przypadki testowe
0
-> 0
1
-> 1
00
00
-> 0
01
10
-> 1
01
11
-> 2
111
010
111
-> 3
101
011
111
-> 4
0111
1110
1100
-> 4
1111111
1110111
1011101
-> 7
111011000
110111100
001111110
011111111
001111110
000111100
000011000
-> 20
000110000
110110010
110111110
110011100
010011111
111111111
111101110
-> 12
plow
.Odpowiedzi:
Galaretka ,
21201817 bajtówWypróbuj online! lub zweryfikuj wszystkie przypadki testowe .
tło
Niech M będzie macierzą bitów takich jak
Zaczynamy od zliczenia liczby 1 bitów w każdej kolumnie M , resetując liczbę za każdym razem, gdy napotkamy 0 bit.
Dla naszej przykładowej macierzy daje to
Następnie obliczamy wszystkie sąsiadujące podlisty każdego wiersza. Osiągamy to, generując wszystkie wycinki długości k , gdzie k zmienia się między 1 a liczbą wpisów w każdym rzędzie.
W przypadku przedostatniego rzędu daje to
Następnie mapujemy każdy plasterek do iloczynu jego minimum i długości. Dla każdego wycinka oblicza to obszar prostokąta 1 bity o maksymalnej wysokości, który ma dany wycinek jako dolny rząd.
Dla wycinków o długości 3 przedostatniego rzędu naszej przykładowej macierzy daje to
Pozostaje tylko wziąć maksimum we wszystkich warstwach wszystkich wierszy.
Dla naszej przykładowej macierzy daje to 12 .
Jak to działa
źródło
MATL,
323127 bajtówWykorzystuje to podejście oparte na splotach 2D z użyciem siły brutalnej. Wszystkie możliwe rozmiary prostokątów są tworzone i splecione z ukształtowaniem terenu. Maksymalnym wynikiem wszystkich zwojów jest maksymalny obszar prostokąta.
Jest to bardzo nieefektywne rozwiązanie, ponieważ w celu zaoszczędzenia bajtów tworzę jądra dla wszystkich prostokątów pomiędzy,
[1, 1]
a[numel(input) numel(input)]
zamiast faktycznie określając liczbę wierszy / kolumn na wejściu, aby określić właściwe zakresy wymiarów prostokąta.Dzięki @Luis za sugerowanie użycia
M
i pominięcie]]
.Wypróbuj online!
Wyjaśnienie
źródło
Julia,
83605753 bajtówWypróbuj online! Ostatni przypadek testowy przekracza limit czasu TIO, ale zweryfikowałem go lokalnie.
Jak to działa
Po pierwsze ! sprawdza, czy jej argument macierzy M składa się wyłącznie z 1 .
Jeśli tak, to ! zwraca sumę wpisów M , która jest równa jego powierzchni.
Jeśli nie ,! wykonuje następujące czynności:
Obracaj M o 0 ° , 90 ° , 180 ° i 270 ° zgodnie z ruchem wskazówek zegara.
Usunięcia pierwszego rzędu dla każdego z czterech obrotów, skutecznie usuwając jeden z górnym rzędzie dolnym rzędzie, skrajnej lewej kolumnie, z prawej strony kolumnie M .
Nazywaj się rekurencyjnie na każdym z podmacierzy.
Zwraca maksymalną wartość zwracaną z wywołań rekurencyjnych.
źródło
JavaScript (ES6), 97 bajtów
Okazuje się, że trochę kręci wciąż wygrywa. Akceptuje tablicę liczb całkowitych. Nie golfowany:
Tablica jest podzielona na wiersze zgodnie z innymi odpowiedziami, więc każdy możliwy zakres wierszy jest zapętlony. Biorąc pod uwagę zakres rzędów, następnym krokiem jest zmierzenie dostępnych prostokątów. Osiąga się to poprzez ANDing rzędów bitowych; wynikiem jest lista bitów, które zostały ustawione w całym zakresie wierszy. Następnie pozostaje znaleźć maksymalną długość ustawionych bitów w rzędzie i pomnożyć ją przez wysokość zakresu. Test bezwstydnie skradziony z @ ed65:
źródło
Python 2.7,
9391898179 bajtówDane wejściowe to lista krotek. Sprawdź mniejsze przypadki testowe tutaj i większe przypadki testowe tutaj .
Bez zapamiętywania dwa ostatnie przypadki testowe przekraczają limit czasu Ideone, ponieważ wymagają one odpowiednio 1530 831 935 i 2 848 806 121 połączeń do f , co zajmuje 39 i 72 minuty na moim komputerze.
Algorytm
Dla danej macierzy M , ogólną ideą jest iteracja po wszystkich podmacierzach M poprzez usunięcie górnych rzędów i obracanie ćwierćobrotów przeciwnie do ruchu wskazówek zegara, śledząc rozmiary napotkanych podmacierzy, które składają się w całości z 1 bitu.
Gra w golfa w bezpośrednią rekurencyjną implementację powyższej idei prowadzi do funkcji f (M), która wykonuje następujące czynności.
Jeśli M nie zawiera żadnych 0 bitów, zwróć liczbę 1 bitów.
Jeśli obróciliśmy już M dwa razy i nie zawiera on 1 bitu, zwróć 0 .
Jeśli obróciliśmy już M pięć razy, zwróć 0 .
Rekurencyjnie wzywaj f na M bez górnego rzędu.
Wywołanie rekurencyjne f na M obrócone o ćwierć obrotu przeciwnie do ruchu wskazówek zegara.
Zwraca maksymalną wartość zwracaną z wywołań rekurencyjnych.
Kod
W implementacji używamy dodatkowego argumentu funkcji t, który domyślnie ma wartość 1, aby śledzić, ile razy już obróciliśmy tę konkretną macierz. Umożliwia to skondensowanie kroków od 1 do 3 w jeden krok poprzez przetestowanie
`t/3`in`M`
i powrót,`M`.count(`t`)
jeśli test się nie powiedzie.Jeśli t = 1 , nie rotowaliśmy tej konkretnej submatrix wcześniej w tej gałęzi.
t / 3 = 0 , więc
`t/3`in`M`
zwróci True iff reprezentacja ciągu M zawiera znak 0 .Jeśli nie, wracamy
`M`.count(`t`)
liczba czasach postać 1 pojawi się w ciągu reprezentującego M .Zauważ, że macierz bez 0 bitów może wystąpić tylko wtedy, gdy t = 1 , ponieważ nie powtarzamy się w tym przypadku.
Jeśli 3 ≤ t ≤ 5 , wcześniej obróciliśmy tę konkretną submatrix co najmniej dwa razy w tej gałęzi.
t / 3 = 1 , więc
`t/3`in`M`
zwróci True iff reprezentacja ciągu M zawiera znak 1 .Jeśli nie, wracamy 0 obliczana jako
`M`.count(`t`)
, ile razy reprezentację ciąg t (czyli postać 3 , 4 lub 5 ) pojawia się w ciągu reprezentującego M .Jeśli t = 6 , wcześniej obróciliśmy tę konkretną submatrię pięć razy w tej gałęzi.
t / 3 = 2 , więc
`t/3`in`M`
zwróci False , ponieważ reprezentacja ciągu M nie zawiera znaku 2 .Wracamy 0 obliczana jako
`M`.count(`t`)
, ile razy postać 6 pojawi się w ciągu reprezentującego M .Jeśli f jeszcze nie powrócił, pozostałe kroki są wykonywane.
f(M[1:])
wywołuje f na M bez górnego rzędu. Ponieważ t nie jest określone, domyślnie przyjmuje wartość 1 , co oznacza, że po raz pierwszy f napotka tę konkretną submatrix w tej gałęzi.f(zip(*M)[::-1],t+1)
wywołania f na M obrócone o ćwierć obrotu przeciwnie do ruchu wskazówek zegara, zwiększając t, aby śledzić czas, w którym obróciliśmy tę konkretną submatrix w tej gałęzi.Przełom czwarta otrzymuje się skompresowanie rzędy M siebie, powracając krotki odpowiednie elementy M rzędów jest, zatem transpozycji M , a następnie odwrócenie kolejności wierszy (czyli umieszczenie górnego rzędu od dołu i odwrotnie ).
Wreszcie
max
zwraca maksimum wartości zwrotnych z wywołań rekurencyjnych.źródło
zip
zwraca listę krotek odpowiadających elementów jej argumentów. Dzięki nieopakowanej liście 2D (macierzy)*M
zasadniczo transponuje wiersze i kolumny, dlategozip(*M[::-1])
wykonuje obrót o 90 ° zgodnie z ruchem wskazówek zegara.JavaScript (ES6), 154
176Edit próbował trochę skrócić, ale nie może konkurować z rozwiązaniem @ Neil
Wypróbuj każdy możliwy prostokąt, zwróć maksymalny rozmiar. Prawdopodobnie ten sam algorytm odpowiedzi Matla, tylko 6 razy dłuższy.
Dane wejściowe jako tablica liczb całkowitych 2d
Mniej golfa
Jest to oryginalny algorytm, wersja w golfa nadużywa wielu funkcji przechodzenia przez tablicę zamiast pętli
Test
źródło
APL (Dyalog Extended) ,
272320 bajtów-3 bajty autorstwa Adama i ngn
Wypróbuj online!
źródło
{⌈/,(×/×1∊⍵⍷⍨⍴∘1)¨⍳⍴⍵}
jest krótszy i prostszy (nawet nie wymaga rozszerzenia).{⌈/∊(×/×⍵⍷⍨⍴∘1)¨⍳⍴⍵}
Brachylog ,
201715 bajtówDzięki Kroppeb za 2 bajty
Wypróbuj online!
Wyjaśnienie
źródło
aa
można zastąpićs
Wypróbuj online!R ,
129122 bajtówWypróbuj online!
Proste i proste podejście z użyciem brutalnej siły.
Rozwinięty kod i objaśnienie:
źródło
Stax , 14 bajtów
Uruchom i debuguj
źródło
Matlab 106 bajtów
Nie golfowany:
Operacja w pętli rozpoczyna się od splotu 2D
conv2()
tablicy wejściowej zp*m
tablicą jedności.==p*m
sprawdza, czy wynikowa tablica zawiera element równyp*m
. Odpowiedni element jest odwrócony1
, wszystkie pozostałe elementy są odwrócone0
.any()
zamienia tablicę w wektor. Kolumny zawierające co najmniej jeden niezerowy wpis są odwracane1
, w przeciwnym razie0
.p*m*()
zwielokrotnia wektor,p*m
zamieniając tym samym wszystko w1
-sp*m
.[__,r]
nawiasy kwadratowe łączą uzyskany wynik z poprzednim maksymalnym obszarem przechowywanym wr
. Na koniecmax()
znajduje maksymalną wartość w wynikowym wektorze.źródło
any()
zwraca,1
jeśli kolumna zawiera niezerowy element i w0
przeciwnym razie.Matlab
(222)(209)Właściwie to rozwiązanie sprawia mi wstyd z powodu podwójnego rozmiaru rzeczywistego rozwiązania w tym samym języku, ale ... cholera, myślałem o tym przez 6 godzin! sztuczka jest nieco odmienna od odpowiedzi Dennisa i Neila.
Funkcja jest wywoływana jako
Mógłbym zaoszczędzić więcej bajtów, jeśli wprowadzę długość macierzy w wymiarach funkcji, chociaż więcej golfa jest w toku.
Jak to działa?
Algorytm ten dodaje do siebie rzeczywistą macierz przesuniętą z niej w lewo, z lekkim kręceniem (&). na dowolnym etapie uzyskana macierz jest ustawiana jako początkowa i dodawana do siebie kilkakrotnie przesuwana w górę, a następnie ponownie uruchamiana od nowa z nową macierzą. Wszystkie podelementy wszystkich macierzy wygenerowanych przez tę operację
(original_matrix+shifted_matrix)&shifted_and_original_matrices)
są zmaksymalizowane do wyniku.przykład:
źródło
Japt , 30 bajtów
Wypróbuj wszystkie przypadki testowe
Około portu galaretki Dennisa. Przypadki testowe to po prostu tablice liczb 2D, przekonwertowane z formatu pytania za pomocą tego .
Wyjaśnienie:
źródło
J , 38 bajtów
Wypróbuj online!
w jaki sposób
źródło