From 1ffd29fd7b0a7e523f24df111a938d46fea44e53 Mon Sep 17 00:00:00 2001 From: Ruslan Akhtariev Date: Mon, 9 Dec 2024 19:40:56 -0800 Subject: [PATCH] sorting --- README.md | 4 ++++ assets/sorting.png | Bin 0 -> 44886 bytes src/Sort.sol | 29 +++++++++++++++++++++++++++++ test/Sort.t.sol | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 assets/sorting.png create mode 100644 src/Sort.sol create mode 100644 test/Sort.t.sol diff --git a/README.md b/README.md index 5e758d9..a28dad9 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,7 @@ If we decide to use ClvrModel to compute the optimal ordering on chain, we need Currently, the ordering complexity is O(n^2) where n is the number of swaps. ![Chart!](assets/chart.png) + +## Sorting Complexity + +![Chart!](assets/sorting.png) diff --git a/assets/sorting.png b/assets/sorting.png new file mode 100644 index 0000000000000000000000000000000000000000..701cba4695c02f52aef337f75acf0d469f3ea0c7 GIT binary patch literal 44886 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�tF+^fe>np2Hc3F|ScTc0<0f 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

y+ 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 literal 0 HcmV?d00001 diff --git a/src/Sort.sol b/src/Sort.sol new file mode 100644 index 0000000..2e0bf8a --- /dev/null +++ b/src/Sort.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +function quickSort(uint[] memory arr, int left, int right) pure { + int i = left; + int j = right; + if (i == j) return; + uint pivot = arr[uint(left + (right - left) / 2)]; + while (i <= j) { + while (arr[uint(i)] < pivot) i++; + while (pivot < arr[uint(j)]) j--; + if (i <= j) { + (arr[uint(i)], arr[uint(j)]) = (arr[uint(j)], arr[uint(i)]); + i++; + j--; + } + } + if (left < j) + quickSort(arr, left, j); + if (i < right) + quickSort(arr, i, right); +} + +contract QuickSort { + function sort(uint[] memory data) public pure returns (uint[] memory) { + quickSort(data, int(0), int(data.length - 1)); + return data; + } +} \ No newline at end of file diff --git a/test/Sort.t.sol b/test/Sort.t.sol new file mode 100644 index 0000000..2a32f64 --- /dev/null +++ b/test/Sort.t.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import {Test} from "forge-std/Test.sol"; +import {QuickSort} from "../src/Sort.sol"; +import { console } from "forge-std/console.sol"; + +contract SortTest is Test { + QuickSort public quickSort; + + function setUp() public { + quickSort = new QuickSort(); + } + + function testSort() public { + for (uint256 i = 10; i <= 400; i+=10) { + runSort(i); + } + } + + function runSort(uint256 size) public { + uint[] memory data = new uint[](size); + for (uint256 i = 0; i < size; i++) { + data[i] = i % 3; + } + + uint256 gas = gasleft(); + quickSort.sort(data); + console.log("Gas (in dollars) used for array of size ", size, " gas: ", gas - gasleft()); + } + + function gasToDollars(uint256 gas) internal pure returns (uint256) { + return gas * 1e9 * 30000 / 1e18; + } +}