first commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
216
Cargo.lock
generated
Normal file
216
Cargo.lock
generated
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argh"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7af5ba06967ff7214ce4c7419c7d185be7ecd6cc4965a8f6e1d8ce0398aad219"
|
||||||
|
dependencies = [
|
||||||
|
"argh_derive",
|
||||||
|
"argh_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argh_derive"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56df0aeedf6b7a2fc67d06db35b09684c3e8da0c95f8f27685cb17e08413d87a"
|
||||||
|
dependencies = [
|
||||||
|
"argh_shared",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argh_shared"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5693f39141bda5760ecc4111ab08da40565d1771038c4a0250f03457ec707531"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "csv"
|
||||||
|
version = "1.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086"
|
||||||
|
dependencies = [
|
||||||
|
"csv-core",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "csv-core"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.148"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.67"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "rust_repartition"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"argh",
|
||||||
|
"csv",
|
||||||
|
"rand",
|
||||||
|
"rand_chacha",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.188"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.188"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.107"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
14
Cargo.toml
Normal file
14
Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "rust_repartition"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
argh = "0.1.12"
|
||||||
|
csv = "1.2.2"
|
||||||
|
rand = "0.8.5"
|
||||||
|
rand_chacha = "0.3.1"
|
||||||
|
serde = "1.0.188"
|
||||||
|
serde_json = "1.0.107"
|
||||||
275
repartition.json
Normal file
275
repartition.json
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Alice",
|
||||||
|
"email": "alice.colin.ensl@gmail.com",
|
||||||
|
"balance_cents": -10040
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Janelle",
|
||||||
|
"email": "janelle.gauthier@orange.fr",
|
||||||
|
"balance_cents": 31304
|
||||||
|
},
|
||||||
|
"amount": 10040
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Arnaud",
|
||||||
|
"email": "arnaud.oliveau@gmail.com",
|
||||||
|
"balance_cents": -34
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Janelle",
|
||||||
|
"email": "janelle.gauthier@orange.fr",
|
||||||
|
"balance_cents": 21264
|
||||||
|
},
|
||||||
|
"amount": 34
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Florine",
|
||||||
|
"email": "florine.dubourg@ens-lyon.fr",
|
||||||
|
"balance_cents": -16413
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Janelle",
|
||||||
|
"email": "janelle.gauthier@orange.fr",
|
||||||
|
"balance_cents": 21230
|
||||||
|
},
|
||||||
|
"amount": 16413
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Bertrand",
|
||||||
|
"email": "bertrand.carro@gmail.com",
|
||||||
|
"balance_cents": -15527
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Janelle",
|
||||||
|
"email": "janelle.gauthier@orange.fr",
|
||||||
|
"balance_cents": 4817
|
||||||
|
},
|
||||||
|
"amount": 4817
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Bertrand",
|
||||||
|
"email": "bertrand.carro@gmail.com",
|
||||||
|
"balance_cents": -10710
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Lambert",
|
||||||
|
"email": "lambertvogin@gmail.com",
|
||||||
|
"balance_cents": 1275
|
||||||
|
},
|
||||||
|
"amount": 1275
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Bertrand",
|
||||||
|
"email": "bertrand.carro@gmail.com",
|
||||||
|
"balance_cents": -9435
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Alix",
|
||||||
|
"email": "jeanne.carro@ens-lyon.fr",
|
||||||
|
"balance_cents": 51765
|
||||||
|
},
|
||||||
|
"amount": 9435
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Morgan",
|
||||||
|
"email": "sterb.morgan@gmail.com",
|
||||||
|
"balance_cents": -16454
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Alix",
|
||||||
|
"email": "jeanne.carro@ens-lyon.fr",
|
||||||
|
"balance_cents": 42330
|
||||||
|
},
|
||||||
|
"amount": 16454
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Xavier",
|
||||||
|
"email": "xavier.onfroy@protonmail.com",
|
||||||
|
"balance_cents": -1541
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Alix",
|
||||||
|
"email": "jeanne.carro@ens-lyon.fr",
|
||||||
|
"balance_cents": 25876
|
||||||
|
},
|
||||||
|
"amount": 1541
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Nattes",
|
||||||
|
"email": "nath.kastylevsky@proton.me",
|
||||||
|
"balance_cents": -1923
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Alix",
|
||||||
|
"email": "jeanne.carro@ens-lyon.fr",
|
||||||
|
"balance_cents": 24335
|
||||||
|
},
|
||||||
|
"amount": 1923
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Joël",
|
||||||
|
"email": "joel@jfelderhoff.fr",
|
||||||
|
"balance_cents": -15277
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Alix",
|
||||||
|
"email": "jeanne.carro@ens-lyon.fr",
|
||||||
|
"balance_cents": 22412
|
||||||
|
},
|
||||||
|
"amount": 15277
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Alban",
|
||||||
|
"email": "Alban.Faure@gmail.com",
|
||||||
|
"balance_cents": -938
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Alix",
|
||||||
|
"email": "jeanne.carro@ens-lyon.fr",
|
||||||
|
"balance_cents": 7135
|
||||||
|
},
|
||||||
|
"amount": 938
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Aaren",
|
||||||
|
"email": "aa.germain@yahoo.com",
|
||||||
|
"balance_cents": -20620
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Alix",
|
||||||
|
"email": "jeanne.carro@ens-lyon.fr",
|
||||||
|
"balance_cents": 6197
|
||||||
|
},
|
||||||
|
"amount": 6197
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Aaren",
|
||||||
|
"email": "aa.germain@yahoo.com",
|
||||||
|
"balance_cents": -14423
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Octave",
|
||||||
|
"email": "octave.ourcival@gmail.com",
|
||||||
|
"balance_cents": 3415
|
||||||
|
},
|
||||||
|
"amount": 3415
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Aaren",
|
||||||
|
"email": "aa.germain@yahoo.com",
|
||||||
|
"balance_cents": -11008
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Florian",
|
||||||
|
"email": "florian.taraveau@ens-lyon.fr",
|
||||||
|
"balance_cents": 608
|
||||||
|
},
|
||||||
|
"amount": 608
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Aaren",
|
||||||
|
"email": "aa.germain@yahoo.com",
|
||||||
|
"balance_cents": -10400
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Blanche",
|
||||||
|
"email": "quentinvila@laposte.net",
|
||||||
|
"balance_cents": 5364
|
||||||
|
},
|
||||||
|
"amount": 5364
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Aaren",
|
||||||
|
"email": "aa.germain@yahoo.com",
|
||||||
|
"balance_cents": -5036
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Adrien",
|
||||||
|
"email": "al.bert95@hotmail.fr",
|
||||||
|
"balance_cents": 36445
|
||||||
|
},
|
||||||
|
"amount": 5036
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Charline",
|
||||||
|
"email": "al.bert95@hotmail.fr",
|
||||||
|
"balance_cents": -7779
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Adrien",
|
||||||
|
"email": "al.bert95@hotmail.fr",
|
||||||
|
"balance_cents": 31409
|
||||||
|
},
|
||||||
|
"amount": 7779
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "KT",
|
||||||
|
"email": "quentinvila@laposte.net",
|
||||||
|
"balance_cents": -10538
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Adrien",
|
||||||
|
"email": "al.bert95@hotmail.fr",
|
||||||
|
"balance_cents": 23630
|
||||||
|
},
|
||||||
|
"amount": 10538
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Bastien",
|
||||||
|
"email": "bastien.durain@ens-lyon.fr",
|
||||||
|
"balance_cents": -9476
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Adrien",
|
||||||
|
"email": "al.bert95@hotmail.fr",
|
||||||
|
"balance_cents": 13092
|
||||||
|
},
|
||||||
|
"amount": 9476
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Danaé",
|
||||||
|
"email": "danae.guiserix@ens-lyon.fr",
|
||||||
|
"balance_cents": -20939
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Adrien",
|
||||||
|
"email": "al.bert95@hotmail.fr",
|
||||||
|
"balance_cents": 3616
|
||||||
|
},
|
||||||
|
"amount": 3616
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": {
|
||||||
|
"name": "Danaé",
|
||||||
|
"email": "danae.guiserix@ens-lyon.fr",
|
||||||
|
"balance_cents": -17323
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"name": "Laureline",
|
||||||
|
"email": "laureline.pinault@ens-lyon.fr",
|
||||||
|
"balance_cents": 17323
|
||||||
|
},
|
||||||
|
"amount": 17323
|
||||||
|
}
|
||||||
|
]
|
||||||
50
src/io.rs
Normal file
50
src/io.rs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
use super::repartition::*;
|
||||||
|
|
||||||
|
const FORMAT_TEXT: &'static str = "<html>
|
||||||
|
<head>
|
||||||
|
<script src=\"/home/jfelderh/Prog/Repartition Alpes/cytoscape.min.js\"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id=\"graph\" style=\"width: auto;height: 500px;\"></div>
|
||||||
|
|
||||||
|
<h3>Balance totale (doit être égal à zéro) : {}€</h3>
|
||||||
|
|
||||||
|
<script type=\"text/javascript\">
|
||||||
|
var cy = cytoscape({
|
||||||
|
|
||||||
|
container: document.getElementById('graph'), // container to render in
|
||||||
|
|
||||||
|
elements:{},
|
||||||
|
|
||||||
|
style: [ // the stylesheet for the graph
|
||||||
|
{
|
||||||
|
selector: 'node',
|
||||||
|
style: {
|
||||||
|
'background-color': '#666',
|
||||||
|
'label': 'data(label)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
selector: 'edge',
|
||||||
|
style: {
|
||||||
|
'width': 3,
|
||||||
|
'label': 'data(label)',
|
||||||
|
'line-color': '#ccc',
|
||||||
|
'target-arrow-color': '#ccc',
|
||||||
|
'target-arrow-shape': 'triangle',
|
||||||
|
'curve-style': 'bezier',
|
||||||
|
'classes': 'outline'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
layout: {
|
||||||
|
name: 'cose',
|
||||||
|
nodeDimensionsIncludeLabels: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
});</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
";
|
||||||
76
src/main.rs
Normal file
76
src/main.rs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
use std::fs;
|
||||||
|
|
||||||
|
mod io;
|
||||||
|
pub mod repartition;
|
||||||
|
|
||||||
|
use argh::FromArgs;
|
||||||
|
use rand::SeedableRng;
|
||||||
|
use rand_chacha::ChaCha8Rng;
|
||||||
|
|
||||||
|
#[derive(FromArgs)]
|
||||||
|
/// Computation of repartition
|
||||||
|
struct Arguments {
|
||||||
|
/// file with all the user in csv format
|
||||||
|
#[argh(option, short = 'u')]
|
||||||
|
user_list_filename: Option<String>,
|
||||||
|
|
||||||
|
/// seed for random generation
|
||||||
|
#[argh(option, short = 's')]
|
||||||
|
seed: Option<u64>,
|
||||||
|
|
||||||
|
/// number of repetitions for random generation
|
||||||
|
#[argh(option, short = 'n', default = "1")]
|
||||||
|
number_repetition: usize,
|
||||||
|
|
||||||
|
/// file with all the transferts in json format
|
||||||
|
#[argh(option, short = 't')]
|
||||||
|
transfert_list_filename: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
use repartition::*;
|
||||||
|
let args: Arguments = argh::from_env();
|
||||||
|
if let Some(filename) = args.user_list_filename {
|
||||||
|
let seed = args.seed.unwrap_or(42);
|
||||||
|
let mut rng = ChaCha8Rng::seed_from_u64(seed);
|
||||||
|
|
||||||
|
let repartition_file = fs::File::open(filename).expect("not able to read file");
|
||||||
|
let mut csv_reader = csv::ReaderBuilder::new()
|
||||||
|
.has_headers(false)
|
||||||
|
.delimiter(b';')
|
||||||
|
.from_reader(repartition_file);
|
||||||
|
|
||||||
|
let user_list = csv_reader
|
||||||
|
.records()
|
||||||
|
.map(Result::unwrap)
|
||||||
|
.map(|record| User {
|
||||||
|
name: record[0].parse::<String>().unwrap().trim_end().to_string(),
|
||||||
|
balance_cents: (record[1].parse::<f64>().unwrap() * 100.) as i32,
|
||||||
|
email: record[2].parse::<String>().unwrap().trim_end().to_string(),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let mut best_repartition =
|
||||||
|
RandomRepartitionBuilder::new(&user_list, &mut rng).build_repartition();
|
||||||
|
let mut best_evaluation = best_repartition.evaluate();
|
||||||
|
for _ in 1..args.number_repetition {
|
||||||
|
let repartition =
|
||||||
|
RandomRepartitionBuilder::new(&user_list, &mut rng).build_repartition();
|
||||||
|
let evaluation = repartition.evaluate();
|
||||||
|
|
||||||
|
if evaluation < best_evaluation {
|
||||||
|
best_evaluation = evaluation;
|
||||||
|
best_repartition = repartition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
serde_json::to_string_pretty(&best_repartition).unwrap()
|
||||||
|
);
|
||||||
|
} else if let Some(filename) = args.transfert_list_filename {
|
||||||
|
let repart: Repartition =
|
||||||
|
serde_json::from_reader(fs::File::open(filename).expect("not able to read file"))
|
||||||
|
.expect("unable to read file");
|
||||||
|
} else {
|
||||||
|
println!("No parameter given, exiting");
|
||||||
|
}
|
||||||
|
}
|
||||||
96
src/repartition.rs
Normal file
96
src/repartition.rs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
use std::cmp::min;
|
||||||
|
|
||||||
|
use rand::prelude::*;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct User {
|
||||||
|
pub name: String,
|
||||||
|
pub email: String,
|
||||||
|
pub balance_cents: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RandomRepartitionBuilder {
|
||||||
|
payers: Vec<User>,
|
||||||
|
|
||||||
|
receivers: Vec<User>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RandomRepartitionBuilder {
|
||||||
|
pub fn new<R>(user_list: &[User], rng: &mut R) -> Self
|
||||||
|
where
|
||||||
|
R: Rng + ?Sized,
|
||||||
|
{
|
||||||
|
let mut payers = user_list
|
||||||
|
.iter()
|
||||||
|
.filter(|u| u.balance_cents < 0)
|
||||||
|
.cloned()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let mut receivers = user_list
|
||||||
|
.iter()
|
||||||
|
.filter(|u| u.balance_cents > 0)
|
||||||
|
.cloned()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
payers.shuffle(rng);
|
||||||
|
receivers.shuffle(rng);
|
||||||
|
let total_balance_payers: i32 = payers.iter().map(|p| p.balance_cents).sum();
|
||||||
|
let total_balance_receivers: i32 = receivers.iter().map(|r| r.balance_cents).sum();
|
||||||
|
assert_eq!(total_balance_payers, -total_balance_receivers);
|
||||||
|
Self { payers, receivers }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_next_receiver(&mut self) -> User {
|
||||||
|
self.receivers.pop().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_next_payer(&mut self) -> User {
|
||||||
|
self.payers.pop().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_repartition(mut self) -> Repartition {
|
||||||
|
let mut rep = Repartition(Vec::new());
|
||||||
|
|
||||||
|
while !self.payers.is_empty() || !self.receivers.is_empty() {
|
||||||
|
let mut payer = self.get_next_payer();
|
||||||
|
let mut receiver = self.get_next_receiver();
|
||||||
|
let amount = min(-payer.balance_cents, receiver.balance_cents);
|
||||||
|
dbg!(amount);
|
||||||
|
let transfert = Transfer {
|
||||||
|
from: payer.clone(),
|
||||||
|
to: receiver.clone(),
|
||||||
|
amount: amount as u32,
|
||||||
|
};
|
||||||
|
payer.balance_cents += amount;
|
||||||
|
receiver.balance_cents -= amount;
|
||||||
|
rep.0.push(transfert);
|
||||||
|
if payer.balance_cents < 0 {
|
||||||
|
self.payers.push(payer);
|
||||||
|
}
|
||||||
|
if receiver.balance_cents > 0 {
|
||||||
|
self.receivers.push(receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rep
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Transfer {
|
||||||
|
pub from: User,
|
||||||
|
pub to: User,
|
||||||
|
pub amount: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Repartition(Vec<Transfer>);
|
||||||
|
|
||||||
|
type Evaluation = (usize);
|
||||||
|
|
||||||
|
impl Repartition {
|
||||||
|
pub fn evaluate(&self) -> Evaluation {
|
||||||
|
self.0.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user