Fork of https://github.com/google/lisp-koans so that I could go through them. THIS CONTAINS ANSWERS.

loops.lsp 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. ;; Copyright 2013 Google Inc.
  2. ;;
  3. ;; Licensed under the Apache License, Version 2.0 (the "License");
  4. ;; you may not use this file except in compliance with the License.
  5. ;; You may obtain a copy of the License at
  6. ;;
  7. ;; http://www.apache.org/licenses/LICENSE-2.0
  8. ;;
  9. ;; Unless required by applicable law or agreed to in writing, software
  10. ;; distributed under the License is distributed on an "AS IS" BASIS,
  11. ;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. ;; See the License for the specific language governing permissions and
  13. ;; limitations under the License.
  14. ;; see http://www.gigamonkeys.com/book/loop-for-black-belts.html
  15. ;; "Loop for blackbelts" for more on the loop macro.
  16. (define-test test-basic-loop
  17. (let* ((letters '(:a :b :c :d))
  18. (loop-result
  19. (loop for letter in letters
  20. collect letter)))
  21. (assert-equal loop-result ____)))
  22. (define-test test-compound-loop
  23. (let* ((letters '(:a :b :c :d))
  24. (loop-result
  25. (loop for letter in letters
  26. for i from 1 to 1000
  27. collect (list i letter))))
  28. (assert-equal loop-result ____)))
  29. (define-test test-counting-loop-skip-by-syntax
  30. "with multiple 'for' clauses, loop ends when the first is exhausted"
  31. (let* ((letters '(:a :b :c :d))
  32. (loop-result
  33. (loop for letter in letters
  34. for i from 0 to 1000 by 5
  35. collect (list i letter))))
  36. (assert-equal loop-result ____ )))
  37. (define-test test-counting-backwards
  38. (let ((loop-result
  39. (loop for i from 10 downto -10 by 5
  40. collect i )))
  41. (assert-equal loop-result ____ )))
  42. (define-test test-loop-in-vs-loop-on
  43. (let* ((letters '(:a :b :c))
  44. (loop-result-in
  45. (loop for letter in letters collect letter))
  46. (loop-result-on
  47. (loop for letter on letters collect letter)))
  48. (assert-equal loop-result-in ____)
  49. (assert-equal loop-result-on ____ )))
  50. (define-test test-loop-in-skip-by
  51. (let* ((letters '(:a :b :c :d :e :f))
  52. (loop-result-in
  53. (loop for letter in letters collect letter))
  54. (loop-result-in-cdr
  55. (loop for letter in letters by #'cdr collect letter))
  56. (loop-result-in-cddr
  57. (loop for letter in letters by #'cddr collect letter))
  58. (loop-result-in-cdddr
  59. (loop for letter in letters by #'cdddr collect letter)))
  60. (assert-equal loop-result-in ____)
  61. (assert-equal loop-result-in-cdr ____)
  62. (assert-equal loop-result-in-cddr ____)
  63. (assert-equal loop-result-in-cdddr ____)))
  64. (define-test test-loop-across-vector
  65. (let* ((my-vector (make-array '(5) :initial-contents '(0 1 2 3 4)))
  66. (loop-result
  67. (loop for val across my-vector collect val)))
  68. (assert-equal ____ loop-result)))
  69. (define-test test-loop-across-2d-array
  70. (let* ((my-array (make-array '(3 3) :initial-contents '((0 1 2) (3 4 5) (6 7 8))))
  71. (loop-result
  72. (loop for i from 0 below (array-total-size my-array) collect (row-major-aref my-array i))))
  73. (assert-equal loop-result ____ )))
  74. (define-test test-loop-across-2d-array-respecting-shape
  75. (let* ((my-array (make-array '(3 2) :initial-contents '((0 1) (2 3) (4 5))))
  76. (loop-result
  77. (loop for i from 0 below (array-dimension my-array 0) collect
  78. (loop for j from 0 below (array-dimension my-array 1) collect
  79. (expt (aref my-array i j) 2)))))
  80. (assert-equal loop-result ____ )))
  81. (defvar books-to-heros)
  82. (setf books-to-heros (make-hash-table :test 'equal))
  83. (setf (gethash "The Hobbit" books-to-heros) "Bilbo")
  84. (setf (gethash "Where The Wild Things Are" books-to-heros) "Max")
  85. (setf (gethash "The Wizard Of Oz" books-to-heros) "Dorothy")
  86. (setf (gethash "The Great Gatsby" books-to-heros) "James Gatz")
  87. (define-test test-loop-over-hash-tables
  88. (let* ((pairs-in-table
  89. (loop for k being the hash-keys in books-to-heros
  90. using (hash-value v)
  91. collect (list k v))))
  92. (assert-equal ____ (length pairs-in-table))
  93. (true-or-false? ____ (find '("The Hobbit" "Bilbo") pairs-in-table :test #'equal))))
  94. (define-test test-value-accumulation-forms
  95. (let ((loop-1
  96. (loop for x in '(1 2 4 8 16)
  97. collect x into collected
  98. count x into counted
  99. sum x into summed
  100. maximize x into maximized
  101. minimize x into minimized
  102. finally (return (list collected counted summed maximized minimized)))))
  103. (destructuring-bind (col count sum max min) loop-1
  104. (assert-equal col ____)
  105. (assert-equal count ____)
  106. (assert-equal sum ____)
  107. (assert-equal max ____)
  108. (assert-equal min ____))))
  109. (define-test test-destructuring-bind
  110. (let* ((count 0)
  111. (result (loop for (a b) in '((1 9) (2 8) (3 7) (4 6))
  112. do (setf count (+ 1 count))
  113. collect (+ a b))))
  114. (assert-equal ____ count)
  115. (assert-equal ____ result)))
  116. (define-test test-conditional-execution
  117. (let ((loop-return
  118. (loop for x in '(1 1 2 3 5 8 13)
  119. when (evenp x) sum x)))
  120. (assert-equal loop-return ____)))
  121. (defun greater-than-10-p (x)
  122. (> x 10))
  123. (define-test test-conditional-with-defun
  124. (let ((loop-return
  125. (loop for x in '(1 1 2 3 5 8 13)
  126. when (greater-than-10-p x) sum x)))
  127. (assert-equal loop-return ____)))
  128. (define-test test-conditional-with-lambda
  129. (let ((loop-return
  130. (loop for x in '(1 1 2 3 5 8 13)
  131. when ((lambda (z) (equal 1 (mod z 3))) x) sum x)))
  132. (assert-equal loop-return ____)))