Powinieneś napisać program lub funkcję, która jako ciąg wejściowy i wyjściowy zwraca ciąg reprezentujący wielobok ascii-art, a zwraca obszar wielokąta.
Dane wejściowe to ciąg znaków składający się ze znaków _ / \ L V space
i newline
definiujący prosty wielokąt (co oznacza brak dodatkowych segmentów, brak dotyku i brak przecięcia).
Obszar pojedynczej komórki to 2
_
dzieli komórkę na rozmiary0
i2
\
dzieli komórkę na rozmiary1
i1
/
dzieli komórkę na rozmiary1
i1
L
dzieli komórkę na rozmiary0
i2
V
dzieli komórkę na rozmiary1
i1
(Dwie stronyV
zawsze będą po tej samej stronie wielokąta, więc są traktowane razem na liście).
Każda postać łączy dwa rogi swojej komórki postaci, której się spodziewasz (np. Lewy górny i prawy górny w przypadku V
).
Przykład o powierzchni 7 ( 1+2+1
w drugim rzędzie i 1+1+1
trzecim):
_
/ \
V\/
Wkład
- Dane wejściowe utworzą prostokąt, tzn. Między znakami nowej linii będzie ta sama liczba znaków.
- Po każdej stronie wielokąta mogą znajdować się dodatkowe białe znaki.
- Końcowy znak nowej linii jest opcjonalny.
Wydajność
- Pojedyncza dodatnia liczba całkowita, obszar wielokąta.
Przykłady
Wyjścia są za ostatnim wierszem ich danych wejściowych.
_
V
1
/L
\/
3
/VV\
L /
L/
14
____/\
\ /
/\/ /
\____/
32
/V\
/ \__
\ /
/\/ /V
L____/
45
To jest golf golfowy, więc wygrywa najkrótszy wpis.
^
celowo?Odpowiedzi:
CJam,
48 4329 bajtówAktualizacja : Dużo grałem w golfa przy użyciu matematyki i sztuczki stanowej * 2 z odpowiedzi orlp.
Jak to działa (nieaktualne, wkrótce aktualizacja)
Dzielimy dane wejściowe na nowy wiersz, a następnie dla każdej części utrzymujemy licznik wystąpień znaków granicznych
L\/
. Ten licznik% 2 powie nam, którą z dwóch partycji wybrać dla wszystkich znaków. Następnie znajdujemy indeks każdego znaku w ciąguL _
.\/V
da-1
odniesienie do ostatniego elementu w tablicy. Po uzyskaniu indeksu używamy4558Zb2/
do utworzenia tablicy,[[2 0] [0 2] [0 2] [1 1]]
a następnie wybieramy poprawną liczbę za pomocą licznika.Wypróbuj online tutaj
źródło
Pyth,
4746453630Wyjaśnienie:
Mamy dwa stany: „w wielokącie” i „poza wielokątem”. Następujące znaki wykonują następujące czynności, czytając je od lewego górnego do prawego dolnego rogu:
Pamiętaj, że „dodaj jeden do obszaru” i „jeśli w wielokącie, dodaj dwa do obszaru” wykluczają się wzajemnie.
źródło
x=
działa. Czy to gdzieś jest udokumentowane?+=
lub*=
czy cokolwiek innego. W tym przypadkux
jest używany jako xor, więc jest dokładnie taki sam jak Python^=
.Siatkówka oka , 293 + 15 = 308
314385bajtówKażda linia przechodzi w osobny plik, więc dodałem 13 do liczby bajtów. Możesz też umieścić to wszystko w jednym pliku i użyć
-s
flagi.<empty>
Oznaczają faktycznie pustych plików lub linii.Niestety, potrzebuję 187 bajtów, aby przekonwertować wynik z jednostkowego na dziesiętny. Chyba powinienem to niedługo zaimplementować .
Wyjaśnienie
Retina jest językiem opartym na wyrażeniach regularnych (który napisałem właśnie po to, aby móc robić takie rzeczy przy pomocy wyrażeń regularnych). Każda para plików / linii definiuje etap zastępowania, przy czym pierwsza linia to wzorzec, a druga linia ciąg zastępujący. Wzorce mogą być poprzedzone
`
-delimitowanym ciągiem konfiguracji, który może zawierać zwykłe modyfikatory wyrażeń regularnych, a także niektóre opcje specyficzne dla Retina. Dla powyższego programu odpowiednie opcje to;
, które tłumią wyjście tego etapu i+
które stosują zamianę w pętli, aż wynik przestanie się zmieniać.Ideą rozwiązania jest policzenie każdej linii osobno, ponieważ zawsze możemy zdecydować na podstawie znaków, które już napotkaliśmy, czy jesteśmy wewnątrz wielokąta, czy poza nim. Oznacza to również, że mogę połączyć całość w jedną linię, ponieważ przejście do początku i końca linii zawsze znajduje się poza wielokątem. Możemy również zauważyć, że
_
i przestrzeń są całkowicie identyczne dla algorytmu przesuwania linii, a także\
i/
. Tak jak w pierwszym etapie zastąpić wszystkie znaki nowej linii i przestrzenie autorem_
a wszystko\
przez/
uproszczenie kodu później.Śledzę bieżący stan wewnątrz / na zewnątrz z postaciami
i
io
jednocześnie używami
s do zliczania obszaru. Aby to zrobić, zaczynam od dodaniao
do połączonej linii, aby zaznaczyć, że jesteśmy poza wielokątem. Dodam teżiio
na samym końcu danych wejściowych, których użyję jako odnośnik do generowania nowych znaków.Następnie pierwsza duża zamiana po prostu zastępuje jedną
i
lubo
następną jedną/V_L
z następną serią znaków, zalewając w ten sposób całość. Tabela wymiany wygląda następująco: kolumny odpowiadają ostatniemu znakowi w tej linii, a wiersze do następnego znaku (gdzieS
jest miejsce na spację i<>
pusty ciąg znaków). Uwzględniłem wszystkie znaki wejściowe, aby pokazać ekwiwalenty, których już użyłem:Zauważ, że końcowy znak zawsze wskazuje, czy po znaku jesteśmy wewnątrz czy poza wielokątem, podczas gdy liczba
i
s odpowiada obszarowi, który należy dodać do wielokąta. Jako przykład podajemy wyniki pierwszych czterech iteracji z ostatniego przykładowego wejścia (zostało to wygenerowane przez starą wersję, która faktycznie zalała każdą linię osobno, ale zasada jest nadal taka sama):Wreszcie, po prostu pozbyłem się wszystkich
o
s i linia łamie się, usuwając wszystko, co pasuje[^i]
, a reszta to konwersja dziesiętna na unarską, która jest raczej nudna.źródło
Perl,
6558 bajtówźródło
$/=\1;$-^=2*y,/\\L,,,$a+=y,/\\V,,||$-for<>;print$a
GNU sed, 290 + 1
+ 1 ma uwzględniać
-r
przełącznika na sed. Komentarze i dodatkowe białe znaki nie są liczone w wyniku.Nie przyjrzałem się zbyt szczegółowo, ale myślę, że prawdopodobnie jest to podobne do odpowiedzi Retina Martina :
Przegląd
:
Notatki
sed
jest zorientowany na linie, więc wymaga trochę pracy, aby przetworzyć wiele linii jednocześnie.N
Komenda robi to poprzez dodanie nowego wiersza potem następną linię do aktualnej przestrzeni wzoru. TrudnośćN
polega na tym, że gdy dotrze do strumienia wejściowego EOF, wychodzised
całkowicie bez żadnej opcji dalszego przetwarzania. Aby obejść ten problem, liczymy bieżący zestaw dwukropków na końcu każdej linii, tuż przed czytaniem w następnej linii.Wydajność:
źródło
C, 93
96 108bajtówEdycja: wziął pod uwagę sugestie w komentarzach, przekształcił while w pętlę pojedynczą dla pętli i całkowicie usunął zmienną „i”.
Oryginalny post:
Wyglądało to na dość zabawny i prosty problem, że w końcu udało mi się założyć tutaj konto.
Tekst wielokąta należy przekazać jako pierwszy argument wiersza poleceń; powinno to działać z dowolną liczbą znaków nowej linii / białych znaków lub bez nich.
To po prostu odczytuje w wielokącie jeden znak na raz, s przełącza, czy obecnie jest w wielokącie, czy poza nim, na „/”, „L” lub „\”, a t wzrasta o 1 na „/”, „V”, i „\” lub o 2, jeśli wewnątrz / 0, jeśli na zewnątrz na „L”, „_”, spacja i nowa linia.
Po raz pierwszy próbuję swoich sił w jakimkolwiek „golfie” (lub C, w stopniu, w jakim różni się od C ++), więc wszelkie uwagi są mile widziane!
źródło
i=t=s=0;
myślę, że C i tak inicjuje wszystkieint
s do 0. Sprawdź także, czy możesz zamienićwhile
pętlę wfor
pętlę; co często oszczędza kilka bajtów....int i,t,s;for(i=t=s=0;c=v[1][i++];t+=s+(c>46^!(c%19)^s))s^=c>13^c%9>4;...
co powinno oszczędzić 4 bajty; jeden {, jeden} i dwa;int i,t,v;
zostać umieszczone przedmain
zamiast w środku, moglibyśmy się pozbyći=t=s=0
całkowicie oszczędzając kolejne 7 bajtów.POSIX sed,
245244POSIX sed, bez rozszerzeń i rozszerzonych wyrażeń regularnych. Dane wejściowe są ograniczone do maksymalnego rozmiaru przestrzeni ładunkowej sed - POSIX upoważnia co najmniej 8192; GNU zarządza więcej. Ta wersja zakłada, że przed kształtem lub po nim nie będzie pustych linii; dodatkowe 10 bajtów kodu, wskazanych w rozwinięciu, może to pomieścić, jeśli jest to wymagane (pierwotne pytanie nie określa).
Rozszerzony i opatrzony adnotacjami
źródło
C, 84 bajtów
Zmieniamy strony, ilekroć widzimy
\
,/
lubL
; zawsze dodajemy jeden dla\\
,/
lubV
, ale dodajemy 2 (jeśli jest w środku) lub 0 (jeśli na zewnątrz) dla spacji, nowej linii,L
lub_
.Zmienne
a
ii
przyjmuje się, że są zerowe przy wprowadzaniu - należy je zresetować, jeśli funkcja ma zostać wywołana więcej niż jeden raz.Nie golfowany:
Program testowy:
źródło