feat: add modular inv

This commit is contained in:
2025-07-17 23:37:06 +08:00
parent 6a69835399
commit d074410004
4 changed files with 194 additions and 53 deletions

63
.gitignore vendored
View File

@@ -1,54 +1,11 @@
# ---> Java out/
# Compiled class file build
*.class classes
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
# ---> macOS
# General
.DS_Store .DS_Store
.AppleDouble .gradle
.LSOverride .classpath
.project
# Icon must end with two \r .settings
Icon *.iml
*.ipr
*.iws
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

100
build.gradle Normal file
View File

@@ -0,0 +1,100 @@
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
def JsonSlurper = Class.forName('groovy.json.JsonSlurper');
def buildJSON = JsonSlurper.newInstance().parseText(new File("build.json").text)
if (buildJSON.application) { apply plugin: 'application' }
def baseProjectName = buildJSON?.project?.name ?: '__project_name__';
def shellCommandName = baseProjectName
def eclipseProjectName = baseProjectName
def eclipseProjectComment = buildJSON?.project?.comment ?: '__project_name_comment__'
def jarManifestMainClass = buildJSON?.project?.main ?: 'SampleMain'
if (buildJSON.application) { mainClassName = jarManifestMainClass }
archivesBaseName = buildJSON?.project?.archiveName ?: baseProjectName
sourceCompatibility = 1.8
targetCompatibility = 1.8
def addRepo = new File(System.getProperty("user.home"), ".build_add.repo")
repositories {
mavenLocal()
// mavenCentral()
maven() { url 'https://maven.aliyun.com/repository/central' }
if (addRepo.exists()) { maven() { url addRepo.text.trim() } }
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
// '-x test' skip unit test
defaultTasks 'packjar'
task packjarsrc << {
ant.jar(destfile: "${baseProjectName}-sources.jar") {
fileset(dir: 'src/main/java', includes: '**/*.java')
}
}
packjarsrc.dependsOn build
task packjar << {
def packtempclasses = "packtempclasses"
def libs = ant.path {
fileset(dir: 'build/libs', includes: '*.jar')
}
libs.list().each {
ant.unzip(dest: packtempclasses, src: it)
}
new File(packtempclasses + "/jar-version-build.txt").write(new Date().format("yyyyMMdd"), "UTF-8")
ant.jar(destfile: "${baseProjectName}.jar") {
fileset(dir: packtempclasses, includes: '**/*.*')
}
ant.delete(dir: packtempclasses)
}
packjar.dependsOn packjarsrc
dependencies {
compile files(fileTree(dir: 'lib', includes: ['*.jar'], excludes: ['*-sources.jar', '*-javadoc.jar']))
if (buildJSON.repo != null && buildJSON.repo.dependencies != null) {
buildJSON.repo.dependencies.each {
compile("${it}")
}
}
if (buildJSON.repo != null && buildJSON.repo.testDependencies != null) {
buildJSON.repo.testDependencies.each {
testCompile("${it}")
}
}
}
eclipse {
project {
name = eclipseProjectName
comment = eclipseProjectComment
}
classpath {
defaultOutputDir = file('classes')
downloadSources = true
file {
whenMerged { classpath ->
classpath.entries.findAll { it.kind=='lib' }.each {
if ((it.path != null) && (it.sourcePath == null) && file(it.path.replace(".jar", "-sources.jar")).exists()) {
it.sourcePath = getFileReferenceFactory().fromPath(it.path.replace(".jar", "-sources.jar"))
}
}
}
}
}
}
eclipseJdt << {
File f = file('.settings/org.eclipse.core.resources.prefs')
f.write('eclipse.preferences.version=1\n')
f.append('encoding/<project>=utf-8')
}

21
build.json Normal file
View File

@@ -0,0 +1,21 @@
{
"project": {
"name": "math",
"main": "SampleMain",
"archiveName": "math"
},
"application": false,
"java": "1.8",
"builder": {
"name": "gradle",
"version": "3.1"
},
"repo": {
"dependencies": [
"me.hatter:commons:3.0"
],
"testDependencies": [
"junit:junit:4.12"
]
}
}

View File

@@ -0,0 +1,63 @@
package me.hatter.math;
import java.math.BigInteger;
import java.util.Arrays;
// https://zhuanlan.zhihu.com/p/426499159
// def modular_inv(a, p):
// x, y, m = 1, 0, p
// while a > 1:
// q = a // m
// t = m
//
// m = np.mod(a, m)
// a = t
// t = y
//
// y, x = x - np.int64(q) * np.int64(y), t
//
// if x < 0:
// x = np.mod(x, p)
// return np.mod(x, p)
public class ModularInv {
public static void main(String[] args) {
for (long i = 1; i < 10000; i++) {
for (long j = 1; j < 10000; j++) {
BigInteger a = BigInteger.valueOf(i);
BigInteger p = BigInteger.valueOf(j);
if (!a.gcd(p).equals(BigInteger.ONE)) {
continue;
}
BigInteger x = a.modInverse(p);
BigInteger y = modularInv(a, p);
System.out.println(Arrays.asList(a, p, a.modInverse(p), modularInv(a, p)));
if (!y.equals(x)) {
throw new RuntimeException();
}
}
}
}
public static BigInteger modularInv(BigInteger a, BigInteger p) {
BigInteger x = BigInteger.ONE;
BigInteger y = BigInteger.ZERO;
BigInteger m = p;
while (a.compareTo(BigInteger.ONE) > 0) {
BigInteger q = a.divide(m);
BigInteger t = m;
m = a.mod(m);
a = t;
t = y;
y = x.subtract(q.multiply(y));
x = t;
if (x.compareTo(BigInteger.ZERO) < 0) {
x = x.mod(p);
}
}
return x.mod(p);
}
}