This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,4 @@
USING: binary-search kernel math.order ;
: binary-search ( seq elt -- index/f )
[ [ <=> ] curry search ] keep = [ drop f ] unless ;

View file

@ -0,0 +1,23 @@
Find := function(v, x)
local low, high, mid;
low := 1;
high := Length(v);
while low <= high do
mid := QuoInt(low + high, 2);
if v[mid] > x then
high := mid - 1;
elif v[mid] < x then
low := mid + 1;
else
return mid;
fi;
od;
return fail;
end;
u := [1..10]*7;
# [ 7, 14, 21, 28, 35, 42, 49, 56, 63, 70 ]
Find(u, 34);
# fail
Find(u, 35);
# 5

View file

@ -0,0 +1,12 @@
def binSearchR
binSearchR = { a, target, offset=0 ->
def n = a.size()
def m = n.intdiv(2)
a.empty \
? ["insertion point": offset] \
: a[m] > target \
? binSearchR(a[0..<m], target, offset) \
: a[m] < target \
? binSearchR(a[(m + 1)..<n], target, offset + m + 1) \
: [index: offset + m]
}

View file

@ -0,0 +1,17 @@
def binSearchI = { aList, target ->
def a = aList
def offset = 0
while (!a.empty) {
def n = a.size()
def m = n.intdiv(2)
if(a[m] > target) {
a = a[0..<m]
} else if (a[m] < target) {
a = a[(m + 1)..<n]
offset += m + 1
} else {
return [index: offset + m]
}
}
return ["insertion point": offset]
}

View file

@ -0,0 +1,17 @@
def a = [] as Set
def random = new Random()
while (a.size() < 20) { a << random.nextInt(30) }
def source = a.sort()
source[0..-2].eachWithIndex { si, i -> assert si < source[i+1] }
println "${source}"
1.upto(5) {
target = random.nextInt(10) + (it - 2) * 10
print "Trial #${it}. Looking for: ${target}"
def answers = [binSearchR, binSearchI].collect { search ->
search(source, target)
}
assert answers[0] == answers[1]
println """
Answer: ${answers[0]}, : ${source[answers[0].values().iterator().next()]}"""
}

View file

@ -0,0 +1,32 @@
REAL :: n=10, array(n)
array = NINT( RAN(n) )
SORT(Vector=array, Sorted=array)
x = NINT( RAN(n) )
idx = binarySearch( array, x )
WRITE(ClipBoard) x, "has position ", idx, "in ", array
END
FUNCTION binarySearch(A, value)
REAL :: A(1), value
low = 1
high = LEN(A)
DO i = 1, high
IF( low > high) THEN
binarySearch = 0
RETURN
ELSE
mid = INT( (low + high) / 2 )
IF( A(mid) > value) THEN
high = mid - 1
ELSEIF( A(mid) < value ) THEN
low = mid + 1
ELSE
binarySearch = mid
RETURN
ENDIF
ENDIF
ENDDO
END

View file

@ -0,0 +1,2 @@
7 has position 9 in 0 0 1 2 3 3 4 6 7 8
5 has position 0 in 0 0 1 2 3 3 4 6 7 8

View file

@ -0,0 +1,11 @@
procedure binsearch(A, target)
if *A = 0 then fail
mid := *A/2 + 1
if target > A[mid] then {
return mid + binsearch(A[(mid+1):0], target)
}
else if target < A[mid] then {
return binsearch(A[1+:(mid-1)], target)
}
return mid
end

View file

@ -0,0 +1,13 @@
procedure main(args)
target := integer(!args) | 3
every put(A := [], 1 to 18 by 2)
outList("Searching", A)
write(target," is ",("at "||binsearch(A, target)) | "not found")
end
procedure outList(prefix, A)
writes(prefix,": ")
every writes(!A," ")
write()
end

View file

@ -0,0 +1 @@
bs=. i. 'Not Found'"_^:(-.@-:) I.

View file

@ -0,0 +1,4 @@
2 3 5 6 8 10 11 15 19 20 bs 11
6
2 3 5 6 8 10 11 15 19 20 bs 12
Not Found

View file

