algorithm.nim 29 KB

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