Jestem na pozycji (0, 0) nieskończonego dwuwymiarowego miasta, które jest doskonale podzielone na bloki wyśrodkowane w każdym punkcie sieci, z których niektóre zawierają budynki. Budynek w pewnym punkcie (x, y) zajmuje cały kwadrat z przeciwległymi narożnikami w (x-.5, y-.5) i (x + .5, y + .5) , łącznie z jego granicą. Budynek jest widoczny, jeśli jest jakiś segment linii od (0, 0) do punktu w budynku, który nie przecina żadnego innego budynku.
Na przykład I (the @
) widzę 6 budynków ( *
) w następującym mieście:
*
*
*
*@
x**
* y
Nie widzę budynku oznaczonego x
, w (-1, -1), ponieważ jest on zasłonięty przez dwa sąsiadujące z nim budynki ; lub ten oznaczony y
at (3, -2), ponieważ jest on zasłonięty przez krawędź budynku (1, -1) .
Wejście
Ciąg wielowierszowy lub lista linii, opcjonalnie wypełnione spacjami w prostokącie. Będzie zawierać tylko:
- singiel
@
(moja pozycja) - Przestrzenie
*
, które reprezentują budynki.
Zawsze będzie co najmniej jeden budynek, a zatem co najmniej jeden widoczny budynek.
Wynik
Liczba widocznych budynków.
Przypadki testowe
*@
1
* *******
@ *
7
*****
**@**
*****
4
*
**
@ **
2
* *
* *
@
4
@
*
***
1
Dzięki @Geobits za tytuł .
Odpowiedzi:
Unity + C #, 589 bajtów
Jest to prawdopodobnie najgorszy język do gry w golfa kodowego (czytaj: gorszy niż Java), ale Unity ma wiele przydatnych funkcji do tego wyzwania.
EDYCJA: pominięto kilka spacji, zwraca długość listy, a nie licznik
Gra w golfa:
Nie golfowany:
Użyłem 3600 raycastów, ponieważ zawiodło w piątym przypadku testowym z niższym. Nadal może zawieść w przypadku jeszcze większych / bardziej precyzyjnych przypadków testowych.
Niestety zarówno kompilacje webgl, jak i pulpity wydają się nie działać, więc mam tylko kod źródłowy do przetestowania na github .
źródło
read: worse than Java
To o 383 bajty mniej niż rozwiązanie Java!total+=1
ztotal++
? Myślę, że innym sposobem na uratowanie niektórych postaci jest stworzenie sześcianu budynku i ustawienie jego pozycji w jednej instrukcji. Wydaje się, żecube
nigdzie nie używasz zmiennej.GameObject b=GameObject.CreatePrimitive(PrimitiveType.Cube);b.transform.position=new Vector3(x,y);
. Nie wiem, czy jest to możliwe w języku C #, ale w Javie możnaGameObject.CreatePrimitive(PrimitiveType.Cube).transform.position=new Vector3(x,y);
zamiast tego pisać .Java 8 lambda,
15061002972942 znakówChciałem pokonać to wyzwanie, ponieważ jest bardzo interesujące. Wynik
(niezbyt golfowy)można zobaczyć tutaj:Oczywiście istnieje to również w wersji bez golfa:
Wygląda więc bardzo trudno, ale jest o wiele łatwiej, niż mogłoby się wydawać. Moim pierwszym pomysłem było użycie jakiegoś algorytmu skrzyżowania, aby sprawdzić, czy linia od mojej pozycji do budynku może być utworzona bez żadnych skrzyżowań. Aby to zrobić, zdecydowałem się użyć algorytmu Cohena-Sutherlanda i narysować linie do wszystkich czterech narożników budynku. To działało całkiem dobrze w pierwszych testach, ale ostatni nie powiódł się. Wkrótce przekonałem się, że jest to przypadek, w którym nie widać rogów, ale część krawędzi. Pomyślałem więc o jakimś castingu promieniowym, takim jak @Blue. Odłożyłem to wyzwanie, ponieważ nie osiągnąłem żadnego postępu. Potem zobaczyłem odpowiedź Blue i przyszedł mi do głowy następujący prosty pomysł: każdy budynek blokuje pewien kąt, pod którym nic więcej nie widać. Muszę tylko śledzić, co można zobaczyć i co jest już ukryte przez inne budynki. Otóż to!
Algorytm działa w następujący sposób: Określa budynek z najmniejszą odległością od osoby. Następnie wyobrażamy sobie cztery linie narysowane od osoby do narożników budynku. Dwa z nich mają ekstremalną wartość: minimalny i maksymalny kąt, pod którym można zobaczyć budynek. Bierzemy je jako zasięg i porównujemy z innymi budynkami, o których wiemy, że można je zobaczyć (żaden na początku). Zakresy mogą się nakładać, obejmować lub nie dotykać. Porównuję zakresy i otrzymuję nowe zakresy budynku, które nie są ukryte przez widoczne budynki. Jeśli po porównaniu z budynkami pozostanie coś jeszcze, budynek będzie również widoczny. Dodajemy pozostały zakres kątów do listy zakresów, aby porównać i zacząć od następnego budynku o następnej większej odległości.
Czasami zakresy mogą się pokrywać w taki sposób, że kończę na zakresie 0 stopni. Te zakresy zostaną przefiltrowane, aby nie pomyłkowo dodać budynku, który nawet nie jest widoczny.
Mam nadzieję, że ktoś zrozumiał to wytłumaczenie :)
Wiem, że ten kod nie jest bardzo golfowy, zrobię to jak najszybciej.To było naprawdę trudne zadanie. Myślałeś, że znalazłeś rozwiązanie, które działa, ale zamiast tego wciąż jesteś daleko. Myślę, że to rozwiązanie działa całkiem dobrze. Nie jest bardzo szybki, ale przynajmniej działa;) Dzięki za tę łamigłówkę!
Aktualizacja
Znalazłem czas na grę w golfa w jedną funkcję, którą w ten sposób można przekształcić w lambdę. Wszystkie funkcje zostały wywołane tylko raz, dzięki czemu można je umieścić w jednej metodzie. Przełączyłem się z list na zestawy, ponieważ oszczędza to dodatkowe znaki. Deklaracje zostały zebrane razem. Porównania zostały zebrane, a postacie zastąpiono wartością ascii. Porównywanie zasięgu można wyrazić jako wiele trójskładników. Kilka sztuczek tu i tam, aby zapobiec długim wyrażeniom, takim jak Double.NEGATIVE_INFINITY. Tam gdzie to możliwe, wykonywane są przypisania liniowe. Aby zaoszczędzić trochę więcej, przerzuciłem się z porównywania kątów w stopniach na porównywanie radianów. Cała zmiana pozwoliła zaoszczędzić ponad 500 znaków, ale mam nadzieję, że uda się uzyskać wszystko poniżej 1000;)
Tam, gdzie to możliwe, usunąłem ogólne i skróciłem porównanie zwrotów, tworząc tablicę z jednym elementem i sprawdzając zamiast tego jej wartość. Zamieniłem również Double.NEGATIVE_INFINITY na PI2 i -PI2, ponieważ są to górne i dolne granice kątów. Teraz ma w końcu mniej niż 1000 znaków!
Połączyłem pętle w celu znalezienia lokalizacji osób i iteratora budynku, aby zapisać niektóre postacie. Niestety wymaga to od nas wycofania powrotu z pętli i nadal skorzystania z przerwy, ale tym razem bez etykiety. I połączyły
max
idistanceSquared
amin
inewDistanceSquared
tak nie są one wymagane w tym samym czasie. Zmieniłem sięInteger.MAX_VALUE
na2e31-1
. Stworzyłem również stałą,half = 0.5
która służy do obliczania narożników budynku. Jest to krótsze w wersji golfowej. Ogółem ocaliliśmy kolejne 30 znaków!źródło