Wzorzec strzelania Prime Nerd

16

Najdłuższy dzień w roku - oto coś do stracenia dodatkowego czasu ...


Przegląd

Pamiętaj, że nie jest to konkurs popularności, a nie graficzne wyzwanie wyjściowe - musisz jedynie wygenerować ciąg 65 536 zer i jedynek. Fragment kodu w dolnej części pytania wyświetli to jako czarno-biały obraz 256 na 256 i obliczy Twój oficjalny wynik. Następnie możesz zapisać obraz i przesłać go do swojej odpowiedzi wraz ze swoim kodem (ponieważ wynik łańcucha nie mieści się w 30 000-znakowej odpowiedzi Stack Exchange).


Punktacja

Wynik obrazu jest sumą wyników jego poszczególnych pikseli. Wynik danego piksela jest sumą podwyników dla każdego z non-prostopadłych , prime odległości pikseli, które są przeciwnego koloru na piksel jest punktowane. Wynik dla każdego takiego piksela to miejsce, w 1/pktórym pznajduje się główna odległość.

W kontekście tego pytania terminy mają następujące definicje:

  • Nie-ortogonalny: piksel nie jest ortogonalny w stosunku do ocenianego piksela, jeśli nie znajduje się w tym samym rzędzie i nie znajduje się w tej samej kolumnie.

  • Główna odległość: piksel znajduje się w największej odległości od punktowanego piksela, jeśli dzieli je odległość euklidesowa, która jest dokładnie liczbą pierwszą. W szczególności odległość to minimalna odległość mierzona toroidalnie - lewy górny piksel to odległośćsqrt(2)od prawego dolnego piksela (wszystkie 4 krawędzie zawinięcia).

  • Kolor przeciwny: piksel ma kolor przeciwny do piksela ocenianego, jeśli ich wartości sumują się do 1. Oznacza to, że pierwszy to 0, a drugi to 1 lub pierwszy to 1, a drugi to 0.

Fragment kodu zawiera przykładowy kod pokazujący sposób oceniania obrazu, ale nie zawiera żadnych optymalizacji ani skutecznego podejścia, wystarczy poprawny kod, aby można było konsekwentnie oceniać końcowe obrazy.

Jeśli cokolwiek w kodzie jest nieprawidłowe, daj mi znać albo w komentarzach, albo na czacie .

JavaScript nie musi być najlepszym językiem do odbierania tego szczególne wyzwanie. Pamiętaj, że kod Snippet celowo nie daje wskazówek co do szybszych podejść. Będzie miał tylko wprowadzone wydajności, które zostały już wykazane w istniejącej odpowiedzi.


Wyobrażanie sobie

Punktowane piksele

Dla intuicyjnego wyczucia rozkładu pikseli punktowanych tutaj (na fioletowo) są nieortogonalne piksele o podstawowej odległości dla piksela (128, 128) obrazu 256 na 256:

obraz nieortogonalnego rozkładu odległości pierwotnej


Losowy obraz

Jest to losowo generowany obraz z przykładowej odpowiedzi w języku Python 3. Ma wynik 138 267,64 i daje ci coś do pokonania.

losowo generowany obraz


Wejście

Kod nie wymaga wprowadzania danych.

Wynik

Kod powinien generować ciąg 65 536 zer i jedynek, reprezentujących piksele czarno-białego obrazu 256 na 256. Cyfry powinny być ciągiem ciągłym, bez separatorów. Kopiowanie i wklejanie może być łatwiejsze, jeśli wyprowadzasz dane do pliku, ale to zależy od ciebie.

Twój kod może także wyświetlać inne informacje, które okażą się przydatne, o ile ciąg będzie można skopiować i wkleić do fragmentu kodu. Na przykład możesz chcieć wyprowadzać najlepszy ciąg znaków do pliku, a najlepszy jak dotąd wynik do STDOUT w regularnych odstępach czasu, pozwalając użytkownikowi wybrać, kiedy zatrzymać wyszukiwanie.


Fragment kodu

