├── README.md ├── challenge.md └── submissions ├── Alex ├── __linklist.js ├── _linklist.js ├── package.json ├── perf │ ├── __linklist.test.js │ ├── _linklist.test.js │ ├── append-shift.js │ ├── append.js │ └── peek.js └── spec │ ├── append.spec.js │ ├── init.spec.js │ ├── isEmpty.spec.js │ ├── isLinkList.spec.js │ ├── multipleLists.spec.js │ ├── peek.spec.js │ ├── remove.spec.js │ └── shift.spec.js ├── Alexander Baygeldin ├── linklist.js └── test.js ├── Alexander Lyakshev ├── main.js └── xnlinklist.js ├── Alexey Efremov ├── README.md ├── benchmark.js ├── index.js ├── lib │ └── _linklist.js ├── package.json └── test.js ├── Almaz Mubinov ├── List102 │ ├── List102.coffee │ └── List102.js ├── README.md ├── benchmark.js └── original_linklist │ └── _linklist.js ├── Andrey Babkin ├── README.md ├── lib │ └── linklist.js ├── package.json └── test.js ├── Avraham Essoudry ├── LinkedListTester.html └── Scripts │ ├── _linklist.js │ ├── generic_linklist.js │ └── tester.js ├── Boris Serduk ├── README.md ├── benchmark.js ├── package.json ├── spec │ ├── basic.spec.js │ ├── support │ │ └── jasmine.json │ └── wrapped.spec.js └── src │ ├── nodejs-linklist.js │ ├── prebuilt-getters.js │ ├── symbol-based.js │ └── wrapped-items.js ├── Borislav Peev └── linkedlist.js ├── Dmitry Karaush and Ruslan Koptev ├── bench.js ├── benchengine.js ├── benches │ ├── indexBench.js │ ├── manyListsBench.js │ ├── sawBench.js │ └── simpleBench.js ├── ll.js ├── lldef.js ├── ourbench.js └── package.json ├── Faur George ├── GenericList.js └── Test.htm ├── Ilya Sonin └── linkedList.js ├── Ivan Babak ├── README.md ├── comparison.js ├── lib │ ├── _linklist.js │ └── linklist.js ├── package.json └── test │ ├── bench.js │ ├── test-extended.js │ └── test.js ├── Kobi ├── linklist.js └── linklistTest.js ├── Mark Ablovacky ├── mine.js ├── original.js └── test.js ├── Mateusz Krzeszowiak ├── BlinkedList.js ├── benchmark │ ├── fifo.js │ ├── fifo.png │ ├── filling.js │ ├── filling.png │ ├── iterating.js │ ├── iterating.png │ ├── lifo.js │ ├── lifo.png │ ├── random.js │ ├── random.png │ └── utils.js ├── package.json ├── readme.html └── test.js ├── Max Melentiev ├── README ├── _linklist.js ├── benchmark │ ├── linked_list.coffee │ ├── linked_list.js │ ├── linked_list_harmony.coffee │ ├── linked_list_harmony.js │ ├── shared.coffee │ └── shared.js ├── linked_list.coffee ├── linked_list.js ├── linked_list_harmony.coffee ├── linked_list_harmony.js ├── linked_list_proc.coffee ├── linked_list_proc.js ├── package.json └── test │ ├── linked_list.coffee │ ├── linked_list.js │ ├── linked_list_harmony.coffee │ ├── linked_list_harmony.js │ ├── linked_list_proc.coffee │ ├── linked_list_proc.js │ ├── linked_list_shared.coffee │ ├── linked_list_shared.js │ └── simple │ └── test-timers-linked-list.js ├── Ori Shalev ├── orilist.js └── test_orilist.js ├── Priel Hakak └── Ver3.js ├── Sergey Shpak ├── README.md ├── challenge.js ├── lib │ ├── _linklistgeneric-1.js │ ├── _linklistgeneric-2.js │ └── _linklistoriginal.js └── package.json ├── Sergii Stryzhevskyi ├── README.md ├── index.js ├── index2.js ├── lib │ ├── _linklist-array-adaptive.js │ ├── _linklist-array.js │ ├── _linklist-arrayid-typed.js │ ├── _linklist-arrayid.js │ ├── _linklist-map.js │ ├── _linklist-object.js │ ├── _linklist-weakmap.js │ └── _linklist.js ├── package.json └── test.js ├── Tehila ├── benchmark │ ├── common.js │ └── lists │ │ ├── lists_append_benchmark.js │ │ ├── lists_init_benchmark.js │ │ ├── lists_isempty_benchmark.js │ │ ├── lists_peek_benchmark.js │ │ ├── lists_remove_benchmark.js │ │ └── lists_shift_benchmark.js ├── lib │ ├── _generic_linklist.js │ └── _linklist.js ├── node.gyp └── test │ └── lists │ ├── test-generic-linked-list-3-level-list.js │ ├── test-generic-linked-list-4-level-list.js │ ├── test-generic-linked-list-idle-items-and-empty-list.js │ ├── test-generic-linked-list-idle-items-and-list.js │ ├── test-generic-linked-list-idle-items.js │ └── test-generic-linked-list-with-list-of-lists.js └── Vasiliy Kostin ├── js.node.megabyte.templated ├── _linklist.js ├── _multilinklist.js ├── _template.js └── benchmark.js └── js.node.megabyte ├── _linklist.js ├── _multilinklist.js └── benchmark.js /challenge.md: -------------------------------------------------------------------------------- 1 | # JS Linked List Challenge 2 | 3 | There are very few really great programmers, and we'd like to give them a chance to prove it to the world, and get a nice prize in return! 4 | 5 | ## The challenge: generalize NodeJS's linklist 6 | NodeJS has a very high performance, low-memory overhead implementation of a linked list: https://github.com/joyent/node/blob/master/lib/_linklist.js. 7 | 8 | This implementation is specific (idle items only), and does not allow list parent to hold two or more different lists in the parent list object. 9 | 10 | Your challenge is to make it generic, while not reducing performance, and include tests to show that performance hasn’t been degraded. 11 | 12 | The fastest, most efficient, most generic implementation wins the prize! 13 | 14 | ## Rules 15 | * Send your solution to meytal@hola.org. Last date for submission is **June 30, 2015**. 16 | * Winners will be announced on **July 10** on this page. 17 | * Solutions should not be publicized until the contest ends and winners are announced. Solutions made public before **June 30** will be rejected. 18 | * JavaScript implementation used for benchmarking is V8 19 | * Each contestant may submit multiple submissions and solutions, and submit additional improvements until the closure date. The best out of those submissions will be selected. 20 | * You may submit more than one submission. 21 | 22 | ## Prizes 23 | * 1st prize: $1500 24 | * 2nd prize: $1000 25 | * 3rd prize: $500 26 | * Most original prize: $350. Will be granted to the most creative, original solution that will achieve amazing performance using out of the box, wild, or non-standard ideas. 27 | * EXTRA!! If you know of a great programmer that you think can win, invite them to take the challenge by email, and copy challengejs@hola.org on that email. If your friend wins, we’ll double-up and send you the winning amount as well! 28 | 29 | ## Why are we doing this 30 | If you are a truly great programmer, we’d like to know you, and to get a chance to tell you more about us. If interested, we'll invite you for an interview. 31 | 32 | -------------------------------------------------------------------------------- /submissions/Alex/__linklist.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function init(list) { 4 | list = list || {}; 5 | list._linkList = {}; 6 | list._linkList._idleNext = list._linkList; 7 | list._linkList._idlePrev = list._linkList; 8 | list.peek = peek; 9 | list.shift = shift; 10 | list.append = append; 11 | list.remove = remove; 12 | list.isEmpty = isEmpty; 13 | list.isLinkList = isLinkList; 14 | return list; 15 | } 16 | exports.init = init; 17 | 18 | // show the most idle item 19 | function peekItem(list) { 20 | if (list._idlePrev == list) return null; 21 | return list._idlePrev; 22 | } 23 | 24 | function peek(list) { 25 | if ('undefined' === typeof list) { 26 | list = this; 27 | return peekItem(list._linkList); 28 | } 29 | if ('undefined' !== typeof list._idlePrev) { 30 | return peekItem(list); 31 | } 32 | return peekItem(list._linkList); 33 | } 34 | exports.peek = peek; 35 | 36 | 37 | // remove the most idle item from the list 38 | var first = null; 39 | function shift(list) { 40 | if ('undefined' === typeof list) { 41 | first = this._linkList._idlePrev; 42 | remove(first); 43 | return first; 44 | } 45 | if ('undefined' !== typeof list._idlePrev) { 46 | first = list._idlePrev; 47 | remove(first); 48 | return first; 49 | } 50 | if ('undefined' !== typeof list._linkList) { 51 | return shift(list._linkList); 52 | } 53 | } 54 | exports.shift = shift; 55 | 56 | 57 | // remove a item from its list 58 | function remove(item) { 59 | if ('undefined' !== typeof item._idleNext) { 60 | item._idleNext._idlePrev = item._idlePrev; 61 | } 62 | if ('undefined' !== typeof item._idlePrev) { 63 | item._idlePrev._idleNext = item._idleNext; 64 | } 65 | 66 | item._idleNext = null; 67 | item._idlePrev = null; 68 | } 69 | exports.remove = remove; 70 | 71 | 72 | function appendToItem(appendTo, item) { 73 | remove(item); 74 | item._idleNext = appendTo._idleNext; 75 | appendTo._idleNext._idlePrev = item; 76 | item._idlePrev = appendTo; 77 | appendTo._idleNext = item; 78 | return appendTo; 79 | } 80 | 81 | // remove a item from its list and place at the end. 82 | function append(list, item) { 83 | if ('undefined' === typeof item) { 84 | item = list; 85 | list = this; 86 | return appendToItem(list._linkList, item); 87 | } 88 | if ('undefined' === typeof list._idleNext) { 89 | return appendToItem(list._linkList, item); 90 | } 91 | return appendToItem(list, item); 92 | } 93 | exports.append = append; 94 | 95 | 96 | function isEmpty(list) { 97 | if ('undefined' === typeof list) { 98 | return this._linkList._idleNext === this._linkList; 99 | } 100 | if ('undefined' !== typeof list._idleNext) { 101 | return list._idleNext === list; 102 | } 103 | if ('undefined' !== typeof list._linkList) { 104 | return list._linkList._idleNext === list._linkList; 105 | } 106 | } 107 | exports.isEmpty = isEmpty; 108 | 109 | 110 | function isLinkList(list) { 111 | if ('undefined' === typeof list) { 112 | list = this; 113 | } 114 | return 'object' === typeof list._linkList; 115 | } 116 | exports.isLinkList = isLinkList; -------------------------------------------------------------------------------- /submissions/Alex/_linklist.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function init(list) { 4 | list._idleNext = list; 5 | list._idlePrev = list; 6 | } 7 | exports.init = init; 8 | 9 | 10 | // show the most idle item 11 | function peek(list) { 12 | if (list._idlePrev == list) return null; 13 | return list._idlePrev; 14 | } 15 | exports.peek = peek; 16 | 17 | 18 | // remove the most idle item from the list 19 | function shift(list) { 20 | var first = list._idlePrev; 21 | remove(first); 22 | return first; 23 | } 24 | exports.shift = shift; 25 | 26 | 27 | // remove a item from its list 28 | function remove(item) { 29 | if (item._idleNext) { 30 | item._idleNext._idlePrev = item._idlePrev; 31 | } 32 | 33 | if (item._idlePrev) { 34 | item._idlePrev._idleNext = item._idleNext; 35 | } 36 | 37 | item._idleNext = null; 38 | item._idlePrev = null; 39 | } 40 | exports.remove = remove; 41 | 42 | 43 | // remove a item from its list and place at the end. 44 | function append(list, item) { 45 | remove(item); 46 | item._idleNext = list._idleNext; 47 | list._idleNext._idlePrev = item; 48 | item._idlePrev = list; 49 | list._idleNext = item; 50 | } 51 | exports.append = append; 52 | 53 | 54 | function isEmpty(list) { 55 | return list._idleNext === list; 56 | } 57 | exports.isEmpty = isEmpty; -------------------------------------------------------------------------------- /submissions/Alex/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "linklist", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "__linklist.js", 6 | "scripts": { 7 | "test": "jasmine-node spec", 8 | "perf": "node perf/_linklist.test.js; node perf/__linklist.test.js" 9 | }, 10 | "author": "treeskar@gmail.com", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "benchmark": "^1.0.0", 14 | "microtime": "^1.4.2", 15 | "jasmine": "^2.3.1", 16 | "jasmine-node": "^1.14.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /submissions/Alex/perf/__linklist.test.js: -------------------------------------------------------------------------------- 1 | var _linklist = require('./../__linklist'); 2 | var microtime = require('microtime'); 3 | 4 | var iteration = 10000000; 5 | 6 | console.log('- __linkList -'); 7 | 8 | // link list initiation 9 | var _list = _linklist.init(); 10 | 11 | // append and remove test 12 | var startTime = microtime.now(); 13 | var _value = 0; 14 | for(var i=0; i -1) { 31 | valueList.splice(index, 1); 32 | } 33 | } 34 | } 35 | 36 | for (var i=0; i 0) { 42 | list.append(array[index-1]); 43 | } 44 | }); 45 | 46 | emptyList(array[array.length-1]); 47 | 48 | it('is all values found', function() { 49 | expect(valueList.length).toEqual(0); 50 | }); 51 | }); -------------------------------------------------------------------------------- /submissions/Alex/spec/peek.spec.js: -------------------------------------------------------------------------------- 1 | var _linklist = require('./../__linklist'); 2 | 3 | describe('Check linkList "Peek" method: ', function () { 4 | var list = _linklist.init(), 5 | i, item, iteration = 10; 6 | 7 | function checkPeekedItem(item, value) { 8 | it('check peeked item "' + value + '"', function () { 9 | expect(item.value).toEqual(value); 10 | }); 11 | } 12 | 13 | for(i=0; i=0.12.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /submissions/Almaz Mubinov/List102/List102.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | class List102 3 | 30/06/2015 4 | Almaz Mubinov, almaz@mubinov.com 5 | ### 6 | class List102 7 | 8 | constructor: ()-> 9 | next_key = "'"+@generateKey()+"'" 10 | prev_key = "'"+@generateKey()+"'" 11 | 12 | # replacing code of functions in runtime =) 13 | for _func of @ 14 | if typeof @[_func] == 'function' and _func != 'generateKey' 15 | source = @[_func]+"" 16 | new_code = source 17 | .replace(/next_key/g, next_key) 18 | .replace(/prev_key/g, prev_key) 19 | 20 | if new_code!=source 21 | eval('this.'+_func+'='+new_code) 22 | 23 | # generate random property key 24 | generateKey: ()-> 25 | if not global._list_102_keys? 26 | global._list_102_keys = [] 27 | 28 | loop 29 | key = Math.random().toString(36) 30 | return key if global._list_102_keys.indexOf(key)==-1 31 | 32 | init: (list)-> 33 | list[next_key] = list 34 | list[prev_key] = list 35 | 36 | # show the most idle item 37 | peek: (list)-> 38 | return if list[prev_key] == list then null else list[prev_key] 39 | 40 | # remove the most idle item from the list 41 | shift: (list)-> 42 | first = list[prev_key] 43 | @remove(first) 44 | return first 45 | 46 | 47 | # remove a item from its list 48 | remove: (item)-> 49 | if item[next_key] 50 | item[next_key][prev_key] = item[prev_key] 51 | 52 | if item[prev_key] 53 | item[prev_key][next_key] = item[next_key] 54 | 55 | item[next_key] = null 56 | item[prev_key] = null 57 | 58 | 59 | # remove a item from its list and place at the end. 60 | append: (list, item)-> 61 | @remove(item) 62 | item[next_key] = list[next_key] 63 | list[next_key][prev_key] = item 64 | item[prev_key] = list 65 | list[next_key] = item 66 | 67 | 68 | isEmpty: (list)-> 69 | return list[next_key] == list 70 | 71 | module.exports = List102 -------------------------------------------------------------------------------- /submissions/Almaz Mubinov/List102/List102.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.9.3 2 | 3 | /* 4 | class List102 5 | 30/06/2015 6 | Almaz Mubinov, almaz@mubinov.com 7 | */ 8 | 9 | (function() { 10 | var List102; 11 | 12 | List102 = (function() { 13 | function List102() { 14 | var _func, new_code, next_key, prev_key, source; 15 | next_key = "'" + this.generateKey() + "'"; 16 | prev_key = "'" + this.generateKey() + "'"; 17 | for (_func in this) { 18 | if (typeof this[_func] === 'function' && _func !== 'generateKey') { 19 | source = this[_func] + ""; 20 | new_code = source.replace(/next_key/g, next_key).replace(/prev_key/g, prev_key); 21 | if (new_code !== source) { 22 | eval('this.' + _func + '=' + new_code); 23 | } 24 | } 25 | } 26 | } 27 | 28 | List102.prototype.generateKey = function() { 29 | var key; 30 | if (global._list_102_keys == null) { 31 | global._list_102_keys = []; 32 | } 33 | while (true) { 34 | key = Math.random().toString(36); 35 | if (global._list_102_keys.indexOf(key) === -1) { 36 | return key; 37 | } 38 | } 39 | }; 40 | 41 | List102.prototype.init = function(list) { 42 | list[next_key] = list; 43 | return list[prev_key] = list; 44 | }; 45 | 46 | List102.prototype.peek = function(list) { 47 | if (list[prev_key] === list) { 48 | return null; 49 | } else { 50 | return list[prev_key]; 51 | } 52 | }; 53 | 54 | List102.prototype.shift = function(list) { 55 | var first; 56 | first = list[prev_key]; 57 | this.remove(first); 58 | return first; 59 | }; 60 | 61 | List102.prototype.remove = function(item) { 62 | if (item[next_key]) { 63 | item[next_key][prev_key] = item[prev_key]; 64 | } 65 | if (item[prev_key]) { 66 | item[prev_key][next_key] = item[next_key]; 67 | } 68 | item[next_key] = null; 69 | return item[prev_key] = null; 70 | }; 71 | 72 | List102.prototype.append = function(list, item) { 73 | this.remove(item); 74 | item[next_key] = list[next_key]; 75 | list[next_key][prev_key] = item; 76 | item[prev_key] = list; 77 | return list[next_key] = item; 78 | }; 79 | 80 | List102.prototype.isEmpty = function(list) { 81 | return list[next_key] === list; 82 | }; 83 | 84 | return List102; 85 | 86 | })(); 87 | 88 | module.exports = List102; 89 | 90 | }).call(this); 91 | -------------------------------------------------------------------------------- /submissions/Almaz Mubinov/README.md: -------------------------------------------------------------------------------- 1 | # Solution for Hola’s Spring JS Competition - 2015 2 | 3 | ##Contestant 4 | 5 | Almaz Mubinov 6 | 7 | mailto:almaz@mubinov.com 8 | 9 | https://github.com/mubinov 10 | 11 | ## Solution 12 | 13 | My solution in **List102/List102.js** (it is compiled from coffescript: **List102/List102.coffee**). 14 | Solution based on very funny hack: we replace source code of our List102 class in runtime for improve performance 15 | 16 | ## How it use 17 | 18 | var List102 = require('./List102/List102'); 19 | var list1 = new List102(); // first list 20 | var list2 = new List102(); // second list 21 | var object = /*some object*/; 22 | list1.init(object); 23 | list2.init(object); // Yes, object holds another list pointers! 24 | 25 | 26 | ## Benchmark 27 | 28 | benchmark.js: 29 | 30 | Benchmark for original linklist: 31 | Timer 1 (creating and appending 100k items): 972ms 32 | Timer 2 (shift random 10k items): 1540ms 33 | Timer 3 (peek random 10k items): 276ms 34 | Timer 4 (remove random 10k items): 413ms 35 | 36 | Benchmark for List102: 37 | Timer 1 (creating and appending 100k items): *823ms* 38 | Timer 2 (shift random 10k items): *1456ms* 39 | Timer 3 (peek random 10k items): *261ms* 40 | Timer 4 (remove random 10k items): *392ms* 41 | 42 | 43 | Full table 44 | 45 | original linklist List102 46 | Timer 1 (creating and appending 100k items) 972 823 47 | Timer 2 (shift random 10k items) 1540 1456 48 | Timer 3 (peek random 10k items) 276 261 49 | Timer 4 (remove random 10k items) 413 392 50 | 51 | 52 | How we can see performance hasn’t been degraded. -------------------------------------------------------------------------------- /submissions/Almaz Mubinov/benchmark.js: -------------------------------------------------------------------------------- 1 | function generateRandomObjects(count){ 2 | var result = []; 3 | for (var i = 0; i < count; i++) { 4 | var obj = {}; 5 | obj[i] = Math.random().toString(36); 6 | result.push(obj); 7 | } 8 | return result; 9 | } 10 | function getRandom(max){ 11 | return Math.floor(Math.random() * max); 12 | } 13 | var i = 0; 14 | var n = 100000; 15 | 16 | // Benchmark for original linklist 17 | var _linklist = require('./original_linklist/_linklist'); 18 | console.log('Benchmark for original linklist:'); 19 | var test_objects = generateRandomObjects(n); 20 | 21 | // Test 1 22 | console.time('\tTimer 1 (creating and appending 100k items)'); 23 | _linklist.init(test_objects[0]); 24 | for (i =1; i < n; i++) { 25 | _linklist.append(test_objects[0], test_objects[i]); 26 | } 27 | console.timeEnd('\tTimer 1 (creating and appending 100k items)'); 28 | 29 | // Test 2 30 | console.time('\tTimer 2 (shift random 10k items)'); 31 | for (i =1; i < n; i++) { 32 | try{ 33 | _linklist.shift(test_objects[getRandom(n)]); 34 | }catch ($e){ 35 | 36 | } 37 | } 38 | console.timeEnd('\tTimer 2 (shift random 10k items)'); 39 | 40 | // Test 3 41 | console.time('\tTimer 3 (peek random 10k items)'); 42 | for (i =1; i < n; i++) { 43 | try{ 44 | m = _linklist.peek(test_objects[getRandom(n)]); 45 | if(m<0){ 46 | console.log('this is unreachable line') 47 | } 48 | }catch ($e){ 49 | 50 | } 51 | } 52 | console.timeEnd('\tTimer 3 (peek random 10k items)'); 53 | 54 | // Test 4 55 | console.time('\tTimer 4 (remove random 10k items)'); 56 | for (i =1; i < n; i++) { 57 | try{ 58 | _linklist.remove(test_objects[getRandom(n)]); 59 | }catch ($e){ 60 | 61 | } 62 | } 63 | console.timeEnd('\tTimer 4 (remove random 10k items)'); 64 | 65 | 66 | //--------------------------------------------------- 67 | console.log('\n\n'); 68 | 69 | // Benchmark for List102 70 | var List102 = require('./List102/List102'); 71 | 72 | console.log('Benchmark for List102:'); 73 | list102 = new List102(); 74 | 75 | // Test 1 76 | console.time('\tTimer 1 (creating and appending 100k items)'); 77 | list102.init(test_objects[0]); 78 | for (i =1; i < n; i++) { 79 | list102.append(test_objects[0], test_objects[i]); 80 | } 81 | console.timeEnd('\tTimer 1 (creating and appending 100k items)'); 82 | 83 | // Test 2 84 | console.time('\tTimer 2 (shift random 10k items)'); 85 | for (i =1; i < n; i++) { 86 | try{ 87 | list102.shift(test_objects[getRandom(n)]); 88 | }catch ($e){ 89 | 90 | } 91 | } 92 | console.timeEnd('\tTimer 2 (shift random 10k items)'); 93 | 94 | // Test 3 95 | console.time('\tTimer 3 (peek random 10k items)'); 96 | for (i =1; i < n; i++) { 97 | try{ 98 | m = list102.peek(test_objects[getRandom(n)]); 99 | if(m<0){ 100 | console.log('this is unreachable line') 101 | } 102 | }catch ($e){ 103 | 104 | } 105 | } 106 | console.timeEnd('\tTimer 3 (peek random 10k items)'); 107 | 108 | // Test 4 109 | console.time('\tTimer 4 (remove random 10k items)'); 110 | for (i =1; i < n; i++) { 111 | try{ 112 | list102.remove(test_objects[getRandom(n)]); 113 | }catch ($e){ 114 | 115 | } 116 | } 117 | console.timeEnd('\tTimer 4 (remove random 10k items)'); -------------------------------------------------------------------------------- /submissions/Almaz Mubinov/original_linklist/_linklist.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 'use strict'; 23 | 24 | function init(list) { 25 | list._idleNext = list; 26 | list._idlePrev = list; 27 | } 28 | exports.init = init; 29 | 30 | 31 | // show the most idle item 32 | function peek(list) { 33 | if (list._idlePrev == list) return null; 34 | return list._idlePrev; 35 | } 36 | exports.peek = peek; 37 | 38 | 39 | // remove the most idle item from the list 40 | function shift(list) { 41 | var first = list._idlePrev; 42 | remove(first); 43 | return first; 44 | } 45 | exports.shift = shift; 46 | 47 | 48 | // remove a item from its list 49 | function remove(item) { 50 | if (item._idleNext) { 51 | item._idleNext._idlePrev = item._idlePrev; 52 | } 53 | 54 | if (item._idlePrev) { 55 | item._idlePrev._idleNext = item._idleNext; 56 | } 57 | 58 | item._idleNext = null; 59 | item._idlePrev = null; 60 | } 61 | exports.remove = remove; 62 | 63 | 64 | // remove a item from its list and place at the end. 65 | function append(list, item) { 66 | remove(item); 67 | item._idleNext = list._idleNext; 68 | list._idleNext._idlePrev = item; 69 | item._idlePrev = list; 70 | list._idleNext = item; 71 | } 72 | exports.append = append; 73 | 74 | 75 | function isEmpty(list) { 76 | return list._idleNext === list; 77 | } 78 | exports.isEmpty = isEmpty; -------------------------------------------------------------------------------- /submissions/Andrey Babkin/README.md: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | + JavaScript code challende url: http://hola.org/challenge_js?l 5 | + Original _linklist code: https://github.com/joyent/node/blob/master/lib/_linklist.js 6 | 7 | Start & Test command 8 | ===================== 9 | 10 | npm start 11 | 12 | or 13 | 14 | npm test 15 | 16 | The program will add 1000000 elements in the created linked list, and then destroy them with the *shift* method. 17 | Consistently used the original library *_linklist*, then used my solution to the same problem. -------------------------------------------------------------------------------- /submissions/Andrey Babkin/lib/linklist.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // List item class 4 | function ListItem() { 5 | this._next = null; 6 | this._prev = null; 7 | } 8 | ListItem.prototype = Object.create(null); 9 | module.exports.ListItem = ListItem; 10 | 11 | // Linked list class 12 | function LinkList() { 13 | var self = this; 14 | 15 | this._first = null; 16 | this._last = null; 17 | 18 | // append new ListItem object with initial data field filled 19 | this.append = function (data) { 20 | var obj = new ListItem(); 21 | obj.data = data; 22 | 23 | if (!self._last) { 24 | self._first = obj; 25 | self._last = obj; 26 | } else { 27 | obj._prev = self._last; 28 | self._last._next = obj; 29 | self._last = obj; 30 | } 31 | }; 32 | 33 | // get last item 34 | this.peek = function () { 35 | return self._last; 36 | }; 37 | 38 | // remove item from list and return it 39 | this.remove = function (item) { 40 | if (!!item) { 41 | if (item._prev) { 42 | item._prev._next = item._next; 43 | } 44 | if (item._next) { 45 | item._next._prev = item._prev; 46 | } 47 | item._prev = null; 48 | item._next = null; 49 | } 50 | return item; 51 | }; 52 | 53 | // returns first ListItem object and remove it from list 54 | this.shift = function () { 55 | var result; 56 | 57 | if (!!self._first) { 58 | result = self._first; 59 | self._first = self._first._next; 60 | } 61 | return self.remove(result); 62 | }; 63 | 64 | // iterator 65 | this.forEach = function (callback) { 66 | var current = self._first, 67 | idx = 0; 68 | if (typeof callback === 'function') { 69 | while (!!current) { 70 | callback(current, idx, self); 71 | idx++; 72 | current = current._next; 73 | } 74 | } 75 | }; 76 | 77 | // map 78 | this.map = function (callback) { 79 | var current = self._first, 80 | result = []; 81 | if (typeof callback !== 'function') { 82 | callback = function (item) { 83 | return item.data; 84 | }; 85 | } 86 | while (!!current) { 87 | result.push(callback(current)); 88 | current = current._next; 89 | } 90 | return result; 91 | }; 92 | 93 | // test if the list is empty 94 | this.isEmpty = function () { 95 | return !self._first; 96 | }; 97 | } 98 | LinkList.prototype = Object.create(null); 99 | module.exports.LinkList = LinkList; -------------------------------------------------------------------------------- /submissions/Andrey Babkin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "linklist", 3 | "description": "link list challenge", 4 | "private": "true", 5 | "license": "proprietary", 6 | "author": { 7 | "name": "Andrew Babkin", 8 | "email": "ab@izh.com" 9 | }, 10 | "scripts": { 11 | "test": "node ./test.js", 12 | "start": "node ./test.js" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /submissions/Andrey Babkin/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | (function () { 4 | 5 | var _linklist = require('_linklist'), 6 | linklist = require('./lib/linklist'); 7 | 8 | var 9 | ITERATIONS = 1000000, 10 | startTime, 11 | listObject, 12 | i, 13 | obj; 14 | 15 | 16 | startTime = Date.now(); 17 | console.log("START ORIGINAL TEST AT", startTime); 18 | 19 | listObject = {}; 20 | _linklist.init(listObject); 21 | 22 | for (i = 0; i < ITERATIONS; i++) { 23 | _linklist.append(listObject, { 24 | idx: i 25 | }); 26 | } 27 | 28 | while (!_linklist.isEmpty(listObject)) { 29 | obj = _linklist.shift(listObject); 30 | //console.log(obj); 31 | } 32 | 33 | console.log("PROCESS TIME IS %d milliseconds", Date.now() - startTime); 34 | 35 | console.log(""); 36 | 37 | startTime = Date.now(); 38 | console.log("START CHALLENGED TEST AT", startTime); 39 | 40 | listObject = {}; 41 | listObject.firstList = new linklist.LinkList(); 42 | for (i = 0; i < ITERATIONS; i++) { 43 | listObject.firstList.append({ 44 | idx: i 45 | }); 46 | } 47 | while (!listObject.firstList.isEmpty()) { 48 | obj = listObject.firstList.shift(); 49 | //console.log(obj); 50 | } 51 | 52 | // iterator test 53 | /*listObject.firstList.forEach(function (item) { 54 | listObject.firstList.remove(item); 55 | });*/ 56 | 57 | // map test 58 | /*console.log(listObject.firstList.map(function (item) { 59 | return item; 60 | }));*/ 61 | 62 | console.log("PROCESS TIME IS %d milliseconds", Date.now() - startTime); 63 | 64 | }()); 65 | -------------------------------------------------------------------------------- /submissions/Avraham Essoudry/LinkedListTester.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Link List Test 6 | 7 | 15 | 18 | 19 | 20 |

