Cel
Biorąc pod uwagę dane wejściowe r
i n
znajdź pierwsze n
liczby naturalne x
, które po obróceniu pierwszej cyfry do ostatniego miejsca uzyskamy x/r
.
Możesz założyć, że 2 <= r <= 9
i 1 <= n <= 65535
.
Możesz napisać program, który pobiera dane wejściowe z argumentów stdin lub wiersza poleceń; lub możesz napisać funkcję, która przyjmuje r
i n
jako parametry. Wyjście jednak powinno być na standardowe wyjście. Wynik powinien wynosić jeden wiersz na wartość x
, sformatowany jako x/r=y
, w kolejności rosnącej x
.
Twoje rozwiązanie musi być w stanie obsłużyć wszystkie ważne sprawy w ciągu jednej minuty na rozsądnym komputerze stacjonarnym.
Przypadki testowe
Wejście: 4 5
Wyjście:
102564/4=25641
205128/4=51282
307692/4=76923
410256/4=102564
512820/4=128205
Wejście: 5 1
Wyjście:714285/5=142857
To jest golf golfowy, więc najmniej bajtów wygrywa. Zwycięska odpowiedź zostanie zaakceptowana za 4 tygodnie (2014-09-19).
Podziękowania za to pytanie należą się mojemu koledze, który pozwolił mi zamieścić to pytanie tutaj :)
źródło
gprof
, jeden przypadek wejściowy dla mojego programu spędza mniej niż pół sekundy w moim kodzie, ale zajmuje łącznie około 80 sekund, co, jak zakładam, musi w większości blokować wyjście.printf
.Odpowiedzi:
Haskell,
182179Druga wersja, prawdopodobnie dalsza gra w golfa, ale tym razem z „właściwym” algorytmem. W szczególności kończy się w ciągu kilku minut za pomocą
r=4
in=65535
, ale znowu mój komputer nie jest ani rozsądny, ani stacjonarny, więc są szanse, że pozostanie w ciągu minuty na innych komputerach.Opiera się na pomyśle
x=10^k*a + m
, w którym pierwsza cyfra0≤a≤9
jest przenoszona do końca w celu uzyskaniay=10*m+a
. Trochę matematyki wynika, żem
można otrzymać jaka*(10^k-r)/(10*r-1)
, więc po prostu zeskanowaća
ponad[1..9]
dla każdegok
od 0 do nieskończoności, i zachować i wydrukować pierwszen
wyniki, dla których powyższe wyrażeniem
jest integralny.fromIntegral
Jest wymagane, ponieważread
ing listę zn
jako jeden z jej elementówmain
, w połączeniu z zastosowaniemn
wtake
, zmusir
abyInt
przez cały czas, co powoduje nieprzyjemnych przelewów z dużych liczb w pytaniu. Mógłbym użyćgenericTake
, ale to wymagaimport
.Ten kod ma również tę zaletę, że można go prawie trywialnie rozszerzyć na bazy inne niż 10.
Dane wejściowe są odczytywane
stdin
, dwie wartości można oddzielić dowolnymi spacjami.źródło
r = 5; n = 65535
w ciągu minuty?y`mod`10
zmod y10
, który jest char krótszyPure Bash (bez zewnętrznych narzędzi), 80 bajtów
Uwaga: bash wykonuje tylko arytmetykę liczb całkowitych, a nie zmiennoprzecinkowe, więc sprawdzamy, czy
x == y * r
zamiastx / r == y
. Również mnożenie powinno zasadniczo być szybsze. Mimo to nie jest to wcale blisko spełnienia wymagań dotyczących wydajności.Wynik:
źródło
C 468
(Niektóre znaki nowej linii, które nie są liczone w liczbie bajtów, zostały dodane powyżej, aby wyeliminować paski przewijania. Tak, liczona jest nowa linia).
Oczekuje argumentów w wierszu poleceń i zakłada, że standardowe wyjście akceptuje ASCII. Środowisko wykonawcze to O (liczba wyjściowych bajtów) = O (n * n).
Nie, nie mogę użyć
printf
. To zajmuje zbyt dużo czasu i przesuwa program ponad limit minut na moim pulpicie. W tej chwili niektóre przypadki testowe zajmują około 30 sekund.Algorytm traktuje dane wyjściowe jako ciągi, a nie liczby, ponieważ szybko stają się one ogromne, a na wydruku są silne wzorce.
Nieco golfisty:
Dowód
że program rozwiązuje problem:
(Na dowód, przyjmujemy, że wszystkie operatory i funkcje są prawdziwymi funkcjami matematycznymi, a nie operacjami komputerowymi, które je przybliżają.
^
Oznacza potęgowanie, a nie bitowe xor.)Dla jasności użyję funkcji
ToDec
do opisania zwykłego procesu zapisywania liczby jako ciągu cyfr dziesiętnych. Jego zasięg to zestaw uporządkowanych krotek{0...9}
. Na przykład,Dla dodatniej liczby całkowitej
n
należy zdefiniowaćL(n)
liczbę cyfr w reprezentacji dziesiętnejn
; lub,Dla dodatniej liczby całkowitej
k
i nieujemnej liczby całkowitejn
zL(n)<k
, zdefiniujRep_k(n)
jako liczbę rzeczywistą uzyskaną przez dodanie zer przed cyframi dziesiętnymin
, jeśli to konieczne, aby uzyskaćk
liczby całkowite, a następnie nieskończone powtarzanie tychk
cyfr po przecinku. Na przykładMnożenie
Rep_k(n) * 10^k
daje cyfryn
przed kropką dziesiętną, a cyfry (wypełnione zerą)n
nieskończenie powtarzane po kropce dziesiętnej. WięcBiorąc pod uwagę dodatnią liczbę całkowitą
r
, załóżmy, żex
jest to rozwiązanie problemu, igdzie
x_1 != 0
ik = L(x)
.Rozwiązaniem
x
jest wielokrotnośćr
iZastosowanie
Rep_k
funkcji daje ładne równanie:Używając zamkniętego formularza z góry,
x_1
musi być w zestawie{1 ... 9}
.r
został określony w zestawie{2 ... 9}
. Teraz jedynym pytaniem jest, dla jakich wartościk
powyższej formułyx
podaje dodatnią liczbę całkowitą? Rozważymy każdą możliwą wartośćr
indywidualnie.Gdy
r
= 2, 3, 6, 8 lub 9,10r-1
wynosi odpowiednio 19, 29, 59, 79 lub 89. We wszystkich przypadkach mianownikp = 10r-1
jest liczbą pierwszą. W liczniku10^k-1
może być tylko wielokrotnośćp
, co dzieje się, gdyZestaw roztworów jest zamykany w trakcie dodawania i odejmowania, co nie skutkuje liczbą ujemną. Tak więc zestaw zawiera wszystkie wielokrotności jakiegoś wspólnego czynnika, który jest również najmniej pozytywnym rozwiązaniem
k
.Kiedy
r = 4
i10r-1 = 39
; lub kiedyr = 7
i10r-1 = 69
mianownik ma 3 razy inną liczbę pierwsząp=(10r-1)/3
.10^k-1
jest zawsze wielokrotnością liczby 3 i ponownie żaden inny czynnik licznika nie może być wielokrotnościąp
, więc ponownie problem zmniejsza się doi znowu wszystkie rozwiązania są wielokrotnościami najmniej pozytywnego rozwiązania
k
.[Nie skończony...]
źródło
Python -
9190Oto pierwszy strzał:
Edycja: Ok, prawdopodobnie jest to sposób na spowolnienie, aby osiągnąć wymagany 1-minutowy limit czasu dla liczb 65K.
źródło
JavaScript - 145
nie grał w golfa:
źródło
(5,4)
. Powodem, dla którego nie zadziała, jest to, że liczby stają się bardzo duże. a) Znacznie większa niż liczba w JS może dokładnie reprezentować ib) zdecydowanie zbyt duża, ponieważ byłoby możliwe, aby iterować po wszystkich liczbach, aby się tam dostać.Python 3 -
223179 bajtówImplementacja rozwiązania TheSpanishInquisition w języku Python:
Biegać:
python3 <whatever you named it>.py
Wynik:
Wyniki:
https://oeis.org/A092697 to pierwsza wartość dla każdego r.
Wydaje się, że tylko niektóre wartości k dają odpowiedzi, a przedział jest regularny. Np. Dla r = 4:
Interwały są następujące:
To tworzy https://oeis.org/A094224 .
Korzystając z tych wartości, można zbudować bardziej wydajną wersję:
Nie mogę jednak (jeszcze) udowodnić, że jest to kontynuowane matematycznie.
Wyniki dla r = 5:
źródło
9 65535
?unsigned long long
do tego użyć i sprawić, aby było to wielordzeniowe, aby zrobić to w ciągu jednej minuty.unsigned long long
ma 64 bity, nie jest wystarczająco duży.