Twoim zadaniem jest napisanie programu lub funkcji, która może wypełnić dany prostokąt liczbami pierwszymi. Wejście width
i height
będzie prostokątem. Dane wyjściowe muszą być listą height
ciągów znaków składających się z width
cyfr i spacji. Każda pozioma (od lewej do prawej) i pionowa (od góry do dołu) sekwencja cyfr (ograniczona spacją lub prostokątami) o długości 2 lub większej musi być liczbą pierwszą. Każda liczba pierwsza może być użyta tylko raz. Zera wiodące są niedozwolone. Końcowy nowy wiersz jest opcjonalny na wyjściu.
Przykład:
With input (5, 3) a valid output would be:
11 13
7 0
173
which scores 11, 13, 173, 17, 103 for a total of 5 points.
Wynik:
Rozmiar prostokąta do oceny będzie wynosił 80, 60
. Każda pozioma lub pionowa liczba pierwsza o długości 2 lub więcej w prostokącie otrzymuje jeden punkt. Odpowiedź z największą liczbą punktów wygrywa. W przypadku remisu wygra najwcześniejsza odpowiedź.
Zasady:
- Standardowe luki są zabronione.
- Twój program nie może być dostosowany do
80, 60
rozmiaru. Jeśli podejrzewam, że odpowiedź jest zoptymalizowana dla tego rozmiaru, zastrzegam sobie prawo do zmiany rozmiaru prostokąta do100, 100
. - Użyte liczby pierwsze muszą być liczbami rzeczywistymi (nie probabilistycznymi ani pseudopierwszymi). Twój program może obliczać lub sprawdzać liczby w czasie wykonywania lub mieć je na stałe zakodowane. Metoda znajdowania liczb pierwszych nie jest ważną częścią wyzwania.
- Twoja odpowiedź powinna zawierać tekst wyjściowy i kod. Jeśli twój program jest zbyt duży, możesz po prostu dołączyć kod podstawowego algorytmu, z małym wyjaśnieniem.
Edycja: wyjaśniono, że potrzebne są prawdziwe liczby pierwsze. Dodano maksymalny rozmiar prostokąta.
Edycja 2: Wyjaśniono, jaki kod należy opublikować.
źródło
Odpowiedzi:
Clingo z Pythonem,
160016891740 liczb pierwszychPodejście
Generuję gigantyczny problem satysfakcji z ograniczeń i rozwiązuję go za pomocą przemysłowego rozwiązania do sprawdzania siły. Dużo magii poświęcono na stosunkowo szybkie rozwiązywanie problemów z zadowalaniem (mimo że ogólnie problem dotyczy NP-zupełności), ale na szczęście nie muszę się tym martwić.
W szczególności ustalam pozycje cyfr we wzorze zaprojektowanym do ścisłego pakowania 4 i 5 cyfr, z okazjonalnymi 2 i 3 cyframi na granicy, i dodam ograniczenia, mówiąc, że każda liczba jest odrębną liczbą pierwszą. Obecne pakowanie wykorzystuje dużą część wszystkich 4 cyfr liczb pierwszych (854 z 1061).
Kod
Stosowanie
Ostrzeżenie: przy 80 × 60 zajmuje to około 8 minut i zużywa 3 GB pamięci. Możesz zacząć od mniejszych rozmiarów, jeśli chcesz tylko, aby działał.
Wyjście (80 × 60, 1740 liczb pierwszych):
źródło
Smalltalk, 1098 liczb pierwszych
Po pierwsze, miłe, trudne pytanie - o czym świadczy dotychczas brak nietrywialnych odpowiedzi.
Miałem rozwiązanie gotujące w pracy, ale musiałem czekać na długi weekend, aby mieć trochę czasu, aby je trochę posprzątać. Mimo to jest dość „ciężki”, więc wybacz tę odpowiedź - na szczęście nie jest to pytanie o golfa. Po drodze było mnóstwo małych błędów, ale jestem prawie pewien, że teraz nie zawiera błędów, chociaż jest wiele miejsca na ulepszenia i dopracowanie.
Język
Moim językiem z wyboru tego rodzaju jest Smalltalk - lepsze debugowanie i możliwość testowania w miarę kodowania bije wszystko, co wiem. Co więcej, nawet niekodujący mogą go przeczytać i zrozumieć podstawy tego, co się dzieje. Poniższy kod ograniczyłem do interesującej części, ponieważ uważałem, że podejście i wyniki będą bardziej interesujące niż kod z podstawowymi danymi, ale plik pełnego kodu jest wklejany tutaj, jeśli ktoś chce go wypróbować (po prostu zapisz jako
*.st
plik i wprowadź go z przeglądarki plików w Pharo). Użyłem Pharo 4.0, który jest FOSS i można go pobrać z pharo.org dla Win / Mac / Linux. Z przyjemnością wklejam tutaj pełny kod, ale jako sugestię wziąłem „powinien zawierać tekst wyjściowy i kod” - daj mi znać, jeśli się mylę.Podejście
Tak więc, pomyślałem sobie, co by było, gdybyś mógł zacząć od środka, umieścić tyle długich liczb pierwszych w pudełku i przejść od tego miejsca? Zacznijmy od
Box
obiektu zawierającego amatrix
, a następnie użyjStuffer
obiektu, aby spróbować go wypełnić, znajdując najlepszyInsertion
(inny obiekt) dla każdego punktu w macierzy i dla każdej liczby pierwszej (zaczynając od długich). Pharo ma fajneMatrix
iPoint
klasowe z wieloma przydatnymi metodami (chociaż matrycowy sposób użycia notacji major-row w porównaniu z użyciem współrzędnych xy punktów może być nieco mylący, jeśli nie będziesz ostrożny).Podstawowe kroki mojego algorytmu to:
Stuffer
instancję dla podanych wymiarów.Konfigurowalny:
W poniższej matrycy użyłem liczb 80 x 60, liczb pierwszych poniżej 20 000 (ponieważ ich łączna długość wynosi nieco mniej niż 10 000 znaków, tj. Maksimum dla wypchanego, choć nieważnego, pola 100 x 100) oraz, po pewnych eksperymentach, następującą ocenę za
each
wstawienie :gdzie
accidentalPrimes
są prostopadłe liczby pierwsze „przypadkowo” utworzone podczas wstawiania między sąsiednimi liczbami pierwszymi inumberOfOverlaps
to, ile znaków jest zastępowanych (np. podczas dodawania znaku3
na końcu11
wstawiania113
). Początkowo miałem większą wagę doaccidentalPrimes
, ale otrzymałem kilka liczb pierwszych w pudełku, robiąc to w ten sposób - nie do końca pewien, dlaczego (nie krępuj się testować / poprawiać).Wynik
Ta matryca zawiera 1098 liczb pierwszych, co stanowi „obciążenie” około 70%.
Oto liczby pierwsze (
box primesUsed asSortedCollection printString
):Jak widać, niektóre „przypadkowe” liczby pierwsze są dość długie ... 20 cyfr dla najdłuższej. :-)
Detale
Aby zrozumieć, jak to działa, oto wynik zrobienia kilku pierwszych kroków - wstawienie
19997
najpierw (jeśli spojrzysz na środek dużej matrycy, zobaczysz19997
tam również), a następnie w dół listy, gdzie jest miejsce w 5x5 pole (>
oznacza wstawianie w prawo,v
oznacza schodzenie w dół; cokolwiek w{}
jest przypadkowo dodanych liczb pierwszych:W przypadku wstawiania bezpośrednio powyżej pudełko staje się 7x7 i jest wypełnione zawartością 5x5 przed kolejnym wstawieniem. Ponownie obliczam liczby pierwsze użyte w tym momencie, ponieważ niektóre są „zwolnione” z powodu nadpisania (
11
zostało wstawione, ale następnie nadpisane przez113
).Kod
Oto najbardziej odpowiednie części kodu:
Klasa faszerująca
Strona klasowa
Strona instancji
Klasa pudełkowa
Strona instancji
Kolekcja
Aha, i
Collection
dla wygody dodałem jedną metodę :Uruchamiam to
Aby uruchomić mój kod, wystarczy wybrać następujący kod w obszarze roboczym („boisko” w Pharo) lub w dowolnym okienku tekstowym i „zrób to” z menu kontekstowego:
Reszta kodu jest stosunkowo nudna.
Jak powiedziałem, miejsce na ulepszenia, ale przy 80x60, każdy cykl zajmuje ponad 3 minuty na moim komputerze. Najwyraźniej wydajność nie była moim zmartwieniem, ale latają dużo liczb pierwszych. To z pewnością było ciekawe wyzwanie. :-)
źródło
JavaScript, wynik 659
Niemal na pewno nieoptymalne.
Wyniki dla 30x30:
A w przypadku 60x60:
źródło