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

iteration.lsp 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. ;; There are many options for iteration in lisp.
  15. ;; This set of koans will introduce a few of the most common ones
  16. ;; Dolist evaluates a form for every element om a list.
  17. (defvar some-primes '(10301 11311 19991 999565999))
  18. (define-test test-dolist
  19. "'dolist' iterates over values in a list, binding each value to a lexical
  20. variable in turn"
  21. (let ((how-many-in-list 0)
  22. (biggest-in-list (first some-primes)))
  23. "this dolist loops over the some-primes, defined above"
  24. (dolist (one-prime some-primes)
  25. (if (> one-prime biggest-in-list)
  26. (setf biggest-in-list one-prime))
  27. (incf how-many-in-list))
  28. (assert-equal 4 how-many-in-list)
  29. (assert-equal 999565999 biggest-in-list))
  30. (let ((sum 0))
  31. "write your own do-list here to calculate the sum of some-primes"
  32. "you may be interested in investigating the 'incf' function"
  33. (dolist (x some-primes)
  34. (incf sum x))
  35. (assert-equal 999607602 sum)))
  36. (define-test test-dolist-with-return
  37. "Dolist can accept a return variable, which will be the return value
  38. upon completion of the iteration."
  39. (let ((my-list '(1 2 3 4))
  40. (my-return))
  41. (dolist (x my-list my-return)
  42. (push (* x x) my-return))
  43. (assert-equal '(16 9 4 1) my-return)))
  44. (define-test test-dotimes
  45. "'dotimes' iterates over the integers from 0 to (limit - 1),
  46. binding them in order to your selected symbol."
  47. (let ((out-list nil))
  48. (dotimes (y 3) (push y out-list))
  49. (assert-equal out-list '(2 1 0))))
  50. (defvar *x* "global")
  51. (define-test test-dotimes-binding
  52. "dotimes establishes a local lexical binding which may shadow
  53. a global value."
  54. (dotimes (*x* 4)
  55. (true-or-false? nil (equal "global" *x*)))
  56. (true-or-false? t (equal "global" *x*)))
  57. (define-test test-loop-until-return
  58. "Loop loops forever, unless some return condition is executed.
  59. Note that the loop macro includes many additional options,
  60. which will be covered in a future koan."
  61. (let ((loop-counter 0))
  62. (loop
  63. (incf loop-counter)
  64. (if (>= loop-counter 100) (return loop-counter)))
  65. (assert-equal 100 loop-counter)))
  66. (define-test test-mapcar
  67. "mapcar takes a list an a function. It returns a new list
  68. with the function applied to each element of the input"
  69. (let ((mc-result (mapcar #'evenp '(1 2 3 4 5))))
  70. (assert-equal mc-result '(nil t nil t nil))))
  71. ;; ----
  72. (defun vowelp (c)
  73. "returns true if c is a vowel"
  74. (find c "AEIOUaeiou"))
  75. (defun vowels-to-xs (my-string)
  76. "converts all vowels in a string to the character 'x'"
  77. (coerce
  78. (loop for c across my-string
  79. with new-c
  80. do (setf new-c (if (vowelp c) #\x c))
  81. collect new-c)
  82. 'string))
  83. (define-test test-mapcar-with-defun
  84. "mapcar is a convenient way to apply a function to a collection"
  85. (assert-equal (vowels-to-xs "Astronomy") "xstrxnxmy")
  86. (let* ((subjects '("Astronomy" "Biology" "Chemistry" "Linguistics"))
  87. (mc-result (mapcar #'vowels-to-xs subjects)))
  88. (assert-equal mc-result '("xstrxnxmy" "Bxxlxgy" "Chxmxstry" "Lxngxxstxcs"))))
  89. ;; ----
  90. (define-test test-mapcar-with-lambda
  91. (let ((mc-result (mapcar (lambda (x) (mod x 10)) '(21 152 403 14))))
  92. (assert-equal mc-result '(1 2 3 4))))