Initial commit
This commit is contained in:
commit
f242d2b0df
420 changed files with 62521 additions and 0 deletions
51
2020/day25/day25.c
Normal file
51
2020/day25/day25.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MODULO 20201227UL
|
||||
#define PUB1 3248366UL
|
||||
#define PUB2 4738476UL
|
||||
|
||||
unsigned long modexp(unsigned long a, unsigned long b, unsigned long n) {
|
||||
if (b == 0) {
|
||||
return (n == 1) ? 0 : 1;
|
||||
}
|
||||
if (b == 1) {
|
||||
return a % n;
|
||||
}
|
||||
if (b % 2 == 0) {
|
||||
unsigned long c = modexp(a, b / 2, n);
|
||||
return (c * c) % n;
|
||||
}
|
||||
return (a * modexp(a, b - 1, n)) % n;
|
||||
}
|
||||
|
||||
unsigned long discrete_logarithm(unsigned long a, unsigned long b,
|
||||
unsigned long n) {
|
||||
unsigned long m = ceil(sqrt(n));
|
||||
unsigned long *table = calloc(n, sizeof(unsigned long));
|
||||
|
||||
for (size_t j = 0; j < m; ++j) {
|
||||
table[modexp(a, j, n)] = j;
|
||||
}
|
||||
unsigned long t = modexp(a, n - m - 1, n);
|
||||
|
||||
unsigned long res = 0;
|
||||
unsigned long c = b;
|
||||
for (size_t i = 0; i < m; ++i) {
|
||||
if (table[c] != 0) {
|
||||
res = table[c] + i * m;
|
||||
break;
|
||||
}
|
||||
c = (c * t) % n;
|
||||
}
|
||||
free(table);
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
unsigned long priv1 = discrete_logarithm(7, PUB1, MODULO);
|
||||
printf("%lu\n", modexp(PUB2, priv1, MODULO));
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
36
2020/day25/day25.rkt
Normal file
36
2020/day25/day25.rkt
Normal file
|
@ -0,0 +1,36 @@
|
|||
#lang racket/base
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (modular-expt a b n)
|
||||
(if (= b 0)
|
||||
(if (= 1 n) 0 1)
|
||||
(let loop ([b b])
|
||||
(cond
|
||||
[(= b 1) (modulo a n)]
|
||||
[(even? b) (define c (loop (quotient b 2)))
|
||||
(modulo (* c c) n)]
|
||||
[else (modulo (* a (loop (sub1 b))) n)]))))
|
||||
|
||||
;; https://en.wikipedia.org/wiki/Baby-step_giant-step
|
||||
(define (discrete-logarithm a b n)
|
||||
(define m (inexact->exact (ceiling (sqrt n))))
|
||||
(define h (for/hash ([j (in-range m)])
|
||||
(values (modular-expt a j n) j)))
|
||||
(define t (modular-expt a (- n m 1) n))
|
||||
(let loop ([c b]
|
||||
[i 0])
|
||||
(if (hash-has-key? h c)
|
||||
(+ (hash-ref h c) (* i m))
|
||||
(loop (modulo (* c t) n) (add1 i)))))
|
||||
|
||||
(define (part1 public1 public2)
|
||||
(define private1 (discrete-logarithm 7 public1 20201227))
|
||||
(modular-expt public2 private1 20201227))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 5764801 17807724) 14897079))
|
||||
|
||||
(module+ main
|
||||
(displayln (part1 3248366 4738476)))
|
2
2020/day25/input
Normal file
2
2020/day25/input
Normal file
|
@ -0,0 +1,2 @@
|
|||
3248366
|
||||
4738476
|
Loading…
Add table
Add a link
Reference in a new issue