Jak wskazał Sp3000 , fragment kodu potrzebował 10 minut na obliczenie wyniku, który jest nieco zbyt wolny, nawet w przypadku celowo nieefektywnej implementacji referencyjnej. Zredagowałem w sugerowanej przez Sp3000 poprawie wstępnego obliczania przesunięć pikseli dla punktacji, a teraz obliczenie wyniku zajmuje kilka sekund.


Jeśli wykorzystasz wynik lub kod innej odpowiedzi jako punkt wyjścia dla własnego kodu, pamiętaj o podaniu kredytu i linku do odpowiedzi uzupełniającej. Odpowiedzi na to pytanie nie muszą podawać przykładowej odpowiedzi ani kodu w pytaniu.

Podziękowania dla Randalla Munroe za termin Nerd Sniping

trichopaks
źródło

Odpowiedzi:

36

CJam, wynik 276496,9062958626

2,128*_(]128*

Okazuje się, że jest optymalny, ponieważ: Nie ma żadnych nieortogonalnych par o odległości 2. Zatem odległość musi być nieparzysta, podobnie jak odległość do kwadratu. Ponieważ p 2 = x 2 + y 2 , jeden z xiy (kwadrat lub nie) musi być nieparzysty, a drugi musi być parzysty. Punkty te są zawsze w przeciwnych kolorach na tym obrazie.

To i jego minus są również jedynymi optymalnymi rozwiązaniami. W optymalnym rozwiązaniu żadne nieortogonalne piksele o pierwotnej odległości nie powinny mieć tego samego koloru. Są po przekątnej sąsiadujące przeciwległe piksele, takie jak (3,4) i (4,3). Wypełniając piksele przeciwnego przeciwnego koloru itp., Możemy uzyskać przekątną tego samego koloru. Zaczynając od każdego piksela po przekątnej, możemy wypełnić wszystkie anty-przekątne w ten sam sposób. Pamiętaj, że się owijają. Jednak nadal jest optymalne, jeśli nie.

jimmy23013
źródło
3
Miałem nadzieję, że ludzie zauważą, że ...
trichoplax
1
Długo zajęło mi wypracowanie optymalnego rozwiązania podczas pisania tego pytania, więc pomyślałem, że warto opublikować to jako wyzwanie. Jak widziałeś to tak szybko? Czy to było po prostu oczywiste, czy miałeś szczególny proces myślowy?
trichoplax
4
PS Nie wiem, kiedy widziałeś to pytanie, ale optymalne rozwiązanie 71 minut po opublikowaniu pytania zasługuje na nagrodę - muszę tylko poczekać 2 dni, zanim będę mógł je przypisać ...
trichoplax
@trichoplax Od pierwszego obrazu wydawało się, że jest wiele punktów na tej samej przekątnej. Na początku myślałem o użyciu szerszych pasków. A potem otworzyłem Gimp, aby zweryfikować mój pomysł. Ku mojemu zdziwieniu otrzymałem całkowicie czarny obraz, kiedy wypełniłem go tym wzorem.
jimmy23013
8
@trichoplax Biorąc pod uwagę, że wiesz, że istnieje optymalne rozwiązanie, myślę, że lepiej byłoby, gdybyś zrewidował pytanie, aby uczynić je mniej możliwym do rozwiązania. Chociaż jimmy23013 szybko to znalazł, zawsze jest kwestią czasu, aż ktoś go znajdzie, a potem to koniec.
xnor
1

Python 3, wynik 138267,64

To minimalna odpowiedź jako przykład tego, co jest wymagane i jako coś do pokonania ...

Obejmuje

  • Nazwa języka
  • Wynik z fragmentu stosu w pytaniu.
  • Obraz zapisany z fragmentu stosu.
  • Kod użyty do wygenerowania ciągu 65 536 zer i jedynek.

Wynik

losowo generowany obraz

Kod

from random import random

output_string = ''
filename = '65536digits.txt'

for t in range(65536):
    digit = int(random() * 2)
    output_string += str(digit)

with open(filename, 'w') as output_file:
    output_file.write(output_string)

To tylko przykład. Python niekoniecznie jest najlepszym językiem dla konkurencyjnych odpowiedzi na to szczególne wyzwanie.

trichopaks
źródło