algorithm.nim 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module implements some common generic algorithms.
  10. ##
  11. ## Basic usage
  12. ## ===========
  13. ##
  14. ## .. code-block::
  15. ## import algorithm
  16. ##
  17. ## type People = tuple
  18. ## year: int
  19. ## name: string
  20. ##
  21. ## var a: seq[People]
  22. ##
  23. ## a.add((2000, "John"))
  24. ## a.add((2005, "Marie"))
  25. ## a.add((2010, "Jane"))
  26. ##
  27. ## # Sorting with default system.cmp
  28. ## a.sort()
  29. ## assert a == @[(year: 2000, name: "John"), (year: 2005, name: "Marie"),
  30. ## (year: 2010, name: "Jane")]
  31. ##
  32. ## proc myCmp(x, y: People): int =
  33. ## if x.name < y.name: -1
  34. ## elif x.name == y.name: 0
  35. ## else: 1
  36. ##
  37. ## # Sorting with custom proc
  38. ## a.sort(myCmp)
  39. ## assert a == @[(year: 2010, name: "Jane"), (year: 2000, name: "John"),
  40. ## (year: 2005, name: "Marie")]
  41. ##
  42. ##
  43. ## See also
  44. ## ========
  45. ## * `sequtils module<sequtils.html>`_ for working with the built-in seq type
  46. ## * `tables module<tables.html>`_ for sorting tables
  47. type
  48. SortOrder* = enum
  49. Descending, Ascending
  50. proc `*`*(x: int, order: SortOrder): int {.inline.} =
  51. ## Flips ``x`` if ``order == Descending``.
  52. ## If ``order == Ascending`` then ``x`` is returned.
  53. ##
  54. ## ``x`` is supposed to be the result of a comparator, i.e.
  55. ## | ``< 0`` for *less than*,
  56. ## | ``== 0`` for *equal*,
  57. ## | ``> 0`` for *greater than*.
  58. runnableExamples:
  59. assert `*`(-123, Descending) == 123
  60. assert `*`(123, Descending) == -123
  61. assert `*`(-123, Ascending) == -123
  62. assert `*`(123, Ascending) == 123
  63. var y = order.ord - 1
  64. result = (x xor y) - y
  65. template fillImpl[T](a: var openArray[T], first, last: int, value: T) =
  66. var x = first
  67. while x <= last:
  68. a[x] = value
  69. inc(x)
  70. proc fill*[T](a: var openArray[T], first, last: Natural, value: T) =
  71. ## Fills the slice ``a[first..last]`` with ``value``.
  72. ##
  73. ## If an invalid range is passed, it raises IndexDefect.
  74. runnableExamples:
  75. var a: array[6, int]
  76. a.fill(1, 3, 9)
  77. assert a == [0, 9, 9, 9, 0, 0]
  78. a.fill(3, 5, 7)
  79. assert a == [0, 9, 9, 7, 7, 7]
  80. doAssertRaises(IndexDefect, a.fill(1, 7, 9))
  81. fillImpl(a, first, last, value)
  82. proc fill*[T](a: var openArray[T], value: T) =
  83. ## Fills the container ``a`` with ``value``.
  84. runnableExamples:
  85. var a: array[6, int]
  86. a.fill(9)
  87. assert a == [9, 9, 9, 9, 9, 9]
  88. a.fill(4)
  89. assert a == [4, 4, 4, 4, 4, 4]
  90. fillImpl(a, 0, a.high, value)
  91. proc reverse*[T](a: var openArray[T], first, last: Natural) =
  92. ## Reverses the slice ``a[first..last]``.
  93. ##
  94. ## If an invalid range is passed, it raises IndexDefect.
  95. ##
  96. ## **See also:**
  97. ## * `reversed proc<#reversed,openArray[T],Natural,int>`_ reverse a slice and returns a ``seq[T]``
  98. ## * `reversed proc<#reversed,openArray[T]>`_ reverse and returns a ``seq[T]``
  99. runnableExamples:
  100. var a = [1, 2, 3, 4, 5, 6]
  101. a.reverse(1, 3)
  102. assert a == [1, 4, 3, 2, 5, 6]
  103. a.reverse(1, 3)
  104. assert a == [1, 2, 3, 4, 5, 6]
  105. doAssertRaises(IndexDefect, a.reverse(1, 7))
  106. var x = first
  107. var y = last
  108. while x < y:
  109. swap(a[x], a[y])
  110. dec(y)
  111. inc(x)
  112. proc reverse*[T](a: var openArray[T]) =
  113. ## Reverses the contents of the container ``a``.
  114. ##
  115. ## **See also:**
  116. ## * `reversed proc<#reversed,openArray[T],Natural,int>`_ reverse a slice and returns a ``seq[T]``
  117. ## * `reversed proc<#reversed,openArray[T]>`_ reverse and returns a ``seq[T]``
  118. runnableExamples:
  119. var a = [1, 2, 3, 4, 5, 6]
  120. a.reverse()
  121. assert a == [6, 5, 4, 3, 2, 1]
  122. a.reverse()
  123. assert a == [1, 2, 3, 4, 5, 6]
  124. reverse(a, 0, max(0, a.high))
  125. proc reversed*[T](a: openArray[T], first: Natural, last: int): seq[T] =
  126. ## Returns the reverse of the slice ``a[first..last]``.
  127. ##
  128. ## If an invalid range is passed, it raises IndexDefect.
  129. ##
  130. ## **See also:**
  131. ## * `reverse proc<#reverse,openArray[T],Natural,Natural>`_ reverse a slice
  132. ## * `reverse proc<#reverse,openArray[T]>`_
  133. runnableExamples:
  134. let
  135. a = [1, 2, 3, 4, 5, 6]
  136. b = a.reversed(1, 3)
  137. assert b == @[4, 3, 2]
  138. assert last >= first-1
  139. var i = last - first
  140. var x = first.int
  141. result = newSeq[T](i + 1)
  142. while i >= 0:
  143. result[i] = a[x]
  144. dec(i)
  145. inc(x)
  146. proc reversed*[T](a: openArray[T]): seq[T] =
  147. ## Returns the reverse of the container ``a``.
  148. ##
  149. ## **See also:**
  150. ## * `reverse proc<#reverse,openArray[T],Natural,Natural>`_ reverse a slice
  151. ## * `reverse proc<#reverse,openArray[T]>`_
  152. runnableExamples:
  153. let
  154. a = [1, 2, 3, 4, 5, 6]
  155. b = reversed(a)
  156. assert b == @[6, 5, 4, 3, 2, 1]
  157. reversed(a, 0, a.high)
  158. proc binarySearch*[T, K](a: openArray[T], key: K,
  159. cmp: proc (x: T, y: K): int {.closure.}): int =
  160. ## Binary search for ``key`` in ``a``. Returns -1 if not found.
  161. ##
  162. ## ``cmp`` is the comparator function to use, the expected return values are
  163. ## the same as that of system.cmp.
  164. runnableExamples:
  165. assert binarySearch(["a", "b", "c", "d"], "d", system.cmp[string]) == 3
  166. assert binarySearch(["a", "b", "d", "c"], "d", system.cmp[string]) == 2
  167. if a.len == 0:
  168. return -1
  169. let len = a.len
  170. if len == 1:
  171. if cmp(a[0], key) == 0:
  172. return 0
  173. else:
  174. return -1
  175. result = 0
  176. if (len and (len - 1)) == 0:
  177. # when `len` is a power of 2, a faster shr can be used.
  178. var step = len shr 1
  179. var cmpRes: int
  180. while step > 0:
  181. let i = result or step
  182. cmpRes = cmp(a[i], key)
  183. if cmpRes == 0:
  184. return i
  185. if cmpRes < 1:
  186. result = i
  187. step = step shr 1
  188. if cmp(a[result], key) != 0: result = -1
  189. else:
  190. var b = len
  191. var cmpRes: int
  192. while result < b:
  193. var mid = (result + b) shr 1
  194. cmpRes = cmp(a[mid], key)
  195. if cmpRes == 0:
  196. return mid
  197. if cmpRes < 0:
  198. result = mid + 1
  199. else:
  200. b = mid
  201. if result >= len or cmp(a[result], key) != 0: result = -1
  202. proc binarySearch*[T](a: openArray[T], key: T): int =
  203. ## Binary search for ``key`` in ``a``. Returns -1 if not found.
  204. runnableExamples:
  205. assert binarySearch([0, 1, 2, 3, 4], 4) == 4
  206. assert binarySearch([0, 1, 4, 2, 3], 4) == 2
  207. binarySearch(a, key, cmp[T])
  208. const
  209. onlySafeCode = true
  210. proc lowerBound*[T, K](a: openArray[T], key: K, cmp: proc(x: T, k: K): int {.
  211. closure.}): int =
  212. ## Returns a position to the first element in the ``a`` that is greater than
  213. ## ``key``, or last if no such element is found.
  214. ## In other words if you have a sorted sequence and you call
  215. ## ``insert(thing, elm, lowerBound(thing, elm))``
  216. ## the sequence will still be sorted.
  217. ##
  218. ## If an invalid range is passed, it raises IndexDefect.
  219. ##
  220. ## The version uses ``cmp`` to compare the elements.
  221. ## The expected return values are the same as that of ``system.cmp``.
  222. ##
  223. ## **See also:**
  224. ## * `upperBound proc<#upperBound,openArray[T],K,proc(T,K)>`_ sorted by ``cmp`` in the specified order
  225. ## * `upperBound proc<#upperBound,openArray[T],T>`_
  226. runnableExamples:
  227. var arr = @[1, 2, 3, 5, 6, 7, 8, 9]
  228. assert arr.lowerBound(3, system.cmp[int]) == 2
  229. assert arr.lowerBound(4, system.cmp[int]) == 3
  230. assert arr.lowerBound(5, system.cmp[int]) == 3
  231. arr.insert(4, arr.lowerBound(4, system.cmp[int]))
  232. assert arr == [1, 2, 3, 4, 5, 6, 7, 8, 9]
  233. result = a.low
  234. var count = a.high - a.low + 1
  235. var step, pos: int
  236. while count != 0:
  237. step = count shr 1
  238. pos = result + step
  239. if cmp(a[pos], key) < 0:
  240. result = pos + 1
  241. count -= step + 1
  242. else:
  243. count = step
  244. proc lowerBound*[T](a: openArray[T], key: T): int = lowerBound(a, key, cmp[T])
  245. ## Returns a position to the first element in the ``a`` that is greater than
  246. ## ``key``, or last if no such element is found.
  247. ## In other words if you have a sorted sequence and you call
  248. ## ``insert(thing, elm, lowerBound(thing, elm))``
  249. ## the sequence will still be sorted.
  250. ##
  251. ## The version uses the default comparison function ``cmp``.
  252. ##
  253. ## **See also:**
  254. ## * `upperBound proc<#upperBound,openArray[T],K,proc(T,K)>`_ sorted by ``cmp`` in the specified order
  255. ## * `upperBound proc<#upperBound,openArray[T],T>`_
  256. proc upperBound*[T, K](a: openArray[T], key: K, cmp: proc(x: T, k: K): int {.
  257. closure.}): int =
  258. ## Returns a position to the first element in the ``a`` that is not less
  259. ## (i.e. greater or equal to) than ``key``, or last if no such element is found.
  260. ## In other words if you have a sorted sequence and you call
  261. ## ``insert(thing, elm, upperBound(thing, elm))``
  262. ## the sequence will still be sorted.
  263. ##
  264. ## If an invalid range is passed, it raises IndexDefect.
  265. ##
  266. ## The version uses ``cmp`` to compare the elements. The expected
  267. ## return values are the same as that of ``system.cmp``.
  268. ##
  269. ## **See also:**
  270. ## * `lowerBound proc<#lowerBound,openArray[T],K,proc(T,K)>`_ sorted by ``cmp`` in the specified order
  271. ## * `lowerBound proc<#lowerBound,openArray[T],T>`_
  272. runnableExamples:
  273. var arr = @[1, 2, 3, 5, 6, 7, 8, 9]
  274. assert arr.upperBound(2, system.cmp[int]) == 2
  275. assert arr.upperBound(3, system.cmp[int]) == 3
  276. assert arr.upperBound(4, system.cmp[int]) == 3
  277. arr.insert(4, arr.upperBound(3, system.cmp[int]))
  278. assert arr == [1, 2, 3, 4, 5, 6, 7, 8, 9]
  279. result = a.low
  280. var count = a.high - a.low + 1
  281. var step, pos: int
  282. while count != 0:
  283. step = count shr 1
  284. pos = result + step
  285. if cmp(a[pos], key) <= 0:
  286. result = pos + 1
  287. count -= step + 1
  288. else:
  289. count = step
  290. proc upperBound*[T](a: openArray[T], key: T): int = upperBound(a, key, cmp[T])
  291. ## Returns a position to the first element in the ``a`` that is not less
  292. ## (i.e. greater or equal to) than ``key``, or last if no such element is found.
  293. ## In other words if you have a sorted sequence and you call
  294. ## ``insert(thing, elm, upperBound(thing, elm))``
  295. ## the sequence will still be sorted.
  296. ##
  297. ## The version uses the default comparison function ``cmp``.
  298. ##
  299. ## **See also:**
  300. ## * `lowerBound proc<#lowerBound,openArray[T],K,proc(T,K)>`_ sorted by ``cmp`` in the specified order
  301. ## * `lowerBound proc<#lowerBound,openArray[T],T>`_
  302. template `<-` (a, b) =
  303. when defined(gcDestructors):
  304. a = move b
  305. elif onlySafeCode:
  306. shallowCopy(a, b)
  307. else:
  308. copyMem(addr(a), addr(b), sizeof(T))
  309. proc merge[T](a, b: var openArray[T], lo, m, hi: int,
  310. cmp: proc (x, y: T): int {.closure.}, order: SortOrder) =
  311. # optimization: If max(left) <= min(right) there is nothing to do!
  312. # 1 2 3 4 ## 5 6 7 8
  313. # -> O(n) for sorted arrays.
  314. # On random data this safes up to 40% of merge calls
  315. if cmp(a[m], a[m+1]) * order <= 0: return
  316. var j = lo
  317. # copy a[j..m] into b:
  318. assert j <= m
  319. when onlySafeCode:
  320. var bb = 0
  321. while j <= m:
  322. b[bb] <- a[j]
  323. inc(bb)
  324. inc(j)
  325. else:
  326. copyMem(addr(b[0]), addr(a[j]), sizeof(T)*(m-j+1))
  327. j = m+1
  328. var i = 0
  329. var k = lo
  330. # copy proper element back:
  331. while k < j and j <= hi:
  332. if cmp(b[i], a[j]) * order <= 0:
  333. a[k] <- b[i]
  334. inc(i)
  335. else:
  336. a[k] <- a[j]
  337. inc(j)
  338. inc(k)
  339. # copy rest of b:
  340. when onlySafeCode:
  341. while k < j:
  342. a[k] <- b[i]
  343. inc(k)
  344. inc(i)
  345. else:
  346. if k < j: copyMem(addr(a[k]), addr(b[i]), sizeof(T)*(j-k))
  347. func sort*[T](a: var openArray[T],
  348. cmp: proc (x, y: T): int {.closure.},
  349. order = SortOrder.Ascending) =
  350. ## Default Nim sort (an implementation of merge sort). The sorting
  351. ## is guaranteed to be stable and the worst case is guaranteed to
  352. ## be O(n log n).
  353. ##
  354. ## The current implementation uses an iterative
  355. ## mergesort to achieve this. It uses a temporary sequence of
  356. ## length ``a.len div 2``. If you do not wish to provide your own
  357. ## ``cmp``, you may use ``system.cmp`` or instead call the overloaded
  358. ## version of ``sort``, which uses ``system.cmp``.
  359. ##
  360. ## .. code-block:: nim
  361. ##
  362. ## sort(myIntArray, system.cmp[int])
  363. ## # do not use cmp[string] here as we want to use the specialized
  364. ## # overload:
  365. ## sort(myStrArray, system.cmp)
  366. ##
  367. ## You can inline adhoc comparison procs with the `do notation
  368. ## <manual_experimental.html#do-notation>`_. Example:
  369. ##
  370. ## .. code-block:: nim
  371. ##
  372. ## people.sort do (x, y: Person) -> int:
  373. ## result = cmp(x.surname, y.surname)
  374. ## if result == 0:
  375. ## result = cmp(x.name, y.name)
  376. ##
  377. ## **See also:**
  378. ## * `sort proc<#sort,openArray[T]>`_
  379. ## * `sorted proc<#sorted,openArray[T],proc(T,T)>`_ sorted by ``cmp`` in the specified order
  380. ## * `sorted proc<#sorted,openArray[T]>`_
  381. ## * `sortedByIt template<#sortedByIt.t,untyped,untyped>`_
  382. runnableExamples:
  383. var d = ["boo", "fo", "barr", "qux"]
  384. proc myCmp(x, y: string): int =
  385. if x.len() > y.len() or x.len() == y.len(): 1
  386. else: -1
  387. sort(d, myCmp)
  388. assert d == ["fo", "qux", "boo", "barr"]
  389. var n = a.len
  390. var b: seq[T]
  391. newSeq(b, n div 2)
  392. var s = 1
  393. while s < n:
  394. var m = n-1-s
  395. while m >= 0:
  396. merge(a, b, max(m-s+1, 0), m, m+s, cmp, order)
  397. dec(m, s*2)
  398. s = s*2
  399. proc sort*[T](a: var openArray[T], order = SortOrder.Ascending) = sort[T](a,
  400. system.cmp[T], order)
  401. ## Shortcut version of ``sort`` that uses ``system.cmp[T]`` as the comparison function.
  402. ##
  403. ## **See also:**
  404. ## * `sort func<#sort,openArray[T],proc(T,T)>`_
  405. ## * `sorted proc<#sorted,openArray[T],proc(T,T)>`_ sorted by ``cmp`` in the specified order
  406. ## * `sorted proc<#sorted,openArray[T]>`_
  407. ## * `sortedByIt template<#sortedByIt.t,untyped,untyped>`_
  408. proc sorted*[T](a: openArray[T], cmp: proc(x, y: T): int {.closure.},
  409. order = SortOrder.Ascending): seq[T] =
  410. ## Returns ``a`` sorted by ``cmp`` in the specified ``order``.
  411. ##
  412. ## **See also:**
  413. ## * `sort func<#sort,openArray[T],proc(T,T)>`_
  414. ## * `sort proc<#sort,openArray[T]>`_
  415. ## * `sortedByIt template<#sortedByIt.t,untyped,untyped>`_
  416. runnableExamples:
  417. let
  418. a = [2, 3, 1, 5, 4]
  419. b = sorted(a, system.cmp[int])
  420. c = sorted(a, system.cmp[int], Descending)
  421. d = sorted(["adam", "dande", "brian", "cat"], system.cmp[string])
  422. assert b == @[1, 2, 3, 4, 5]
  423. assert c == @[5, 4, 3, 2, 1]
  424. assert d == @["adam", "brian", "cat", "dande"]
  425. result = newSeq[T](a.len)
  426. for i in 0 .. a.high:
  427. result[i] = a[i]
  428. sort(result, cmp, order)
  429. proc sorted*[T](a: openArray[T], order = SortOrder.Ascending): seq[T] =
  430. ## Shortcut version of ``sorted`` that uses ``system.cmp[T]`` as the comparison function.
  431. ##
  432. ## **See also:**
  433. ## * `sort func<#sort,openArray[T],proc(T,T)>`_
  434. ## * `sort proc<#sort,openArray[T]>`_
  435. ## * `sortedByIt template<#sortedByIt.t,untyped,untyped>`_
  436. runnableExamples:
  437. let
  438. a = [2, 3, 1, 5, 4]
  439. b = sorted(a)
  440. c = sorted(a, Descending)
  441. d = sorted(["adam", "dande", "brian", "cat"])
  442. assert b == @[1, 2, 3, 4, 5]
  443. assert c == @[5, 4, 3, 2, 1]
  444. assert d == @["adam", "brian", "cat", "dande"]
  445. sorted[T](a, system.cmp[T], order)
  446. template sortedByIt*(seq1, op: untyped): untyped =
  447. ## Convenience template around the ``sorted`` proc to reduce typing.
  448. ##
  449. ## The template injects the ``it`` variable which you can use directly in an
  450. ## expression.
  451. ##
  452. ## Because the underlying ``cmp()`` is defined for tuples you can do
  453. ## a nested sort.
  454. ##
  455. ## **See also:**
  456. ## * `sort func<#sort,openArray[T],proc(T,T)>`_
  457. ## * `sort proc<#sort,openArray[T]>`_
  458. ## * `sorted proc<#sorted,openArray[T],proc(T,T)>`_ sorted by ``cmp`` in the specified order
  459. ## * `sorted proc<#sorted,openArray[T]>`_
  460. runnableExamples:
  461. type Person = tuple[name: string, age: int]
  462. var
  463. p1: Person = (name: "p1", age: 60)
  464. p2: Person = (name: "p2", age: 20)
  465. p3: Person = (name: "p3", age: 30)
  466. p4: Person = (name: "p4", age: 30)
  467. people = @[p1, p2, p4, p3]
  468. assert people.sortedByIt(it.name) == @[(name: "p1", age: 60), (name: "p2",
  469. age: 20), (name: "p3", age: 30), (name: "p4", age: 30)]
  470. # Nested sort
  471. assert people.sortedByIt((it.age, it.name)) == @[(name: "p2", age: 20),
  472. (name: "p3", age: 30), (name: "p4", age: 30), (name: "p1", age: 60)]
  473. var result = sorted(seq1, proc(x, y: typeof(items(seq1), typeOfIter)): int =
  474. var it {.inject.} = x
  475. let a = op
  476. it = y
  477. let b = op
  478. result = cmp(a, b))
  479. result
  480. func isSorted*[T](a: openArray[T],
  481. cmp: proc(x, y: T): int {.closure.},
  482. order = SortOrder.Ascending): bool =
  483. ## Checks to see whether ``a`` is already sorted in ``order``
  484. ## using ``cmp`` for the comparison. Parameters identical
  485. ## to ``sort``. Requires O(n) time.
  486. ##
  487. ## **See also:**
  488. ## * `isSorted proc<#isSorted,openArray[T]>`_
  489. runnableExamples:
  490. let
  491. a = [2, 3, 1, 5, 4]
  492. b = [1, 2, 3, 4, 5]
  493. c = [5, 4, 3, 2, 1]
  494. d = ["adam", "brian", "cat", "dande"]
  495. e = ["adam", "dande", "brian", "cat"]
  496. assert isSorted(a) == false
  497. assert isSorted(b) == true
  498. assert isSorted(c) == false
  499. assert isSorted(c, Descending) == true
  500. assert isSorted(d) == true
  501. assert isSorted(e) == false
  502. result = true
  503. for i in 0..<len(a)-1:
  504. if cmp(a[i], a[i+1]) * order > 0:
  505. return false
  506. proc isSorted*[T](a: openArray[T], order = SortOrder.Ascending): bool =
  507. ## Shortcut version of ``isSorted`` that uses ``system.cmp[T]`` as the comparison function.
  508. ##
  509. ## **See also:**
  510. ## * `isSorted func<#isSorted,openArray[T],proc(T,T)>`_
  511. runnableExamples:
  512. let
  513. a = [2, 3, 1, 5, 4]
  514. b = [1, 2, 3, 4, 5]
  515. c = [5, 4, 3, 2, 1]
  516. d = ["adam", "brian", "cat", "dande"]
  517. e = ["adam", "dande", "brian", "cat"]
  518. assert isSorted(a) == false
  519. assert isSorted(b) == true
  520. assert isSorted(c) == false
  521. assert isSorted(c, Descending) == true
  522. assert isSorted(d) == true
  523. assert isSorted(e) == false
  524. isSorted(a, system.cmp[T], order)
  525. proc product*[T](x: openArray[seq[T]]): seq[seq[T]] =
  526. ## Produces the Cartesian product of the array. Warning: complexity
  527. ## may explode.
  528. runnableExamples:
  529. assert product(@[@[1], @[2]]) == @[@[1, 2]]
  530. assert product(@[@["A", "K"], @["Q"]]) == @[@["K", "Q"], @["A", "Q"]]
  531. result = newSeq[seq[T]]()
  532. if x.len == 0:
  533. return
  534. if x.len == 1:
  535. result = @x
  536. return
  537. var
  538. indexes = newSeq[int](x.len)
  539. initial = newSeq[int](x.len)
  540. index = 0
  541. var next = newSeq[T]()
  542. next.setLen(x.len)
  543. for i in 0..(x.len-1):
  544. if len(x[i]) == 0: return
  545. initial[i] = len(x[i])-1
  546. indexes = initial
  547. while true:
  548. while indexes[index] == -1:
  549. indexes[index] = initial[index]
  550. index += 1
  551. if index == x.len: return
  552. indexes[index] -= 1
  553. for ni, i in indexes:
  554. next[ni] = x[ni][i]
  555. result.add(next)
  556. index = 0
  557. indexes[index] -= 1
  558. proc nextPermutation*[T](x: var openArray[T]): bool {.discardable.} =
  559. ## Calculates the next lexicographic permutation, directly modifying ``x``.
  560. ## The result is whether a permutation happened, otherwise we have reached
  561. ## the last-ordered permutation.
  562. ##
  563. ## If you start with an unsorted array/seq, the repeated permutations
  564. ## will **not** give you all permutations but stop with last.
  565. ##
  566. ## **See also:**
  567. ## * `prevPermutation proc<#prevPermutation,openArray[T]>`_
  568. runnableExamples:
  569. var v = @[0, 1, 2, 3]
  570. assert v.nextPermutation() == true
  571. assert v == @[0, 1, 3, 2]
  572. assert v.nextPermutation() == true
  573. assert v == @[0, 2, 1, 3]
  574. assert v.prevPermutation() == true
  575. assert v == @[0, 1, 3, 2]
  576. v = @[3, 2, 1, 0]
  577. assert v.nextPermutation() == false
  578. assert v == @[3, 2, 1, 0]
  579. if x.len < 2:
  580. return false
  581. var i = x.high
  582. while i > 0 and x[i-1] >= x[i]:
  583. dec i
  584. if i == 0:
  585. return false
  586. var j = x.high
  587. while j >= i and x[j] <= x[i-1]:
  588. dec j
  589. swap x[j], x[i-1]
  590. x.reverse(i, x.high)
  591. result = true
  592. proc prevPermutation*[T](x: var openArray[T]): bool {.discardable.} =
  593. ## Calculates the previous lexicographic permutation, directly modifying
  594. ## ``x``. The result is whether a permutation happened, otherwise we have
  595. ## reached the first-ordered permutation.
  596. ##
  597. ## **See also:**
  598. ## * `nextPermutation proc<#nextPermutation,openArray[T]>`_
  599. runnableExamples:
  600. var v = @[0, 1, 2, 3]
  601. assert v.prevPermutation() == false
  602. assert v == @[0, 1, 2, 3]
  603. assert v.nextPermutation() == true
  604. assert v == @[0, 1, 3, 2]
  605. assert v.prevPermutation() == true
  606. assert v == @[0, 1, 2, 3]
  607. if x.len < 2:
  608. return false
  609. var i = x.high
  610. while i > 0 and x[i-1] <= x[i]:
  611. dec i
  612. if i == 0:
  613. return false
  614. x.reverse(i, x.high)
  615. var j = x.high
  616. while j >= i and x[j-1] < x[i-1]:
  617. dec j
  618. swap x[i-1], x[j]
  619. result = true
  620. when isMainModule:
  621. # Tests for lowerBound
  622. var arr = @[1, 2, 3, 5, 6, 7, 8, 9]
  623. assert arr.lowerBound(0) == 0
  624. assert arr.lowerBound(4) == 3
  625. assert arr.lowerBound(5) == 3
  626. assert arr.lowerBound(10) == 8
  627. arr = @[1, 5, 10]
  628. assert arr.lowerBound(4) == 1
  629. assert arr.lowerBound(5) == 1
  630. assert arr.lowerBound(6) == 2
  631. # Tests for isSorted
  632. var srt1 = [1, 2, 3, 4, 4, 4, 4, 5]
  633. var srt2 = ["iello", "hello"]
  634. var srt3 = [1.0, 1.0, 1.0]
  635. var srt4: seq[int]
  636. assert srt1.isSorted(cmp) == true
  637. assert srt2.isSorted(cmp) == false
  638. assert srt3.isSorted(cmp) == true
  639. assert srt4.isSorted(cmp) == true
  640. var srtseq = newSeq[int]()
  641. assert srtseq.isSorted(cmp) == true
  642. # Tests for reversed
  643. var arr1 = @[0, 1, 2, 3, 4]
  644. assert arr1.reversed() == @[4, 3, 2, 1, 0]
  645. for i in 0 .. high(arr1):
  646. assert arr1.reversed(0, i) == arr1.reversed()[high(arr1) - i .. high(arr1)]
  647. assert arr1.reversed(i, high(arr1)) == arr1.reversed()[0 .. high(arr1) - i]
  648. proc rotateInternal[T](arg: var openArray[T]; first, middle, last: int): int =
  649. ## A port of std::rotate from c++. Ported from `this reference <http://www.cplusplus.com/reference/algorithm/rotate/>`_.
  650. result = first + last - middle
  651. if first == middle or middle == last:
  652. return
  653. assert first < middle
  654. assert middle < last
  655. # m prefix for mutable
  656. var
  657. mFirst = first
  658. mMiddle = middle
  659. next = middle
  660. swap(arg[mFirst], arg[next])
  661. mFirst += 1
  662. next += 1
  663. if mFirst == mMiddle:
  664. mMiddle = next
  665. while next != last:
  666. swap(arg[mFirst], arg[next])
  667. mFirst += 1
  668. next += 1
  669. if mFirst == mMiddle:
  670. mMiddle = next
  671. next = mMiddle
  672. while next != last:
  673. swap(arg[mFirst], arg[next])
  674. mFirst += 1
  675. next += 1
  676. if mFirst == mMiddle:
  677. mMiddle = next
  678. elif next == last:
  679. next = mMiddle
  680. proc rotatedInternal[T](arg: openArray[T]; first, middle, last: int): seq[T] =
  681. result = newSeq[T](arg.len)
  682. for i in 0 ..< first:
  683. result[i] = arg[i]
  684. let n = last - middle
  685. let m = middle - first
  686. for i in 0 ..< n:
  687. result[first+i] = arg[middle+i]
  688. for i in 0 ..< m:
  689. result[first+n+i] = arg[first+i]
  690. for i in last ..< arg.len:
  691. result[i] = arg[i]
  692. proc rotateLeft*[T](arg: var openArray[T]; slice: HSlice[int, int];
  693. dist: int): int {.discardable.} =
  694. ## Performs a left rotation on a range of elements. If you want to rotate
  695. ## right, use a negative ``dist``. Specifically, ``rotateLeft`` rotates
  696. ## the elements at ``slice`` by ``dist`` positions.
  697. ##
  698. ## | The element at index ``slice.a + dist`` will be at index ``slice.a``.
  699. ## | The element at index ``slice.b`` will be at ``slice.a + dist -1``.
  700. ## | The element at index ``slice.a`` will be at ``slice.b + 1 - dist``.
  701. ## | The element at index ``slice.a + dist - 1`` will be at ``slice.b``.
  702. ##
  703. ## Elements outside of ``slice`` will be left unchanged.
  704. ## The time complexity is linear to ``slice.b - slice.a + 1``.
  705. ## If an invalid range (``HSlice``) is passed, it raises IndexDefect.
  706. ##
  707. ## ``slice``
  708. ## The indices of the element range that should be rotated.
  709. ##
  710. ## ``dist``
  711. ## The distance in amount of elements that the data should be rotated.
  712. ## Can be negative, can be any number.
  713. ##
  714. ## **See also:**
  715. ## * `rotateLeft proc<#rotateLeft,openArray[T],int>`_ for a version which rotates the whole container
  716. ## * `rotatedLeft proc<#rotatedLeft,openArray[T],HSlice[int,int],int>`_ for a version which returns a ``seq[T]``
  717. runnableExamples:
  718. var a = [0, 1, 2, 3, 4, 5]
  719. a.rotateLeft(1 .. 4, 3)
  720. assert a == [0, 4, 1, 2, 3, 5]
  721. a.rotateLeft(1 .. 4, 3)
  722. assert a == [0, 3, 4, 1, 2, 5]
  723. a.rotateLeft(1 .. 4, -3)
  724. assert a == [0, 4, 1, 2, 3, 5]
  725. doAssertRaises(IndexDefect, a.rotateLeft(1 .. 7, 2))
  726. let sliceLen = slice.b + 1 - slice.a
  727. let distLeft = ((dist mod sliceLen) + sliceLen) mod sliceLen
  728. arg.rotateInternal(slice.a, slice.a+distLeft, slice.b + 1)
  729. proc rotateLeft*[T](arg: var openArray[T]; dist: int): int {.discardable.} =
  730. ## Default arguments for slice, so that this procedure operates on the entire
  731. ## ``arg``, and not just on a part of it.
  732. ##
  733. ## **See also:**
  734. ## * `rotateLeft proc<#rotateLeft,openArray[T],HSlice[int,int],int>`_ for a version which rotates a range
  735. ## * `rotatedLeft proc<#rotatedLeft,openArray[T],int>`_ for a version which returns a ``seq[T]``
  736. runnableExamples:
  737. var a = [1, 2, 3, 4, 5]
  738. a.rotateLeft(2)
  739. assert a == [3, 4, 5, 1, 2]
  740. a.rotateLeft(4)
  741. assert a == [2, 3, 4, 5, 1]
  742. a.rotateLeft(-6)
  743. assert a == [1, 2, 3, 4, 5]
  744. let arglen = arg.len
  745. let distLeft = ((dist mod arglen) + arglen) mod arglen
  746. arg.rotateInternal(0, distLeft, arglen)
  747. proc rotatedLeft*[T](arg: openArray[T]; slice: HSlice[int, int],
  748. dist: int): seq[T] =
  749. ## Same as ``rotateLeft``, just with the difference that it does
  750. ## not modify the argument. It creates a new ``seq`` instead.
  751. ##
  752. ## Elements outside of ``slice`` will be left unchanged.
  753. ## If an invalid range (``HSlice``) is passed, it raises IndexDefect.
  754. ##
  755. ## ``slice``
  756. ## The indices of the element range that should be rotated.
  757. ##
  758. ## ``dist``
  759. ## The distance in amount of elements that the data should be rotated.
  760. ## Can be negative, can be any number.
  761. ##
  762. ## **See also:**
  763. ## * `rotateLeft proc<#rotateLeft,openArray[T],HSlice[int,int],int>`_ for the in-place version of this proc
  764. ## * `rotatedLeft proc<#rotatedLeft,openArray[T],int>`_ for a version which rotates the whole container
  765. runnableExamples:
  766. var a = @[1, 2, 3, 4, 5]
  767. a = rotatedLeft(a, 1 .. 4, 3)
  768. assert a == @[1, 5, 2, 3, 4]
  769. a = rotatedLeft(a, 1 .. 3, 2)
  770. assert a == @[1, 3, 5, 2, 4]
  771. a = rotatedLeft(a, 1 .. 3, -2)
  772. assert a == @[1, 5, 2, 3, 4]
  773. let sliceLen = slice.b + 1 - slice.a
  774. let distLeft = ((dist mod sliceLen) + sliceLen) mod sliceLen
  775. arg.rotatedInternal(slice.a, slice.a+distLeft, slice.b+1)
  776. proc rotatedLeft*[T](arg: openArray[T]; dist: int): seq[T] =
  777. ## Same as ``rotateLeft``, just with the difference that it does
  778. ## not modify the argument. It creates a new ``seq`` instead.
  779. ##
  780. ## **See also:**
  781. ## * `rotateLeft proc<#rotateLeft,openArray[T],int>`_ for the in-place version of this proc
  782. ## * `rotatedLeft proc<#rotatedLeft,openArray[T],HSlice[int,int],int>`_ for a version which rotates a range
  783. runnableExamples:
  784. var a = @[1, 2, 3, 4, 5]
  785. a = rotatedLeft(a, 2)
  786. assert a == @[3, 4, 5, 1, 2]
  787. a = rotatedLeft(a, 4)
  788. assert a == @[2, 3, 4, 5, 1]
  789. a = rotatedLeft(a, -6)
  790. assert a == @[1, 2, 3, 4, 5]
  791. let arglen = arg.len
  792. let distLeft = ((dist mod arglen) + arglen) mod arglen
  793. arg.rotatedInternal(0, distLeft, arg.len)
  794. when isMainModule:
  795. var list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  796. let list2 = list.rotatedLeft(1 ..< 9, 3)
  797. let expected = [0, 4, 5, 6, 7, 8, 1, 2, 3, 9, 10]
  798. doAssert list.rotateLeft(1 ..< 9, 3) == 6
  799. doAssert list == expected
  800. doAssert list2 == @expected
  801. var s0, s1, s2, s3, s4, s5 = "xxxabcdefgxxx"
  802. doAssert s0.rotateLeft(3 ..< 10, 3) == 7
  803. doAssert s0 == "xxxdefgabcxxx"
  804. doAssert s1.rotateLeft(3 ..< 10, 2) == 8
  805. doAssert s1 == "xxxcdefgabxxx"
  806. doAssert s2.rotateLeft(3 ..< 10, 4) == 6
  807. doAssert s2 == "xxxefgabcdxxx"
  808. doAssert s3.rotateLeft(3 ..< 10, -3) == 6
  809. doAssert s3 == "xxxefgabcdxxx"
  810. doAssert s4.rotateLeft(3 ..< 10, -10) == 6
  811. doAssert s4 == "xxxefgabcdxxx"
  812. doAssert s5.rotateLeft(3 ..< 10, 11) == 6
  813. doAssert s5 == "xxxefgabcdxxx"
  814. block product:
  815. doAssert product(newSeq[seq[int]]()) == newSeq[seq[int]](), "empty input"
  816. doAssert product(@[newSeq[int](), @[], @[]]) == newSeq[seq[int]](), "bit more empty input"
  817. doAssert product(@[@[1, 2]]) == @[@[1, 2]], "a simple case of one element"
  818. doAssert product(@[@[1, 2], @[3, 4]]) == @[@[2, 4], @[1, 4], @[2, 3], @[1,
  819. 3]], "two elements"
  820. doAssert product(@[@[1, 2], @[3, 4], @[5, 6]]) == @[@[2, 4, 6], @[1, 4, 6],
  821. @[2, 3, 6], @[1, 3, 6], @[2, 4, 5], @[1, 4, 5], @[2, 3, 5], @[1, 3, 5]], "three elements"
  822. doAssert product(@[@[1, 2], @[]]) == newSeq[seq[int]](), "two elements, but one empty"
  823. block lowerBound:
  824. doAssert lowerBound([1, 2, 4], 3, system.cmp[int]) == 2
  825. doAssert lowerBound([1, 2, 2, 3], 4, system.cmp[int]) == 4
  826. doAssert lowerBound([1, 2, 3, 10], 11) == 4
  827. block upperBound:
  828. doAssert upperBound([1, 2, 4], 3, system.cmp[int]) == 2
  829. doAssert upperBound([1, 2, 2, 3], 3, system.cmp[int]) == 4
  830. doAssert upperBound([1, 2, 3, 5], 3) == 3
  831. block fillEmptySeq:
  832. var s = newSeq[int]()
  833. s.fill(0)
  834. block testBinarySearch:
  835. var noData: seq[int]
  836. doAssert binarySearch(noData, 7) == -1
  837. let oneData = @[1]
  838. doAssert binarySearch(oneData, 1) == 0
  839. doAssert binarySearch(onedata, 7) == -1
  840. let someData = @[1, 3, 4, 7]
  841. doAssert binarySearch(someData, 1) == 0
  842. doAssert binarySearch(somedata, 7) == 3
  843. doAssert binarySearch(someData, -1) == -1
  844. doAssert binarySearch(someData, 5) == -1
  845. doAssert binarySearch(someData, 13) == -1
  846. let moreData = @[1, 3, 5, 7, 4711]
  847. doAssert binarySearch(moreData, -1) == -1
  848. doAssert binarySearch(moreData, 1) == 0
  849. doAssert binarySearch(moreData, 5) == 2
  850. doAssert binarySearch(moreData, 6) == -1
  851. doAssert binarySearch(moreData, 4711) == 4
  852. doAssert binarySearch(moreData, 4712) == -1