Initial commit
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
/target
|
||||||
|
|
||||||
|
out.bin
|
||||||
Generated
+404
@@ -0,0 +1,404 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ansiterm"
|
||||||
|
version = "0.12.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ab587f5395da16dd2e6939adf53dede583221b320cadfb94e02b5b7b9bf24cc"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitvec"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
|
||||||
|
dependencies = [
|
||||||
|
"funty",
|
||||||
|
"radium",
|
||||||
|
"tap",
|
||||||
|
"wyz",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console"
|
||||||
|
version = "0.15.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
|
||||||
|
dependencies = [
|
||||||
|
"encode_unicode",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"unicode-width",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.8.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encode_unicode"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "funty"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indicatif"
|
||||||
|
version = "0.17.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3"
|
||||||
|
dependencies = [
|
||||||
|
"console",
|
||||||
|
"instant",
|
||||||
|
"number_prefix",
|
||||||
|
"portable-atomic",
|
||||||
|
"rayon",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "instant"
|
||||||
|
version = "0.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.158"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "number_prefix"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "portable-atomic"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.86"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "radium"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tap"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wrinkler"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"ansiterm",
|
||||||
|
"bitvec",
|
||||||
|
"indicatif",
|
||||||
|
"rand",
|
||||||
|
"rayon",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wyz"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
|
||||||
|
dependencies = [
|
||||||
|
"tap",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.7.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"zerocopy-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.7.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "wrinkler"
|
||||||
|
version = "0.0.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ansiterm = "0.12.2"
|
||||||
|
bitvec = "1.0.1"
|
||||||
|
indicatif = { version = "0.17.8", features = ["rayon"] }
|
||||||
|
rand = "0.8.5"
|
||||||
|
rayon = "1.10.0"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tincidunt efficitur magna. In non malesuada tellus. Nam at suscipit enim, ut tempor risus. Suspendisse varius ultrices ipsum, eget sollicitudin risus cursus sit amet. Donec congue sed mauris eget aliquam. Praesent vestibulum nibh quis purus blandit sollicitudin. Integer ac libero condimentum, faucibus ex eu, scelerisque augue. Donec nulla sem, luctus id finibus eget, porta nec felis. Curabitur at orci nisl. Donec et ligula nec odio dictum placerat in et felis.
|
||||||
|
|
||||||
|
Etiam mollis sodales felis et auctor. Fusce at vestibulum est. Mauris mattis arcu sit amet risus blandit, nec rhoncus lorem elementum. Morbi molestie arcu dolor, ut molestie leo egestas pulvinar. Maecenas imperdiet felis vitae orci commodo, in feugiat nisl sollicitudin. Nunc a interdum nisl. Integer eleifend posuere nunc in rhoncus. Curabitur gravida tempus facilisis. Morbi imperdiet urna ut vehicula feugiat. Sed eget tortor vitae mauris vehicula convallis. Nunc mollis enim vitae massa pellentesque, nec mattis odio vestibulum. Cras rutrum vehicula pellentesque.
|
||||||
|
|
||||||
|
Morbi semper ultricies tellus non dignissim. Cras hendrerit ultrices est, ac luctus mi commodo sed. Proin vitae erat vel libero vehicula euismod. Vivamus efficitur justo at neque dictum, eu vestibulum nisl porta. Sed et felis in urna suscipit tincidunt sed ut orci. Phasellus dictum dolor eget tellus rhoncus, eu posuere est porta. Aenean mollis consequat lacus ac efficitur. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas feugiat eros lorem, in volutpat ligula pulvinar in. Vestibulum tempus lectus elit, vitae congue lacus vestibulum et. Curabitur sollicitudin justo vel aliquet sodales. In pulvinar quam ac lectus pharetra gravida. Aenean metus justo, porta id scelerisque id, sodales vel orci. Pellentesque efficitur orci justo, sit amet tincidunt ante interdum a.
|
||||||
|
|
||||||
|
Pellentesque bibendum, lorem nec accumsan hendrerit, est lorem gravida lacus, id elementum dolor augue sit amet nisl. Vestibulum hendrerit congue elit. Nam ullamcorper mi eget ornare interdum. Sed quis luctus tortor, quis lobortis nibh. Praesent fringilla dolor eget purus porttitor accumsan. Pellentesque condimentum ante id vestibulum vestibulum. Aenean id mauris fringilla, laoreet velit vitae, vulputate metus. Curabitur augue lorem, posuere tristique tempus nec, luctus ac ex. Suspendisse sagittis, ex vel facilisis pharetra, tellus magna sollicitudin purus, ac posuere velit nibh eu felis. Vestibulum blandit orci tempor nunc ultricies, in fermentum magna sollicitudin. Proin metus velit, posuere non faucibus ut, auctor eget nulla. Ut tortor nunc, egestas vel molestie dignissim, ultrices eget ex. Aliquam ac odio efficitur, laoreet nulla at, rutrum urna.
|
||||||
|
|
||||||
|
Nulla facilisis velit quis turpis congue gravida. Praesent sagittis dui lacus, id vestibulum lorem pharetra nec. Nunc facilisis, lectus vel auctor accumsan, nisl erat cursus lorem, quis rhoncus leo ex nec tortor. Nunc sit amet diam sed lacus dignissim accumsan. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque dignissim gravida nunc eu iaculis. Donec mattis nulla non neque cursus, at sodales erat rutrum. Praesent lobortis dignissim mi at rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Phasellus malesuada orci vitae risus vestibulum facilisis. Proin faucibus consequat aliquet. Morbi convallis urna orci, eu tincidunt mauris feugiat et. Morbi id efficitur diam, et lobortis dui.
|
||||||
|
|
||||||
|
Pellentesque a metus laoreet, suscipit purus at, ornare sapien. Phasellus blandit ipsum quis urna iaculis, pharetra ornare magna pretium. Etiam imperdiet purus erat, eu vehicula nibh elementum et. Nullam vel accumsan massa. Ut mauris lorem, iaculis auctor finibus in, pretium at odio. Pellentesque sed congue risus. Quisque id libero urna.
|
||||||
|
|
||||||
|
Mauris sagittis aliquet hendrerit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas consectetur, augue non suscipit consectetur, diam dolor pellentesque felis, sed malesuada massa magna nec dui. Nulla a risus eros. Curabitur sem arcu, malesuada ac dui ac, eleifend mollis est. Morbi in mauris accumsan, mattis magna vel, volutpat ligula. Curabitur eget elit sapien. Nulla facilisi. Pellentesque tristique enim sit amet lectus ornare consectetur. In viverra nulla sem, vitae egestas nulla pulvinar a. Aliquam vehicula purus id dolor porttitor accumsan. In augue magna, mollis eu convallis sed, gravida non arcu. Integer ac ullamcorper nulla, porttitor vestibulum augue. Nulla pretium, ex sed vulputate pretium, mauris metus vulputate felis, vel iaculis lacus ante vel mauris.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
vec2 z,v,e=vec2(.000035,-.000035);float t,tt,b,g,g2,bb;vec3 np,bp,pp,po,no,al,ld;float bo(vec3 p,vec3 r){p=abs(p)-r;return max(max(p.x,p.y),p.z);}mat2 r2(float r){return mat2(cos(r),sin(r),-sin(r),cos(r));}vec2 fb(vec3 p,float m){p.y+=bb*.05;vec2 h,t=vec2(bo(p,vec3(5,1,3)),3);t.x=max(t.x,-(length(p)-2.5));t.x=max(abs(t.x)-.2,(p.y-0.4));h=vec2(bo(p,vec3(5,1,3)),6);h.x=max(h.x,-(length(p)-2.5));h.x=max(abs(h.x)-.1,(p.y-0.5));t=t.x<h.x?t:h;h=vec2(bo(p+vec3(0,0.4,0),vec3(5.4,0.4,3.4)),m);h.x=max(h.x,-(length(p)-2.5));t=t.x<h.x?t:h;h=vec2(length(p)-2.,m);t=t.x<h.x?t:h;t.x*=0.7;return t;}vec2 mp(vec3 p){pp=bp=p;bp.yz=p.yz*=r2(sin(pp.x*.3-tt*.5)*.4);p.yz*=r2(1.57);b=sin(pp.x*.2+tt);bb=cos(pp.x*.2+tt);p.x=mod(p.x-tt*2.,10.)-5.;vec4 np=vec4(p*.4,.4);for(int i=0;i<4;i++){np.xyz=abs(np.xyz)-vec3(1,1.2,0);np.xyz=2.*clamp(np.xyz,-vec3(0),vec3(2,0.,4.3+bb))-np.xyz;np=np*(1.3)/clamp(dot(np.xyz,np.xyz),0.1,.92);}vec2 h,t=fb(abs(np.xyz)-vec3(2,0,0),5.);t.x/=np.w;t.x=max(t.x,bo(p,vec3(5,5,10)));np*=0.5;np.yz*=r2(.785);np.yz+=2.5;h=fb(abs(np.xyz)-vec3(0,4.5,0),7.);h.x=max(h.x,-bo(p,vec3(20,5,5)));h.x/=np.w*1.5;t=t.x<h.x?t:h;h=vec2(bo(np.xyz,vec3(0.0,b*20.,0.0)),6);h.x/=np.w*1.5;g2+=0.1/(0.1*h.x*h.x*(1000.-b*998.));t=t.x<h.x?t:h;h=vec2(0.6*bp.y+sin(p.y*5.)*0.03,6);t=t.x<h.x?t:h;h=vec2(length(cos(bp.xyz*.6+vec3(tt,tt,0)))+0.003,6);g+=0.1/(0.1*h.x*h.x*4000.);t=t.x<h.x?t:h;return t;}vec2 tr(vec3 ro,vec3 rd){vec2 h,t=vec2(.1);for(int i=0;i<128;i++){h=mp(ro+rd*t.x);if(h.x<.0001||t.x>40.)break;t.x+=h.x;t.y=h.y;}if(t.x>40.)t.y=0.;return t;}#define a(d)clamp(mp(po+no*d).x/d,0.,1.)
|
||||||
|
#define s(d)smoothstep(0.,1.,mp(po+ld*d).x/d)
|
||||||
|
void mainImage(out vec4 fragColor,in vec2 fragCoord){vec2 uv=(fragCoord.xy/iResolution.xy-0.5)/vec2(iResolution.y/iResolution.x,1);tt=mod(iTime,62.8318);vec3 ro=mix(vec3(1),vec3(-0.5,1,-1),ceil(sin(tt*.5)))*vec3(10,2.8+0.75*smoothstep(-1.5,1.5,1.5*cos(tt+0.2)),cos(tt*0.3)*3.1),cw=normalize(vec3(0)-ro),cu=normalize(cross(cw,normalize(vec3(0,1,0)))),cv=normalize(cross(cu,cw)),rd=mat3(cu,cv,cw)*normalize(vec3(uv,.5)),co,fo;ld=normalize(vec3(.2,.4,-.3));co=fo=vec3(.1,.2,.3)-length(uv)*.1-rd.y*.2;z=tr(ro,rd);t=z.x;if(z.y>0.){po=ro+rd*t;no=normalize(e.xyy*mp(po+e.xyy).x+e.yyx*mp(po+e.yyx).x+e.yxy*mp(po+e.yxy).x+e.xxx*mp(po+e.xxx).x);al=mix(vec3(0.1,0.2,.4),vec3(0.1,0.4,.7),.5+0.5*sin(bp.y*7.));if(z.y<5.)al=vec3(0);if(z.y>5.)al=vec3(1);if(z.y>6.)al=mix(vec3(1,.5,0),vec3(.9,.3,.1),.5+.5*sin(bp.y*7.));float dif=max(0.,dot(no,ld)),fr=pow(1.+dot(no,rd),4.),sp=pow(max(dot(reflect(-ld,no),-rd),0.),40.);co=mix(sp+mix(vec3(.8),vec3(1),abs(rd))*al*(a(.1)*a(.2)+.2)*(dif+s(2.)),fo,min(fr,.2));co=mix(fo,co,exp(-.0003*t*t*t));}fragColor=vec4(pow(co+g*.2+g2*mix(vec3(1.,.5,0),vec3(.9,.3,.1),.5+.5*sin(bp.y*3.)),vec3(0.65)),1);}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
#define R gl_TexCoord[0]
|
||||||
|
uniform sampler2D D;float P=acos(-1.),T=2*P;vec4 r,c=0*R,m=c;void S(){r=fract(1e4*sin(r)+r.wxyz);}vec2 pl(float a){return vec2(cos(a),sin(a));}mat3 rx(float a){return mat3(1,0,0,0,cos(a),sin(a),0,-sin(a),cos(a));}mat3 ry(float a){return mat3(cos(a),0,sin(a),0,1,0,-sin(a),0,cos(a));}vec2 H(vec2 p){vec3 r=vec3(p,1);for(int i=0;i<4;i++)r=fract(1e4*sin(r)+r.yzx);return r.xy;}vec2 N(vec2 p){vec2 i=floor(p),f=p-i,o=vec2(0,1);return mix(mix(H(i),H(i+o),f.y),mix(H(i+o.yx),H(i+o.y),f.y),f.x);}vec2 pr(vec2 u){vec2 y=0*u,n=y+2;for(int i=0;i<8;i++)y+=N(u*n)/n,n*=2;return y;}void main(){vec2 v=gl_FragCoord.xy;r=vec4(v,R.yz);S();S();S();S();S();S();S();S();float tt=R.z*7/48,w=floor(tt)*step(2,tt),z=1-.3*smoothstep(-.7,.0,-abs(tt-2.1))+.2*smoothstep(-1,0,-abs(tt-20));if(tt<8)z-=pow(tt/8,48);if(R.w==0){ivec2 j=ivec2(v);m[j.x%3]=exp(float(1-j.y%3));vec2 u=vec2(j/3),y=3*u/R.xy,t,h;m.xy*=vec2(.8,.9);if(tt<2){t=abs(mod(v,180+R.z)-90);t=max(t/4,t-t.yx);h=10+8*step(1,tt)+vec2(0,.5);c+=smoothstep(-.5,.5,-cos(dot(2*v-R.xy,vec2(4))/6e3-T*tt))*(1-smoothstep(h.x,h.y,max(t.x,t.y)));}else if(tt<4){t=pr(u/24+T);c+=mix(step(fract(.4*R.z+2*t.x),.2),dot(normalize(t-.5),pl(20*tt)),.2*(.5-.5*cos(T*tt))*smoothstep(2,4,tt));}else if(tt<8){t=(2*v-R.xy)/R.y,h=t;for(int i=0;i<2;++i)t+=(.3+.5*smoothstep(5,7,tt))*(pr(3*t+7+(tt-6))-.5);c+=max(step(fract(4*length(t)-R.z),.1),.04*dot(normalize(h-t),t));}else if(tt<12){t=v/R.xy;w=R.z;for(int i=max(0,tt-11.9)*100;i<12;i++){z=.5+.2*sin(w+7*floor(tt));if(t.x<z)t.x/=z,w=.6+w*1.1;else t.x=(t.x-z)/(1-z);w+=.5;t=t.yx;}c+=.5+.5*cos(.5*P*w);}else if(tt<16){t=N(floor(vec2(.5*v.x+R.y*pr(.8*(.5*v)/R.y+3).x*smoothstep(0,1,smoothstep(12.7,15.2,tt)),0)));c+=max(.02*t.y,4*fract(t.x-.3*R.z-y.y)-3);m=mix(vec4(.3),m,.15+.85*smoothstep(.0,.25,max(abs(tt-13.4)-.5,0)));}else{w=1.7;h=pl(floor(min(tt+step(17.85,tt)+step(17.9,tt),19)-4)*P/3);y=(((2+h.y)*v-R.xy)/R.y+.06*H(vec2(j/int(50-50*h.x*h.y)))+3)*mat2(1,1,-1,1)/6;y*=mat2(h.x,h.y,-h.y,h.x);for(int i=0;i<14;i++){w*=.6*(1-smoothstep(18,21,tt));t=abs(fract(y+=vec2(4,1)*R.z/200)-.5);c+=w*step(min(t.x,t.y),.01);y*=1.5;}}c=max(c*m,0);}else if(R.w==1){for(int i=0;i<200;i++){S();float h=fract(clamp(tt,2,20)-1e-5),s=1.2*pow(1-h,5.5);vec2 f=.07*sqrt(r.z)*pl(T*r.w),u=(v+r.xy-.5-.5*R.xy)/R.y,rv=pl(.2*(R.z-.1*h+99*min(0,w-12)));mat3 rm=rx(.3*rv.x)*ry(.6*rv.y);vec3 o=rm*vec3(z*.5*f,-s-1),d=rm*normalize(vec3(z*u-f,s+2));c+=texelFetch(D,ivec2(R.y*(o.xy-d.xy*o.z/d.z)+.5*R.xy),0)+.01*pow(.5+.5*d.y,3);}c/=125;}else{v/=R.xy;for(float a=0;a<T;a+=.63)c+=max(textureLod(D,v+7.8*pl(a)/R.xy+.011*R.xy/R.x,5.5)-.06,0);c=pow(texture(D,v)+.02*c,vec4(.45))+.01*(r.x-.5);}gl_FragColor=c;}
|
||||||
+521
@@ -0,0 +1,521 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
|
#![allow(clippy::match_bool, clippy::cast_precision_loss)]
|
||||||
|
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
use ansiterm::{Color, Style};
|
||||||
|
use bitvec::{order::Msb0, view::AsBits};
|
||||||
|
use indicatif::ParallelProgressIterator;
|
||||||
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
|
|
||||||
|
const PROB_BITS: u32 = 20;
|
||||||
|
|
||||||
|
const PROB_FULL: u32 = 1 << PROB_BITS;
|
||||||
|
const PROB_MAX: u32 = PROB_FULL - 1;
|
||||||
|
const PROB_MIN: u32 = 1;
|
||||||
|
const PROB_HALF: u32 = PROB_MAX / 2;
|
||||||
|
|
||||||
|
trait Model: Debug {
|
||||||
|
fn prob(&self) -> u32;
|
||||||
|
fn update(&mut self, bit: bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Constant {
|
||||||
|
prob: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Constant {
|
||||||
|
fn new(prob: u32) -> Self {
|
||||||
|
Self { prob }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Model for Constant {
|
||||||
|
fn prob(&self) -> u32 {
|
||||||
|
self.prob
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, _bit: bool) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Stationary {
|
||||||
|
prob: u32,
|
||||||
|
bias: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stationary {
|
||||||
|
fn with_bias(bias: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
prob: PROB_HALF,
|
||||||
|
bias,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Model for Stationary {
|
||||||
|
fn prob(&self) -> u32 {
|
||||||
|
self.prob.clamp(PROB_MIN, PROB_MAX)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, bit: bool) {
|
||||||
|
debug_assert!(self.bias > 0);
|
||||||
|
|
||||||
|
let mut prob: u64 = u64::from(self.prob);
|
||||||
|
prob *= u64::from(self.bias - 1);
|
||||||
|
prob += match bit {
|
||||||
|
true => PROB_FULL.into(),
|
||||||
|
false => 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
prob /= u64::from(self.bias);
|
||||||
|
self.prob = prob.try_into().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Cycle {
|
||||||
|
models: Vec<Box<dyn Model>>,
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cycle {
|
||||||
|
fn new(count: usize, mut model: impl FnMut() -> Box<dyn Model>) -> Self {
|
||||||
|
let mut models = Vec::new();
|
||||||
|
for _ in 0..count {
|
||||||
|
models.push(model());
|
||||||
|
}
|
||||||
|
|
||||||
|
Self { models, index: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn empty() -> Self {
|
||||||
|
Self {
|
||||||
|
models: Vec::new(),
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push(&mut self, model: impl Model + 'static) {
|
||||||
|
self.models.push(Box::new(model));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill(&mut self, count: usize, model: impl Model + Clone + 'static) {
|
||||||
|
self.models.extend(
|
||||||
|
std::iter::repeat(model)
|
||||||
|
.map(|m| -> Box<dyn Model> { Box::new(m) })
|
||||||
|
.take(count),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Model for Cycle {
|
||||||
|
fn prob(&self) -> u32 {
|
||||||
|
self.models[self.index].prob()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, bit: bool) {
|
||||||
|
self.models[self.index].update(bit);
|
||||||
|
|
||||||
|
self.index += 1;
|
||||||
|
self.index %= self.models.len();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ShiftTable {
|
||||||
|
models: Vec<Box<dyn Model>>,
|
||||||
|
bits: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShiftTable {
|
||||||
|
fn new(count: usize, mut model: impl FnMut() -> Box<dyn Model>) -> Self {
|
||||||
|
let mut models = Vec::new();
|
||||||
|
for _ in 0..count {
|
||||||
|
models.push(model());
|
||||||
|
}
|
||||||
|
|
||||||
|
Self { models, bits: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Model for ShiftTable {
|
||||||
|
fn prob(&self) -> u32 {
|
||||||
|
self.models[self.bits].prob()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, bit: bool) {
|
||||||
|
self.models[self.bits].update(bit);
|
||||||
|
|
||||||
|
self.bits <<= 1;
|
||||||
|
self.bits |= usize::from(bit);
|
||||||
|
self.bits %= self.models.len();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct HashTable {
|
||||||
|
models: Vec<Box<dyn Model>>,
|
||||||
|
history: u64,
|
||||||
|
mask: u64,
|
||||||
|
hash_mul: u64,
|
||||||
|
hash_add: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HashTable {
|
||||||
|
fn new(
|
||||||
|
x1: u64,
|
||||||
|
x2: u64,
|
||||||
|
mask: u64,
|
||||||
|
count: usize,
|
||||||
|
mut make_model: impl FnMut() -> Box<dyn Model>,
|
||||||
|
) -> Self {
|
||||||
|
let mut models = Vec::new();
|
||||||
|
for _ in 0..count {
|
||||||
|
models.push(make_model());
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
models,
|
||||||
|
history: 0,
|
||||||
|
mask,
|
||||||
|
hash_mul: x1,
|
||||||
|
hash_add: x2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash(&self) -> u64 {
|
||||||
|
(self.history & self.mask)
|
||||||
|
.wrapping_mul(self.hash_mul)
|
||||||
|
.wrapping_add(self.hash_add)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Model for HashTable {
|
||||||
|
fn prob(&self) -> u32 {
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
|
let index = self.hash() as usize % self.models.len();
|
||||||
|
self.models[index].prob()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, bit: bool) {
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
|
let index = self.hash() as usize % self.models.len();
|
||||||
|
self.models[index].update(bit);
|
||||||
|
|
||||||
|
self.history <<= 1;
|
||||||
|
self.history |= u64::from(bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ByteModel {
|
||||||
|
probs: [u32; 8],
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ByteModel {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
probs: [PROB_HALF; 8],
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Model for ByteModel {
|
||||||
|
fn prob(&self) -> u32 {
|
||||||
|
self.probs[self.index].clamp(PROB_MIN, PROB_MAX)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, bit: bool) {
|
||||||
|
const BIAS: u32 = 128;
|
||||||
|
const MARGIN: u32 = 1;
|
||||||
|
|
||||||
|
self.probs[self.index] *= BIAS - 1;
|
||||||
|
self.probs[self.index] += match bit {
|
||||||
|
true => PROB_MAX,
|
||||||
|
false => PROB_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.probs[self.index] /= BIAS;
|
||||||
|
|
||||||
|
self.index += 1;
|
||||||
|
self.index %= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct LogMix {
|
||||||
|
models: Vec<Box<dyn Model>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LogMix {
|
||||||
|
fn empty() -> Self {
|
||||||
|
Self { models: Vec::new() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push(&mut self, model: impl Model + 'static) {
|
||||||
|
self.models.push(Box::new(model));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Model for LogMix {
|
||||||
|
fn prob(&self) -> u32 {
|
||||||
|
let mut acc = 0.0;
|
||||||
|
for model in &self.models {
|
||||||
|
let prob = model.prob();
|
||||||
|
debug_assert!(prob <= PROB_MAX);
|
||||||
|
debug_assert!(prob >= PROB_MIN);
|
||||||
|
|
||||||
|
let p = f64::from(prob) / f64::from(PROB_FULL);
|
||||||
|
acc += (p / (1.0 - p)).ln();
|
||||||
|
}
|
||||||
|
|
||||||
|
acc /= self.models.len() as f64;
|
||||||
|
let p = ((-acc).exp() + 1.0).recip();
|
||||||
|
|
||||||
|
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
||||||
|
let n = (f64::from(PROB_FULL) * p) as u32;
|
||||||
|
n.clamp(PROB_MIN, PROB_MAX)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, bit: bool) {
|
||||||
|
for model in &mut self.models {
|
||||||
|
model.update(bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_model(x1: u64, x2: u64) -> impl Model {
|
||||||
|
let _ = x1;
|
||||||
|
let _ = x2;
|
||||||
|
|
||||||
|
let mut mix = LogMix::empty();
|
||||||
|
mix.push(Cycle::new(8, || Box::new(Stationary::with_bias(16))));
|
||||||
|
mix.push(ShiftTable::new(1 << 12, || Box::new(Stationary::with_bias(4))));
|
||||||
|
//mix.push(ShiftTable::new(1 << 14, || Box::new(Stationary::with_bias(2))));
|
||||||
|
mix.push(HashTable::new(x1, x2, u64::MAX >> 16, 1 << 14, || Box::new(Stationary::with_bias(2))));
|
||||||
|
|
||||||
|
//Constant::new(PROB_HALF)
|
||||||
|
//Stationary::with_bias(4)
|
||||||
|
//Cycle::new(8, || Box::new(Stationary::with_bias(32)))
|
||||||
|
//ShiftTable::new(1 << 16, || Box::new(Stationary::with_bias(4)))
|
||||||
|
//HashTable::new(x1, x2, ((1 << 24) - 1) << 4, 1 << 16, || Box::new(Stationary::with_bias(4)))
|
||||||
|
mix
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Encoder {
|
||||||
|
low: u32,
|
||||||
|
high: u32,
|
||||||
|
output: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encoder {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
low: 0,
|
||||||
|
high: u32::MAX,
|
||||||
|
output: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push(&mut self, prob: u32, bit: bool) -> f64 {
|
||||||
|
debug_assert!(prob <= PROB_MAX);
|
||||||
|
debug_assert!(prob >= PROB_MIN);
|
||||||
|
debug_assert!(self.low < self.high);
|
||||||
|
|
||||||
|
let range = self.high - self.low;
|
||||||
|
let delta = (range as u128 * prob as u128) >> PROB_BITS;
|
||||||
|
let mid = self.low + u32::try_from(delta).unwrap();
|
||||||
|
|
||||||
|
match bit {
|
||||||
|
false => self.low = mid + 1,
|
||||||
|
true => self.high = mid,
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_range = self.high - self.low;
|
||||||
|
|
||||||
|
#[allow(clippy::items_after_statements)]
|
||||||
|
const TOP_BYTE: u32 = u32::BITS - 8;
|
||||||
|
while (self.high ^ self.low) >> TOP_BYTE == 0 {
|
||||||
|
let byte = self.high >> TOP_BYTE;
|
||||||
|
self.output.push(byte as u8);
|
||||||
|
|
||||||
|
self.low <<= 8;
|
||||||
|
self.high <<= 8;
|
||||||
|
self.high |= 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
let p = f64::from(new_range) / f64::from(range);
|
||||||
|
debug_assert!(p <= 1.0);
|
||||||
|
debug_assert!(0.0 <= p);
|
||||||
|
-p.log2()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish(mut self) -> Vec<u8> {
|
||||||
|
const TOP_BYTE: u32 = u32::BITS - 8;
|
||||||
|
self.output.push((self.high >> TOP_BYTE) as u8);
|
||||||
|
self.output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Decoder<I> {
|
||||||
|
input: I,
|
||||||
|
low: u32,
|
||||||
|
high: u32,
|
||||||
|
val: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Iterator<Item = u8>> Decoder<I> {
|
||||||
|
fn new(input: impl IntoIterator<IntoIter = I>) -> Self {
|
||||||
|
let mut input = input.into_iter();
|
||||||
|
let mut val = 0;
|
||||||
|
|
||||||
|
for _ in 0..4 {
|
||||||
|
val <<= 8;
|
||||||
|
val |= u32::from(input.next().unwrap_or(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
input,
|
||||||
|
low: 0,
|
||||||
|
high: u32::MAX,
|
||||||
|
val,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pull(&mut self, prob: u32) -> bool {
|
||||||
|
debug_assert!(prob <= PROB_MAX);
|
||||||
|
debug_assert!(prob >= PROB_MIN);
|
||||||
|
debug_assert!(self.low <= self.val);
|
||||||
|
debug_assert!(self.val <= self.high);
|
||||||
|
debug_assert!(self.low < self.high);
|
||||||
|
|
||||||
|
let range = self.high - self.low;
|
||||||
|
let delta = (range as u128 * prob as u128) >> PROB_BITS;
|
||||||
|
let mid = self.low + u32::try_from(delta).unwrap();
|
||||||
|
let bit = self.val <= mid;
|
||||||
|
|
||||||
|
match bit {
|
||||||
|
false => self.low = mid + 1,
|
||||||
|
true => self.high = mid,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::items_after_statements)]
|
||||||
|
const TOP_BYTE: u32 = u32::BITS - 8;
|
||||||
|
while (self.high ^ self.low) >> TOP_BYTE == 0 {
|
||||||
|
self.low <<= 8;
|
||||||
|
|
||||||
|
self.high <<= 8;
|
||||||
|
self.high |= 0xff;
|
||||||
|
|
||||||
|
self.val <<= 8;
|
||||||
|
self.val |= u32::from(self.input.next().unwrap_or(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
bit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bench(bytes: &[u8], x1: u64, x2: u64) -> usize {
|
||||||
|
let bits = bytes.as_bits::<Msb0>();
|
||||||
|
let mut model = create_model(x1, x2);
|
||||||
|
let mut encoder = Encoder::new();
|
||||||
|
|
||||||
|
for bit in bits {
|
||||||
|
let prob = model.prob();
|
||||||
|
encoder.push(prob, *bit);
|
||||||
|
model.update(*bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
encoder.finish().len()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
||||||
|
fn gradient(x: f64) -> Color {
|
||||||
|
let r = (16.0 * x).min(255.0) as u8;
|
||||||
|
let g = (255.0 - 16.0 * x).max(0.0) as u8;
|
||||||
|
let b = 255 - (16.0 * (x - 8.0)).abs().min(255.0) as u8;
|
||||||
|
Color::RGB(r, g, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
//let text = include_bytes!("../data/shader.txt");
|
||||||
|
let text = include_bytes!("../data/wackelkontakt.glsl");
|
||||||
|
let bits = text.as_bits::<Msb0>();
|
||||||
|
|
||||||
|
let (x1, x2) = (0..10_000)
|
||||||
|
.into_par_iter()
|
||||||
|
.map(|_| (rand::random::<u64>(), rand::random::<u64>()))
|
||||||
|
.progress()
|
||||||
|
.min_by_key(|&(x1, x2)| bench(text, x1, x2))
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
println!("x1 = {x1:x}, x2 = {x2:x}");
|
||||||
|
|
||||||
|
let mut encoder = Encoder::new();
|
||||||
|
let mut model = create_model(x1, x2);
|
||||||
|
|
||||||
|
let mut line = 0.0;
|
||||||
|
let mut total = 0.0;
|
||||||
|
|
||||||
|
for (k, &byte) in text.iter().enumerate() {
|
||||||
|
let mut entropy = 0.0;
|
||||||
|
|
||||||
|
for bit in [byte].as_bits::<Msb0>() {
|
||||||
|
let prob = model.prob();
|
||||||
|
entropy += encoder.push(prob, *bit);
|
||||||
|
model.update(*bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
total += entropy;
|
||||||
|
line += entropy;
|
||||||
|
|
||||||
|
if k > 0 && k % 128 == 0 {
|
||||||
|
println!(" | {:.3}", line / 8.0);
|
||||||
|
line = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let color = gradient(entropy);
|
||||||
|
let style = Style::new().on(color);
|
||||||
|
let ch = char::from_u32(byte.into())
|
||||||
|
.filter(char::is_ascii_graphic)
|
||||||
|
.unwrap_or('.');
|
||||||
|
|
||||||
|
print!("{}", style.paint(ch.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{s:w$} | {:.3}",
|
||||||
|
line / 8.0,
|
||||||
|
s = "",
|
||||||
|
w = 128 - text.len() % 128
|
||||||
|
);
|
||||||
|
|
||||||
|
let data = encoder.finish();
|
||||||
|
println!("text size: {} bytes", text.len());
|
||||||
|
println!(
|
||||||
|
"data size: {} bytes ({:.3} bits)",
|
||||||
|
data.len(),
|
||||||
|
total - (8 * data.len()) as f64
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
" ratio: {:.3}%",
|
||||||
|
100.0 * data.len() as f64 / text.len() as f64
|
||||||
|
);
|
||||||
|
std::fs::write("out.bin", &data).unwrap();
|
||||||
|
|
||||||
|
let mut decoder = Decoder::new(data);
|
||||||
|
let mut model = create_model(x1, x2);
|
||||||
|
|
||||||
|
for expected_bit in bits {
|
||||||
|
let prob = model.prob();
|
||||||
|
let bit = decoder.pull(prob);
|
||||||
|
model.update(bit);
|
||||||
|
|
||||||
|
assert_eq!(*expected_bit, bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user