Created
July 17, 2012 23:59
-
-
Save Janiczek/3133037 to your computer and use it in GitHub Desktop.
Binary search in Erlang
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| %% I wondered if I'm in the 10% of devs that can write binary search correctly: | |
| %% http://reprog.wordpress.com/2010/04/19/are-you-one-of-the-10-percent/ | |
| %% The automated test cases at http://www.mac-guyver.com/switham/2010/04/Binary_Search/ | |
| %% (edited for Erlang below) say I am. Well, nice to know :) | |
| -module(binary_search). | |
| -export([binary_search/2]). | |
| -include_lib("eunit/include/eunit.hrl"). | |
| binary_search(List, N) -> | |
| Length = length(List), | |
| Middle = (Length + 1) div 2, %% saves us hassle with odd/even indexes | |
| case Middle of | |
| 0 -> -1; %% empty list -> item not found | |
| _ -> | |
| Item = lists:nth(Middle, List), | |
| case Item of | |
| N -> Middle; %% yay, found it! | |
| _ -> case Item > N of | |
| true -> binary_search(lists:sublist(List, Length - Middle), N); %% LT, search on left side | |
| false -> binary_search(lists:nthtail(Middle, List), N) %% GT, search on right side | |
| end | |
| end | |
| end. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| run: | |
| erlc binary_search.erl | |
| erl -noshell -s binary_search test -s init stop | |
| tests: | |
| python write_tests.py >binary_search_tests.erl | |
| erlc binary_search_tests.erl | |
| all: tests run |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $ make all | |
| python write_tests.py >binary_search_tests.erl | |
| erlc binary_search_tests.erl | |
| erlc binary_search.erl | |
| erl -noshell -s binary_search test -s init stop | |
| All 4096 tests passed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python | |
| # based on http://www.mac-guyver.com/switham/2010/04/Binary_Search/ | |
| # edited for Erlang :) | |
| # now essentially prints out a file with all the EUnit tests | |
| from random import * | |
| # 0.0 <= random() < 1.0; a <= randrange( a, b ) < b for int(a) < int(b). | |
| if __name__ == "__main__": | |
| print "-module(binary_search_tests)." | |
| print "-include_lib(\"eunit/include/eunit.hrl\")." | |
| for n in range( 1, 4097 ): | |
| size = int( 2.0 ** (random() * 8) - 1 ) # size can be zero. | |
| if random() < .5: | |
| A = range( size ) # every number in range | |
| else: | |
| A = [ randrange(size) for i in range(size) ] # random numbers | |
| A.sort() | |
| want_there = size > 0 and random() < .5 | |
| if want_there: | |
| T = A[ randrange(size) ] | |
| else: | |
| theres = dict( [ ( x, True ) for x in A ] ) | |
| not_theres = [ x for x in range( -1, size+1 ) if not x in theres ] | |
| T = not_theres[ randrange( len(not_theres) ) ] | |
| is_there = T in A | |
| assert( is_there == want_there ) | |
| print "a_%d_test() ->" % (n) | |
| print " ?assert%s(binary_search:binary_search(%s, %d) =:= -1)." % (["","Not"][is_there], A, T) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It seems like this solution does not return the index of the element. So I created another one based on your solution which returns the index.
https://gist.github.com/ColdFreak/888e9a0a5cbed5ddc1a3