обзор
В этом задании вам дадут два числа, которые оба будут с небольшим смещением, большим, чем кратное среднего числа. Вы должны вывести число среднего размера, которое является почти делителем обоих чисел, за исключением небольшого смещения.
Размер числа участвующего будет параметризирован параметром сложности, l
. Ваша цель состоит в том, чтобы решить проблему за максимально возможное время l
менее чем за 1 минуту.
Настроить
В данной проблеме будет секретное число p
, которое будет случайным числом l^2
( l*l
). Будет два умножителя, q1, q2
которые будут случайными l^3
числами битов, и будет два смещения r1, r2
, которые будут случайными l
числами битов.
Вход в вашу программу будет x1, x2
определен как:
x1 = p * q1 + r1
x2 = p * q2 + r2
Вот программа для генерации тестовых случаев в Python:
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)
Первая строка вывода - это возможное решение, в то время как вторая и третья строки - это ввод, который будет выдан вашей программе.
Ваша программа
Учитывая x1
, x2
и l
, вы должны найти l^2
битовое число p'
такое, что x1 % p'
и x2 % p'
оба являются l
битовыми числами. p
всегда будет работать, хотя могут быть и другие возможности. Вот функция для проверки решения:
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)
пример
Предположим, l
равен 3. Программа-генератор выбирает 9-битное число для p
, которое в данном случае равно 442
. Генератор выбирает два 3
битовых числа для r1, r2
, которые являются 4, 7
. Генератор выбирает два 27
битовых числа для q1, q2
, которые являются 117964803, 101808039
. Из-за этих выборов, x1, x2
есть 52140442930, 44999153245
.
Ваша программа будет предоставлена 52140442930, 44999153245
в качестве входных данных, и должен выводить 9-битное число (в диапазоне [256, 511]
) такой , что 52140442930
и по 44999153245
модулю этого числа дают 3 битовых чисел (в диапазоне [4, 7]
). 442
является единственным таким значением в этом случае, поэтому ваша программа должна будет выводить 442
.
Больше примеров
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
счет
Как уже упоминалось выше, оценка вашей программы является самой высокой l
которую программа завершает менее чем за 1 минуту. Точнее говоря, ваша программа будет запущена на 5 случайных экземплярах с этим l
, и она должна вывести правильный ответ на все 5, со средним временем менее 1 минуты. Оценка программы будет самой высокой, на l
которой она преуспевает. Tiebreaker будет в среднем на это l
.
Чтобы дать вам представление о том, к каким показателям нужно стремиться, я написал очень простой решатель грубой силы. Он получил 5 баллов. Я написал гораздо более интересный решатель. Он получил оценку 12 или 13, в зависимости от удачи.
Детали
Для идеальной сопоставимости ответов я буду рассчитывать время подачи заявок на своем ноутбуке, чтобы давать канонические оценки. Я также буду запускать одни и те же случайно выбранные экземпляры во всех представлениях, чтобы немного облегчить удачу. Мой ноутбук имеет 4 процессора, процессор i5-4300U @ 1,9 ГГц, 7,5 ГБ оперативной памяти.
Не стесняйтесь размещать предварительную оценку, основанную на вашем собственном времени, просто дайте понять, является ли она предварительной или канонической.
Пусть победит самая быстрая программа!
источник
l^2
число бит, которое находится вl
-битах от фактора обоих чисел, работает. Там, как правило, только один, однако.Ответы:
Ржавчина, L = 13
src/main.rs
Cargo.toml
Бежать
источник
Mathematica, L = 5
вот быстрое 5 решение
Вход
[x1, x2, L]
для того, чтобы кто-нибудь мог проверить это, вот генератор ключей
выберите L значение прогона, код, и вы получите три числа.
поместите последние два вместе с L в качестве ввода, и вы должны получить первый
источник
Mathematica, L = 12
вход [x1, x2, L]
для того, чтобы кто-нибудь мог проверить это, вот генератор ключей
выберите значение L, запустите код, и вы получите три числа.
поместите последние два вместе с L в качестве ввода, и вы должны получить первый
источник
l = 12
, это дало неправильный результат. В частности, результирующий делитель представлял собой 146-битное число, что слишком велико. Я думаю, что вам нужно всего лишь небольшое изменение, чтобы это исправить.l^2
биты, но вы также должны проверить, что в нем не большеl^2
битов.Питон, L = 15, среднее время 39,9 с
Этот код основан на том факте, что произведение x1 - r на все возможные значения r должно быть кратным p, и произведение x2 - r также должно быть. Большую часть времени тратят на получение gcd двух продуктов, каждый из которых имеет около 60 000 000 бит. Затем gcd, который имеет только около 250000 битов, снова сравнивается с каждым из значений xr, чтобы извлечь p 'кандидатов. Если они слишком велики, используется пробное деление, чтобы уменьшить их до соответствующего диапазона.
Это основано на библиотеке gmpy2 для Python, которая является тонкой оболочкой для библиотеки GNU MP, которая, в частности, имеет действительно хорошую процедуру gcd.
Этот код является однопоточным.
источник