Przegląd
W tym wyzwaniu otrzymasz dwie liczby, które są małym przesunięciem większym niż wielokrotność liczby średniej wielkości. Musisz wypisać średnią liczbę, która jest prawie dzielnikiem obu liczb, z wyjątkiem niewielkiego przesunięcia.
Wielkość zaangażowanych numery będą programowane przez parametr trudności, l. Twoim celem jest rozwiązanie problemu w jak największym stopniu lw mniej niż 1 minutę.
Ustawiać
W danym problemie będzie tajny numer p, który będzie losową l^2( l*l) liczbą bitów. Będą dwa mnożniki, q1, q2które będą losowymi l^3liczbami bitowymi, i będą dwa przesunięcia r1, r2, które będą losowymi lliczbami bitowymi.
Dane wejściowe do Twojego programu będą x1, x2zdefiniowane jako:
x1 = p * q1 + r1
x2 = p * q2 + r2
Oto program do generowania przypadków testowych w Pythonie:
from random import randrange
from sys import argv
l = int(argv[1])
def randbits(bits):
return randrange(2 ** (bits - 1), 2 ** bits)
p = randbits(l ** 2)
print(p)
for i in range(2):
q_i = randbits(l ** 3)
r_i = randbits(l)
print(q_i * p + r_i)
Pierwszy wiersz wyniku jest możliwym rozwiązaniem, natomiast drugi i trzeci wiersz to dane wejściowe, które otrzyma Twój program.
Twój program
Biorąc pod uwagę x1, x2i ltrzeba znaleźć l^2numer bitu p'takie, że x1 % p'i x2 % p'są zarówno lnumery bitowe. pzawsze będzie działać, choć mogą istnieć inne możliwości. Oto funkcja weryfikacji rozwiązania:
def is_correct(x1, x2, l, p_prime):
p_prime_is_good = p_prime >> (l**2 - 1) and not p_prime >> l ** 2
x1_is_good = (x1 % p_prime) >> (l-1) and not (x1 % p_prime) >> l
x2_is_good = (x2 % p_prime) >> (l-1) and not (x2 % p_prime) >> l
return bool(p_prime_is_good and x1_is_good and x2_is_good)
Przykład
Załóżmy, że ljest to 3. Generator wybiera 9-bitową liczbę p, która w tym przypadku jest 442. Generator wybiera dwa 3bitowych liczb dla r1, r2, które są 4, 7. Generator wybiera dwa 27bitowych liczb dla q1, q2, które są 117964803, 101808039. Z powodu tych wyborów x1, x2są 52140442930, 44999153245.
Twój program byłby podawany 52140442930, 44999153245jako dane wejściowe i musi wypisać 9-bitową liczbę (w zakresie [256, 511]), tak aby 52140442930i 44999153245modulo ta liczba dawała 3-bitowe liczby (w zakresie [4, 7]). 442jest jedyną taką wartością w tym przypadku, więc twój program musiałby generować dane wyjściowe 442.
Więcej przykładów
l = 2
x1 = 1894
x2 = 2060
p = 11
No other p'.
l = 3
x1 = 56007668599
x2 = 30611458895
p = 424
No other p'.
l = 6
x1 = 4365435975875889219149338064474396898067189178953471159903352227492495111071
x2 = 6466809655659049447127736275529851894657569985804963410176865782113074947167
p = 68101195620
I don't know whether there are other p'.
l = 12
x1 = 132503538560485423319724633262218262792296147003813662398252348727558616998821387759658729802732555377599590456096450977511271450086857949046098328487779612488702544062780731169071526325427862701033062986918854245283037892816922645703778218888876645148150396130125974518827547039720412359298502758101864465267219269598121846675000819173555118275197412936184329860639224312426860362491131729109976241526141192634523046343361089218776687819810873911761177080056675776644326080790638190845283447304699879671516831798277084926941086929776037986892223389603958335825223
x2 = 131643270083452525545713630444392174853686642378302602432151533578354175874660202842105881983788182087244225335788180044756143002547651778418104898394856368040582966040636443591550863800820890232349510212502022967044635049530630094703200089437589000344385691841539471759564428710508659169951391360884974854486267690231936418935298696990496810984630182864946252125857984234200409883080311780173125332191068011865349489020080749633049912518609380810021976861585063983190710264511339441915235691015858985314705640801109163008926275586193293353829677264797719957439635
p = 12920503469397123671484716106535636962543473
I don't know whether there are other p'.
l = 12
x1 = 202682323504122627687421150801262260096036559509855209647629958481910539332845439801686105377638207777951377858833355315514789392768449139095245989465034831121409966815913228535487871119596033570221780568122582453813989896850354963963579404589216380209702064994881800638095974725735826187029705991851861437712496046570494304535548139347915753682466465910703584162857986211423274841044480134909827293577782500978784365107166584993093904666548341384683749686200216537120741867400554787359905811760833689989323176213658734291045194879271258061845641982134589988950037
x2 = 181061672413088057213056735163589264228345385049856782741314216892873615377401934633944987733964053303318802550909800629914413353049208324641813340834741135897326747139541660984388998099026320957569795775586586220775707569049815466134899066365036389427046307790466751981020951925232623622327618223732816807936229082125018442471614910956092251885124883253591153056364654734271407552319665257904066307163047533658914884519547950787163679609742158608089946055315496165960274610016198230291033540306847172592039765417365770579502834927831791804602945514484791644440788
p = 21705376375228755718179424140760701489963164
Punktacja
Jak wspomniano powyżej, wynik twojego programu jest najwyższy, lktóry program ukończy w czasie krótszym niż 1 minuta. Mówiąc dokładniej, twój program będzie działał na 5 losowych instancjach z tym li musi wypisać poprawną odpowiedź na wszystkich 5, przy średnim czasie poniżej 1 minuty. Wynik programu będzie najwyższy l, jeśli odniesie sukces. Tiebreaker będzie na to średni czas l.
Aby dać ci wyobrażenie o tym, do jakich wyników chcesz dążyć, napisałem bardzo prosty solute brute-force. Otrzymał ocenę 5. Napisałem znacznie bardziej wymyślny solver. Otrzymał wynik 12 lub 13, w zależności od szczęścia.
Detale
Aby uzyskać doskonałą porównywalność między odpowiedziami, będę przesyłać czas na laptopie, aby uzyskać wyniki kanoniczne. Będę również uruchamiał te same losowo wybrane instancje dla wszystkich zgłoszeń, aby nieco złagodzić szczęście. Mój laptop ma 4 procesory, procesor i5-4300U przy 1,9 GHz, 7,5G pamięci RAM.
Możesz opublikować tymczasowy wynik na podstawie własnego harmonogramu, po prostu wyjaśnij, czy jest on tymczasowy, czy kanoniczny.
Niech wygra najszybszy program!
l^2liczba lbitów oddalona od bycia czynnikiem obu liczb. Zazwyczaj jednak jest tylko jeden.