@ -0,0 +1,13 @@
'X Y L H M'=. i.5 NB. Setting mnemonics for boxes
f=. &({::) NB. Fetching the contents of a box
o=. @: NB. Composing verbs (functions)
boxes=. ; , a: $~ 3: NB. Appending 3 (empty) boxes to the inputs
LowHigh=. (0 ; # o (X f)) (L,H)} ] NB. Setting the low and high bounds
midpoint=. < o (<. o (2 %~ L f + H f)) M} ] NB. Updating the midpoint
case=. >: o * o (Y f - M f { X f) NB. Less=0, equal=1, or greater=2
squeeze=. (< o (_1 + M f) H} ])`(< o _: L} ])`(< o (1 + M f) L} ])@.case
return=. (M f) o ((<@:('Not Found'"_) M} ]) ^: (_ ~: L f))
bs=. return o (squeeze o midpoint ^: (L f <: H f) ^:_) o LowHigh o boxes

View file

@ -0,0 +1,11 @@
'X Y L H M'=. i.5 NB. Setting mnemonics for boxes
f=. &({::) NB. Fetching the contents of a box
o=. @: NB. Composing verbs (functions)
boxes=. a: ,~ ; NB. Appending 1 (empty) box to the inputs
midpoint=. < o (<. o (2 %~ L f + H f)) M} ] NB. Updating the midpoint
case=. >: o * o (Y f - M f { X f) NB. Less=0, equal=1, or greater=2
recur=. (X f bs Y f ; L f ; (_1 + M f))`(M f)`(X f bs Y f ; (1 + M f) ; H f)@.case
bs=. (recur o midpoint`('Not Found'"_) @. (H f < L f) o boxes) :: ([ bs ] ; 0 ; (<: o # o [))

View file

@ -0,0 +1,19 @@
dim theArray(100)
for i = 1 to 100
theArray(i) = i
next i
print binarySearch(80,30,90)
wait
FUNCTION binarySearch(val, lo, hi)
IF hi < lo THEN
binarySearch = 0
ELSE
middle = int((hi + lo) / 2):print middle
if val < theArray(middle) then binarySearch = binarySearch(val, lo, middle-1)
if val > theArray(middle) then binarySearch = binarySearch(val, middle+1, hi)
if val = theArray(middle) then binarySearch = middle
END IF
END FUNCTION

View file

@ -0,0 +1,7 @@
to bsearch :value :a :lower :upper
if :upper < :lower [output []]
localmake "mid int (:lower + :upper) / 2
if item :mid :a > :value [output bsearch :value :a :lower :mid-1]
if item :mid :a < :value [output bsearch :value :a :mid+1 :upper]
output :mid
end

View file

@ -0,0 +1,10 @@
define(`notfound',`-1')dnl
define(`midsearch',`ifelse(defn($1[$4]),$2,$4,
`ifelse(eval(defn($1[$4])>$2),1,`binarysearch($1,$2,$3,decr($4))',`binarysearch($1,$2,incr($4),$5)')')')dnl
define(`binarysearch',`ifelse(eval($4<$3),1,notfound,`midsearch($1,$2,$3,eval(($3+$4)/2),$4)')')dnl
dnl
define(`setrange',`ifelse(`$3',`',$2,`define($1[$2],$3)`'setrange($1,incr($2),shift(shift(shift($@))))')')dnl
define(`asize',decr(setrange(`a',1,1,3,5,7,11,13,17,19,23,29)))dnl
dnl
binarysearch(`a',5,1,asize)
binarysearch(`a',8,1,asize)

View file

@ -0,0 +1,25 @@
fn binarySearchIterative arr value =
(
lower = 1
upper = arr.count
while lower <= upper do
(
mid = (lower + upper) / 2
if arr[mid] > value then
(
upper = mid - 1
)
else if arr[mid] < value then
(
lower = mid + 1
)
else
(
return mid
)
)
-1
)
arr = #(1, 3, 4, 5, 6, 7, 8, 9, 10)
result = binarySearchIterative arr 6

View file

@ -0,0 +1,30 @@
fn binarySearchRecursive arr value lower upper =
(
if lower == upper then
(
if arr[lower] == value then
(
return lower
)
else
(
return -1
)
)
mid = (lower + upper) / 2
if arr[mid] > value then
(
return binarySearchRecursive arr value lower (mid-1)
)
else if arr[mid] < value then
(
return binarySearchRecursive arr value (mid+1) upper
)
else
(
return mid
)
)
arr = #(1, 3, 4, 5, 6, 7, 8, 9, 10)
result = binarySearchRecursive arr 6 1 arr.count

View file

@ -0,0 +1,15 @@
BinarySearch := proc( A, value, low, high )
description "recursive binary search";
if high < low then
FAIL
else
local mid := iquo( high + low, 2 );
if A[ mid ] > value then
thisproc( A, value, low, mid - 1 )
elif A[ mid ] < value then
thisproc( A, value, mid + 1, high )
else
mid
end if
end if
end proc:

View file

@ -0,0 +1,17 @@
BinarySearch := proc( A, value )
description "iterative binary search";
local low, high;
low, high := ( lowerbound, upperbound )( A );
while low <= high do
local mid := iquo( low + high, 2 );
if A[ mid ] > value then
high := mid - 1
elif A[ mid ] < value then
low := mid + 1
else
return mid
end if
end do;
FAIL
end proc:

View file

@ -0,0 +1,17 @@
> N := 10:
> P := [seq]( ithprime( i ), i = 1 .. N ):
> BinarySearch( P, 12, 1, N ); # recursive version
FAIL
> BinarySearch( P, 13, 1, N ); # recursive version
6
> BinarySearch( Array( P ), 13, 1, N ); # make P into an array
6
> PP := Array( -2 .. 7, P ): # check it works if the array is not 1-based.
> BinarySearch( PP, 13 ); # iterative version
3
> PP[ 3 ];
13

View file

@ -0,0 +1,9 @@
BinarySearchRecursive[x_List, val_, lo_, hi_] :=
Module[{mid = lo + Round@((hi - lo)/2)},
If[hi < lo, Return[-1]];
Return[
Which[x[[mid]] > val, BinarySearchRecursive[x, val, lo, mid - 1],
x[[mid]] < val, BinarySearchRecursive[x, val, mid + 1, hi],
True, mid]
];
]

View file

@ -0,0 +1,10 @@
BinarySearch[x_List, val_] := Module[{lo = 1, hi = Length@x, mid},
While[lo <= hi,
mid = lo + Round@((hi - lo)/2);
Which[x[[mid]] > val, hi = mid - 1,
x[[mid]] < val, lo = mid + 1,
True, Return[mid]
];
];
Return[-1];
]

View file

@ -0,0 +1,20 @@
find(L, n) := block([i: 1, j: length(L), k, p],
if n < L[i] or n > L[j] then 0 else (
while j - i > 0 do (
k: quotient(i + j, 2),
p: L[k],
if n < p then j: k - 1 elseif n > p then i: k + 1 else i: j: k
),
if n = L[i] then i else 0
)
)$
".."(a, b) := if a < b then makelist(i, i, a, b) else makelist(i, i, a, b, -1)$
infix("..")$
a: sublist(1 .. 1000, primep)$
find(a, 27);
0
find(a, 421);
82