Niektóre liczby, takie jak: 6, 12, 20, 30, 42, 56, 60, 90, 120 itd., Które można wyrazić jako iloczyn kolejnych liczb całkowitych, jak pokazano poniżej.
6 = 2 * 3
12 = 3 * 4
30 = 5 * 6
60 = 3 * 4 * 5
90 = 9 * 10
120 = 4 * 5 * 6
Napisz program lub funkcję, która wyświetli listę kolejnych liczb całkowitych, których iloczyn równa się podanej liczbie.
Przykłady liczb, które nie pasują do tej logiki, to:
99 = 9 * 11 (Product of non-consecutive numbers)
121 = 11 * 11 (Same numbers)
2 = 1 * 2 (Product of itself and 1)
13 = 13 (Product of only one number)
Należy pamiętać, że w przypadku 2 = 2 * 1
nie uważamy tego za prawidłowy wynik, ponieważ liczba całkowita pomnożona przez 1 daje ten sam wynik. W przypadku tego pytania weźmiemy pod uwagę tylko liczby całkowite> = 2 w produkcie.
Wejście
Prawidłowa 32-bitowa liczba całkowita dodatnia. Może być ze standardowego wejścia, argumentu funkcji itp.
Wynik
Lista kolejnych liczb całkowitych> = 2 (w kolejności rosnącej lub malejącej). Jeśli istnieje kilka kombinacji kolejnych liczb całkowitych, wystarczy podać jedno wystąpienie. Jeśli podasz więcej, będzie dobrze.
Ograniczenia
Uruchomienie kodu na standardowym komputerze w rozsądnym czasie (<5 minut) dla wszystkich prawidłowych danych wejściowych (dodatnie 32-bitowe liczby całkowite). Jeśli istnieje kolejny produkt liczb całkowitych, kod powinien wypisać jeden lub więcej w wyznaczonym terminie. W przeciwnym razie kod powinien zakończyć się bez wyjścia w wyznaczonym terminie.
To jest kod golfowy, więc wygrywa najkrótszy kod w bajtach.
30=5*6
.Odpowiedzi:
Java - 124
Począwszy od 2, pętle te zaczynają się, aż liczba początkowa będzie> pierwiastek kwadratowy celu (lub cel zostanie osiągnięty dokładnie). Jeśli produkt jest niski, mnoży się przez wysoką liczbę i zwiększa go. Jeśli jest wysoki, dzieli przez liczbę początkową i zwiększa ją.
Na przykład dla 30 sprawdziłby:
Generuje rozdzielony spacjami ciąg czynników w porządku rosnącym.
Z podziałami linii:
źródło
Python -
104 97 9592 wypróbujJeśli
n
np. Jest wcześniej ustawiony na 120, program wypisuje dwa rozwiązania:źródło
+=
. Ale brakuje mi++
w Pythonie ...if s>=n
iif s/n
są równoważne, więc możesz dostarczyć wszystkie rozwiązania w tej samej liczbie znaków.s=s*(i+c)
nas*=i+c
.Clojure -
127109 bajtówPrzykład:
Wyjaśnienie:
Jest to podstawowe, dość niezoptymalizowane podejście funkcjonalne. Tworzę leniwą listę wszystkich możliwości, używając prostej pętli nad nimi (pomija wszystkie kombinacje, które dawałyby zbyt duże liczby, zapobiegając przepełnieniu) i biorę pierwszą z nich. Jeśli nie ma żadnych możliwości, zwraca zero.
Najłatwiej przetestować na http://tryclj.com/ .
Zauważyłem też, że mogę zwrócić wszystkie możliwości:
120 bajtów102 bajty , ale daje wyniki w zagnieżdżonej liście.Przykład:
źródło
CJam, 31 bajtów
To podejście oparte na brutalnej sile, ale czas wykonania to tylko kilka sekund przy użyciu oficjalnego interpretera Java .
Jeśli chcesz przetestować kod za pomocą interpretera online , powinieneś utrzymywać odpowiednio niski poziom danych wejściowych. Coś mniej niż 2 26 nadal działa na moim komputerze.
Przykłady
Jak to działa
źródło
Java, 162
zwraca tablicę liczb całkowitych lub
null
jeśli nie istnieją kolejne liczby.bez golfa:
źródło
C 105
110spróbuj144 z bonusem: ten iteruje każdą liczbę i znajduje pasujące produkty
źródło
k < n
idzie z powodu zbyt wysokiejk *= l++
. Mógłbym dołączyć długo niepodpisany na początku, ale ... to zrujnowałoby życiePHP 258 znaków, 201 nie licząc funkcji silni.
Najprostszym sposobem matematycznego wyrażenia „następujących po sobie czynników, które są równe liczbie”, jest
X!/Y!
GdzieX
jest najwyższa liczba iY
najniższa minus jeden. Niestety przestałem pobierać rachunek różniczkowy, zanim nauczyłem się go rozwiązywaćZ = X!/Y!
, więc musiałem go nieco brutalizować.Brudna, nie golfowa wersja:
Przykładowe dane wyjściowe:
Gra w golfa:
Wynik:
Nie spodziewałem się, że czas działania będzie tak szybki!
źródło
Pyth , 35
Uwaga: Mój kod faktycznie znajduje najkrótszą reprezentację wejścia jako reprezentację kolejnych liczb całkowitych> = 2, więc przy nieprawidłowym wprowadzeniu wydrukuje listę 1 elementów, być może po bardzo długim czasie. Ponieważ w opisie problemu podano, że dane wejściowe będą prawidłowe, zakładam, że jest to prawidłowe.
Krótkie wyjaśnienie:
Zasadniczo program przechowuje górną i dolną granicę zakresu, oblicza iloczyn liczb w zakresie za pomocą redukcji, dostosowuje punkty końcowe w razie potrzeby i powtarza, aż iloczyn równa się wartości wejściowej.
Długie wyjaśnienie:
Dla każdego fragmentu kodu podam równoważny python, a także bardziej szczegółowe wyjaśnienie i uzasadnienie.
Jvw
=>J=eval(input())
Standardowy sposób wprowadzania danych w Pyth.
Kr2 4
=>K=range(2,4)
=>K=[2,3]
Oto pierwsza dziwna część: Zamiast przechowywać punkty końcowe jako osobne zmienne, przechowuję je jako elementy listy. Przyczyna wkrótce będzie jasna. Ponadto zamiast wykonywać proste zadanie, którym w Pyth byłby
K[2 3)
, używam zakresu do zapisania postaci.W-ZJ
=>while Z-J
=>while Z!=J
W tym momencie możesz zapytać: „Co to jest Z? Nie zdefiniowałeś go”. W Pyth wszystkie zmienne są wstępnie zdefiniowane. Z zaczyna się od 0. Jednak Z zostanie później ustawione na wartość produktu, więc to sprawdzenie będzie służyć do zakończenia pętli while, gdy lista będzie miała prawidłową wartość.
~@K>JZ1
=>K[J>Z] += 1
Oto dlaczego przechowuję wartości na liście, a nie w osobnych zmiennych: Chcę zwiększyć jeden z dwóch punktów końcowych, w zależności od tego, czy produkt jest obecnie zbyt wysoki, czy zbyt niski. Byłby to dość długi warunek, gdyby punkty końcowe były odrębnymi zmiennymi, ale dzięki magii indeksowania list staje się krótki. Ponadto fakt, że ta kontrola występuje przed produktem, oraz fakt, że Z jest inicjowane na 0, zapewniają, że K będzie
[2,4]
w momencie, gdy przyjmiemy produkt, które są odpowiednimi punktami końcowymi.=YurGHK
=>Y=reduce(lambda G,H: range(G,H),K)
=>Y=range(K[0],K[1])
Teraz potrzebuję faktycznej listy, że produkt zostanie przejęty i zostanie wydrukowany, jeśli nam się uda. Oczywiście użyjemy funkcji zasięgu. Trudność polega na uzyskaniu danych wejściowych do funkcji zakresu. Oczywistym sposobem na to byłoby indeksowanie listy
=Yr'K@K1
. Jednak używając funkcji redukcji na tej liście dwóch elementów, możemy ją skrócić o znak.=Zu*NTY
=>Z=reduce(lambda N,T: N*T,Y)
A teraz, przez cały ten romans, operacja zmniejszania w celu znalezienia produktu z listy.
)
=> Zakończ podczasY
=>print(Y)
Po sukcesie wydrukuj listę.
Przykładowy przebieg:
źródło
Java - 115
Nieco mniej golfa:
źródło
System.out.println
w golfa ,System.out.print
a średnik na końcufor(int k=1,x=j;(x*=j+k)<i;k++)
jest nie tylko niepotrzebny, ale także powoduje błędy.x
,j
,k
Są poza zakresem w ostatnichif/for
bloków powodu;
. Po usunięciu;
nic nie drukuje.print
oznaczałoby, że musi dodać znak spacji, aby uniknąć łączenia liczb.Matlab (88)
Kod oczekuje, że liczba zostanie zapisana
x
i wyprowadzonal
.Ponieważ
13! > 2^32
ten kod wyszukuje tylko produkty o długości od 2 do 12. Ten kod ma stały czas działania około 0,001 s.źródło
Scala - 86
Ten kod jest bardzo nieefektywny, ale jego optymalizacja dodałaby tylko kilka dodatkowych znaków. Wykorzystuje funkcjonalne podejście do sprawdzania produktów wszystkich możliwych kolejnych sekwencji. (kolejna sekwencja liczb całkowitych jest reprezentowana jako obiekt Range w Scali)
bez golfa:
źródło
CJam obecnie nie działa dla dużych liczb z powodu długiego czasu obliczeń
To jest mój najkrótszy kod CJam. Test na stronie http://cjam.aditsu.net/ . Działa poprzez: zdefiniowanie danych wejściowych jako A; tworzenie tablicy wszystkich liczb od 0 do A-1; Kopnięcie 0; wykopywanie najmniejszych liczb do momentu pomnożenia wszystkich liczb w tablicy nie jest większe niż A; sprawdzanie, czy jest większe niż A; jeśli nie, tworzenie tablicy od 0 do A-2; i powtarzanie aż do znalezienia odpowiedzi. Jeśli nie zostanie znaleziony, zgłoszony zostanie wyjątek. Nie uważałem, że potrzebne są spacje między liczbami, więc są one zawarte w drugim kodzie, który ma 32 znaki.
źródło
Dart - 102 znaki
To jest powolne wdrożenie. Można to zrobić szybciej, ale wymaga to więcej znaków (np. Wykonywanie pętli tylko do
i*i<n
)(102 znaki nie zawierają podziałów linii i spacji wiodących).
Aby go użyć, zrób coś takiego:
źródło
JavaScript, 88
Kod do gry w golfa:
Łatwiejszy do odczytania (ładnie rozmieszczony) kod:
Dla każdej liczby od 2 do liczby wejściowej wyszukuje iloczyn kolejnych liczb całkowitych od bieżącej liczby z powrotem do 2. Jeśli ten produkt jest równy liczbie wejściowej, to jest wyprowadzana seria kolejnych liczb wraz z pierwotną liczbą wejściową .
Wyprowadza numer wejściowy, a następnie kolejne liczby całkowite, których iloczynem jest liczba wejściowa.
Na przykład f (120) generuje alert z tekstem „120,5,4,3,2”, a następnie drugi alert z tekstem „120,6,5,4”.
źródło