SassySort 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +3 -0
- data/README.md +47 -0
- data/lib/SassySort.rb +15 -0
- data/stylesheets/_SassySort.scss +17 -0
- data/stylesheets/algorithms/_bubble-sort.scss +11 -0
- data/stylesheets/algorithms/_comb-sort.scss +21 -0
- data/stylesheets/algorithms/_insertion-sort.scss +12 -0
- data/stylesheets/algorithms/_quick-sort.scss +21 -0
- data/stylesheets/algorithms/_selection-sort.scss +14 -0
- data/stylesheets/algorithms/_shell-sort.scss +18 -0
- data/stylesheets/helpers/_sort.scss +12 -0
- data/stylesheets/helpers/_str-compare.scss +22 -0
- data/stylesheets/helpers/_swap.scss +16 -0
- data/stylesheets/settings/_order.scss +4 -0
- metadata +59 -0
data/CHANGELOG.md
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Sass sort
|
|
2
|
+
=========
|
|
3
|
+
|
|
4
|
+
Here are a couple of ways to sort values (including strings) in Sass (~> 3.3).
|
|
5
|
+
|
|
6
|
+
**Disclaimer!** While it can be useful to sort numbers in Sass in case of the making of a modular scale or something, it is rarely the case for strings. The main idea behind this repository is to push Sass' syntax to its limit. Long story short: *because we can*.
|
|
7
|
+
|
|
8
|
+
## Available algorithms
|
|
9
|
+
|
|
10
|
+
* [Comb sort](http://en.wikipedia.org/wiki/Comb_sort)
|
|
11
|
+
* [Quick sort](http://en.wikipedia.org/wiki/Quicksort)
|
|
12
|
+
* [Shell sort](http://en.wikipedia.org/wiki/Shellsort)
|
|
13
|
+
* [Bubble sort](http://en.wikipedia.org/wiki/Bubble_sort)
|
|
14
|
+
* [Selection sort](http://en.wikipedia.org/wiki/Selection_sort)
|
|
15
|
+
* [Insertion sort](http://en.wikipedia.org/wiki/Insertion_sort)
|
|
16
|
+
|
|
17
|
+
## Benchmark
|
|
18
|
+
|
|
19
|
+
### 50 items long list
|
|
20
|
+
* quick -> 0.238s / 0.226s / 0.202s / 0.206s / 0.226s => **0.2195s**
|
|
21
|
+
* comb -> 0.350s / 0.323s / 0.330s / 0.324s / 0.328s => **0.3310s**
|
|
22
|
+
* shell -> 0.412s / 0.355s / 0.359s / 0.372s / 0.437s => **0.3869s**
|
|
23
|
+
* insertion -> 0.400s / 0.42s / 0.406s / 0.399s / 0.468s => **0.4185s**
|
|
24
|
+
* selection -> 0.635s / 0.579s / 0.580s / 0.601s / 0.611s => **0.6012s**
|
|
25
|
+
* bubble -> 0.976s / 0.830s / 0.802s / 0.824s / 0.936s => **0.8736s**
|
|
26
|
+
|
|
27
|
+
### 100 items long list
|
|
28
|
+
* quick -> 0.592s / 0.547s / 0.569s / 0.541s / 0.548s => **0.5594s**
|
|
29
|
+
* comb -> 0.946s / 0.903s / 0.897s / 0.902s / 0.905s => **0.9106s**
|
|
30
|
+
* shell -> 1.413s / 1.435s / 1.425s / 1.489s / 1.408s => **1.4340s**
|
|
31
|
+
* insertion -> 1.744s / 1.625s / 1.583s / 1.572s / 1.608s => **1.6263s**
|
|
32
|
+
* selection -> 2.605s / 2.462s / 2.502s / 2.490s / 2.477s => **2.5072s**
|
|
33
|
+
* bubble -> 3.828s / 3.699s / 3.704s / 3.672s / 3.743s => **3.7292s**
|
|
34
|
+
|
|
35
|
+
`quicksort` is well named since it is by far the fastest algorithm: about 3 times faster than `shellsort` and `insertionsort` implementations, 4 times faster than `selectionsort` and 7 times faster than `bubblesort`.
|
|
36
|
+
|
|
37
|
+
## Install as a Compass extension
|
|
38
|
+
|
|
39
|
+
1. `gem install SassySort`
|
|
40
|
+
2. Add `require 'SassySort'` to your `config.rb`
|
|
41
|
+
3. Import it in your stylesheets with `@import 'SassySort'`
|
|
42
|
+
|
|
43
|
+
## Credits
|
|
44
|
+
|
|
45
|
+
Thanks to [mgechev](https://github.com/mgechev) for [his work on sorting algorithms](https://github.com/mgechev/javascript-algorithms/tree/master/src/sorting) in JavaScript which has been a great help for implementing sorting algorithms in Sass.
|
|
46
|
+
|
|
47
|
+
More informations about sorting algorithms at [http://www.sorting-algorithms.com/](http://www.sorting-algorithms.com/).
|
data/lib/SassySort.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'compass'
|
|
2
|
+
|
|
3
|
+
extension_path = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
|
4
|
+
Compass::Frameworks.register('SassySort', :path => extension_path)
|
|
5
|
+
|
|
6
|
+
# Version is a number. If a version contains alphas, it will be created as a prerelease version
|
|
7
|
+
# Date is in the form of YYYY-MM-DD
|
|
8
|
+
module SassySort
|
|
9
|
+
VERSION = "0.0.1"
|
|
10
|
+
DATE = "2014-02-19"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module Sass::Script::Functions
|
|
14
|
+
|
|
15
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Order to deal with
|
|
2
|
+
@import "settings/order";
|
|
3
|
+
|
|
4
|
+
// Helpers
|
|
5
|
+
@import "helpers/str-compare";
|
|
6
|
+
@import "helpers/swap";
|
|
7
|
+
|
|
8
|
+
// Sorting algorithms
|
|
9
|
+
@import "algorithms/comb-sort";
|
|
10
|
+
@import "algorithms/quick-sort";
|
|
11
|
+
@import "algorithms/shell-sort";
|
|
12
|
+
@import "algorithms/bubble-sort";
|
|
13
|
+
@import "algorithms/selection-sort";
|
|
14
|
+
@import "algorithms/insertion-sort";
|
|
15
|
+
|
|
16
|
+
// Sort function
|
|
17
|
+
@import "helpers/sort";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
@function bubble-sort($list, $order: $default-order) {
|
|
2
|
+
@for $i from 1 through length($list) {
|
|
3
|
+
@for $j from $i * -1 through -1 {
|
|
4
|
+
$j: abs($j);
|
|
5
|
+
@if $j > 1 and _str-compare(nth($list, $j), nth($list, $j - 1), $order) {
|
|
6
|
+
$list: _swap($list, $j, $j - 1);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
@return $list;
|
|
11
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
@function comb-sort($list, $order: $default-order) {
|
|
2
|
+
$gap: length($list);
|
|
3
|
+
$shrink: 1.3;
|
|
4
|
+
$swapped: false;
|
|
5
|
+
|
|
6
|
+
@while $gap != 1 or $swapped != false {
|
|
7
|
+
$gap: floor($gap / $shrink);
|
|
8
|
+
@if $gap < 1 { $gap: 1 }
|
|
9
|
+
$i: 1;
|
|
10
|
+
$swapped: false;
|
|
11
|
+
@while $i + $gap <= length($list) {
|
|
12
|
+
@if not _str-compare(nth($list, $i), nth($list, $i + $gap), $order) {
|
|
13
|
+
$list: _swap($list, $i, $i + $gap);
|
|
14
|
+
$swapped: true;
|
|
15
|
+
}
|
|
16
|
+
$i: $i + 1;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@return $list;
|
|
21
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
@function insertion-sort($list, $order: $default-order) {
|
|
2
|
+
@for $i from 1 through length($list) {
|
|
3
|
+
$current: nth($list, $i);
|
|
4
|
+
$j: $i - 1;
|
|
5
|
+
@while $j > 0 and not _str-compare(nth($list, $j), $current, $order) {
|
|
6
|
+
$list: set-nth($list, $j + 1, nth($list, $j));
|
|
7
|
+
$j: $j - 1;
|
|
8
|
+
}
|
|
9
|
+
$list: set-nth($list, $j + 1, $current);
|
|
10
|
+
}
|
|
11
|
+
@return $list;
|
|
12
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
@function quick-sort($list, $order: $default-order) {
|
|
2
|
+
$less: ();
|
|
3
|
+
$equal: ();
|
|
4
|
+
$large: ();
|
|
5
|
+
@if length($list) > 1 {
|
|
6
|
+
$seed: nth($list, ceil(length($list) / 2));
|
|
7
|
+
@each $item in $list {
|
|
8
|
+
@if $item == $seed {
|
|
9
|
+
$equal: append($equal, $item, list-separator($list));
|
|
10
|
+
}
|
|
11
|
+
@else if _str-compare($item, $seed, $order) {
|
|
12
|
+
$less: append($less, $item, list-separator($list));
|
|
13
|
+
}
|
|
14
|
+
@else if not _str-compare($item, $seed, $order) {
|
|
15
|
+
$large: append($large, $item, list-separator($list));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
@return join(join(quick-sort($less, $order), $equal), quick-sort($large, $order));
|
|
19
|
+
}
|
|
20
|
+
@return $list;
|
|
21
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
@function selection-sort($list, $order: $default-order) {
|
|
2
|
+
@for $i from 1 through length($list) {
|
|
3
|
+
$idx: $i;
|
|
4
|
+
$min: nth($list, $i);
|
|
5
|
+
@for $j from $i + 1 through length($list) {
|
|
6
|
+
@if not _str-compare($min, nth($list, $j), $order) {
|
|
7
|
+
$min: nth($list, $j);
|
|
8
|
+
$idx: $j;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
$list: _swap($list, $i, $idx);
|
|
12
|
+
}
|
|
13
|
+
@return $list;
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
@function shell-sort($list, $order: $default-order) {
|
|
2
|
+
$gaps: 701, 301, 132, 57, 23, 10, 4, 1;
|
|
3
|
+
@for $k from 1 through length($gaps) {
|
|
4
|
+
$gap: nth($gaps, $k);
|
|
5
|
+
$i: $gap;
|
|
6
|
+
@while $i <= length($list) {
|
|
7
|
+
$current: nth($list, $i);
|
|
8
|
+
$j: $i;
|
|
9
|
+
@while $j >= $gap and $j - $gap > 0 and not _str-compare(nth($list, $j - $gap), $current, $order) {
|
|
10
|
+
$list: set-nth($list, $j, nth($list, $j - $gap));
|
|
11
|
+
$j: $j - $gap;
|
|
12
|
+
}
|
|
13
|
+
$list: set-nth($list, $j, $current);
|
|
14
|
+
$i: $i + $gap;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
@return $list;
|
|
18
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Sort function
|
|
2
|
+
// Delaying to an algorithm-specific function
|
|
3
|
+
// depending on the algorithm specified
|
|
4
|
+
//
|
|
5
|
+
// @param $list: list to sort
|
|
6
|
+
// @param $order: order to deal with
|
|
7
|
+
// @param $algorithm: algorithm to use
|
|
8
|
+
//
|
|
9
|
+
// @return [list]: sorted list
|
|
10
|
+
@function sort($list, $order: $default-order, $algorithm: "quick") {
|
|
11
|
+
@return call("#{$algorithm}-sort", $list, $order);
|
|
12
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Compares two string to determine which comes first
|
|
2
|
+
//
|
|
3
|
+
// @param $a: first string
|
|
4
|
+
// @parem $b: second string
|
|
5
|
+
// @param $order: order to deal with
|
|
6
|
+
//
|
|
7
|
+
// @return $boolean
|
|
8
|
+
@function _str-compare($a, $b, $order) {
|
|
9
|
+
@if type-of($a) == number and type-of($b) == number {
|
|
10
|
+
@return $a < $b;
|
|
11
|
+
}
|
|
12
|
+
$a: to-lower-case($a + unquote(""));
|
|
13
|
+
$b: to-lower-case($b + unquote(""));
|
|
14
|
+
@for $i from 1 through min(str-length($a), str-length($b)) {
|
|
15
|
+
$char-a: str-slice($a, $i, $i);
|
|
16
|
+
$char-b: str-slice($b, $i, $i);
|
|
17
|
+
@if $char-a and $char-b and index($order, $char-a) != index($order, $char-b) {
|
|
18
|
+
@return index($order, $char-a) < index($order, $char-b);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
@return str-length($a) < str-length($b);
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Swaps values at indexes $a and $b from $list
|
|
2
|
+
//
|
|
3
|
+
// @param $list: list to update
|
|
4
|
+
// @param $a: index of first element
|
|
5
|
+
// @param $b: index of second element
|
|
6
|
+
//
|
|
7
|
+
// @return list
|
|
8
|
+
@function _swap($list, $a, $b) {
|
|
9
|
+
@if abs($a) > length($list) or abs($b) > length($list) {
|
|
10
|
+
@return $list;
|
|
11
|
+
}
|
|
12
|
+
$tmp: nth($list, $a);
|
|
13
|
+
$list: set-nth($list, $a, nth($list, $b));
|
|
14
|
+
$list: set-nth($list, $b, $tmp);
|
|
15
|
+
@return $list;
|
|
16
|
+
}
|
metadata
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: SassySort
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Hugo Giraudel
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2014-02-19 00:00:00.000000000 Z
|
|
13
|
+
dependencies: []
|
|
14
|
+
description: Sass sorting function
|
|
15
|
+
email:
|
|
16
|
+
- hugo.giraudel@gmail.com
|
|
17
|
+
executables: []
|
|
18
|
+
extensions: []
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- README.md
|
|
22
|
+
- CHANGELOG.md
|
|
23
|
+
- lib/SassySort.rb
|
|
24
|
+
- stylesheets/algorithms/_bubble-sort.scss
|
|
25
|
+
- stylesheets/algorithms/_comb-sort.scss
|
|
26
|
+
- stylesheets/algorithms/_insertion-sort.scss
|
|
27
|
+
- stylesheets/algorithms/_quick-sort.scss
|
|
28
|
+
- stylesheets/algorithms/_selection-sort.scss
|
|
29
|
+
- stylesheets/algorithms/_shell-sort.scss
|
|
30
|
+
- stylesheets/helpers/_sort.scss
|
|
31
|
+
- stylesheets/helpers/_str-compare.scss
|
|
32
|
+
- stylesheets/helpers/_swap.scss
|
|
33
|
+
- stylesheets/settings/_order.scss
|
|
34
|
+
- stylesheets/_SassySort.scss
|
|
35
|
+
homepage: https://github.com/HugoGiraudel/SassySort/
|
|
36
|
+
licenses: []
|
|
37
|
+
post_install_message:
|
|
38
|
+
rdoc_options: []
|
|
39
|
+
require_paths:
|
|
40
|
+
- lib
|
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
|
+
none: false
|
|
43
|
+
requirements:
|
|
44
|
+
- - ! '>='
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
48
|
+
none: false
|
|
49
|
+
requirements:
|
|
50
|
+
- - ! '>='
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: 1.3.6
|
|
53
|
+
requirements: []
|
|
54
|
+
rubyforge_project: SassySort
|
|
55
|
+
rubygems_version: 1.8.24
|
|
56
|
+
signing_key:
|
|
57
|
+
specification_version: 3
|
|
58
|
+
summary: A collection of famous sorting algorithms implemented in Sass for Sass.
|
|
59
|
+
test_files: []
|