Visão geral
Nesse desafio, você receberá dois números, ambos com um pequeno deslocamento maior que um múltiplo de um número de tamanho médio. Você deve produzir um número de tamanho médio que seja quase um divisor de ambos os números, exceto por um pequeno deslocamento.
O tamanho dos números envolvidos será parametrizado por um parâmetro de dificuldade l
,. Seu objetivo é resolver o problema o maior possível l
em menos de 1 minuto.
Configuração
Em um determinado problema, haverá um número secreto p
, que será um número de bit aleatório l^2
( l*l
). Haverá dois multiplicadores, q1, q2
que serão l^3
números de bits aleatórios , e haverá dois deslocamentos r1, r2
, que serão l
números de bits aleatórios .
A entrada para o seu programa será x1, x2
definida como:
x1 = p * q1 + r1
x2 = p * q2 + r2
Aqui está um programa para gerar casos de teste, em 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)
A primeira linha de saída é uma solução possível, enquanto a segunda e a terceira linhas são a entrada que seu programa receberá.
O seu programa
Dado x1
, x2
e l
, você deve encontrar um l^2
número de bits p'
tal que x1 % p'
e x2 % p'
sejam ambos l
números de bits. p
sempre funcionará, embora possa haver outras possibilidades. Aqui está uma função para verificar uma solução:
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)
Exemplo
Suponha que l
seja 3. O programa gerador escolhe um número de 9 bits para p
, que neste caso é 442
. O gerador escolhe 3
números de dois bits para r1, r2
, quais são 4, 7
. O gerador escolhe 27
números de dois bits para q1, q2
, quais são 117964803, 101808039
. Por causa dessas escolhas, x1, x2
são 52140442930, 44999153245
.
Seu programa seria dado 52140442930, 44999153245
como entrada e deve gerar um número de 9 bits (no intervalo [256, 511]
) tal que, 52140442930
e 44999153245
esse módulo, forneça números de 3 bits (no intervalo [4, 7]
). 442
é o único valor nesse caso; portanto, seu programa precisaria produzir 442
.
Mais exemplos
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
Pontuação
Como mencionado acima, a pontuação do seu programa é a mais alta possível l
em menos de 1 minuto. Mais especificamente, seu programa será executado em 5 instâncias aleatórias com isso l
e deve gerar uma resposta correta em todas as 5, com um tempo médio inferior a 1 minuto. A pontuação de um programa será a mais alta l
possível. O desempate será o tempo médio para isso l
.
Para ter uma idéia de quais pontuações apontar, escrevi um solucionador de força bruta muito simples. Obteve uma pontuação de 5. Escrevi um solucionador muito mais sofisticado. Tem uma pontuação de 12 ou 13, dependendo da sorte.
Detalhes
Para uma perfeita comparabilidade entre as respostas, cronometrarei os envios no meu laptop para fornecer pontuações canônicas. Também executarei as mesmas instâncias escolhidas aleatoriamente em todos os envios, para aliviar um pouco a sorte. Meu laptop possui 4 CPUs, i5-4300U CPU a 1,9 GHz, 7,5G de RAM.
Sinta-se à vontade para postar uma pontuação provisória com base no seu próprio tempo, apenas deixe claro se é provisória ou canônica.
Que ganhe o programa mais rápido!
fonte
l^2
número de bit que esteja al
menos de um fator de ambos os números funciona. No entanto, normalmente há apenas um.Respostas:
Ferrugem, L = 13
src/main.rs
Cargo.toml
Para correr
fonte
Mathematica, L = 5
aqui está uma solução rápida 5
Entrada
[x1, x2, L]
para que alguém possa testar isso, aqui está o gerador de chaves
escolha o valor L executado, o código e você obterá três números.
coloque os dois últimos junto com L como entrada e você deverá obter o primeiro
fonte
Mathematica, L = 12
entrada [x1, x2, L]
para que alguém possa testar isso, aqui está o gerador de chaves
escolha o valor L, execute o código e você obterá três números.
coloque os dois últimos junto com L como entrada e você deverá obter o primeiro
fonte
l = 12
, deu um resultado incorreto. Especificamente, o divisor resultante era um número de 146 bits, que é muito grande. Acho que você precisará apenas de uma pequena alteração para corrigir isso.l^2
bits, mas também precisa verificar se ela possui no máximol^2
bits.Python, L = 15, tempo médio 39,9s
Esse código é baseado no fato de que o produto de x1 - r para todos os valores possíveis de r deve ser um múltiplo de p e o produto de x2 - r também. Na maioria das vezes, é gasto o MDC dos dois produtos, cada um com cerca de 60.000.000 de bits. O gcd, que possui apenas cerca de 250.000 bits, é comparado a cada um dos valores xr mais uma vez, para extrair candidatos p '. Se eles são um pouco grandes demais, a divisão de teste é usada para reduzi-los ao intervalo apropriado.
Isso se baseia na biblioteca gmpy2 para Python, que é um invólucro fino para a biblioteca GNU MP, que em particular possui uma rotina gcd realmente boa.
Este código é de thread único.
fonte