Operations on regular items

21 |
Normal implementation (ms.): ??
22 |
Generic implementation (ms.): ??
23 | 24 |

Operations on list items

25 |
Normal implementation (ms.): NOT SUPPORTED
26 |
Generic implementation (ms.): ??
27 | 28 | -------------------------------------------------------------------------------- /submissions/Avraham Essoudry/Scripts/_linklist.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | define(function(require, exports, module) { 23 | 'use strict'; 24 | 25 | function init(list) { 26 | list._idleNext = list; 27 | list._idlePrev = list; 28 | } 29 | exports.init = init; 30 | 31 | // show the most idle item 32 | function peek(list) { 33 | if (list._idlePrev == list) return null; 34 | return list._idlePrev; 35 | } 36 | exports.peek = peek; 37 | 38 | // remove the most idle item from the list 39 | function shift(list) { 40 | var first = list._idlePrev; 41 | remove(first); 42 | return first; 43 | } 44 | exports.shift = shift; 45 | 46 | // remove a item from its list 47 | function remove(item) { 48 | if (item._idleNext) { 49 | item._idleNext._idlePrev = item._idlePrev; 50 | } 51 | 52 | if (item._idlePrev) { 53 | item._idlePrev._idleNext = item._idleNext; 54 | } 55 | 56 | item._idleNext = null; 57 | item._idlePrev = null; 58 | } 59 | exports.remove = remove; 60 | 61 | // remove a item from its list and place at the end. 62 | function append(list, item) { 63 | remove(item); 64 | item._idleNext = list._idleNext; 65 | list._idleNext._idlePrev = item; 66 | item._idlePrev = list; 67 | list._idleNext = item; 68 | } 69 | exports.append = append; 70 | 71 | function isEmpty(list) { 72 | return list._idleNext === list; 73 | } 74 | exports.isEmpty = isEmpty; 75 | }); -------------------------------------------------------------------------------- /submissions/Avraham Essoudry/Scripts/generic_linklist.js: -------------------------------------------------------------------------------- 1 | // Copyright Essoudry Avraham 2 | 3 | define(function(require, exports, module) { 4 | 'use strict'; 5 | 6 | function init(list) { 7 | list._itemsNext = list; 8 | list._itemsPrev = list; 9 | } 10 | exports.init = init; 11 | 12 | // show the most idle item 13 | function peek(list) { 14 | return list._itemsPrev === list ? null : list._itemsPrev; 15 | } 16 | exports.peek = peek; 17 | 18 | // remove the most idle item from the list 19 | function shift(list) { 20 | return remove(list._itemsPrev); 21 | } 22 | exports.shift = shift; 23 | 24 | // remove a item from its list 25 | function remove(item) { 26 | if (item._idleNext) { 27 | if(item._idleNext._idlePrev === item) { 28 | item._idleNext._idlePrev = item._idlePrev; 29 | } 30 | else { 31 | item._idleNext._itemsPrev = item._idlePrev; 32 | } 33 | } 34 | 35 | if (item._idlePrev) { 36 | if(item._idlePrev._idleNext === item) { 37 | item._idlePrev._idleNext = item._idleNext; 38 | } 39 | else { 40 | item._idlePrev._itemsNext = item._idleNext; 41 | } 42 | } 43 | 44 | item._idleNext = null; 45 | item._idlePrev = null; 46 | return item; 47 | } 48 | exports.remove = remove; 49 | 50 | // remove a item from its list and place at the end. 51 | function append(list, item) { 52 | remove(item); 53 | item._idleNext = list._itemsNext; 54 | if(list._itemsNext === list) { 55 | list._itemsPrev = item; 56 | } 57 | else { 58 | list._itemsNext._idlePrev = item; 59 | } 60 | item._idlePrev = list; 61 | list._itemsNext = item; 62 | } 63 | exports.append = append; 64 | 65 | function isEmpty(list) { 66 | return list._itemsNext === list; 67 | } 68 | exports.isEmpty = isEmpty; 69 | }); -------------------------------------------------------------------------------- /submissions/Avraham Essoudry/Scripts/tester.js: -------------------------------------------------------------------------------- 1 | // Copyright Essoudry Avraham 2 | 3 | define(function(require, exports, module) { 4 | 'use strict'; 5 | function testRegular(Ilinklist) { 6 | var iterations = 1000000; 7 | 8 | var objects = []; 9 | for(var i=0; i 0) { 41 | var first = result.results[0]; 42 | for (var i = 1; i < result.results.length; i++) { 43 | var r = result.results[i]; 44 | r.percent = ~~((r.t - first.t)*1000)/100; 45 | } 46 | } 47 | 48 | result.end = "success"; 49 | result.name = name; 50 | if (end) 51 | end(result); 52 | }); 53 | 54 | } 55 | exports.bench = bench; 56 | 57 | function recursive(i, len, f, finish) { 58 | if (i != len) { 59 | f(i, function () {recursive(i+1, len, f, finish)}); 60 | } else { 61 | finish(); 62 | } 63 | } 64 | 65 | function log(msg) { 66 | console.log(msg) 67 | } -------------------------------------------------------------------------------- /submissions/Dmitry Karaush and Ruslan Koptev/benches/indexBench.js: -------------------------------------------------------------------------------- 1 | 2 | var L = require(process.argv[2]); 3 | 4 | var list = {name: "list"}; 5 | L.init(list); 6 | 7 | var COUNT = process.argv[3]; 8 | var INDEX = process.argv[4]; 9 | 10 | var startTime = new Date().getTime(); 11 | 12 | //append COUNT nodes to list 13 | for (var i = 0; i < COUNT; i++) 14 | L.append(list, {num: i}); 15 | 16 | //get INDEX node from list 17 | var n = list._idlePrev; 18 | for (var i = 0; i < INDEX; i++) 19 | n = n._idlePrev; 20 | 21 | var endTime = new Date().getTime(); 22 | console.log( ( (endTime-startTime)/1000) ); -------------------------------------------------------------------------------- /submissions/Dmitry Karaush and Ruslan Koptev/benches/manyListsBench.js: -------------------------------------------------------------------------------- 1 | var L = require(process.argv[2]); 2 | 3 | var lists = []; 4 | var nodes = []; 5 | 6 | var LISTS_COUNT = process.argv[3]; 7 | var NODES_COUNT = process.argv[4]; 8 | 9 | for (var i = 0; i < LISTS_COUNT; i++) { 10 | lists[i] = {listNum: i}; 11 | lists[i].id = L.init(lists[i]); 12 | } 13 | 14 | for (var i = 0; i < NODES_COUNT; i++) { 15 | nodes[i] = {nodeNum: i}; 16 | } 17 | 18 | var startTime = new Date().getTime(); 19 | 20 | //append 21 | for (var i = 0; i < LISTS_COUNT; i++) { 22 | for (var j = 0; j < NODES_COUNT; j++) { 23 | L.append(lists[i], nodes[j], lists[i].id); 24 | } 25 | } 26 | 27 | //peek 28 | for (var i = 0; i < LISTS_COUNT; i++) { 29 | L.peek(lists[i], lists[i].id); 30 | } 31 | 32 | //shift 33 | for (var i = 0; i < LISTS_COUNT; i++) { 34 | L.shift(lists[i], lists[i].id); 35 | } 36 | //append 37 | for (var i = 0; i < LISTS_COUNT; i++) { 38 | for (var j = 0; j < NODES_COUNT; j++) { 39 | L.append(lists[i], nodes[j], lists[i].id); 40 | } 41 | } 42 | 43 | //remove 44 | for (var i = 0; i < LISTS_COUNT; i++) { 45 | for (var j = 0; j < NODES_COUNT; j++) { 46 | L.remove(nodes[j], lists[i].id); 47 | } 48 | } 49 | 50 | var endTime = new Date().getTime(); 51 | 52 | console.log( ( (endTime-startTime)/1000) ); -------------------------------------------------------------------------------- /submissions/Dmitry Karaush and Ruslan Koptev/benches/sawBench.js: -------------------------------------------------------------------------------- 1 | 2 | var L = require(process.argv[2]); 3 | var list = { name: 'list' }; 4 | L.init(list); 5 | 6 | var COUNT = process.argv[3]; 7 | 8 | var nodes = []; 9 | 10 | for (var i = 0; i < COUNT; i++) { 11 | nodes[i] = { number: i }; 12 | }; 13 | 14 | var sawStep = Math.round(COUNT/100); 15 | 16 | var i = 0, k = 0; 17 | 18 | var startTime = new Date().getTime(); 19 | 20 | while(i < COUNT) { 21 | k = 0; 22 | while (k < sawStep) { 23 | L.append(list, nodes[i]); 24 | k++; 25 | i++; 26 | }; 27 | k = 0; 28 | i-=sawStep; 29 | while (k < sawStep) { 30 | L.remove(nodes[i]); 31 | k+=2; 32 | i+=2; 33 | }; 34 | } 35 | 36 | var endTime = new Date().getTime(); 37 | console.log(((endTime-startTime)/1000)) -------------------------------------------------------------------------------- /submissions/Dmitry Karaush and Ruslan Koptev/benches/simpleBench.js: -------------------------------------------------------------------------------- 1 | 2 | var L = require(process.argv[2]); 3 | var list = { name: 'list' }; 4 | L.init(list); 5 | 6 | var COUNT = process.argv[3]; 7 | 8 | var nodes = []; 9 | for (var i = 0; i < COUNT; i++) { 10 | nodes[i] = { number: i }; 11 | } 12 | 13 | var startTime = new Date().getTime(); 14 | 15 | for (var i = 0; i < COUNT; i++) { 16 | L.append(list, nodes[i]); 17 | } 18 | // Peek all items from list 19 | for (var i = 0; i < COUNT; i++) { 20 | L.peek(list); 21 | }; 22 | 23 | // Shift all items from list 24 | for (var i = 0; i < COUNT; i++) { 25 | L.shift(list); 26 | }; 27 | 28 | // Append nodes to list 29 | for (var i = 0; i < COUNT; i++) { 30 | L.append(list, nodes[i]); 31 | } 32 | 33 | // Remove items from list 34 | for (var i = 0; i < COUNT; i++) { 35 | L.remove(nodes[i]); 36 | } 37 | 38 | var endTime = new Date().getTime(); 39 | console.log(((endTime - startTime)/1000)) -------------------------------------------------------------------------------- /submissions/Dmitry Karaush and Ruslan Koptev/ll.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var gId = 0; 3 | 4 | function init(list) { 5 | //Simple version 6 | list._idleNext = list; 7 | list._idlePrev = list; 8 | //With multiple parent lists 9 | list._links = []; 10 | list._links[gId] = {prev: list, next: list}; 11 | return gId++; 12 | } 13 | exports.init = init; 14 | 15 | 16 | // show the most idle item 17 | function peek(list,id) { 18 | // If list has multiple parents 19 | if(id) { 20 | var prev = list._links[id].prev; 21 | if (prev == list) 22 | return null; 23 | return prev; 24 | } 25 | 26 | // Simple version 27 | var prev = list._idlePrev; 28 | if (prev == list) 29 | return null; 30 | return prev; 31 | } 32 | exports.peek = peek; 33 | 34 | 35 | // remove the most idle item from the list 36 | function shift(list,id) { 37 | if (id) { 38 | var first = list._links[id].prev; 39 | remove(first, id); 40 | } else { 41 | var first = list._idlePrev; 42 | remove(first); 43 | } 44 | return first; 45 | } 46 | exports.shift = shift; 47 | 48 | 49 | // remove a item from its list 50 | function remove(item,id) { 51 | if (id) { 52 | var cItem = item._links[id]; 53 | if (cItem) { 54 | var cItemNext = cItem.next; 55 | var cItemPrev = cItem.prev; 56 | if (cItemNext) { 57 | cItemNext._links[id].prev = cItemPrev; 58 | } 59 | 60 | if (cItemPrev) { 61 | cItemPrev._links[id].next = cItemNext; 62 | } 63 | 64 | cItem.next = null; 65 | cItem.prev = null; 66 | }; 67 | } else { 68 | if (item._idleNext) { 69 | item._idleNext._idlePrev = item._idlePrev; 70 | } 71 | 72 | if (item._idlePrev) { 73 | item._idlePrev._idleNext = item._idleNext; 74 | } 75 | 76 | item._idleNext = null; 77 | item._idlePrev = null; 78 | } 79 | } 80 | exports.remove = remove; 81 | 82 | 83 | // remove a item from its list and place at the end. 84 | function append(list, item, id) { 85 | if (id) { 86 | if(item._links) { 87 | remove(item,id); //destroy links in this list 88 | } else { 89 | item._links = []; 90 | } 91 | var cItem = item._links[id] = []; 92 | var cList = list._links[id]; 93 | var cListNext = cList.next; 94 | cItem.next = cListNext; 95 | cListNext._links[id].prev = item; 96 | cItem.prev = list; 97 | cList.next = item; 98 | } else { 99 | if(item._idleNext) { 100 | remove(item); 101 | } 102 | var cListNext = list._idleNext; 103 | item._idleNext = cListNext; 104 | cListNext._idlePrev = item; 105 | item._idlePrev = list; 106 | list._idleNext = item; 107 | } 108 | } 109 | exports.append = append; 110 | 111 | 112 | function isEmpty(list,id) { 113 | if(id) 114 | return list._links[id].next === list; 115 | 116 | return list._idleNext === list; 117 | } 118 | exports.isEmpty = isEmpty; -------------------------------------------------------------------------------- /submissions/Dmitry Karaush and Ruslan Koptev/lldef.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function init(list) { 4 | list._idleNext = list; 5 | list._idlePrev = list; 6 | } 7 | exports.init = init; 8 | 9 | 10 | // show the most idle item 11 | function peek(list) { 12 | if (list._idlePrev == list) return null; 13 | return list._idlePrev; 14 | } 15 | exports.peek = peek; 16 | 17 | 18 | // remove the most idle item from the list 19 | function shift(list) { 20 | var first = list._idlePrev; 21 | remove(first); 22 | return first; 23 | } 24 | exports.shift = shift; 25 | 26 | 27 | // remove a item from its list 28 | function remove(item) { 29 | if (item._idleNext) { 30 | item._idleNext._idlePrev = item._idlePrev; 31 | } 32 | 33 | if (item._idlePrev) { 34 | item._idlePrev._idleNext = item._idleNext; 35 | } 36 | 37 | item._idleNext = null; 38 | item._idlePrev = null; 39 | } 40 | exports.remove = remove; 41 | 42 | 43 | // remove a item from its list and place at the end. 44 | function append(list, item) { 45 | remove(item); 46 | item._idleNext = list._idleNext; 47 | list._idleNext._idlePrev = item; 48 | item._idlePrev = list; 49 | list._idleNext = item; 50 | } 51 | exports.append = append; 52 | 53 | 54 | function isEmpty(list) { 55 | return list._idleNext === list; 56 | } 57 | exports.isEmpty = isEmpty; -------------------------------------------------------------------------------- /submissions/Dmitry Karaush and Ruslan Koptev/ourbench.js: -------------------------------------------------------------------------------- 1 | /* 2 | Running benches: 3 | saw-bench (benches/sawBench.js) 4 | index-bench (benches/indexBench.js) 5 | simple-bench (benches/simpleBench.js) 6 | nodes-in-lists (benches/manyListsBench.js) 7 | */ 8 | 9 | var engine = require("./benchengine.js"); 10 | 11 | var sources = [ "./../lldef.js", "./../ll.js"]; 12 | var names = ["Std (default)", "Our impl"]; 13 | var tests = [ 14 | function (f) { 15 | //100 append, 50 remove, 100 append... 16 | engine.bench( 17 | "saw-bench", // name of bench 18 | "benches/sawBench.js", // bench file 19 | sources, // implementations 20 | [10000000], // count of nodes 21 | true, // debug off 22 | f // callback 23 | ); 24 | }, 25 | //get value by index in list 26 | function (f) { 27 | engine.bench( 28 | "index-bench", 29 | "benches/indexBench.js", 30 | sources, 31 | [10000000, 9999999], // 1 - count of nodes, 2 - index 32 | true, 33 | f 34 | ); 35 | }, 36 | // append, shift, remove and so on. 37 | function (f) { 38 | engine.bench( 39 | "simple-bench", 40 | "benches/simpleBench.js", 41 | sources, 42 | [10000000], // count of nodes 43 | true, 44 | f 45 | ); 46 | }, 47 | //like simpleBench, but with many parent lists 48 | function (f) { 49 | engine.bench( 50 | "nodes-in-lists", 51 | "benches/manyListsBench.js", 52 | ["./../ll.js"], 53 | [1000, 5000], // 1 - count of lists, 2 - count of nodes 54 | true, 55 | f 56 | ); 57 | } 58 | ]; 59 | 60 | //-----Function for start benches------- 61 | 62 | var bench_results = []; 63 | function recursiveBench(arr, i, finish) { 64 | if (i != arr.length) { 65 | arr[i](function (result) { 66 | bench_results.push(result); 67 | recursiveBench(arr, i+1, finish); 68 | }); 69 | } else { 70 | finish(bench_results); 71 | } 72 | }; 73 | //------Functions for draw table--------- 74 | function addSpaces(str, len) { 75 | var spaces = len - str.length; 76 | while (spaces) { 77 | str = str + " "; 78 | spaces--; 79 | } 80 | return str; 81 | } 82 | 83 | function newColumn(arr, arrlen) { 84 | var column = ""; 85 | for (var i = 0; i < arr.length; i++) { 86 | if (arr[i]) 87 | column += addSpaces(arr[i]+"", arrlen[i]); 88 | column += " "; 89 | } 90 | return column; 91 | } 92 | 93 | //-----Start------ 94 | var lens = [13,15,15,15]; 95 | recursiveBench(tests, 0, function (results) { 96 | 97 | //header 98 | console.log("\n"+newColumn([ 99 | "Name of Impl", 100 | results[0].name, 101 | results[1].name, 102 | results[2].name, 103 | results[3].name 104 | ], lens)); 105 | 106 | for (var i = 0; i < names.length; i++) { 107 | var name = names[i]; 108 | var source = sources[i]; 109 | if (source.file) 110 | source = source.file; 111 | var res = []; 112 | for (var j = 0; j < results.length; j++) { 113 | var r = searchResultByFile(results[j], source); 114 | if (r == null) { 115 | res[res.length] = "---"; 116 | continue; 117 | } 118 | 119 | var r_str = r.t+"s"; 120 | res[res.length] = r_str; 121 | } 122 | 123 | console.log(newColumn([ 124 | name, 125 | res[0], 126 | res[1], 127 | res[2], 128 | res[3] 129 | ], lens)) 130 | } 131 | }); 132 | 133 | function searchResultByFile(bench, file) { 134 | for (var i = 0; i < bench.results.length; i++) { 135 | if (bench.results[i].file == file) 136 | return bench.results[i]; 137 | } 138 | return null; 139 | } -------------------------------------------------------------------------------- /submissions/Dmitry Karaush and Ruslan Koptev/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ll-just", 3 | "version": "1.0.0", 4 | "description": "Linkedlist implementation for holajs challenge", 5 | "main": "ll.js", 6 | "scripts": { 7 | "startbench": "node bench.js" 8 | }, 9 | "author": "Just", 10 | "license": "ISC", 11 | "dependencies": { 12 | "benchmark": "~1.x" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /submissions/Faur George/Test.htm: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Javascript Generic List Implementation 5 | 6 | 7 | 8 | 51 | 52 | 53 | 54 |

55 | 56 | 57 | -------------------------------------------------------------------------------- /submissions/Ilya Sonin/linkedList.js: -------------------------------------------------------------------------------- 1 | 2 | function init(list) { 3 | list._idleNext = list; 4 | list._idlePrev = list; 5 | list._next = null; //this is a new field that holds an item whose _idleNext is the same as the _idleNext of this list 6 | } 7 | exports.init = init; 8 | 9 | // show the most idle item 10 | function peek(list) { 11 | if (list._idlePrev == list) return null; 12 | return list._idlePrev; 13 | } 14 | exports.peek = peek; 15 | 16 | // remove the most idle item from the list 17 | function shift(list) { 18 | if(list._idlePrev == list) 19 | return null; 20 | var first = lastNext(list._idlePrev); 21 | remove(first); 22 | return first; 23 | } 24 | exports.shift = shift; 25 | 26 | // returns the last item in the next list 27 | function lastNext(list){ 28 | if(list._next==null) 29 | return list; 30 | if(list._next._next==null){ 31 | var ret = list._next._next; 32 | list._next = null; 33 | return ret; 34 | } 35 | return lastNext(list._next); 36 | } 37 | 38 | // remove a item from its list 39 | function remove(item) { 40 | if (item._idleNext) { 41 | item._idleNext._idlePrev = item._idlePrev; 42 | } 43 | if (item._idlePrev) { 44 | item._idlePrev._idleNext = item._idleNext; 45 | } 46 | item._idleNext = null; 47 | item._idlePrev = null; 48 | } 49 | exports.remove = remove; 50 | 51 | // remove a item from its list and place at the end. 52 | function append(list, item) { 53 | remove(item); 54 | item._idleNext = list._idleNext; 55 | list._idleNext._idlePrev = item; 56 | item._idlePrev = list; 57 | list._idleNext = item; 58 | } 59 | exports.append = append; 60 | 61 | //binds an item to the next of the list but not appending the list to the item 62 | function bind(list, item) { 63 | if(item._idlePrev != item._idlePrev) 64 | list._next = item._idlePrev; 65 | item._idlePrev = list; 66 | list._idleNext._idlePrev = list._idleNext._idlePrev._next; 67 | list._idleNext = item; 68 | } 69 | 70 | function isEmpty(list) { 71 | return list._idleNext === list; 72 | } 73 | exports.isEmpty = isEmpty; 74 | -------------------------------------------------------------------------------- /submissions/Ivan Babak/README.md: -------------------------------------------------------------------------------- 1 | The [node timers linklist](https://github.com/joyent/node/blob/master/lib/_linklist.js), reimplemented for the challenge: http://hola.org/challenge_js?l 2 | 3 | Goal: generalize and allow list parent to hold two or more different lists in the parent list object. 4 | 5 | Run the tests and the benchmark: 6 | ```bash 7 | node comparison.js 8 | ``` 9 | The tests verify the original API consistency and the multi-list implementation of the reworked version. 10 | The benchmark compares performance of the original and the reworked versions in the basic scenarios. 11 | 12 | Use as a module: 13 | ```javascript 14 | var L = require('./lib/linklist.js'); 15 | ``` 16 | 17 | See the comments in the `lib/linklist.js` for the implementation details. 18 | -------------------------------------------------------------------------------- /submissions/Ivan Babak/comparison.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var implementations = { 4 | "original": require('./lib/_linklist'), 5 | "sompylasar's": require('./lib/linklist') 6 | }; 7 | 8 | Object.keys(implementations).forEach(function (key) { 9 | console.log(key + ' > running original tests...'); 10 | 11 | require('./test/test')(implementations[key]); 12 | 13 | console.log(key + ' > original tests passed.'); 14 | 15 | if (key !== "original") { 16 | console.log(key + ' > running extended tests...'); 17 | 18 | require('./test/test-extended')(implementations[key]); 19 | 20 | console.log(key + ' > extended tests passed.'); 21 | } 22 | 23 | console.log(''); 24 | }); 25 | 26 | 27 | console.log('benchmarking...\n'); 28 | require('./test/bench')(implementations, function () { 29 | console.log('benchmark done.'); 30 | }); 31 | -------------------------------------------------------------------------------- /submissions/Ivan Babak/lib/_linklist.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 'use strict'; 23 | 24 | function init(list) { 25 | list._idleNext = list; 26 | list._idlePrev = list; 27 | } 28 | exports.init = init; 29 | 30 | 31 | // show the most idle item 32 | function peek(list) { 33 | if (list._idlePrev == list) return null; 34 | return list._idlePrev; 35 | } 36 | exports.peek = peek; 37 | 38 | 39 | // remove the most idle item from the list 40 | function shift(list) { 41 | var first = list._idlePrev; 42 | remove(first); 43 | return first; 44 | } 45 | exports.shift = shift; 46 | 47 | 48 | // remove a item from its list 49 | function remove(item) { 50 | if (item._idleNext) { 51 | item._idleNext._idlePrev = item._idlePrev; 52 | } 53 | 54 | if (item._idlePrev) { 55 | item._idlePrev._idleNext = item._idleNext; 56 | } 57 | 58 | item._idleNext = null; 59 | item._idlePrev = null; 60 | } 61 | exports.remove = remove; 62 | 63 | 64 | // remove a item from its list and place at the end. 65 | function append(list, item) { 66 | remove(item); 67 | item._idleNext = list._idleNext; 68 | list._idleNext._idlePrev = item; 69 | item._idlePrev = list; 70 | list._idleNext = item; 71 | } 72 | exports.append = append; 73 | 74 | 75 | function isEmpty(list) { 76 | return list._idleNext === list; 77 | } 78 | exports.isEmpty = isEmpty; 79 | -------------------------------------------------------------------------------- /submissions/Ivan Babak/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "node-linklist", 4 | "version": "0.0.1", 5 | "description": "http://hola.org/challenge_js?l", 6 | "main": "lib/linklist.js", 7 | "scripts": { 8 | "start": "node comparison.js" 9 | }, 10 | "author": "sompylasar ", 11 | "license": "MIT", 12 | "dependencies": { 13 | "benchmark": "^1.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /submissions/Ivan Babak/test/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Tests taken from https://github.com/joyent/node/blob/857975d5e7e0d7bf38577db0478d9e5ede79922e/test/simple/test-timers-linked-list.js 4 | 5 | var assert = require('assert'); 6 | 7 | module.exports = function (L) { 8 | 9 | var list = { name: 'list' }; 10 | var A = { name: 'A' }; 11 | var B = { name: 'B' }; 12 | var C = { name: 'C' }; 13 | var D = { name: 'D' }; 14 | 15 | 16 | L.init(list); 17 | L.init(A); 18 | L.init(B); 19 | L.init(C); 20 | L.init(D); 21 | 22 | assert.ok(L.isEmpty(list)); 23 | assert.equal(null, L.peek(list)); 24 | 25 | L.append(list, A); 26 | // list -> A 27 | assert.equal(A, L.peek(list)); 28 | 29 | L.append(list, B); 30 | // list -> A -> B 31 | assert.equal(A, L.peek(list)); 32 | 33 | L.append(list, C); 34 | // list -> A -> B -> C 35 | assert.equal(A, L.peek(list)); 36 | 37 | L.append(list, D); 38 | // list -> A -> B -> C -> D 39 | assert.equal(A, L.peek(list)); 40 | 41 | var x = L.shift(list); 42 | assert.equal(A, x); 43 | // list -> B -> C -> D 44 | assert.equal(B, L.peek(list)); 45 | 46 | x = L.shift(list); 47 | assert.equal(B, x); 48 | // list -> C -> D 49 | assert.equal(C, L.peek(list)); 50 | 51 | // B is already removed, so removing it again shouldn't hurt. 52 | L.remove(B); 53 | // list -> C -> D 54 | assert.equal(C, L.peek(list)); 55 | 56 | // Put B back on the list 57 | L.append(list, B); 58 | // list -> C -> D -> B 59 | assert.equal(C, L.peek(list)); 60 | 61 | L.remove(C); 62 | // list -> D -> B 63 | assert.equal(D, L.peek(list)); 64 | 65 | L.remove(B); 66 | // list -> D 67 | assert.equal(D, L.peek(list)); 68 | 69 | L.remove(D); 70 | // list 71 | assert.equal(null, L.peek(list)); 72 | 73 | 74 | assert.ok(L.isEmpty(list)); 75 | 76 | 77 | L.append(list, D); 78 | // list -> D 79 | assert.equal(D, L.peek(list)); 80 | 81 | L.append(list, C); 82 | L.append(list, B); 83 | L.append(list, A); 84 | // list -> D -> C -> B -> A 85 | 86 | // Append should REMOVE C from the list and append it to the end. 87 | L.append(list, C); 88 | 89 | // list -> D -> B -> A -> C 90 | assert.equal(D, L.shift(list)); 91 | // list -> B -> A -> C 92 | assert.equal(B, L.peek(list)); 93 | assert.equal(B, L.shift(list)); 94 | // list -> A -> C 95 | assert.equal(A, L.peek(list)); 96 | assert.equal(A, L.shift(list)); 97 | // list -> C 98 | assert.equal(C, L.peek(list)); 99 | assert.equal(C, L.shift(list)); 100 | // list 101 | assert.ok(L.isEmpty(list)); 102 | 103 | }; 104 | -------------------------------------------------------------------------------- /submissions/Kobi/linklist.js: -------------------------------------------------------------------------------- 1 | /* 2 | Author: kobi( kobi@napuzba.com ) 3 | 4 | This is generic implementation of linked list. 5 | It try to follow _linklist module semantics but not its api :-). 6 | */ 7 | 8 | 'use strict'; 9 | 10 | // Item in the list 11 | function Item(value) { 12 | this.value = value ; 13 | this.prev = null ; 14 | this.next = null ; 15 | 16 | this.remove = function() { 17 | if ( this.prev != null ) { 18 | this.prev.next = this.next; 19 | } 20 | if ( this.next != null ) { 21 | this.next.prev = this.prev; 22 | } 23 | this.next = this.prev = null; 24 | return this; 25 | } 26 | 27 | this.addBefore = function(root) { 28 | this.prev = root.prev; 29 | this.next = root; 30 | root.prev.next = this; 31 | root.prev = this; 32 | return this; 33 | } 34 | } 35 | 36 | // The link list 37 | function List() { 38 | this.root = new Item(null); 39 | this.root.prev = this.root; 40 | this.root.next = this.root; 41 | 42 | // Whether the list is empty 43 | this.isEmpty = function() { 44 | return this.root.next == this.root; 45 | } 46 | 47 | // return the first value in the list, or null if the list is empty. 48 | this.peek = function() { 49 | return this.root.next.value; 50 | } 51 | 52 | // append value to the list. return an handle to the value. 53 | // The handle can be used to: 54 | // - using remove() - fast removal of the item from its current list 55 | // - using moveEnd() - move the value from its current list and append it to the current list 56 | this.append = function(value) { 57 | return (new Item(value)).addBefore(this.root); 58 | } 59 | 60 | // Remove the first value from the list and return it. if empty - return null 61 | this.shift = function() { 62 | var item = this.root.next; 63 | if ( item == this.root ) { 64 | return null; 65 | } 66 | return item.remove().value; 67 | } 68 | 69 | this.remove = function(item) { 70 | item.remove().value; 71 | } 72 | 73 | // Remove the item from its list and append it the current list 74 | this.moveEnd = function(item) { 75 | item.remove().addBefore(this.root); 76 | } 77 | 78 | // return string representation of the list 79 | this.dump = function() { 80 | var ss = ''; 81 | var item = this.root.next; 82 | while ( item != this.root ) { 83 | if (ss != '') { 84 | ss += ' -> '; 85 | } 86 | ss += item.value; 87 | item = item.next; 88 | } 89 | return ss; 90 | } 91 | } 92 | 93 | exports.List = List; -------------------------------------------------------------------------------- /submissions/Mark Ablovacky/original.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 'use strict'; 23 | 24 | function init(list) { 25 | list._idleNext = list; 26 | list._idlePrev = list; 27 | } 28 | exports.init = init; 29 | 30 | 31 | // show the most idle item 32 | function peek(list) { 33 | if (list._idlePrev == list) return null; 34 | return list._idlePrev; 35 | } 36 | exports.peek = peek; 37 | 38 | 39 | // remove the most idle item from the list 40 | function shift(list) { 41 | var first = list._idlePrev; 42 | remove(first); 43 | return first; 44 | } 45 | exports.shift = shift; 46 | 47 | 48 | // remove a item from its list 49 | function remove(item) { 50 | if (item._idleNext) { 51 | item._idleNext._idlePrev = item._idlePrev; 52 | } 53 | 54 | if (item._idlePrev) { 55 | item._idlePrev._idleNext = item._idleNext; 56 | } 57 | 58 | item._idleNext = null; 59 | item._idlePrev = null; 60 | } 61 | exports.remove = remove; 62 | 63 | 64 | // remove a item from its list and place at the end. 65 | function append(list, item) { 66 | remove(item); 67 | item._idleNext = list._idleNext; 68 | list._idleNext._idlePrev = item; 69 | item._idlePrev = list; 70 | list._idleNext = item; 71 | } 72 | exports.append = append; 73 | 74 | 75 | function isEmpty(list) { 76 | return list._idleNext === list; 77 | } 78 | exports.isEmpty = isEmpty; 79 | -------------------------------------------------------------------------------- /submissions/Mateusz Krzeszowiak/benchmark/fifo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This benchmark shows BlinkedList capabilities to mimic FIFO(queue) behaviour. 3 | * 4 | * 1. Fill container with elements. 5 | * 2. Shift half of the elements. 6 | * 3. Fill container back. 7 | */ 8 | 9 | /** 10 | * Lets require dependencies. Some of them have to be assigned to global namespace because of the way 11 | * benchmark.js works. 12 | */ 13 | var Benchmark = require('benchmark'); 14 | global.LinkList = require('_linklist'); 15 | global.BlinkedList = require('../BlinkedList.js'); 16 | global.Utils = require('./utils.js'); 17 | 18 | var fifoSuite = new Benchmark.Suite() 19 | 20 | .add('LinkList FIFO using append() and shift()', { 21 | 'setup': function () { 22 | var list = {}; 23 | LinkList.init(list); 24 | Utils.fillLinkList(list, Utils.testLength); 25 | }, 26 | 'fn': function () { 27 | Utils.shiftLinkList(list, Math.floor(Utils.testLength / 2)); 28 | Utils.fillLinkList(list, Math.floor(Utils.testLength / 2)); 29 | } 30 | }) 31 | 32 | .add('Array FIFO using push() and shift()', { 33 | 'setup': function () { 34 | var array = []; 35 | Utils.fillArray(array, Utils.testLength); 36 | }, 37 | 'fn': function () { 38 | Utils.shiftArray(array, Math.floor(Utils.testLength / 2)); 39 | Utils.fillArray(array, Math.floor(Utils.testLength / 2)); 40 | } 41 | }) 42 | 43 | .add('BlinkedList FIFO push() and shift()', { 44 | 'setup': function () { 45 | var list = new BlinkedList(Utils.testLength); 46 | Utils.fillArray(list, Utils.testLength); 47 | }, 48 | 'fn': function () { 49 | Utils.shiftArray(list, Math.floor(Utils.testLength / 2)); 50 | Utils.fillArray(list, Math.floor(Utils.testLength / 2)); 51 | } 52 | }) 53 | 54 | .on('cycle', function(event) { 55 | console.log(String(event.target)); 56 | }) 57 | .on('complete', function() { 58 | console.log('Fastest is ' + this.filter('fastest').pluck('name')); 59 | console.log(); 60 | }); 61 | 62 | console.log("Container as FIFO benchmark."); 63 | Utils.testLength = 100; 64 | console.log("Benchmarking for " + Utils.testLength + " elements."); 65 | fifoSuite.run(); 66 | 67 | Utils.testLength = 1000; 68 | console.log("Benchmarking for " + Utils.testLength + " elements."); 69 | fifoSuite.run(); 70 | 71 | Utils.testLength = 10000; 72 | console.log("Benchmarking for " + Utils.testLength + " elements."); 73 | fifoSuite.run(); 74 | 75 | 76 | -------------------------------------------------------------------------------- /submissions/Mateusz Krzeszowiak/benchmark/fifo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hola/challenge_linked_list/db931205f5e83c343abd0b8d876d3d5620a6e5d6/submissions/Mateusz Krzeszowiak/benchmark/fifo.png -------------------------------------------------------------------------------- /submissions/Mateusz Krzeszowiak/benchmark/filling.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This benchmark tests filling containers with 100, 10000 and 1000000 elements. 3 | */ 4 | 5 | /** 6 | * Lets require dependencies. Some of them have to be assigned to global namespace because of the way 7 | * benchmark.js works. 8 | */ 9 | var Benchmark = require('benchmark'); 10 | global.LinkList = require('_linklist'); 11 | global.BlinkedList = require('../BlinkedList.js'); 12 | global.Utils = require('./utils.js'); 13 | 14 | var fillingSuite = new Benchmark.Suite() 15 | .add('LinkList filling with push()', { 16 | 'setup': function () { 17 | var list = {}; 18 | }, 19 | 'fn': function () { 20 | list = {}; 21 | LinkList.init(list); 22 | Utils.fillLinkList(list, Utils.testLength); 23 | } 24 | }) 25 | 26 | .add('Array filling with push()', { 27 | 'setup': function () { 28 | var array; 29 | }, 30 | 'fn': function () { 31 | array = []; 32 | Utils.fillArray(array, Utils.testLength); 33 | } 34 | }) 35 | 36 | .add('Array filling with []', { 37 | 'setup': function () { 38 | var array; 39 | }, 40 | 'fn': function () { 41 | array = []; 42 | Utils.fillArraySet(array, Utils.testLength); 43 | } 44 | }) 45 | 46 | .add('BlinkedList filling with push()', { 47 | 'setup': function () { 48 | var list; 49 | }, 50 | 'fn': function () { 51 | list = new BlinkedList(Utils.testLength); 52 | Utils.fillArray(list, Utils.testLength); 53 | } 54 | }) 55 | 56 | .on('cycle', function(event) { 57 | console.log(String(event.target)); 58 | }) 59 | .on('complete', function() { 60 | console.log('Fastest is ' + this.filter('fastest').pluck('name')); 61 | console.log(); 62 | }); 63 | 64 | console.log("Container filling benchmark."); 65 | Utils.testLength = 100; 66 | console.log("Benchmarking for " + Utils.testLength + " elements."); 67 | fillingSuite.run(); 68 | 69 | Utils.testLength = 10000; 70 | console.log("Benchmarking for " + Utils.testLength + " elements."); 71 | fillingSuite.run(); 72 | 73 | Utils.testLength = 1000000; 74 | console.log("Benchmarking for " + Utils.testLength + " elements."); 75 | fillingSuite.run(); -------------------------------------------------------------------------------- /submissions/Mateusz Krzeszowiak/benchmark/filling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hola/challenge_linked_list/db931205f5e83c343abd0b8d876d3d5620a6e5d6/submissions/Mateusz Krzeszowiak/benchmark/filling.png -------------------------------------------------------------------------------- /submissions/Mateusz Krzeszowiak/benchmark/iterating.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This benchmark tests iterating containers with 100, 10000 and 1000000 elements. 3 | */ 4 | 5 | /** 6 | * Lets require dependencies. Some of them have to be assigned to global namespace because of the way 7 | * benchmark.js works. 8 | */ 9 | var Benchmark = require('benchmark'); 10 | global.LinkList = require('_linklist'); 11 | global.BlinkedList = require('../BlinkedList.js'); 12 | global.Utils = require('./utils.js'); 13 | 14 | var iteratingSuite = new Benchmark.Suite() 15 | .add('LinkList iteration', { 16 | 'setup': function () { 17 | var list = {}; 18 | LinkList.init(list); 19 | Utils.fillLinkList(list, Utils.testLength); 20 | }, 21 | 'fn': function () { 22 | Utils.iterateNodeList(list); 23 | } 24 | }) 25 | 26 | .add('Array iteration', { 27 | 'setup': function () { 28 | var array = []; 29 | Utils.fillArray(array, Utils.testLength); 30 | }, 31 | 'fn': function () { 32 | Utils.iterateArray(array); 33 | } 34 | }) 35 | 36 | .add('BlinkedList iteration with next(), current()', { 37 | 'setup': function () { 38 | var array = new BlinkedList(Utils.testLength); 39 | Utils.fillArray(array, Utils.testLength); 40 | }, 41 | 'fn': function () { 42 | Utils.iterateBlinkedList(array); 43 | } 44 | }) 45 | 46 | .add('BlinkedList iteration with []', { 47 | 'setup': function () { 48 | var array = new BlinkedList(Utils.testLength); 49 | Utils.fillArray(array, Utils.testLength); 50 | }, 51 | 'fn': function () { 52 | Utils.iterateBlinkedArray(array); 53 | } 54 | }) 55 | 56 | .on('cycle', function(event) { 57 | console.log(String(event.target)); 58 | }) 59 | .on('complete', function() { 60 | console.log('Fastest is ' + this.filter('fastest').pluck('name')); 61 | console.log(); 62 | }); 63 | 64 | console.log("Container iterating."); 65 | Utils.testLength = 1000; 66 | console.log("Benchmarking for " + Utils.testLength + " elements."); 67 | iteratingSuite.run(); 68 | 69 | Utils.testLength = 10000; 70 | console.log("Benchmarking for " + Utils.testLength + " elements."); 71 | iteratingSuite.run(); 72 | 73 | Utils.testLength = 100000; 74 | console.log("Benchmarking for " + Utils.testLength + " elements."); 75 | iteratingSuite.run(); -------------------------------------------------------------------------------- /submissions/Mateusz Krzeszowiak/benchmark/iterating.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hola/challenge_linked_list/db931205f5e83c343abd0b8d876d3d5620a6e5d6/submissions/Mateusz Krzeszowiak/benchmark/iterating.png -------------------------------------------------------------------------------- /submissions/Mateusz Krzeszowiak/benchmark/lifo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This benchmark shows BlinkedList capabilities to mimic LIFO(stack) behaviour. 3 | * Node's LinkList doesn't implement required methods so it's not included in this test. 4 | * 5 | * 1. Fill container with elements. 6 | * 2. Pop half of the elements. 7 | * 3. Fill container back. 8 | */ 9 | 10 | /** 11 | * Lets require dependencies. Some of them have to be assigned to global namespace because of the way 12 | * benchmark.js works. 13 | */ 14 | var Benchmark = require('benchmark'); 15 | global.BlinkedList = require('../BlinkedList.js'); 16 | global.Utils = require('./utils.js'); 17 | 18 | var lifoSuite = new Benchmark.Suite() 19 | .add('Array LIFO using push() and pop()', { 20 | 'setup': function () { 21 | var array = []; 22 | Utils.fillArray(array, Utils.testLength); 23 | }, 24 | 'fn': function () { 25 | Utils.popArray(array, Math.floor(Utils.testLength / 2)); 26 | Utils.fillArray(array, Math.floor(Utils.testLength / 2)); 27 | } 28 | }) 29 | 30 | .add('BlinkedList LIFO push() and pop()', { 31 | 'setup': function () { 32 | var list = new BlinkedList(Utils.testLength); 33 | Utils.fillArray(list, Utils.testLength); 34 | }, 35 | 'fn': function () { 36 | Utils.popArray(list, Math.floor(Utils.testLength / 2)); 37 | Utils.fillArray(list, Math.floor(Utils.testLength / 2)); 38 | } 39 | }) 40 | 41 | .on('cycle', function(event) { 42 | console.log(String(event.target)); 43 | }) 44 | .on('complete', function() { 45 | console.log('Fastest is ' + this.filter('fastest').pluck('name')); 46 | console.log(); 47 | }); 48 | 49 | console.log("Container as LIFO benchmark."); 50 | Utils.testLength = 100; 51 | console.log("Benchmarking for " + Utils.testLength + " elements."); 52 | lifoSuite.run(); 53 | 54 | Utils.testLength = 1000; 55 | console.log("Benchmarking for " + Utils.testLength + " elements."); 56 | lifoSuite.run(); 57 | 58 | Utils.testLength = 10000; 59 | console.log("Benchmarking for " + Utils.testLength + " elements."); 60 | lifoSuite.run(); -------------------------------------------------------------------------------- /submissions/Mateusz Krzeszowiak/benchmark/lifo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hola/challenge_linked_list/db931205f5e83c343abd0b8d876d3d5620a6e5d6/submissions/Mateusz Krzeszowiak/benchmark/lifo.png -------------------------------------------------------------------------------- /submissions/Mateusz Krzeszowiak/benchmark/random.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This benchmark tests random access to elements in containers with 100, 10000 and 1000000 elements. 3 | */ 4 | 5 | /** 6 | * Lets require dependencies. Some of them have to be assigned to global namespace because of the way 7 | * benchmark.js works. 8 | */ 9 | var Benchmark = require('benchmark'); 10 | global.LinkList = require('_linklist'); 11 | global.BlinkedList = require('../BlinkedList.js'); 12 | global.Utils = require('./utils.js'); 13 | 14 | var randomAccessSuite = new Benchmark.Suite() 15 | .add('LinkList random element access', { 16 | 'setup': function () { 17 | var list = {}; 18 | LinkList.init(list); 19 | Utils.fillLinkList(list, Utils.testLength); 20 | }, 21 | 'fn': function () { 22 | Utils.randomAccessNodeList(list, Math.floor(Math.random() * Utils.testLength)); 23 | } 24 | }) 25 | 26 | .add('Array random element access', { 27 | 'setup': function () { 28 | var array = []; 29 | Utils.fillArray(array, Utils.testLength); 30 | }, 31 | 'fn': function () { 32 | Utils.randomAccessArray(array, Math.floor(Math.random() * Utils.testLength)); 33 | } 34 | }) 35 | 36 | .add('BlinkedList random element access', { 37 | 'setup': function () { 38 | var array = new BlinkedList(Utils.testLength); 39 | Utils.fillArray(array, Utils.testLength); 40 | }, 41 | 'fn': function () { 42 | Utils.randomAccessBlinkedList(array, Math.floor(Math.random() * Utils.testLength)); 43 | } 44 | }) 45 | .on('cycle', function(event) { 46 | console.log(String(event.target)); 47 | }) 48 | .on('complete', function() { 49 | console.log('Fastest is ' + this.filter('fastest').pluck('name')); 50 | console.log(); 51 | }); 52 | 53 | console.log("Random access benchmark."); 54 | Utils.testLength = 100; 55 | console.log("Benchmarking for " + Utils.testLength + " elements."); 56 | randomAccessSuite.run(); 57 | 58 | Utils.testLength = 10000; 59 | console.log("Benchmarking for " + Utils.testLength + " elements."); 60 | randomAccessSuite.run(); 61 | 62 | Utils.testLength = 1000000; 63 | console.log("Benchmarking for " + Utils.testLength + " elements."); 64 | randomAccessSuite.run(); -------------------------------------------------------------------------------- /submissions/Mateusz Krzeszowiak/benchmark/random.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hola/challenge_linked_list/db931205f5e83c343abd0b8d876d3d5620a6e5d6/submissions/Mateusz Krzeszowiak/benchmark/random.png -------------------------------------------------------------------------------- /submissions/Mateusz Krzeszowiak/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BlinkedList", 3 | "description": "The fastest linked list implementation for NodeJS", 4 | "author": "Mateusz Krzeszowiak ", 5 | "version": "0.1.0", 6 | "private": true, 7 | "devDependencies": { 8 | "benchmark": "~1" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/README: -------------------------------------------------------------------------------- 1 | There are three implementations of linked list: 2 | 3 | - First I've made OOP implementation (linked_list file). 4 | It was good enough, but a little bit slower than original _linklist. 5 | It's interface differs from original and there are methods 6 | for compatibility. There is #push method, it only works with elements that 7 | don't belong to list yet. It's performance is same as original #append (sometimes 8 | slightly slower). Fully compatible #append method is 3-4 times slower than 9 | original. 10 | This is my final implementation. After it I've made some tries but they weren't faster. 11 | 12 | - Then I've made implementation (linked_list_harmony file) using WeakMap 13 | (for ECMAScript 2015 mode), but it was much slower than original. 14 | 15 | - Then I've tried procedural style (linked_list_proc file), but it is also 16 | not so fast. 17 | 18 | 19 | Code is written in CoffeeScript, compiled files are also included. 20 | 21 | To run benchmarks: 22 | 23 | - Install benchmark.js with: 24 | $ npm install 25 | 26 | - Run benchmark with: 27 | $ node benchmark/linked_list.js 28 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/_linklist.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 'use strict'; 23 | 24 | function init(list) { 25 | list._idleNext = list; 26 | list._idlePrev = list; 27 | } 28 | exports.init = init; 29 | 30 | 31 | // show the most idle item 32 | 33 | function peek(list) { 34 | if (list._idlePrev == list) return null; 35 | return list._idlePrev; 36 | } 37 | exports.peek = peek; 38 | 39 | 40 | // remove the most idle item from the list 41 | 42 | function shift(list) { 43 | var first = list._idlePrev; 44 | remove(first); 45 | return first; 46 | } 47 | exports.shift = shift; 48 | 49 | 50 | // remove a item from its list 51 | 52 | function remove(item) { 53 | if (item._idleNext) { 54 | item._idleNext._idlePrev = item._idlePrev; 55 | } 56 | 57 | if (item._idlePrev) { 58 | item._idlePrev._idleNext = item._idleNext; 59 | } 60 | 61 | item._idleNext = null; 62 | item._idlePrev = null; 63 | } 64 | exports.remove = remove; 65 | 66 | 67 | // remove a item from its list and place at the end. 68 | 69 | function append(list, item) { 70 | remove(item); 71 | item._idleNext = list._idleNext; 72 | list._idleNext._idlePrev = item; 73 | item._idlePrev = list; 74 | list._idleNext = item; 75 | } 76 | exports.append = append; 77 | 78 | 79 | function isEmpty(list) { 80 | return list._idleNext === list; 81 | } 82 | exports.isEmpty = isEmpty; 83 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/benchmark/linked_list.coffee: -------------------------------------------------------------------------------- 1 | shared_bm = require('./shared') 2 | LinkedList = require('../linked_list') 3 | LinkedListProc = require('../linked_list_proc') 4 | shared_bm(LinkedList, LinkedListProc) 5 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/benchmark/linked_list.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var LinkedList, LinkedListProc, shared_bm; 4 | 5 | shared_bm = require('./shared'); 6 | 7 | LinkedList = require('../linked_list'); 8 | 9 | LinkedListProc = require('../linked_list_proc'); 10 | 11 | shared_bm(LinkedList, LinkedListProc); 12 | 13 | }).call(this); 14 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/benchmark/linked_list_harmony.coffee: -------------------------------------------------------------------------------- 1 | shared_bm = require('./shared') 2 | LinkedList = require('../linked_list_harmony') 3 | LinkedListProc = require('../linked_list_proc') 4 | shared_bm(LinkedList, LinkedListProc) 5 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/benchmark/linked_list_harmony.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var LinkedList, LinkedListProc, shared_bm; 4 | 5 | shared_bm = require('./shared'); 6 | 7 | LinkedList = require('../linked_list_harmony'); 8 | 9 | LinkedListProc = require('../linked_list_proc'); 10 | 11 | shared_bm(LinkedList, LinkedListProc); 12 | 13 | }).call(this); 14 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/benchmark/shared.coffee: -------------------------------------------------------------------------------- 1 | Benchmark = require('benchmark') 2 | OriginalList = require('../_linklist') 3 | assert = require('assert') 4 | 5 | module.exports = (LinkedList, LinkedListProc) -> 6 | original = null 7 | tested = null 8 | tested_proc = null 9 | 10 | do reset = -> 11 | original = name: 'original' 12 | OriginalList.init(original) 13 | tested = new LinkedList 14 | tested_proc = name: 'proc' 15 | LinkedListProc.init(tested_proc) 16 | 17 | suite_options = 18 | onCycle: (event) -> 19 | reset() 20 | console.log(String(event.target)) 21 | onComplete: -> 22 | console.log("Fastest is #{@filter('fastest').pluck('name')}") 23 | 24 | new Benchmark.Suite(suite_options) 25 | .add 'tested#push', -> 26 | tested.push name: 'new' 27 | .add 'tested#append', -> 28 | tested.append name: 'new' 29 | .add 'tested_proc#append', -> 30 | LinkedListProc.append tested_proc, name: 'new' 31 | .add 'original#append', -> 32 | OriginalList.append original, name: 'new' 33 | .run() 34 | 35 | # new Benchmark.Suite(suite_options) 36 | # .add 'tested#push & #begin', -> 37 | # tested.push name: 'new' 38 | # assert.ok(tested.begin.name == 'new') 39 | # .add 'tested#push & #peek', -> 40 | # tested.push name: 'new' 41 | # assert.ok(tested.peek().name == 'new') 42 | # .add 'tested#append & #peek', -> 43 | # tested.append name: 'new' 44 | # assert.ok(tested.peek().name == 'new') 45 | # .add 'tested_proc#append & #peek', -> 46 | # LinkedListProc.append tested_proc, name: 'new' 47 | # assert.ok(LinkedListProc.peek(tested_proc).name == 'new') 48 | # .add 'original#append & #peek', -> 49 | # OriginalList.append original, name: 'new' 50 | # assert.ok(OriginalList.peek(original).name == 'new') 51 | # .run() 52 | 53 | # new Benchmark.Suite(suite_options) 54 | # .add 'tested#push | #shift & #isEmpty randomly', -> 55 | # if Math.random() < 0.05 56 | # tested.shift() unless tested.isEmpty() 57 | # else 58 | # tested.push name: 'new' 59 | # .add 'tested#append | #shift & #isEmpty randomly', -> 60 | # if Math.random() < 0.05 61 | # tested.shift() unless tested.isEmpty() 62 | # else 63 | # tested.append name: 'new' 64 | # .add 'tested_proc#append | #shift & #isEmpty randomly', -> 65 | # if Math.random() < 0.05 66 | # LinkedListProc.shift(tested_proc) unless LinkedListProc.isEmpty(tested_proc) 67 | # else 68 | # LinkedListProc.append tested_proc, name: 'new' 69 | # .add 'original#append | #shift & #isEmpty randomly', -> 70 | # if Math.random() < 0.05 71 | # OriginalList.shift(original) unless OriginalList.isEmpty(original) 72 | # else 73 | # OriginalList.append original, name: 'new' 74 | # .run() 75 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/benchmark/shared.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var Benchmark, OriginalList, assert; 4 | 5 | Benchmark = require('benchmark'); 6 | 7 | OriginalList = require('../_linklist'); 8 | 9 | assert = require('assert'); 10 | 11 | module.exports = function(LinkedList, LinkedListProc) { 12 | var original, reset, suite_options, tested, tested_proc; 13 | original = null; 14 | tested = null; 15 | tested_proc = null; 16 | (reset = function() { 17 | original = { 18 | name: 'original' 19 | }; 20 | OriginalList.init(original); 21 | tested = new LinkedList; 22 | tested_proc = { 23 | name: 'proc' 24 | }; 25 | return LinkedListProc.init(tested_proc); 26 | })(); 27 | suite_options = { 28 | onCycle: function(event) { 29 | reset(); 30 | return console.log(String(event.target)); 31 | }, 32 | onComplete: function() { 33 | return console.log("Fastest is " + (this.filter('fastest').pluck('name'))); 34 | } 35 | }; 36 | return new Benchmark.Suite(suite_options).add('tested#push', function() { 37 | return tested.push({ 38 | name: 'new' 39 | }); 40 | }).add('tested#append', function() { 41 | return tested.append({ 42 | name: 'new' 43 | }); 44 | }).add('tested_proc#append', function() { 45 | return LinkedListProc.append(tested_proc, { 46 | name: 'new' 47 | }); 48 | }).add('original#append', function() { 49 | return OriginalList.append(original, { 50 | name: 'new' 51 | }); 52 | }).run(); 53 | }; 54 | 55 | }).call(this); 56 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/linked_list.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | class LinkedList 3 | @_counter: 0 4 | 5 | constructor: (id) -> 6 | id ?= LinkedList._counter += 1 7 | @_prevProp = "_llistPrev#{id}" 8 | @_nextProp = "_llistNext#{id}" 9 | # @ownedProp = "_llistOwned#{id}" 10 | 11 | push: (item) -> 12 | # item[@ownedProp] = true 13 | target = @end 14 | if target 15 | target[@_nextProp] = item 16 | item[@_prevProp] = target 17 | @end = item 18 | else 19 | @begin = @end = item 20 | 21 | unshift: (item) -> 22 | # item[@ownedProp] = true 23 | if @begin 24 | @begin[@_prevProp] = item 25 | item[@_nextProp] = @begin 26 | @begin = item 27 | else 28 | @begin = @end = item 29 | 30 | pop: -> 31 | @remove(@end) 32 | 33 | shift: -> 34 | @remove(@begin) 35 | 36 | remove: (item) -> 37 | # owned_prop = @ownedProp 38 | if item#?[owned_prop] 39 | prev = item[@_prevProp] 40 | next = item[@_nextProp] 41 | # item[owned_prop] = null 42 | @begin = next if item == @begin 43 | @end = prev if item == @end 44 | return item unless prev || next 45 | next?[@_prevProp] = prev 46 | prev?[@_nextProp] = next 47 | item[@_prevProp] = item[@_nextProp] = null 48 | item 49 | # else 50 | # item 51 | 52 | # Compatibility: 53 | peek: -> @begin 54 | isEmpty: -> !@begin 55 | append: (item) -> 56 | @push @remove(item) 57 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/linked_list.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var LinkedList; 4 | 5 | module.exports = LinkedList = (function() { 6 | LinkedList._counter = 0; 7 | 8 | function LinkedList(id) { 9 | if (id == null) { 10 | id = LinkedList._counter += 1; 11 | } 12 | this._prevProp = "_llistPrev" + id; 13 | this._nextProp = "_llistNext" + id; 14 | } 15 | 16 | LinkedList.prototype.push = function(item) { 17 | var target; 18 | target = this.end; 19 | if (target) { 20 | target[this._nextProp] = item; 21 | item[this._prevProp] = target; 22 | return this.end = item; 23 | } else { 24 | return this.begin = this.end = item; 25 | } 26 | }; 27 | 28 | LinkedList.prototype.unshift = function(item) { 29 | if (this.begin) { 30 | this.begin[this._prevProp] = item; 31 | item[this._nextProp] = this.begin; 32 | return this.begin = item; 33 | } else { 34 | return this.begin = this.end = item; 35 | } 36 | }; 37 | 38 | LinkedList.prototype.pop = function() { 39 | return this.remove(this.end); 40 | }; 41 | 42 | LinkedList.prototype.shift = function() { 43 | return this.remove(this.begin); 44 | }; 45 | 46 | LinkedList.prototype.remove = function(item) { 47 | var next, prev; 48 | if (item) { 49 | prev = item[this._prevProp]; 50 | next = item[this._nextProp]; 51 | if (item === this.begin) { 52 | this.begin = next; 53 | } 54 | if (item === this.end) { 55 | this.end = prev; 56 | } 57 | if (!(prev || next)) { 58 | return item; 59 | } 60 | if (next != null) { 61 | next[this._prevProp] = prev; 62 | } 63 | if (prev != null) { 64 | prev[this._nextProp] = next; 65 | } 66 | item[this._prevProp] = item[this._nextProp] = null; 67 | return item; 68 | } 69 | }; 70 | 71 | LinkedList.prototype.peek = function() { 72 | return this.begin; 73 | }; 74 | 75 | LinkedList.prototype.isEmpty = function() { 76 | return !this.begin; 77 | }; 78 | 79 | LinkedList.prototype.append = function(item) { 80 | return this.push(this.remove(item)); 81 | }; 82 | 83 | return LinkedList; 84 | 85 | })(); 86 | 87 | }).call(this); 88 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/linked_list_harmony.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | class LinkedList 3 | @_counter: 0 4 | 5 | constructor: -> 6 | @map = new WeakMap 7 | 8 | push: (item) -> 9 | if @end 10 | @map.set item, [@end, null] 11 | @map.get(@end)[1] = item 12 | @end = item 13 | else 14 | @map.set item, Array(2) 15 | @begin = @end = item 16 | 17 | unshift: (item) -> 18 | if @begin 19 | @map.set item, [null, @begin] 20 | @map.get(@begin)[0] = item 21 | @begin = item 22 | else 23 | map.set item, Array(2) 24 | @begin = @end = item 25 | 26 | pop: -> 27 | @remove(@end) 28 | 29 | shift: -> 30 | @remove(@begin) 31 | 32 | remove: (item) -> 33 | links = @map.get(item) 34 | return item unless links 35 | @map.delete(item) 36 | prev = links[0] 37 | next = links[1] 38 | @begin = next if item == @begin 39 | @end = prev if item == @end 40 | @map.get(next)[0] = prev if next 41 | @map.get(prev)[1] = next if prev 42 | item 43 | 44 | # Compatibility: 45 | peek: -> @begin 46 | isEmpty: -> !@begin 47 | append: (item) -> 48 | @push @remove(item) 49 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/linked_list_harmony.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var LinkedList; 4 | 5 | module.exports = LinkedList = (function() { 6 | LinkedList._counter = 0; 7 | 8 | function LinkedList() { 9 | this.map = new WeakMap; 10 | } 11 | 12 | LinkedList.prototype.push = function(item) { 13 | if (this.end) { 14 | this.map.set(item, [this.end, null]); 15 | this.map.get(this.end)[1] = item; 16 | return this.end = item; 17 | } else { 18 | this.map.set(item, Array(2)); 19 | return this.begin = this.end = item; 20 | } 21 | }; 22 | 23 | LinkedList.prototype.unshift = function(item) { 24 | if (this.begin) { 25 | this.map.set(item, [null, this.begin]); 26 | this.map.get(this.begin)[0] = item; 27 | return this.begin = item; 28 | } else { 29 | map.set(item, Array(2)); 30 | return this.begin = this.end = item; 31 | } 32 | }; 33 | 34 | LinkedList.prototype.pop = function() { 35 | return this.remove(this.end); 36 | }; 37 | 38 | LinkedList.prototype.shift = function() { 39 | return this.remove(this.begin); 40 | }; 41 | 42 | LinkedList.prototype.remove = function(item) { 43 | var links, next, prev; 44 | links = this.map.get(item); 45 | if (!links) { 46 | return item; 47 | } 48 | this.map["delete"](item); 49 | prev = links[0]; 50 | next = links[1]; 51 | if (item === this.begin) { 52 | this.begin = next; 53 | } 54 | if (item === this.end) { 55 | this.end = prev; 56 | } 57 | if (next) { 58 | this.map.get(next)[0] = prev; 59 | } 60 | if (prev) { 61 | this.map.get(prev)[1] = next; 62 | } 63 | return item; 64 | }; 65 | 66 | LinkedList.prototype.peek = function() { 67 | return this.begin; 68 | }; 69 | 70 | LinkedList.prototype.isEmpty = function() { 71 | return !this.begin; 72 | }; 73 | 74 | LinkedList.prototype.append = function(item) { 75 | return this.push(this.remove(item)); 76 | }; 77 | 78 | return LinkedList; 79 | 80 | })(); 81 | 82 | }).call(this); 83 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/linked_list_proc.coffee: -------------------------------------------------------------------------------- 1 | counter = 0 2 | 3 | module.exports = LinkedList = 4 | init: (list, id) -> 5 | id ?= counter += 1 6 | list._prevProp = "_llistPrev#{id}" 7 | list._nextProp = "_llistNext#{id}" 8 | list[list._nextProp] = list 9 | list[list._prevProp] = list 10 | 11 | peek: (list) -> 12 | item = list[list._prevProp] 13 | item unless item == list 14 | 15 | shift: (list) -> 16 | LinkedList.remove list, list[list._prevProp] 17 | 18 | remove: (list, item) -> 19 | if item[list._nextProp] 20 | item[list._nextProp][list._prevProp] = item[list._prevProp] 21 | if item[list._prevProp] 22 | item[list._prevProp][list._nextProp] = item[list._nextProp] 23 | item[list._nextProp] = null 24 | item[list._prevProp] = null 25 | item 26 | 27 | append: (list, item) -> 28 | LinkedList.remove list, item 29 | item[list._nextProp] = list[list._nextProp] 30 | list[list._nextProp][list._prevProp] = item 31 | item[list._prevProp] = list 32 | list[list._nextProp] = item 33 | return 34 | 35 | isEmpty: (list) -> 36 | list[list._nextProp] == list 37 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/linked_list_proc.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var LinkedList, counter; 4 | 5 | counter = 0; 6 | 7 | module.exports = LinkedList = { 8 | init: function(list, id) { 9 | if (id == null) { 10 | id = counter += 1; 11 | } 12 | list._prevProp = "_llistPrev" + id; 13 | list._nextProp = "_llistNext" + id; 14 | list[list._nextProp] = list; 15 | return list[list._prevProp] = list; 16 | }, 17 | peek: function(list) { 18 | var item; 19 | item = list[list._prevProp]; 20 | if (item !== list) { 21 | return item; 22 | } 23 | }, 24 | shift: function(list) { 25 | return LinkedList.remove(list, list[list._prevProp]); 26 | }, 27 | remove: function(list, item) { 28 | if (item[list._nextProp]) { 29 | item[list._nextProp][list._prevProp] = item[list._prevProp]; 30 | } 31 | if (item[list._prevProp]) { 32 | item[list._prevProp][list._nextProp] = item[list._nextProp]; 33 | } 34 | item[list._nextProp] = null; 35 | item[list._prevProp] = null; 36 | return item; 37 | }, 38 | append: function(list, item) { 39 | LinkedList.remove(list, item); 40 | item[list._nextProp] = list[list._nextProp]; 41 | list[list._nextProp][list._prevProp] = item; 42 | item[list._prevProp] = list; 43 | list[list._nextProp] = item; 44 | }, 45 | isEmpty: function(list) { 46 | return list[list._nextProp] === list; 47 | } 48 | }; 49 | 50 | }).call(this); 51 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "linklist", 3 | "version": "0.0.1", 4 | "description": "linked list for hola", 5 | "main": "linked_list.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "devDependencies": { 13 | "benchmark": "1.0.0", 14 | "microtime": "*" 15 | }, 16 | "author": "Max Melentiev", 17 | "license": "MIT" 18 | } 19 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/test/linked_list.coffee: -------------------------------------------------------------------------------- 1 | LinkedList = require('../linked_list') 2 | shared_examples = require('./linked_list_shared') 3 | shared_examples(LinkedList) 4 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/test/linked_list.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var LinkedList, shared_examples; 4 | 5 | LinkedList = require('../linked_list'); 6 | 7 | shared_examples = require('./linked_list_shared'); 8 | 9 | shared_examples(LinkedList); 10 | 11 | }).call(this); 12 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/test/linked_list_harmony.coffee: -------------------------------------------------------------------------------- 1 | LinkedList = require('../linked_list_harmony') 2 | shared_examples = require('./linked_list_shared') 3 | shared_examples(LinkedList) 4 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/test/linked_list_harmony.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var LinkedList, shared_examples; 4 | 5 | LinkedList = require('../linked_list_harmony'); 6 | 7 | shared_examples = require('./linked_list_shared'); 8 | 9 | shared_examples(LinkedList); 10 | 11 | }).call(this); 12 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/test/linked_list_proc.coffee: -------------------------------------------------------------------------------- 1 | assert = require('assert') 2 | L = require('../linked_list_proc') 3 | 4 | list = name: 'list' 5 | A = name: 'A' 6 | B = name: 'B' 7 | C = name: 'C' 8 | D = name: 'D' 9 | 10 | 11 | L.init(list) 12 | L.init(A) 13 | L.init(B) 14 | L.init(C) 15 | L.init(D) 16 | 17 | assert.ok(L.isEmpty(list)) 18 | assert.equal(null, L.peek(list)) 19 | 20 | L.append(list, A) 21 | # list -> A 22 | assert.equal(A, L.peek(list)) 23 | 24 | L.append(list, B) 25 | # list -> A -> B 26 | assert.equal(A, L.peek(list)) 27 | 28 | L.append(list, C) 29 | # list -> A -> B -> C 30 | assert.equal(A, L.peek(list)) 31 | 32 | L.append(list, D) 33 | # list -> A -> B -> C -> D 34 | assert.equal(A, L.peek(list)) 35 | 36 | x = L.shift(list) 37 | assert.equal(A, x) 38 | # list -> B -> C -> D 39 | assert.equal(B, L.peek(list)) 40 | 41 | x = L.shift(list) 42 | assert.equal(B, x) 43 | # list -> C -> D 44 | assert.equal(C, L.peek(list)) 45 | 46 | # B is already removed, so removing it again shouldn't hurt. 47 | L.remove(list, B) 48 | # list -> C -> D 49 | assert.equal(C, L.peek(list)) 50 | 51 | # Put B back on the list 52 | L.append(list, B) 53 | # list -> C -> D -> B 54 | assert.equal(C, L.peek(list)) 55 | 56 | L.remove(list, C) 57 | # list -> D -> B 58 | assert.equal(D, L.peek(list)) 59 | 60 | L.remove(list, B) 61 | # list -> D 62 | assert.equal(D, L.peek(list)) 63 | 64 | L.remove(list, D) 65 | # list 66 | assert.equal(null, L.peek(list)) 67 | 68 | 69 | assert.ok(L.isEmpty(list)) 70 | 71 | 72 | L.append(list, D) 73 | # list -> D 74 | assert.equal(D, L.peek(list)) 75 | 76 | L.append(list, C) 77 | L.append(list, B) 78 | L.append(list, A) 79 | # list -> D -> C -> B -> A 80 | 81 | # Append should REMOVE C from the list and append it to the end. 82 | L.append(list, C) 83 | 84 | # list -> D -> B -> A -> C 85 | assert.equal(D, L.shift(list)) 86 | # list -> B -> A -> C 87 | assert.equal(B, L.peek(list)) 88 | assert.equal(B, L.shift(list)) 89 | # list -> A -> C 90 | assert.equal(A, L.peek(list)) 91 | assert.equal(A, L.shift(list)) 92 | # list -> C 93 | assert.equal(C, L.peek(list)) 94 | assert.equal(C, L.shift(list)) 95 | # list 96 | assert.ok(L.isEmpty(list)) 97 | 98 | # extra 99 | other_list = name: 'other' 100 | L.init other_list 101 | 102 | L.append(list, A) 103 | L.append(other_list, A) 104 | assert.equal(A, L.peek(list)) 105 | assert.equal(A, L.peek(other_list)) 106 | 107 | L.remove(list, A) 108 | assert.equal(null, L.peek(list)) 109 | assert.equal(A, L.peek(other_list)) 110 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/test/linked_list_proc.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var A, B, C, D, L, assert, list, other_list, x; 4 | 5 | assert = require('assert'); 6 | 7 | L = require('../linked_list_proc'); 8 | 9 | list = { 10 | name: 'list' 11 | }; 12 | 13 | A = { 14 | name: 'A' 15 | }; 16 | 17 | B = { 18 | name: 'B' 19 | }; 20 | 21 | C = { 22 | name: 'C' 23 | }; 24 | 25 | D = { 26 | name: 'D' 27 | }; 28 | 29 | L.init(list); 30 | 31 | L.init(A); 32 | 33 | L.init(B); 34 | 35 | L.init(C); 36 | 37 | L.init(D); 38 | 39 | assert.ok(L.isEmpty(list)); 40 | 41 | assert.equal(null, L.peek(list)); 42 | 43 | L.append(list, A); 44 | 45 | assert.equal(A, L.peek(list)); 46 | 47 | L.append(list, B); 48 | 49 | assert.equal(A, L.peek(list)); 50 | 51 | L.append(list, C); 52 | 53 | assert.equal(A, L.peek(list)); 54 | 55 | L.append(list, D); 56 | 57 | assert.equal(A, L.peek(list)); 58 | 59 | x = L.shift(list); 60 | 61 | assert.equal(A, x); 62 | 63 | assert.equal(B, L.peek(list)); 64 | 65 | x = L.shift(list); 66 | 67 | assert.equal(B, x); 68 | 69 | assert.equal(C, L.peek(list)); 70 | 71 | L.remove(list, B); 72 | 73 | assert.equal(C, L.peek(list)); 74 | 75 | L.append(list, B); 76 | 77 | assert.equal(C, L.peek(list)); 78 | 79 | L.remove(list, C); 80 | 81 | assert.equal(D, L.peek(list)); 82 | 83 | L.remove(list, B); 84 | 85 | assert.equal(D, L.peek(list)); 86 | 87 | L.remove(list, D); 88 | 89 | assert.equal(null, L.peek(list)); 90 | 91 | assert.ok(L.isEmpty(list)); 92 | 93 | L.append(list, D); 94 | 95 | assert.equal(D, L.peek(list)); 96 | 97 | L.append(list, C); 98 | 99 | L.append(list, B); 100 | 101 | L.append(list, A); 102 | 103 | L.append(list, C); 104 | 105 | assert.equal(D, L.shift(list)); 106 | 107 | assert.equal(B, L.peek(list)); 108 | 109 | assert.equal(B, L.shift(list)); 110 | 111 | assert.equal(A, L.peek(list)); 112 | 113 | assert.equal(A, L.shift(list)); 114 | 115 | assert.equal(C, L.peek(list)); 116 | 117 | assert.equal(C, L.shift(list)); 118 | 119 | assert.ok(L.isEmpty(list)); 120 | 121 | other_list = { 122 | name: 'other' 123 | }; 124 | 125 | L.init(other_list); 126 | 127 | L.append(list, A); 128 | 129 | L.append(other_list, A); 130 | 131 | assert.equal(A, L.peek(list)); 132 | 133 | assert.equal(A, L.peek(other_list)); 134 | 135 | L.remove(list, A); 136 | 137 | assert.equal(null, L.peek(list)); 138 | 139 | assert.equal(A, L.peek(other_list)); 140 | 141 | }).call(this); 142 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/test/linked_list_shared.coffee: -------------------------------------------------------------------------------- 1 | assert = require('assert') 2 | 3 | module.exports = (LinkedList) -> 4 | list = new LinkedList 5 | A = name: 'A' 6 | B = name: 'B' 7 | C = name: 'C' 8 | D = name: 'D' 9 | 10 | assert.ok(list.isEmpty()) 11 | assert.equal(null, list.peek()) 12 | 13 | list.append(A) 14 | # list -> A 15 | assert.equal(A, list.peek()) 16 | 17 | list.append(B) 18 | # list -> A -> B 19 | assert.equal(A, list.peek()) 20 | 21 | list.append(C) 22 | # list -> A -> B -> C 23 | assert.equal(A, list.peek()) 24 | 25 | list.append(D) 26 | # list -> A -> B -> C -> D 27 | assert.equal(A, list.peek()) 28 | 29 | x = list.shift() 30 | assert.equal(A, x) 31 | # list -> B -> C -> D 32 | assert.equal(B, list.peek()) 33 | 34 | x = list.shift() 35 | assert.equal(B, x) 36 | # list -> C -> D 37 | assert.equal(C, list.peek()) 38 | 39 | # B is already removed, so removing it again shouldn't hurt. 40 | list.remove(B) 41 | # list -> C -> D 42 | assert.equal(C, list.peek()) 43 | 44 | # Put B back on the list 45 | list.append(B) 46 | # list -> C -> D -> B 47 | assert.equal(C, list.peek()) 48 | 49 | list.remove(C) 50 | # list -> D -> B 51 | assert.equal(D, list.peek()) 52 | 53 | list.remove(B) 54 | # list -> D 55 | assert.equal(D, list.peek()) 56 | 57 | list.remove(D) 58 | # list 59 | assert.equal(null, list.peek()) 60 | 61 | 62 | assert.ok(list.isEmpty()) 63 | 64 | 65 | list.append(D) 66 | # list -> D 67 | assert.equal(D, list.peek()) 68 | 69 | list.append(C) 70 | list.append(B) 71 | list.append(A) 72 | # list -> D -> C -> B -> A 73 | 74 | # Append should REMOVE C from the list and append it to the end. 75 | list.append(C) 76 | 77 | # list -> D -> B -> A -> C 78 | assert.equal(D, list.shift()) 79 | # list -> B -> A -> C 80 | assert.equal(B.name, list.peek().name) 81 | assert.equal(B, list.shift()) 82 | # list -> A -> C 83 | assert.equal(A, list.peek()) 84 | assert.equal(A, list.shift()) 85 | # list -> C 86 | assert.equal(C, list.peek()) 87 | assert.equal(C, list.shift()) 88 | # list 89 | assert.ok(list.isEmpty()) 90 | 91 | # extra 92 | other_list = new LinkedList 93 | 94 | list.append(A) 95 | other_list.append(A) 96 | assert.equal(A, list.peek()) 97 | assert.equal(A, other_list.peek()) 98 | 99 | list.remove(A) 100 | assert.equal(null, list.peek()) 101 | assert.equal(A, other_list.peek()) 102 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/test/linked_list_shared.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.8.0 2 | (function() { 3 | var assert; 4 | 5 | assert = require('assert'); 6 | 7 | module.exports = function(LinkedList) { 8 | var A, B, C, D, list, other_list, x; 9 | list = new LinkedList; 10 | A = { 11 | name: 'A' 12 | }; 13 | B = { 14 | name: 'B' 15 | }; 16 | C = { 17 | name: 'C' 18 | }; 19 | D = { 20 | name: 'D' 21 | }; 22 | assert.ok(list.isEmpty()); 23 | assert.equal(null, list.peek()); 24 | list.append(A); 25 | assert.equal(A, list.peek()); 26 | list.append(B); 27 | assert.equal(A, list.peek()); 28 | list.append(C); 29 | assert.equal(A, list.peek()); 30 | list.append(D); 31 | assert.equal(A, list.peek()); 32 | x = list.shift(); 33 | assert.equal(A, x); 34 | assert.equal(B, list.peek()); 35 | x = list.shift(); 36 | assert.equal(B, x); 37 | assert.equal(C, list.peek()); 38 | list.remove(B); 39 | assert.equal(C, list.peek()); 40 | list.append(B); 41 | assert.equal(C, list.peek()); 42 | list.remove(C); 43 | assert.equal(D, list.peek()); 44 | list.remove(B); 45 | assert.equal(D, list.peek()); 46 | list.remove(D); 47 | assert.equal(null, list.peek()); 48 | assert.ok(list.isEmpty()); 49 | list.append(D); 50 | assert.equal(D, list.peek()); 51 | list.append(C); 52 | list.append(B); 53 | list.append(A); 54 | list.append(C); 55 | assert.equal(D, list.shift()); 56 | assert.equal(B.name, list.peek().name); 57 | assert.equal(B, list.shift()); 58 | assert.equal(A, list.peek()); 59 | assert.equal(A, list.shift()); 60 | assert.equal(C, list.peek()); 61 | assert.equal(C, list.shift()); 62 | assert.ok(list.isEmpty()); 63 | other_list = new LinkedList; 64 | list.append(A); 65 | other_list.append(A); 66 | assert.equal(A, list.peek()); 67 | assert.equal(A, other_list.peek()); 68 | list.remove(A); 69 | assert.equal(null, list.peek()); 70 | return assert.equal(A, other_list.peek()); 71 | }; 72 | 73 | }).call(this); 74 | -------------------------------------------------------------------------------- /submissions/Max Melentiev/test/simple/test-timers-linked-list.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | // var common = require('../common'); 23 | var assert = require('assert'); 24 | var L = require('../../_linklist'); 25 | 26 | 27 | var list = { 28 | name: 'list' 29 | }; 30 | var A = { 31 | name: 'A' 32 | }; 33 | var B = { 34 | name: 'B' 35 | }; 36 | var C = { 37 | name: 'C' 38 | }; 39 | var D = { 40 | name: 'D' 41 | }; 42 | 43 | 44 | L.init(list); 45 | L.init(A); 46 | L.init(B); 47 | L.init(C); 48 | L.init(D); 49 | 50 | assert.ok(L.isEmpty(list)); 51 | assert.equal(null, L.peek(list)); 52 | 53 | L.append(list, A); 54 | // list -> A 55 | assert.equal(A, L.peek(list)); 56 | 57 | L.append(list, B); 58 | // list -> A -> B 59 | assert.equal(A, L.peek(list)); 60 | 61 | L.append(list, C); 62 | // list -> A -> B -> C 63 | assert.equal(A, L.peek(list)); 64 | 65 | L.append(list, D); 66 | // list -> A -> B -> C -> D 67 | assert.equal(A, L.peek(list)); 68 | 69 | var x = L.shift(list); 70 | assert.equal(A, x); 71 | // list -> B -> C -> D 72 | assert.equal(B, L.peek(list)); 73 | 74 | x = L.shift(list); 75 | assert.equal(B, x); 76 | // list -> C -> D 77 | assert.equal(C, L.peek(list)); 78 | 79 | // B is already removed, so removing it again shouldn't hurt. 80 | L.remove(B); 81 | // list -> C -> D 82 | assert.equal(C, L.peek(list)); 83 | 84 | // Put B back on the list 85 | L.append(list, B); 86 | // list -> C -> D -> B 87 | assert.equal(C, L.peek(list)); 88 | 89 | L.remove(C); 90 | // list -> D -> B 91 | assert.equal(D, L.peek(list)); 92 | 93 | L.remove(B); 94 | // list -> D 95 | assert.equal(D, L.peek(list)); 96 | 97 | L.remove(D); 98 | // list 99 | assert.equal(null, L.peek(list)); 100 | 101 | 102 | assert.ok(L.isEmpty(list)); 103 | 104 | 105 | L.append(list, D); 106 | // list -> D 107 | assert.equal(D, L.peek(list)); 108 | 109 | L.append(list, C); 110 | L.append(list, B); 111 | L.append(list, A); 112 | // list -> D -> C -> B -> A 113 | 114 | // Append should REMOVE C from the list and append it to the end. 115 | L.append(list, C); 116 | 117 | // list -> D -> B -> A -> C 118 | assert.equal(D, L.shift(list)); 119 | // list -> B -> A -> C 120 | assert.equal(B, L.peek(list)); 121 | assert.equal(B, L.shift(list)); 122 | // list -> A -> C 123 | assert.equal(A, L.peek(list)); 124 | assert.equal(A, L.shift(list)); 125 | // list -> C 126 | assert.equal(C, L.peek(list)); 127 | assert.equal(C, L.shift(list)); 128 | // list 129 | assert.ok(L.isEmpty(list)); 130 | 131 | // extra 132 | var other_list = {name: 'other'}; 133 | L.init(other_list); 134 | 135 | L.append(list, A); 136 | L.append(other_list, A); 137 | assert.equal(null, L.peek(list)); // assert failure, should be A 138 | assert.equal(A, L.peek(other_list)); 139 | -------------------------------------------------------------------------------- /submissions/Ori Shalev/orilist.js: -------------------------------------------------------------------------------- 1 | // Written by Ori Shalev, ori.shalev@gmail.com 2 | // Submitting to hola! coding challenge http://hola.org/challenge_js?m 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a 5 | // copy of this software and associated documentation files (the 6 | // "Software"), to deal in the Software without restriction, including 7 | // without limitation the rights to use, copy, modify, merge, publish, 8 | // distribute, sublicense, and/or sell copies of the Software, and to permit 9 | // persons to whom the Software is furnished to do so, subject to the 10 | // following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included 13 | // in all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 18 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | 'use strict'; 24 | 25 | var fs = require('fs'); 26 | var linklist = require('_linklist'); 27 | var tmp = require('tmp'); 28 | var tosource = require('tosource'); 29 | 30 | var sourceCode = 31 | "var remove = (" + tosource(linklist.remove) + ");\n" + 32 | "exports.remove = remove;\n" + 33 | "exports.init = (" + tosource(linklist.init) + ");\n" + 34 | "exports.peek = (" + tosource(linklist.peek) + ");\n" + 35 | "exports.shift = (" + tosource(linklist.shift) + ");\n" + 36 | "exports.append = (" + tosource(linklist.append) + ");\n" + 37 | "exports.isEmpty = (" + tosource(linklist.isEmpty) + ");\n"; 38 | 39 | 40 | module.exports = function(name, dontCache) { 41 | var genfile = null; 42 | var g; 43 | if (!dontCache) { 44 | try { 45 | genfile = '/tmp/_orilist_' + name + '.js'; 46 | if (!fs.existsSync(genfile)) { 47 | fs.writeFileSync(genfile, sourceCode.replace(/idle/g, name)); 48 | } 49 | } 50 | catch(err) { 51 | genfile = null; 52 | } 53 | } 54 | if (!genfile) { 55 | genfile = tmp.fileSync({ postfix: '.js' }).name; 56 | fs.writeFileSync(genfile, sourceCode.replace(/idle/g, name)); 57 | } 58 | var g = require(genfile); 59 | return { init: g.init, 60 | peek: g.peek, 61 | shift: g.shift, 62 | remove: g.remove, 63 | append: g.append, 64 | isEmpty: g.isEmpty }; 65 | }; 66 | 67 | -------------------------------------------------------------------------------- /submissions/Ori Shalev/test_orilist.js: -------------------------------------------------------------------------------- 1 | 2 | var L = require('./orilist')('idle1'); 3 | //var L = require('./orilist')('idle1', true); // this variation doesn't leave files in /tmp 4 | //var L = require('_linklist'); 5 | 6 | var main = function() 7 | { 8 | var a = { v: -1 }; 9 | L.init(a); 10 | 11 | for (i = 0; i < 10000000; i++) { 12 | L.append(a, {v: i}) 13 | } 14 | 15 | } 16 | 17 | main() 18 | 19 | -------------------------------------------------------------------------------- /submissions/Sergey Shpak/lib/_linklistgeneric-1.js: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * Tools 3 | * General Link List 4 | * Copyright 2015 Sergii Shpak 5 | * MIT License, http://shps.mit-license.org 6 | ************************************************************/ 7 | 8 | /* The main idea of this solution is creation (and partial caching) 9 | * of unique 'List' Constructors per each list instance */ 10 | 11 | var listCounter = 0, 12 | Item = function (prev, next) { 13 | this.prev = prev; 14 | this.next = next; 15 | }, 16 | List = function (Item) { 17 | 18 | this.key = new Item(this, this); 19 | 20 | this.append = function (item) { 21 | this.remove(item).key = new Item(this, this.key.next); 22 | this.key.next.key.prev = item; 23 | this.key.next = item; 24 | }; 25 | 26 | this.remove = function (item) { 27 | if (!item.key) return item; 28 | item.key.next.key.prev = item.key.prev; 29 | item.key.prev.key.next = item.key.next; 30 | item.key = null; 31 | return item; 32 | }; 33 | 34 | this.shift = function () { 35 | return this.remove(this.key.prev); 36 | }; 37 | 38 | this.peek = function () { 39 | if (this.key.prev === this) return null; 40 | return this.key.prev; 41 | }; 42 | 43 | this.isEmpty = function () { 44 | return this.key.next === this; 45 | }; 46 | 47 | // Get List key, if list has been created without 'name' 48 | this.getKey = function () { 49 | return "key" 50 | }; 51 | 52 | }.toString(), 53 | 54 | ListConstructorBody = List.substring(List.indexOf("{") + 1, List.lastIndexOf("}")), 55 | 56 | ListConstructorsCache = {}; 57 | 58 | 59 | module.exports = function (name) { 60 | 61 | var Constructor = ListConstructorsCache[name] || 62 | new Function("Item", ListConstructorBody.replace(/key/g, name || ("__list_" + listCounter++ ))); 63 | 64 | // Cache Constructors only with passed name 65 | if (name) ListConstructorsCache[name] = Constructor; 66 | return new Constructor(Item); 67 | }; -------------------------------------------------------------------------------- /submissions/Sergey Shpak/lib/_linklistgeneric-2.js: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * Tools 3 | * General Link List 4 | * Copyright 2015 Sergii Shpak 5 | * MIT License, http://shps.mit-license.org 6 | ************************************************************/ 7 | 8 | /* The main idea of this solution is creation of anonymous Item instances, 9 | * which are linked between themselves and list instance */ 10 | 11 | 12 | var listCounter = 0, 13 | // 'ItemGeneric' is used to profile memory heap snapshot 14 | ItemGeneric = function( id, prev, next, data ) { 15 | 16 | this.id = id; 17 | this.prev = prev; 18 | this.next = next; 19 | this.data = data; 20 | }, 21 | List = function( id ) { 22 | 23 | this.id = id; 24 | this.next = this; 25 | this.prev = this; 26 | 27 | this.append = function( data ) { 28 | return this.next = this.next.prev = 29 | new ItemGeneric(id, this, this.next, data); 30 | }; 31 | 32 | this.remove = function( item ) { 33 | if(!item.prev) return item; 34 | item.next.prev = item.prev; 35 | item.prev.next = item.next; 36 | return item.data; // return item 37 | }; 38 | 39 | this.shift = function() { 40 | return this.remove(this.prev); 41 | }; 42 | 43 | this.peek = function() { 44 | if(this.prev === this) return null; 45 | return this.prev.data; 46 | }; 47 | 48 | this.isEmpty = function() { 49 | return this.next === this; 50 | }; 51 | 52 | this.inList = function(item){ 53 | return this.id === item.id; 54 | } 55 | }; 56 | 57 | module.exports = function( name ) { 58 | return new List(name || "list_" + listCounter++); 59 | }; -------------------------------------------------------------------------------- /submissions/Sergey Shpak/lib/_linklistoriginal.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 'use strict'; 23 | 24 | function init(list) { 25 | list._idleNext = list; 26 | list._idlePrev = list; 27 | } 28 | exports.init = init; 29 | 30 | 31 | // show the most idle item 32 | function peek(list) { 33 | if (list._idlePrev == list) return null; 34 | return list._idlePrev; 35 | } 36 | exports.peek = peek; 37 | 38 | 39 | // remove the most idle item from the list 40 | function shift(list) { 41 | var first = list._idlePrev; 42 | remove(first); 43 | return first; 44 | } 45 | exports.shift = shift; 46 | 47 | 48 | // remove a item from its list 49 | function remove(item) { 50 | if (item._idleNext) { 51 | item._idleNext._idlePrev = item._idlePrev; 52 | } 53 | 54 | if (item._idlePrev) { 55 | item._idlePrev._idleNext = item._idleNext; 56 | } 57 | 58 | item._idleNext = null; 59 | item._idlePrev = null; 60 | } 61 | exports.remove = remove; 62 | 63 | 64 | // remove a item from its list and place at the end. 65 | function append(list, item) { 66 | remove(item); 67 | item._idleNext = list._idleNext; 68 | list._idleNext._idlePrev = item; 69 | item._idlePrev = list; 70 | list._idleNext = item; 71 | } 72 | exports.append = append; 73 | 74 | 75 | function isEmpty(list) { 76 | return list._idleNext === list; 77 | } 78 | exports.isEmpty = isEmpty; -------------------------------------------------------------------------------- /submissions/Sergey Shpak/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generic-link-list", 3 | "version": "0.0.1", 4 | "main": "challenge.js", 5 | "dependencies": { 6 | "benchmark": "~1.0.0", 7 | "heapdump": "~0.3.6" 8 | }, 9 | "readmeFilename": "README.md", 10 | "description": "The challenge: generalize NodeJS's linklist, http://hola.org/challenge_js?l", 11 | "author": { 12 | "name": "Sergey Shpak", 13 | "email": "sergey.shpak.web@gmail.com" 14 | }, 15 | "license": "MIT", 16 | "repository": "" 17 | } 18 | -------------------------------------------------------------------------------- /submissions/Sergii Stryzhevskyi/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Sergii Stryzhevskyi on 6/20/15. 3 | */ 4 | var Benchmark = require('benchmark'); 5 | var LinkedListDefault = require('./lib/_linklist.js'); 6 | var LinkedListArray = require('./lib/_linklist-array.js'); 7 | var LinkedListArrayAdaptive = require('./lib/_linklist-array-adaptive.js'); 8 | var LinkedListMap = require('./lib/_linklist-map.js'); 9 | var LinkedListWeakMap = require('./lib/_linklist-weakmap.js'); 10 | var LinkedListArrayId = require('./lib/_linklist-arrayid.js'); 11 | var LinkedListObject = require('./lib/_linklist-object.js'); 12 | var test = require('./test.js'); 13 | 14 | var assert = { 15 | equal: function () { 16 | }, 17 | ok: function () { 18 | } 19 | }; 20 | var suite = new Benchmark.Suite; 21 | var results = ['\nTest similar to default but with new feature']; 22 | 23 | function runBunch(L, customList) { 24 | test.runTest(L, customList, assert); 25 | 26 | } 27 | // add tests 28 | suite 29 | .add('Default (Joyent\'s) linked list\t', function () { 30 | runBunch(LinkedListDefault, false); 31 | }) 32 | .add('Array (splice) linked list\t', function () { 33 | runBunch(LinkedListArray, true) 34 | }) 35 | .add('Array (adaptive) linked list\t', function () { 36 | runBunch(LinkedListArrayAdaptive, true) 37 | }) 38 | .add('Array of IDs linked list\t', function () { 39 | runBunch(LinkedListArrayId, true) 40 | }) 41 | .add('Object linked list\t\t', function () { 42 | runBunch(LinkedListObject, true) 43 | }) 44 | .add('Map linked list\t\t\t', function () { 45 | runBunch(LinkedListMap, true) 46 | }) 47 | .add('WeakMap linked list\t\t', function () { 48 | runBunch(LinkedListWeakMap, true) 49 | }) 50 | .on('cycle', function (event) { 51 | results.push(String(event.target)); 52 | }) 53 | .on('complete', function () { 54 | results.push('Fastest is ' + this.filter('fastest').pluck('name')); 55 | console.log(results.join('\n')); 56 | }) 57 | .run({'async': true}); -------------------------------------------------------------------------------- /submissions/Sergii Stryzhevskyi/index2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Sergii Stryzhevskyi on 6/20/15. 3 | */ 4 | var Benchmark = require('benchmark'); 5 | var LinkedListDefault = require('./lib/_linklist.js'); 6 | var LinkedListArray = require('./lib/_linklist-array.js'); 7 | var LinkedListArrayAdaptive = require('./lib/_linklist-array-adaptive.js'); 8 | var LinkedListMap = require('./lib/_linklist-map.js'); 9 | var LinkedListWeakMap = require('./lib/_linklist-weakmap.js'); 10 | var LinkedListArrayId = require('./lib/_linklist-arrayid.js'); 11 | var LinkedListObject = require('./lib/_linklist-object.js'); 12 | 13 | var suite = new Benchmark.Suite; 14 | /** 15 | * Change this 1..10000 16 | * @type {number} 17 | */ 18 | var count = 100; 19 | var results = ['\nTest with "append" and "remove" for list with ' + count + ' elements']; 20 | var benchmarks = []; 21 | 22 | function runBunch(L) { 23 | var lists = [], list; 24 | var root = {name : 'root'}; 25 | L.init(root); 26 | for(var i =0;i -1) { 32 | list._.splice(index, 1); 33 | } 34 | } 35 | exports.remove = remove; 36 | 37 | 38 | // remove a item from its list and place at the end. 39 | function append(list, item) { 40 | remove(item, list); 41 | list._.push(item); 42 | } 43 | exports.append = append; 44 | 45 | 46 | function isEmpty(list) { 47 | return list._.length === 0; 48 | } 49 | exports.isEmpty = isEmpty; 50 | -------------------------------------------------------------------------------- /submissions/Sergii Stryzhevskyi/lib/_linklist-arrayid-typed.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var seq = 0, items = Object.create(null); 3 | function init(list) { 4 | list._ = new Int8Array; 5 | list._id = seq++; 6 | items[list._id] = list; 7 | } 8 | exports.init = init; 9 | 10 | 11 | // show the most idle item 12 | function peek(list) { 13 | if(list._.length){ 14 | return items[list._[0]]; 15 | } 16 | return null; 17 | } 18 | exports.peek = peek; 19 | 20 | 21 | // remove the most idle item from the list 22 | function shift(list) { 23 | var first = items[list._[0]]; 24 | remove(first, list); 25 | return first; 26 | } 27 | exports.shift = shift; 28 | 29 | 30 | // remove a item from its list 31 | function remove(item, list) { 32 | var i = 0, index = -1, len = list._.length, id= item._id; 33 | for (; i < len; i++) { 34 | if (list._[i] === id) { 35 | index = i; 36 | break; 37 | } 38 | } 39 | if (index > -1) { 40 | var a = new Array, i = 0; 41 | for(i;i -1) { 40 | var a = new Array, i = 0; 41 | for(i;i", 11 | "license": "ISC", 12 | "dependencies": { 13 | "benchmark": "^1.0.0", 14 | "microtime": "^1.4.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /submissions/Tehila/benchmark/lists/lists_append_benchmark.js: -------------------------------------------------------------------------------- 1 | var common = require('../common.js'); 2 | 3 | var bench = common.createBenchmark(main, { 4 | module: ['_generic_linklist', '_linklist'] 5 | }); 6 | 7 | function main(conf) { 8 | 9 | var module = require(conf.module); 10 | var list = {name: 'list'}; 11 | var item1 = {name: 'A'} 12 | var item2 = {name: 'B'} 13 | 14 | module.init(list); 15 | 16 | module.append(list, item1); 17 | 18 | bench.start(); 19 | 20 | module.append(list, item2); 21 | 22 | bench.end(1); 23 | } 24 | -------------------------------------------------------------------------------- /submissions/Tehila/benchmark/lists/lists_init_benchmark.js: -------------------------------------------------------------------------------- 1 | var common = require('../common.js'); 2 | 3 | var bench = common.createBenchmark(main, { 4 | module: ['_generic_linklist', '_linklist'] 5 | }); 6 | 7 | function main(conf) { 8 | 9 | var module = require(conf.module); 10 | var list = {name: 'list'}; 11 | 12 | bench.start(); 13 | 14 | module.init(list); 15 | 16 | bench.end(1); 17 | } 18 | -------------------------------------------------------------------------------- /submissions/Tehila/benchmark/lists/lists_isempty_benchmark.js: -------------------------------------------------------------------------------- 1 | var common = require('../common.js'); 2 | 3 | var bench = common.createBenchmark(main, { 4 | module: ['_generic_linklist', '_linklist'] 5 | }); 6 | 7 | function main(conf) { 8 | 9 | var module = require(conf.module); 10 | var list = {name: 'list'}; 11 | var item1 = {name: 'A'} 12 | 13 | module.init(list); 14 | module.append(list, item1); 15 | 16 | bench.start(); 17 | 18 | module.isEmpty(list); 19 | 20 | bench.end(1); 21 | } 22 | -------------------------------------------------------------------------------- /submissions/Tehila/benchmark/lists/lists_peek_benchmark.js: -------------------------------------------------------------------------------- 1 | var common = require('../common.js'); 2 | 3 | var bench = common.createBenchmark(main, { 4 | module: ['_generic_linklist', '_linklist'] 5 | }); 6 | 7 | function main(conf) { 8 | 9 | var module = require(conf.module); 10 | var list = {name: 'list'}; 11 | var item1 = {name: 'A'} 12 | 13 | 14 | module.init(list); 15 | module.append(list, item1); 16 | 17 | bench.start(); 18 | 19 | module.peek(list); 20 | 21 | bench.end(1); 22 | } 23 | -------------------------------------------------------------------------------- /submissions/Tehila/benchmark/lists/lists_remove_benchmark.js: -------------------------------------------------------------------------------- 1 | var common = require('../common.js'); 2 | 3 | var bench = common.createBenchmark(main, { 4 | module: ['_generic_linklist', '_linklist'] 5 | }); 6 | 7 | function main(conf) { 8 | 9 | var module = require(conf.module); 10 | var list = {name: 'list'}; 11 | var item1 = {name: 'A'} 12 | var item2 = {name: 'B'} 13 | var item3 = {name: 'C'} 14 | 15 | 16 | module.init(list); 17 | module.append(list, item1); 18 | module.append(list, item2); 19 | module.append(list, item3); 20 | 21 | bench.start(); 22 | 23 | module.remove(item3, list); 24 | 25 | bench.end(1); 26 | } 27 | -------------------------------------------------------------------------------- /submissions/Tehila/benchmark/lists/lists_shift_benchmark.js: -------------------------------------------------------------------------------- 1 | var common = require('../common.js'); 2 | 3 | var bench = common.createBenchmark(main, { 4 | module: ['_generic_linklist', '_linklist'] 5 | }); 6 | 7 | function main(conf) { 8 | 9 | var module = require(conf.module); 10 | var list = {name: 'list'}; 11 | var item1 = {name: 'A'} 12 | var item2 = {name: 'B'} 13 | 14 | module.init(list); 15 | module.append(list, item1); 16 | module.append(list, item2); 17 | 18 | bench.start(); 19 | 20 | module.shift(list); 21 | 22 | bench.end(1); 23 | } 24 | -------------------------------------------------------------------------------- /submissions/Tehila/lib/_generic_linklist.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function init(list) { 4 | list._next = list; 5 | list._prev = list; 6 | list._tail = list; 7 | } 8 | exports.init = init; 9 | 10 | 11 | // show the most idle item 12 | function peek(list) { 13 | if (list._tail == list) 14 | return null; 15 | return list._next; 16 | } 17 | exports.peek = peek; 18 | 19 | 20 | // remove the most idle item from the list 21 | function shift(list) { 22 | var first = list._next; 23 | remove(first, list); 24 | return first; 25 | } 26 | exports.shift = shift; 27 | 28 | 29 | // remove a item from its list 30 | function remove(item, list) { 31 | var itemTail = getItemTail(item); 32 | if (itemTail._next) { 33 | itemTail._next._prev = item._prev; 34 | } 35 | 36 | if (item._prev) { 37 | item._prev._next = itemTail._next; 38 | } 39 | 40 | if (list._tail == itemTail) { 41 | list._tail = item._prev; 42 | } 43 | 44 | if (item._tail) { 45 | itemTail._next = item; 46 | item._prev = itemTail; 47 | } 48 | else { 49 | item._next = null; 50 | item._prev = null; 51 | } 52 | 53 | } 54 | exports.remove = remove; 55 | 56 | 57 | // remove a item from its list and place at the end. 58 | function append(list, item) { 59 | remove(item, list); 60 | var itemTail = getItemTail(item); 61 | itemTail._next = list; 62 | item._prev = list._prev; 63 | list._prev._next = item; 64 | list._prev = itemTail 65 | list._tail = itemTail; 66 | } 67 | exports.append = append; 68 | 69 | 70 | function isEmpty(list) { 71 | return list._tail == list; 72 | } 73 | exports.isEmpty = isEmpty; 74 | 75 | 76 | function isList(item) { 77 | return item._tail != undefined; 78 | } 79 | exports.isList = isList; 80 | 81 | 82 | function getItemTail(item) { 83 | if (item._tail) 84 | return item._tail; 85 | return item; 86 | } 87 | 88 | -------------------------------------------------------------------------------- /submissions/Tehila/lib/_linklist.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 'use strict'; 23 | 24 | function init(list) { 25 | list._idleNext = list; 26 | list._idlePrev = list; 27 | } 28 | exports.init = init; 29 | 30 | 31 | // show the most idle item 32 | function peek(list) { 33 | if (list._idlePrev == list) return null; 34 | return list._idlePrev; 35 | } 36 | exports.peek = peek; 37 | 38 | 39 | // remove the most idle item from the list 40 | function shift(list) { 41 | var first = list._idlePrev; 42 | remove(first); 43 | return first; 44 | } 45 | exports.shift = shift; 46 | 47 | 48 | // remove a item from its list 49 | function remove(item) { 50 | if (item._idleNext) { 51 | item._idleNext._idlePrev = item._idlePrev; 52 | } 53 | 54 | if (item._idlePrev) { 55 | item._idlePrev._idleNext = item._idleNext; 56 | } 57 | 58 | item._idleNext = null; 59 | item._idlePrev = null; 60 | } 61 | exports.remove = remove; 62 | 63 | 64 | // remove a item from its list and place at the end. 65 | function append(list, item) { 66 | remove(item); 67 | item._idleNext = list._idleNext; 68 | list._idleNext._idlePrev = item; 69 | item._idlePrev = list; 70 | list._idleNext = item; 71 | } 72 | exports.append = append; 73 | 74 | 75 | function isEmpty(list) { 76 | return list._idleNext === list; 77 | } 78 | exports.isEmpty = isEmpty; 79 | -------------------------------------------------------------------------------- /submissions/Tehila/test/lists/test-generic-linked-list-4-level-list.js: -------------------------------------------------------------------------------- 1 | 2 | var common = require('../common'); 3 | var assert = require('assert'); 4 | var L = require('_generic_linklist'); 5 | var list = { name: 'list' }; 6 | var q1 = { name: 'q1' }; 7 | var q2 = { name: 'q2' }; 8 | var q11 = { name: 'q11' }; 9 | var q12 = { name: 'q12' }; 10 | var q21 = { name: 'q21' }; 11 | var q22 = { name: 'q22' }; 12 | var q111 = { name: 'q111' }; 13 | var q112 = { name: 'q112' }; 14 | var q121 = { name: 'q121' }; 15 | var q122 = { name: 'q122' }; 16 | var q211 = { name: 'q211' }; 17 | var q212 = { name: 'q212' }; 18 | var q221 = { name: 'q221' }; 19 | var q222 = { name: 'q222' }; 20 | var q111I1 = { name: 'q111I1' }; 21 | var q111I2 = { name: 'q111I2' }; 22 | var q112I1 = { name: 'q112I1' }; 23 | var q112I2 = { name: 'q112I2' }; 24 | var q121I1 = { name: 'q121I1' }; 25 | var q121I2 = { name: 'q121I2' }; 26 | var q122I1 = { name: 'q122I1' }; 27 | var q122I2 = { name: 'q122I2' }; 28 | var q211I1 = { name: 'q211I1' }; 29 | var q211I2 = { name: 'q211I2' }; 30 | var q212I1 = { name: 'q212I1' }; 31 | var q212I2 = { name: 'q212I2' }; 32 | var q221I1 = { name: 'q221I1' }; 33 | var q221I2 = { name: 'q221I2' }; 34 | var q222I1 = { name: 'q222I1' }; 35 | var q222I2 = { name: 'q222I2' }; 36 | 37 | L.init(q1); 38 | L.init(q2); 39 | L.init(q11); 40 | L.init(q12); 41 | L.init(q21); 42 | L.init(q22); 43 | L.init(q111); 44 | L.init(q112); 45 | L.init(q121); 46 | L.init(q122); 47 | L.init(q211); 48 | L.init(q212); 49 | L.init(q221); 50 | L.init(q222); 51 | L.init(list); 52 | 53 | L.append(q111, q111I1); 54 | L.append(q111, q111I2); 55 | L.append(q112, q112I1); 56 | L.append(q112, q112I2); 57 | L.append(q121, q121I1); 58 | L.append(q121, q121I2); 59 | L.append(q122, q122I1); 60 | L.append(q122, q122I2); 61 | L.append(q211, q211I1); 62 | L.append(q211, q211I2); 63 | L.append(q212, q212I1); 64 | L.append(q212, q212I2); 65 | L.append(q221, q221I1); 66 | L.append(q221, q221I2); 67 | L.append(q222, q222I1); 68 | L.append(q222, q222I2); 69 | 70 | L.append(q11, q111); 71 | L.append(q11, q112); 72 | 73 | L.append(q12, q121); 74 | L.append(q12, q122); 75 | 76 | L.append(q21, q211); 77 | L.append(q21, q212); 78 | 79 | L.append(q22, q221); 80 | L.append(q22, q222); 81 | 82 | L.append(q1, q11); 83 | L.append(q1, q12); 84 | 85 | L.append(q2, q21); 86 | L.append(q2, q22); 87 | 88 | L.append(list, q1); 89 | L.append(list, q2); 90 | 91 | assert.equal(q1, L.peek(list)); 92 | assert.equal(q11, L.peek(q1)); 93 | assert.equal(q21, L.peek(q2)); 94 | assert.equal(q111, L.peek(q11)); 95 | assert.equal(q121, L.peek(q12)); 96 | assert.equal(q211, L.peek(q21)); 97 | assert.equal(q221, L.peek(q22)); 98 | 99 | assert.equal(q111I1, L.peek(q111)); 100 | assert.equal(q112I1, L.peek(q112)); 101 | assert.equal(q121I1, L.peek(q121)); 102 | assert.equal(q122I1, L.peek(q122)); 103 | assert.equal(q211I1, L.peek(q211)); 104 | assert.equal(q212I1, L.peek(q212)); 105 | assert.equal(q221I1, L.peek(q221)); 106 | assert.equal(q222I1, L.peek(q222)); 107 | 108 | L.remove(q112, q11); 109 | L.remove(q12, q1); 110 | L.append(list, q112); 111 | assert.equal(q112I1, L.peek(q112)); 112 | assert.equal(q111, L.peek(q11)); 113 | assert.equal(q1, L.peek(list)); 114 | assert.equal(q1, L.shift(list)); 115 | assert.equal(q2, L.shift(list)); 116 | assert.equal(q112, L.peek(list)); 117 | assert.equal(q11, L.shift(q1)); 118 | assert.equal(null, L.peek(q1)); -------------------------------------------------------------------------------- /submissions/Tehila/test/lists/test-generic-linked-list-idle-items-and-empty-list.js: -------------------------------------------------------------------------------- 1 | 2 | var common = require('../common'); 3 | var assert = require('assert'); 4 | var L = require('_generic_linklist'); 5 | 6 | 7 | var list = { name: 'list' }; 8 | var listB = { name: 'listB' }; 9 | 10 | var A = { name: 'A' }; 11 | var C = { name: 'C' }; 12 | var D = { name: 'D' }; 13 | 14 | L.init(list); 15 | L.init(listB); 16 | 17 | assert.ok(L.isEmpty(list)); 18 | assert.equal(null, L.peek(list)); 19 | assert.ok(L.isEmpty(listB)); 20 | assert.equal(null, L.peek(listB)); 21 | 22 | L.append(list, A); 23 | // list -> A 24 | assert.equal(A, L.peek(list)); 25 | 26 | L.append(list, listB); 27 | // list -> A -> listB 28 | assert.equal(A, L.peek(list)); 29 | 30 | L.append(list, C); 31 | // list -> A -> listB -> C 32 | assert.equal(A, L.peek(list)); 33 | 34 | L.append(list, D); 35 | // list -> A -> listB -> C -> D 36 | assert.equal(A, L.peek(list)); 37 | 38 | var x = L.shift(list); 39 | assert.equal(A, x); 40 | // list -> listB -> C -> D 41 | assert.equal(listB, L.peek(list)); 42 | 43 | x = L.shift(list); 44 | assert.equal(listB, x); 45 | // list -> C -> D 46 | assert.equal(C, L.peek(list)); 47 | 48 | // listB is already removed, so removing it again shouldn't hurt. 49 | L.remove(listB, list); 50 | // list -> C -> D 51 | assert.equal(C, L.peek(list)); 52 | 53 | // Put listB back on the list 54 | L.append(list, listB); 55 | // list -> C -> D -> listB 56 | assert.equal(C, L.peek(list)); 57 | 58 | L.remove(C, list); 59 | // list -> D -> listB 60 | assert.equal(D, L.peek(list)); 61 | 62 | L.remove(listB, list); 63 | // list -> D 64 | assert.equal(D, L.peek(list)); 65 | 66 | L.remove(D, list); 67 | // list 68 | assert.equal(null, L.peek(list)); 69 | 70 | 71 | assert.ok(L.isEmpty(list)); 72 | 73 | 74 | L.append(list, D); 75 | // list -> D 76 | assert.equal(D, L.peek(list)); 77 | 78 | L.append(list, C); 79 | L.append(list, listB); 80 | L.append(list, A); 81 | // list -> D -> C -> listB -> A 82 | 83 | // Append should REMOVE C from the list and append it to the end. 84 | L.append(list, C); 85 | 86 | // list -> D -> listB -> A -> C 87 | assert.equal(D, L.shift(list)); 88 | // list -> listB -> A -> C 89 | assert.equal(listB, L.peek(list)); 90 | assert.equal(listB, L.shift(list)); 91 | // list -> A -> C 92 | assert.equal(A, L.peek(list)); 93 | assert.equal(A, L.shift(list)); 94 | // list -> C 95 | assert.equal(C, L.peek(list)); 96 | assert.equal(C, L.shift(list)); 97 | // list 98 | assert.ok(L.isEmpty(list)); 99 | 100 | -------------------------------------------------------------------------------- /submissions/Tehila/test/lists/test-generic-linked-list-idle-items.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | var common = require('../common'); 23 | var assert = require('assert'); 24 | var L = require('_generic_linklist'); 25 | 26 | 27 | var list = { name: 'list' }; 28 | var A = { name: 'A' }; 29 | var B = { name: 'B' }; 30 | var C = { name: 'C' }; 31 | var D = { name: 'D' }; 32 | 33 | L.init(list); 34 | 35 | assert.ok(L.isEmpty(list)); 36 | assert.equal(null, L.peek(list)); 37 | 38 | L.append(list, A); 39 | // list -> A 40 | assert.equal(A, L.peek(list)); 41 | 42 | L.append(list, B); 43 | // list -> A -> B 44 | assert.equal(A, L.peek(list)); 45 | 46 | L.append(list, C); 47 | // list -> A -> B -> C 48 | assert.equal(A, L.peek(list)); 49 | 50 | L.append(list, D); 51 | // list -> A -> B -> C -> D 52 | assert.equal(A, L.peek(list)); 53 | 54 | var x = L.shift(list); 55 | assert.equal(A, x); 56 | // list -> B -> C -> D 57 | assert.equal(B, L.peek(list)); 58 | 59 | x = L.shift(list); 60 | assert.equal(B, x); 61 | // list -> C -> D 62 | assert.equal(C, L.peek(list)); 63 | 64 | // B is already removed, so removing it again shouldn't hurt. 65 | L.remove(B, list); 66 | // list -> C -> D 67 | assert.equal(C, L.peek(list)); 68 | 69 | // Put B back on the list 70 | L.append(list, B); 71 | // list -> C -> D -> B 72 | assert.equal(C, L.peek(list)); 73 | 74 | L.remove(C, list); 75 | // list -> D -> B 76 | assert.equal(D, L.peek(list)); 77 | 78 | L.remove(B, list); 79 | // list -> D 80 | assert.equal(D, L.peek(list)); 81 | 82 | L.remove(D, list); 83 | // list 84 | assert.equal(null, L.peek(list)); 85 | 86 | 87 | assert.ok(L.isEmpty(list)); 88 | 89 | 90 | L.append(list, D); 91 | // list -> D 92 | assert.equal(D, L.peek(list)); 93 | 94 | L.append(list, C); 95 | L.append(list, B); 96 | L.append(list, A); 97 | // list -> D -> C -> B -> A 98 | 99 | // Append should REMOVE C from the list and append it to the end. 100 | L.append(list, C); 101 | 102 | // list -> D -> B -> A -> C 103 | assert.equal(D, L.shift(list)); 104 | // list -> B -> A -> C 105 | assert.equal(B, L.peek(list)); 106 | assert.equal(B, L.shift(list)); 107 | // list -> A -> C 108 | assert.equal(A, L.peek(list)); 109 | assert.equal(A, L.shift(list)); 110 | // list -> C 111 | assert.equal(C, L.peek(list)); 112 | assert.equal(C, L.shift(list)); 113 | // list 114 | assert.ok(L.isEmpty(list)); 115 | 116 | -------------------------------------------------------------------------------- /submissions/Vasiliy Kostin/js.node.megabyte.templated/_linklist.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 'use strict'; 23 | 24 | function init(list) { 25 | list._idleNext = list; 26 | list._idlePrev = list; 27 | } 28 | module.exports.init = init; 29 | 30 | 31 | // show the most idle item 32 | function peek(list) { 33 | if (list._idlePrev == list) return null; 34 | return list._idlePrev; 35 | } 36 | exports.peek = peek; 37 | 38 | 39 | // remove the most idle item from the list 40 | function shift(list) { 41 | var first = list._idlePrev; 42 | remove(first); 43 | return first; 44 | } 45 | exports.shift = shift; 46 | 47 | 48 | // remove a item from its list 49 | function remove(item) { 50 | if (item._idleNext) { 51 | item._idleNext._idlePrev = item._idlePrev; 52 | } 53 | 54 | if (item._idlePrev) { 55 | item._idlePrev._idleNext = item._idleNext; 56 | } 57 | 58 | item._idleNext = null; 59 | item._idlePrev = null; 60 | } 61 | exports.remove = remove; 62 | 63 | 64 | // remove a item from its list and place at the end. 65 | function append(list, item) { 66 | remove(item); 67 | item._idleNext = list._idleNext; 68 | list._idleNext._idlePrev = item; 69 | item._idlePrev = list; 70 | list._idleNext = item; 71 | } 72 | exports.append = append; 73 | 74 | 75 | function isEmpty(list) { 76 | return list._idleNext === list; 77 | } 78 | exports.isEmpty = isEmpty; -------------------------------------------------------------------------------- /submissions/Vasiliy Kostin/js.node.megabyte.templated/_multilinklist.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var listsNamesCounter=0; 4 | 5 | function requireFromString(src, filename) 6 | { 7 | var Module = module.constructor; 8 | var m = new Module(); 9 | m._compile(src, filename); 10 | return m.exports; 11 | } 12 | 13 | function getListInstance() 14 | { 15 | var fs = require('fs'); 16 | var tmp = fs.readFileSync('_template.js', "utf8"); 17 | tmp = tmp.replace(new RegExp('␞', 'g'), listsNamesCounter); 18 | 19 | var ret = requireFromString(tmp,'_template'+listsNamesCounter+'.js'); 20 | 21 | listsNamesCounter++; 22 | ret.init(); 23 | return ret; 24 | } 25 | module.exports.getListInstance = getListInstance; 26 | -------------------------------------------------------------------------------- /submissions/Vasiliy Kostin/js.node.megabyte.templated/_template.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 'use strict'; 23 | 24 | function init() { 25 | this._idleNext␞ = this; 26 | this._idlePrev␞ = this; 27 | } 28 | module.exports.init = init; 29 | 30 | 31 | // show the most idle item 32 | function peek() { 33 | if (this._idlePrev␞ == this) return null; 34 | return this._idlePrev␞; 35 | } 36 | module.exports.peek = peek; 37 | 38 | 39 | // remove the most idle item from the list 40 | function shift() { 41 | var first = this._idlePrev␞; 42 | remove(first); 43 | return first; 44 | } 45 | module.exports.shift = shift; 46 | 47 | 48 | // remove a item from its list 49 | function remove(item) { 50 | if (item._idleNext␞) { 51 | item._idleNext␞._idlePrev␞ = item._idlePrev␞; 52 | } 53 | 54 | if (item._idlePrev␞) { 55 | item._idlePrev␞._idleNext␞ = item._idleNext␞; 56 | } 57 | 58 | item._idleNext␞ = null; 59 | item._idlePrev␞ = null; 60 | } 61 | module.exports.remove = remove; 62 | 63 | 64 | // remove a item from its list and place at the end. 65 | function append(item) { 66 | remove(item); 67 | item._idleNext␞ = this._idleNext␞; 68 | this._idleNext␞._idlePrev␞ = item; 69 | item._idlePrev␞ = this; 70 | this._idleNext␞ = item; 71 | } 72 | module.exports.append = append; 73 | 74 | 75 | function isEmpty() { 76 | return this._idleNext␞ === this; 77 | } 78 | module.exports.isEmpty = isEmpty; -------------------------------------------------------------------------------- /submissions/Vasiliy Kostin/js.node.megabyte/_linklist.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 'use strict'; 23 | 24 | function init(list) { 25 | list._idleNext = list; 26 | list._idlePrev = list; 27 | } 28 | module.exports.init = init; 29 | 30 | 31 | // show the most idle item 32 | function peek(list) { 33 | if (list._idlePrev == list) return null; 34 | return list._idlePrev; 35 | } 36 | exports.peek = peek; 37 | 38 | 39 | // remove the most idle item from the list 40 | function shift(list) { 41 | var first = list._idlePrev; 42 | remove(first); 43 | return first; 44 | } 45 | exports.shift = shift; 46 | 47 | 48 | // remove a item from its list 49 | function remove(item) { 50 | if (item._idleNext) { 51 | item._idleNext._idlePrev = item._idlePrev; 52 | } 53 | 54 | if (item._idlePrev) { 55 | item._idlePrev._idleNext = item._idleNext; 56 | } 57 | 58 | item._idleNext = null; 59 | item._idlePrev = null; 60 | } 61 | exports.remove = remove; 62 | 63 | 64 | // remove a item from its list and place at the end. 65 | function append(list, item) { 66 | remove(item); 67 | item._idleNext = list._idleNext; 68 | list._idleNext._idlePrev = item; 69 | item._idlePrev = list; 70 | list._idleNext = item; 71 | } 72 | exports.append = append; 73 | 74 | 75 | function isEmpty(list) { 76 | return list._idleNext === list; 77 | } 78 | exports.isEmpty = isEmpty; -------------------------------------------------------------------------------- /submissions/Vasiliy Kostin/js.node.megabyte/_multilinklist.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 23 | //modified for multi-listing by Megabyte 24 | 25 | 'use strict'; 26 | 27 | var listsNamesCounter=0; 28 | 29 | function init(list) { 30 | 31 | list.id=listsNamesCounter; 32 | listsNamesCounter++; 33 | 34 | 35 | list._idleNext = list; 36 | list._idlePrev = list; 37 | } 38 | exports.init = init; 39 | 40 | 41 | // show the most idle item 42 | function peek(list) { 43 | if (list._idlePrev == list) return null; 44 | return list._idlePrev.value; 45 | } 46 | exports.peek = peek; 47 | 48 | 49 | // remove the most idle item from the list 50 | function shift(list) { 51 | var first = list._idlePrev; 52 | _remove_raw(list, first); 53 | 54 | return first.value; 55 | 56 | } 57 | exports.shift = shift; 58 | 59 | 60 | // remove a item from its list 61 | function remove(list,item) { 62 | var raw_item=item._lists[list.id]; 63 | if(raw_item) 64 | { 65 | _remove_raw(list,raw_item); 66 | } 67 | } 68 | exports.remove = remove; 69 | 70 | 71 | function _remove_raw(list,raw_item) { 72 | 73 | if (raw_item._idleNext) { 74 | raw_item._idleNext._idlePrev = raw_item._idlePrev; 75 | } 76 | 77 | if (raw_item._idlePrev) { 78 | raw_item._idlePrev._idleNext = raw_item._idleNext; 79 | } 80 | 81 | raw_item._idleNext = null; 82 | raw_item._idlePrev = null; 83 | } 84 | 85 | 86 | // remove a item from its list and place at the end. 87 | function append(list, item) { 88 | if(item._lists) 89 | { 90 | //prevent twice adding in to one list 91 | var raw_item=item._lists[list.id]; 92 | if(raw_item) 93 | { 94 | _remove_raw(list,raw_item); 95 | } 96 | } 97 | else 98 | { 99 | item._lists=[]; 100 | } 101 | 102 | if(!raw_item) 103 | { 104 | 105 | //low performance here 106 | 107 | raw_item = {value:item, _idleNext: list._idleNext,_idlePrev:list}; 108 | 109 | item._lists[list.id]=raw_item; 110 | } 111 | else 112 | { 113 | raw_item._idleNext=list._idleNext; 114 | raw_item._idlePrev=list; 115 | } 116 | 117 | list._idleNext._idlePrev = raw_item; 118 | 119 | list._idleNext = raw_item; 120 | } 121 | exports.append = append; 122 | 123 | 124 | function isEmpty(list) { 125 | return list._idleNext === list; 126 | } 127 | exports.isEmpty = isEmpty; -------------------------------------------------------------------------------- /submissions/Vasiliy Kostin/js.node.megabyte/benchmark.js: -------------------------------------------------------------------------------- 1 | //Megabyte 2015 2 | 3 | var _linklist = require('./_linklist'); 4 | var _multilinklist = require('./_multilinklist'); 5 | 6 | echo('benchmark begin'); 7 | echo(''); 8 | 9 | var ITERATIONS=400000; 10 | 11 | var results=[]; 12 | results.push('sdasd'); 13 | 14 | 15 | testList(_linklist, 'OLD'); 16 | 17 | 18 | testList(_multilinklist, 'NEW MULTI'); 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | echo('benchmark end'); 27 | echo('Press any key to exit...'); 28 | process.stdin.setRawMode(true); 29 | process.stdin.resume(); 30 | process.stdin.on('data', process.exit.bind(process, 0)); 31 | 32 | 33 | 34 | function testList(l, listName) 35 | { 36 | var list1; 37 | var list2; 38 | benchmarkFunctions([ 39 | 40 | listName+' list testing:', 41 | function () 42 | { 43 | list1={}; 44 | list2={}; 45 | echo('Initialisation lists', true); 46 | 47 | l.init(list1); 48 | l.init(list2); 49 | echo('list1 is empty: '+l.isEmpty(list1)); 50 | echo('list2 is empty: '+l.isEmpty(list2)); 51 | 52 | }, 53 | 54 | //------------------------------------------------------------ 55 | 'Adding '+ITERATIONS+' robots in to list1', 56 | function () 57 | { 58 | 59 | for(var i = 0; i 0) 136 | { 137 | var title=functions.shift(); 138 | if(title) 139 | { 140 | echo(title,true); 141 | var f = functions.shift(); 142 | if(f) 143 | { 144 | _benchmarkFunctionInside(f); 145 | echo(''); 146 | } 147 | } 148 | } 149 | } 150 | 151 | rTime=0; 152 | function rememberTime() 153 | { 154 | var d = new Date(); 155 | rTime = d.getTime(); 156 | } 157 | function echoElapsedTime() 158 | { 159 | 160 | var d = new Date(); 161 | var eTime = (d.getTime()-rTime); 162 | echo ('time elapsed: '+eTime+' ms'); 163 | return eTime; 164 | } 165 | 166 | function echo(txt,isBold) 167 | { 168 | if(isBold) 169 | { 170 | txt='-='+txt+'=-'; 171 | } 172 | console.log(txt); 173 | } 174 | 175 | --------------------------------------------------------------------------------