Rozważ tablicę A
długości n
. Tablica zawiera tylko dodatnie liczby całkowite. Na przykład A = (1,1,2,2)
. Zdefiniujmy f(A)
jako zbiór sum wszystkich niepustych, sąsiadujących pod-macierzy A
. W tym przypadku f(A) = {1,2,3,4,5,6}
. Kroki do produkcji f(A)
są następujące:
Podziemne A
są (1), (1), (2), (2), (1,1), (1,2), (2,2), (1,1,2), (1,2,2), (1,1,2,2)
. Ich odpowiednie kwoty to 1,1,2,2,2,3,4,4,5,6
. Zestaw, który otrzymujesz z tej listy, jest zatem {1,2,3,4,5,6}
.
Zadanie
Biorąc pod uwagę zestaw sum S
podanych w posortowanej kolejności, zawierający tylko dodatnie liczby całkowite i długość tablicy n
, Twoim zadaniem jest wyprowadzenie co najmniej jednej X
takiej tablicy f(X) = S
.
Na przykład, jeśli S = {1,2,3,5,6}
i n = 3
wtedy poprawnym wynikiem jest X = (1,2,3)
.
Jeśli nie ma takiej tablicy, X
kod powinien wypisać dowolną stałą wartość.
Przykłady
Wejście:, n=4, S = (1, 3, 4, 5, 6, 8, 9, 10, 13)
możliwe wyjście:X = (3, 5, 1, 4)
Wejście:, n=6, S = (2, 3, 4, 5, 7, 8, 9, 10, 12, 14, 17, 22)
możliwe wyjście:X = (5, 3, 2, 2, 5, 5)
Wejście:, n=6, S = (2, 4, 6, 8, 10, 12, 16)
możliwe wyjście:X = (4, 2, 2, 2, 2, 4)
Wejście:, n=6, S = (1, 2, 3, 4, 6, 7, 8, 10, 14)
możliwe wyjście:X = (4, 2, 1, 1, 2, 4)
Wejście: n=10, S = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 23, 24, 25)
możliwe wyjścia: X = (1, 1, 3, 1, 2, 1, 2, 5, 4, 5)
.
Wejście: n=15, S = (1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31)
możliwe wyjścia: X = (1, 2, 1, 3, 3, 1, 3, 3, 1, 3, 3, 1, 2, 1, 3)
.
Format wejściowy i wyjściowy
Twój kod może pobierać dane wejściowe i generować dane wyjściowe w dowolnym, łatwym dla człowieka formacie, który uważasz za dogodny. Proszę jednak pokazać wyniki testowania na przykładach w pytaniu.
Czas trwania
Musisz być w stanie uruchomić kod do końca dla wszystkich przykładów w pytaniu. Zasadniczo powinno to być poprawne n
, 15
ale nie trzeba udowadniać, że byłoby wystarczająco szybkie dla wszystkich danych wejściowych.
Odpowiedzi:
Łuska , 20 bajtów
Wypróbuj online!
Zwraca jedno rozwiązanie lub pustą listę, jeśli nie istnieje. Ostatni przypadek testowy (
n=15
) kończy się w TIO w 3,8 sekundy.Wyjaśnienie
Program składa się z dwóch części. W pierwszej części (
¡
i po jej prawej stronie) tworzymy nieskończoną listę, którejk
elementem jest lista zawierająca wszystkie listy długości, wk
których znajdują się sumy plasterkówS
. Robimy to indukcyjnie, zaczynając od 1-elementowych wycinkówS
i na każdym kroku poprzedzając każdy elementS
do każdej listy i zachowując te, których sumy prefiksów są w środkuS
. W drugiej części (!
i po lewej stronie) bierzemyn
element th listy, który zawieran
listy długości . Spośród nich wybieramy pierwszy, którego sumy plasterków faktycznie zawierają każdy elementS
.W kodzie najpierw zamieńmy
o
iȯ
(które składają się z dwóch i trzech funkcji w jedną) nawiasy dla zachowania przejrzystości.Niektóre części wymagają wyjaśnienia. W tym programie
⁰¹
oba indeksy górne odnoszą się do pierwszego argumentuS
. Jeśli jednakα
jest funkcją,α¹
oznacza to „zastosujα
doS
”, a⁰α
oznacza „podłączS
do drugiego argumentuα
”. Funkcja¦
sprawdza, czy jej pierwszy argument zawiera wszystkie elementy drugiego (liczenie krotności), więcS
powinien być drugim argumentem.W pierwszej części
¡
używaną funkcję można interpretować jakoS(f~Λ€∫)(×:)¹
. KombinatorS
zachowuje się jakSαβγ -> (αγ)(βγ)
, co oznacza, że możemy go uprościć(f~Λ€∫¹)(×:¹)
. Druga część×:¹
to „łączenie zS
przygotowaniem”, a jej wynik jest przekazywany do pierwszej części. Pierwsza częśćf~Λ€∫¹
działa w ten sposób. Funkcjaf
filtruje listę według warunku, którym w tym przypadku jest~Λ€∫¹
. Otrzymuje listę listL
, więc mamy~Λ€∫¹L
. Kombinator~
zachowuje się tak~αβγδε -> α(βδ)(γε)
: pierwszy argument jest przekazywany doβ
, drugi doγ
, a wyniki są łączone zα
. Oznacza to, że mamyΛ(€¹)(∫L)
. Ostatnia część∫L
to tylko skumulowane sumyL
,€¹
jest funkcją, która sprawdza członkostwoS
iΛ
przyjmuje warunek (tutaj€¹
) oraz listę (tutaj∫L
) i sprawdza, czy wszystkie elementy go spełniają. Mówiąc najprościej, filtrujemy wyniki mieszania według tego, czy są w nich sumy skumulowaneS
.źródło
Rubin , 135 bajtów
Wypróbuj online!
Skorzystaj z pierwszego wyszukiwania. n = 10 działa na TIO, n = 15 zajmuje więcej niż minutę, ale działa na moim komputerze.
Rubinowy , 147 bajtów
Wypróbuj online!
Wersja zoptymalizowana, działa na TIO przez n = 15 (~ 20 sekund)
W rzeczywistości jest to początek podejścia bez użycia siły. Mam nadzieję, że ktoś nad tym popracuje i znajdzie kompletne rozwiązanie.
Pierwsze pomysły:
Co prowadzi nas do kolejnej optymalizacji:
Rubinowy , 175 bajtów
Wypróbuj online!
~ 8,5 sekundy w TIO. Nie jest zły...
... i tak dalej (do wdrożenia)
źródło
Haskell,
117111 bajtów6 bajtów zapisanych dzięki @nimi!
Wypróbuj online!
f
r
i
n
s
Kiedy
n
zero (gra w golfan<1
), lista musi być gotowa, więc sprawdzamy, czy wszystkie wartości zostały zauważone. Jeśli nie, zwracamy pustą listę, aby wskazać brak rozwiązań, w przeciwnym razie zwracamy listę singletonów zawierającą pustą listę, do której wybrane elementy zostaną dodane. Przypadek ten można również rozwiązać za pomocą dodatkowych równańJeśli
n
nie jest zero, wracamyJest to lista (1) list, z których pochodzi pierwszy element (2),
s
a reszta (5) pochodzi z wywołania rekurencyjnego, pod warunkiem (4), że są wszystkie nowe sumys
. Nowe sumy są obliczane w (3) - uwagat
pochodzi z listy singletonów, brzydkiego golfowego hacka dla tego, co w idiomatycznym Haskell byłobylet t=y:map(y+)i
. Wywołanie rekurencyjne (5) otrzymuje jako nowyr
zestaw stary bez tych elementów, które pojawiają się wśród nowych sumt
.Główna funkcja
&
wywołuje funkcję pomocnika, mówiąc, że wciąż musimy zobaczyć wszystkie wartości (r=s
) i że nie ma jeszcze żadnych sum (i=[]
).W przypadku siedmiu kolejnych bajtów możemy ograniczyć obliczenia, aby dać tylko pierwszy wynik (jeśli istnieje), który jest znacznie szybszy i obsługuje wszystkie przypadki testowe w mniej niż 2 sekundy.
Wypróbuj online! (jest to pierwszy wariant tylko starej wersji starej wersji)
źródło
map
, tylko próbowałem,<$>
ale to wymagało dodatkowych parens ... @Anush Nie mam pomysłu na rozwiązanie wielomianoweCzysty , 177 bajtów
Wypróbuj online!
n=15
Sprawa testowa zajmuje około 40 sekund na moim komputerze , ale limit czasu dla TIO.Czysty , 297 bajtów
Wypróbuj online!
Ten zawiera kilka optymalizacji wykonanych przez GB a także niektóre własne. Myślę, że kilka z nich może być bardziej ogólnych, więc dodam wyjaśnienie, kiedy to się skończy.
Na moim komputerze zajmuje to około 10 sekund, a TIO - 40 sekund.
źródło
@mention
ty jutro, kiedy będą na nogach, niestety nie masz dzisiaj czasu.Python 3 , 177 bajtów
Wypróbuj online!
(dodano kilka nowych linii / spacji, aby uniknąć konieczności przewijania kodu przez czytelników)
Bezpośredni port mojej odpowiedzi Jelly (z pewnymi modyfikacjami, patrz sekcja „uwaga” poniżej)
Lokalny wynik uruchomienia:
Słyszałem, że
itertools
jest to pełne, ale moja najlepszacombinations
implementacja jest jeszcze bardziej szczegółowa:Uwaga .
a[p//n:p%n+1]
zajmuje około 2x dłużej, ale oszczędza niektóre bajty.combinations
zwróceniu iteratora jest to bardziej przyjazne dla pamięci.źródło
Galaretka , 35 bajtów
Wypróbuj online!
Uruchom lokalnie: (n = 15 zajmuje więcej niż 1 GB pamięci RAM)
(faktycznie uruchomiłem wersję zakodowaną w UTF8, która zajmuje więcej niż 35 bajtów, ale wynik jest taki sam)
To rozwiązanie wykorzystuje zwarcie w celu skrócenia czasu pracy.
Wyjaśnienie
Zauważamy, że sumy wszystkich niepustych prefiksów są obecne na wejściu i ściśle się zwiększają. Możemy również założyć, że największy i drugi co do wielkości element jest sumą prefiksu.
Dlatego możemy rozważyć wszystkie sposoby wyborun - 2 odrębne elementy od pierwszego | S.| -2 elementy (są ( | S| -2n - 2) takie listy), oblicz kolejne różnice w celu odzyskania elementów; następnie sprawdź, czy jest ważna naiwnie (zdobądź wszystkon2) podzakresy, oblicz sumę, unikaj. Całkowita długość subarrays wynosi okołon3)6 )
Nie przetestowane (ale powinny mieć identyczną wydajność)
Galaretka , 32 bajty
Wypróbuj online!
Bardziej nieefektywna wersja (bez zwarcia):
Galaretka , 27 bajtów
Wypróbuj online!
W przypadku testu n = 15 zajmuje do 2 GB pamięci RAM i nie kończy się po ~ 37 minutach.
Uwaga :
Ẇ§
można zastąpićÄÐƤẎ
. Może być bardziej wydajny.źródło
APL (NARS), znaki 758, bajty 1516
Funkcja G w G x (za pomocą funkcji H) znajdowałaby wszystkie permutacje x. Funkcja d w xdy sprawdza, czy tablica y generuje po tablicy ćwiczeń x zwracając wartość logiczną. Funkcja F w x F y zwróci tablicę r o długości x, tak że ydr jest prawdą (= 1) Trochę dłuższa niż implementacja, ale to ta, która oblicza wszystkie przypadki w teście mniej czasu ... Ostatni przypadek dla n = 15 działa tylko 20 sekund ... muszę powiedzieć, że nie znajduje wielu rozwiązań, zwraca tylko jedno rozwiązanie (w końcu wydaje się, że tak) w krótszym czasie (niezbadany test dla różnych danych wejściowych ...) 16 + 39 + 42 + 8 + 11 + 11 + 18 + 24 + 24 + 54 + 11 + 12 + 7 + 45 + 79 + 69 + 12 + 38 + 26 + 72 + 79 + 27 + 15 + 6 + 13 (758)
źródło