Aperçu
Dans ce défi, vous recevrez deux nombres qui sont tous deux un petit décalage plus grand qu'un multiple d'un nombre de taille moyenne. Vous devez sortir un nombre de taille moyenne qui est presque un diviseur des deux nombres, à l'exception d'un petit décalage.
La taille des effectifs concernés sera paramétré par un paramètre de difficulté, l
. Votre objectif est de résoudre le problème le plus largement possible l
en moins d'une minute.
Installer
Dans un problème donné, il y aura un nombre secret p
, qui sera un nombre aléatoire l^2
( l*l
). Il y aura deux multiplicateurs, q1, q2
qui seront des l^3
nombres de bits aléatoires , et il y aura deux décalages r1, r2
, qui seront des l
nombres de bits aléatoires .
L'entrée dans votre programme sera x1, x2
définie comme suit:
x1 = p * q1 + r1
x2 = p * q2 + r2
Voici un programme pour générer des cas de test, en 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)
La première ligne de sortie est une solution possible, tandis que les deuxième et troisième lignes sont l'entrée que votre programme recevra.
Votre programme
Étant donné x1
, x2
et l
, vous devez trouver un l^2
nombre de bits p'
tel que x1 % p'
et x2 % p'
sont tous deux l
des nombres de bits. p
fonctionnera toujours, bien qu'il puisse y avoir d'autres possibilités. Voici une fonction pour vérifier une solution:
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)
Exemple
Supposons que l
3. Le programme générateur choisit un nombre de 9 bits pour p
, qui dans ce cas est 442
. Le générateur sélectionne deux 3
nombres de bits pour r1, r2
, qui sont 4, 7
. Le générateur sélectionne deux 27
nombres de bits pour q1, q2
, qui sont 117964803, 101808039
. En raison de ces choix, le x1, x2
sont 52140442930, 44999153245
.
Votre programme serait donné 52140442930, 44999153245
en entrée et doit sortir un nombre de 9 bits (dans la plage [256, 511]
) tel que 52140442930
et 44999153245
modulo ce nombre donne des nombres de 3 bits (dans la plage [4, 7]
). 442
est la seule valeur de ce type dans ce cas, donc votre programme devrait sortir 442
.
Plus d'exemples
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
Notation
Comme mentionné ci-dessus, le score de votre programme est le plus élevé l
que le programme termine en moins d'une minute. Plus précisément, votre programme sera exécuté sur 5 instances aléatoires avec cela l
, et il doit produire une réponse correcte sur les 5, avec un temps moyen inférieur à 1 minute. Le score d'un programme sera le plus élevé l
auquel il réussira. Tiebreaker sera le temps moyen à ce sujet l
.
Pour vous donner une idée des scores à viser, j'ai écrit un solveur de force brute très simple. Il a obtenu un score de 5. J'ai écrit un solveur beaucoup plus sophistiqué. Il a obtenu un score de 12 ou 13, selon la chance.
Détails
Pour une parfaite comparabilité entre les réponses, je chronomètre les soumissions sur mon ordinateur portable pour donner des scores canoniques. Je vais également exécuter les mêmes instances choisies au hasard sur toutes les soumissions, pour alléger quelque peu la chance. Mon ordinateur portable possède 4 processeurs, un processeur i5-4300U à 1,9 GHz, 7,5 G de RAM.
N'hésitez pas à publier un score provisoire basé sur votre propre timing, indiquez simplement s'il est provisoire ou canonique.
Que le programme le plus rapide gagne!
la source
l^2
nombre de bits qui est àl
-bits d'être un facteur des deux nombres fonctionne. Cependant, il n'y en a généralement qu'un.Réponses:
Rouille, L = 13
src/main.rs
Cargo.toml
Courir
la source
Mathematica, L = 5
voici une solution rapide à 5
Entrée
[x1, x2, L]
afin que tout le monde puisse le tester, voici le générateur de clés
choisissez la valeur L exécutée, le code et vous obtiendrez trois nombres.
placez les deux derniers avec L comme entrée, et vous devriez obtenir le premier
la source
Mathematica, L = 12
contribution [x1, x2, L]
afin que tout le monde puisse le tester, voici le générateur de clés
choisissez la valeur L, exécutez le code et vous obtiendrez trois nombres.
placez les deux derniers avec L comme entrée, et vous devriez obtenir le premier
la source
l = 12
, cela a donné un résultat incorrect. Plus précisément, le diviseur résultant était un nombre de 146 bits, ce qui est trop grand. Je pense que vous n'aurez besoin que d'un petit changement pour résoudre ce problème.l^2
bits, mais vous devez également vérifier qu'elle contient au plus del^2
bits.Python, L = 15, temps moyen 39,9 s
Ce code est basé sur le fait que le produit de x1 - r pour toutes les valeurs possibles de r doit être un multiple de p, et le produit de x2 - r doit également l'être. La plupart du temps est consacré à prendre le gcd des deux produits, chacun ayant environ 60 000 000 bits. Le pgcd, qui n'a que 250 000 bits environ, est ensuite à nouveau comparé à chacune des valeurs xr, pour extraire p 'candidats. S'ils sont un peu trop grands, la division d'essai est utilisée pour les réduire à la plage appropriée.
Ceci est basé sur la bibliothèque gmpy2 pour Python, qui est un wrapper mince pour la bibliothèque GNU MP, qui a en particulier une très bonne routine gcd.
Ce code est monothread.
la source