{"id":17236879,"url":"https://github.com/redodo/ranger","last_synced_at":"2025-03-26T01:42:50.107Z","repository":{"id":88413845,"uuid":"591647226","full_name":"redodo/ranger","owner":"redodo","description":"Rust solution of bloomon challenge using SIMD","archived":false,"fork":false,"pushed_at":"2023-02-05T22:44:49.000Z","size":1432,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-30T23:16:07.455Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/redodo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-21T12:04:21.000Z","updated_at":"2023-01-28T16:10:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"86436726-3134-4f96-b293-799109fcf9b0","html_url":"https://github.com/redodo/ranger","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redodo%2Franger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redodo%2Franger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redodo%2Franger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redodo%2Franger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/redodo","download_url":"https://codeload.github.com/redodo/ranger/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245573841,"owners_count":20637670,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T05:37:09.622Z","updated_at":"2025-03-26T01:42:50.087Z","avatar_url":"https://github.com/redodo.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rust solution of bloomon challenge using SIMD\n\nThis solution uses 512-bit SIMD vectors to store and compare stem stock to stem\nrequirements per design. The vectors that are used have 32 lanes of `u16` values. This\nallows for every possible species (a to z) to have a maximum of 65535 of stock.\n\nThe feasibility of a design can be checked in a couple of operations, regardless of the\namount of stems in a design:\n\n1. Take the maximum amount of stems we can take: `stems = simd_min(stock, design.max_stems)`\n2. Check if we have enough stems: `reduce_sum(stems) \u003e= design.total`\n3. Check if we at least one of each needed stem: `all(simd_ge(stems, design.min_stems))`\n\nAfter this we have enough stems. However, since we took the maximum amount possible per\nstem, we need to make sure that we return the excess amount of stems we took. This is\ndone over a simple iteration where stems are returned to the stock until the amount\nrequired by the design is met.\n\nBesides this a number of other optimizations are implemented:\n\n- On input of a stem, only designs with that stem are checked.\n- Total stems in stock is separately kept, and designs are skipped when the total stems\n  in stock does not meet the design requirements.\n- The implicit minimum of a species in a design is increased from 1 where possible. For\n  example, *AL5a5* requires at least 5 times *a*, and *BL5a1b5* requires at least 4\n  times *a*.\n- The maximum species in a design is decreased where possible. For example, *AL10a5*\n  can not have more than 5 times *a*, and *BL5a1b5* can not have more than 4 times *a*.\n- The maximum possible stems per species in any design is used to skip bouquet creation\n  if a stem is input that already exceeds the stock by this amount.\n\n## How to run it\n\nMake a release build:\n```bash\ncargo build --release\n```\n\nRun it:\n```bash\ntarget/release/ranger\n```\n\n## Comparison to other solutions\n\n*These benchmarks were run on an AMD Ryzen 7 1700.*\n\n[redodo/cstem](https://github.com/redodo/cstem) (C):\n\n```bash\n$ multitime -n100 -q -s0 -i \"cat samples/1m.txt\" ./cstem\n===\u003e multitime results\n1: -i \"cat samples/1m.txt\" -q ./cstem\n            Mean        Std.Dev.    Min         Median      Max\nreal        0.097       0.012       0.079       0.091       0.116\nuser        0.095       0.012       0.075       0.090       0.116\nsys         0.002       0.002       0.000       0.000       0.007\n```\n\nredodo/ranger (Rust):\n\n```bash\n$ multitime -n100 -q -s0 -i \"cat samples/1m.txt\" ./ranger\n===\u003e multitime results\n1: -i \"cat samples/1m.txt\" -q ./ranger\n            Mean        Std.Dev.    Min         Median      Max\nreal        0.124       0.013       0.107       0.118       0.145\nuser        0.103       0.013       0.073       0.102       0.130\nsys         0.021       0.006       0.003       0.020       0.036\n```\n\n[edelooff/carrange](https://github.com/edelooff/carrange) (C++):\n\n```bash\n$ multitime -n100 -q -s0 -i \"cat samples/1m.txt\" ./composer\n===\u003e multitime results\n1: -i \"cat samples/1m.txt\" -q ./composer\n            Mean        Std.Dev.    Min         Median      Max\nreal        0.177       0.013       0.161       0.171       0.214\nuser        0.157       0.014       0.131       0.153       0.200\nsys         0.020       0.007       0.003       0.020       0.037\n```\n\n[Gradecak/rs-bouquets](https://github.com/Gradecak/rs-bouquets) (Rust):\n\n```bash\n$ multitime -n100 -q -s0 -i \"cat samples/1m.txt\" ./rs-bouquets\n===\u003e multitime results\n1: -i \"cat samples/1m.txt\" -q ./rs-bouquets\n            Mean        Std.Dev.    Min         Median      Max\nreal        0.360       0.015       0.338       0.356       0.396\nuser        0.338       0.017       0.311       0.336       0.379\nsys         0.021       0.008       0.003       0.020       0.043\n```\n\n## Benchmark of reference solution\n\nThis gets its own section because compiled languages are in a league of their own.\n\n[reference solution](https://github.com/bloomon/code-challenge-verifier/blob/master/reference.py) (Python 3.10):\n\n```bash\n$ multitime -n10 -q -s0 -i \"cat samples/1m.txt\" python3.10 reference.py\n===\u003e multitime results\n1: -i \"cat samples/1m.txt\" -q python3.10 reference.py\n            Mean        Std.Dev.    Min         Median      Max\nreal        20.417      0.122       20.154      20.424      20.570\nuser        20.339      0.136       20.088      20.333      20.522\nsys         0.031       0.029       0.006       0.021       0.111\n```\n\nCuriously, the reference solution was slower in Python 3.11 🤔\n\n[reference solution](https://github.com/bloomon/code-challenge-verifier/blob/master/reference.py) (Python 3.11):\n\n```bash\n$ multitime -n10 -q -s0 -i \"cat samples/1m.txt\" python3.11 reference.py\n===\u003e multitime results\n1: -i \"cat samples/1m.txt\" -q python3.11 reference.py\n            Mean        Std.Dev.    Min         Median      Max\nreal        26.699      0.333       26.163      26.691      27.391\nuser        26.613      0.348       26.117      26.619      27.332\nsys         0.026       0.026       0.000       0.016       0.091\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredodo%2Franger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fredodo%2Franger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredodo%2Franger/lists"}