-
Notifications
You must be signed in to change notification settings - Fork 566
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test stuff, begin working on solved koans
- Loading branch information
Showing
47 changed files
with
3,461 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,4 +31,4 @@ | |
#:macros | ||
#+quicklisp #:threads | ||
#:extra-credit | ||
) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
;;; Copyright 2013 Google Inc. | ||
;;; | ||
;;; Licensed under the Apache License, Version 2.0 (the "License"); | ||
;;; you may not use this file except in compliance with the License. | ||
;;; You may obtain a copy of the License at | ||
;;; | ||
;;; http://www.apache.org/licenses/LICENSE-2.0 | ||
;;; | ||
;;; Unless required by applicable law or agreed to in writing, software | ||
;;; distributed under the License is distributed on an "AS IS" BASIS, | ||
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
;;; See the License for the specific language governing permissions and | ||
;;; limitations under the License. | ||
|
||
(define-test basic-array-stuff | ||
;; We make an 8x8 array and then fill it with a checkerboard pattern. | ||
(let ((chess-board (make-array '(8 8)))) | ||
;; (DOTIMES (X 8) ...) will iterate with X taking values from 0 to 7. | ||
(dotimes (x 8) | ||
(dotimes (y 8) | ||
;; AREF stands for "array reference". | ||
(setf (aref chess-board x y) (if (evenp (+ x y)) :black :white)))) | ||
(assert-true (typep chess-board 'array)) | ||
(assert-equal :black (aref chess-board 0 0)) | ||
(assert-equal :white (aref chess-board 2 3)) | ||
;; The function ARRAY-RANK returns the number of dimensions of the array. | ||
(assert-equal 2 (array-rank chess-board)) | ||
;; The function ARRAY-DIMENSIONS returns a list of the cardinality of the | ||
;; array dimensions. | ||
(assert-equal '(8 8) (array-dimensions chess-board)) | ||
;; ARRAY-TOTAL-SIZE returns the total number of elements in the array. | ||
(assert-equal 64 (array-total-size chess-board)))) | ||
|
||
(define-test make-your-own-array | ||
;; Make your own array that satisfies the test. | ||
(let ((color-cube (make-array '(3 3 3)))) | ||
;; You may need to modify your array after you create it. | ||
(setf (aref color-cube 0 1 2) :red | ||
(aref color-cube 2 1 0) :white) | ||
(if (typep color-cube '(simple-array T (3 3 3))) | ||
(progn | ||
(assert-equal 3 (array-rank color-cube)) | ||
(assert-equal '(3 3 3) (array-dimensions color-cube)) | ||
(assert-equal 27 (array-total-size color-cube)) | ||
(assert-equal (aref color-cube 0 1 2) :red) | ||
(assert-equal (aref color-cube 2 1 0) :white)) | ||
(assert-true nil)))) | ||
|
||
(define-test adjustable-array | ||
;; The size of an array does not need to be constant. | ||
(let ((x (make-array '(2 2) :initial-element 5 :adjustable t))) | ||
(assert-equal 5 (aref x 1 0)) | ||
(assert-equal '(2 2) (array-dimensions x)) | ||
(adjust-array x '(3 4)) | ||
(assert-equal '(3 4) (array-dimensions x)))) | ||
|
||
(define-test make-array-from-list | ||
;; One can create arrays with initial contents. | ||
(let ((x (make-array '(4) :initial-contents '(:one :two :three :four)))) | ||
(assert-equal '(4) (array-dimensions x)) | ||
(assert-equal :one (aref x 0)))) | ||
|
||
(define-test row-major-index | ||
;; Row major indexing is a way to access elements with a single integer, | ||
;; rather than a list of integers. | ||
(let ((my-array (make-array '(2 2 2 2)))) | ||
(dotimes (i (* 2 2 2 2)) | ||
(setf (row-major-aref my-array i) i)) | ||
(assert-equal 0 (aref my-array 0 0 0 0)) | ||
(assert-equal 15 (aref my-array 1 1 1 1)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
;;; Copyright 2013 Google Inc. | ||
;;; | ||
;;; Licensed under the Apache License, Version 2.0 (the "License"); | ||
;;; you may not use this file except in compliance with the License. | ||
;;; You may obtain a copy of the License at | ||
;;; | ||
;;; http://www.apache.org/licenses/LICENSE-2.0 | ||
;;; | ||
;;; Unless required by applicable law or agreed to in writing, software | ||
;;; distributed under the License is distributed on an "AS IS" BASIS, | ||
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
;;; See the License for the specific language governing permissions and | ||
;;; limitations under the License. | ||
|
||
;;; ╭╮ ╭╮ /////// | ||
;;; ┃┃ ┃┃/////// | ||
;;; ┃┃╭┳━━┳━━╮ ┃┃╭┳━━┳━━┳━╮╭━━╮ | ||
;;; ┃┃┣┫━━┫╭╮┃ ┃╰╯┫╭╮┃╭╮┃╭╮┫━━┫ | ||
;;; ┃╰┫┣━━┃╰╯┃ ┃╭╮┫╰╯┃╭╮┃┃┃┣━━┃ | ||
;;; ╰━┻┻━━┫╭━╯/╰╯╰┻━━┻╯╰┻╯╰┻━━╯ | ||
;;; ┃┃ ////// | ||
;;; ╰╯////// | ||
|
||
;;; Welcome to the Lisp Koans. | ||
;;; May the code stored here influence your enlightenment as a programmer. | ||
|
||
;;; In order to progress, fill in the blanks, denoted via ____ in source code. | ||
;;; Sometimes, you will be asked to provide values that are equal to something. | ||
|
||
(define-test fill-in-the-blanks | ||
(assert-equal 2 2) | ||
(assert-equal 3.14 3.14) | ||
(assert-equal "Hello World" "Hello World")) | ||
|
||
;;; Sometimes, you will be asked to say whether something is true or false, | ||
;;; In Common Lisp, the canonical values for truth and falsehood are T and NIL. | ||
|
||
(define-test assert-true | ||
(assert-true t)) | ||
|
||
(define-test assert-false | ||
(assert-false nil)) | ||
|
||
(define-test true-or-false | ||
(true-or-false? t (= 34 34)) | ||
(true-or-false? nil (= 19 78))) | ||
|
||
;;; Since T and NIL are symbols, you can type them in lowercase or uppercase; | ||
;;; by default, Common Lisp will automatically upcase them upon reading. | ||
|
||
(define-test upcase-downcase | ||
;; Try inserting a lowercase t here. | ||
(assert-equal t T) | ||
;; Try inserting an uppercase NIL here. | ||
(assert-equal NIL nil)) | ||
|
||
;;; Sometimes, you will be asked to provide a part of an expression that must be | ||
;;; either true or false. | ||
|
||
(define-test a-true-assertion | ||
(assert-true (= 4 (+ 2 2)))) | ||
|
||
(define-test a-false-assertion | ||
(assert-false (= 5 (+ 2 2)))) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
;;; Copyright 2013 Google Inc. | ||
;;; | ||
;;; Licensed under the Apache License, Version 2.0 (the "License"); | ||
;;; you may not use this file except in compliance with the License. | ||
;;; You may obtain a copy of the License at | ||
;;; | ||
;;; http://www.apache.org/licenses/LICENSE-2.0 | ||
;;; | ||
;;; Unless required by applicable law or agreed to in writing, software | ||
;;; distributed under the License is distributed on an "AS IS" BASIS, | ||
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
;;; See the License for the specific language governing permissions and | ||
;;; limitations under the License. | ||
|
||
;;; Lists in lisp are forms beginning and ending with rounded parentheses. | ||
;;; Atoms are symbols, numbers, or other forms usually separated by whitespace | ||
;;; or parentheses. | ||
|
||
(define-test list-or-atom | ||
;; The function LISTP will return true if the input is a list. | ||
;; The function ATOM will return true if the input is an atom. | ||
(true-or-false? t (listp '(1 2 3))) | ||
(true-or-false? nil (atom '(1 2 3))) | ||
(true-or-false? t (listp '("heres" "some" "strings"))) | ||
(true-or-false? nil (atom '("heres" "some" "strings"))) | ||
(true-or-false? nil (listp "a string")) | ||
(true-or-false? t (atom "a string")) | ||
(true-or-false? nil (listp 2)) | ||
(true-or-false? t (atom 2)) | ||
(true-or-false? t (listp '(("first" "list") ("second" "list")))) | ||
(true-or-false? nil (atom '(("first" "list") ("second" "list"))))) | ||
|
||
(define-test the-duality-of-nil | ||
;; The empty list, NIL, is unique in that it is both a list and an atom. | ||
(true-or-false? t (listp nil)) | ||
(true-or-false? t (atom nil))) | ||
|
||
(define-test keywords | ||
;; Symbols like :HELLO or :LIKE-THIS are keywords. They are treated | ||
;; differently in Lisp: they are constants that always evaluate to themselves. | ||
(true-or-false? t (equal :this-is-a-keyword :this-is-a-keyword)) | ||
(true-or-false? t (equal :this-is-a-keyword ':this-is-a-keyword)) | ||
(true-or-false? nil (equal :this-is-a-keyword :this-is-also-a-keyword))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
;;; Copyright 2013 Google Inc. | ||
;;; | ||
;;; Licensed under the Apache License, Version 2.0 (the "License"); | ||
;;; you may not use this file except in compliance with the License. | ||
;;; You may obtain a copy of the License at | ||
;;; | ||
;;; http://www.apache.org/licenses/LICENSE-2.0 | ||
;;; | ||
;;; Unless required by applicable law or agreed to in writing, software | ||
;;; distributed under the License is distributed on an "AS IS" BASIS, | ||
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
;;; See the License for the specific language governing permissions and | ||
;;; limitations under the License. | ||
|
||
;;; Backquote notation is similar to quoting, except it allows for parts of the | ||
;;; resulting expression to be "unquoted". | ||
|
||
(define-test backquote-basics | ||
(let ((x '(123)) | ||
(z '(7 8 9))) | ||
;; ' quotes an expression normally. | ||
(assert-equal ____ '(x 45 6 z)) | ||
;; ` backquotes an expression; without any unquotes, it is equivalent to | ||
;; using the normal quote. | ||
(assert-equal ____ `(x 45 6 z)) | ||
;; , unquotes a part of the expression. | ||
(assert-equal ____ `(,x 45 6 z)) | ||
(assert-equal ____ `(,x 45 6 ,z)) | ||
;; ,@ splices an expression into the into the list surrounding it. | ||
(assert-equal ____ `(,x 45 6 ,@z)) | ||
(assert-equal ____ `(,@x 45 6 ,@z)))) | ||
|
||
(define-test backquote-forms | ||
;; Because of its properties, backquote is useful for constructing Lisp forms | ||
;; that are macroexpansions or parts of macroexpansions. | ||
(let ((variable 'x)) | ||
;; Fill in the blank without without using backquote/unquote notation. | ||
(assert-equal ____ | ||
`(if (typep ,variable 'string) | ||
(format nil "The value of ~A is ~A" ',variable ,variable) | ||
(error 'type-error :datum ,variable | ||
:expected-type 'string)))) | ||
(let ((error-type 'type-error) | ||
(error-arguments '(:datum x :expected-type 'string))) | ||
;; Fill in the blank without without using backquote/unquote notation. | ||
(assert-equal ____ | ||
`(if (typep x 'string) | ||
(format nil "The value of ~A is ~A" 'x x) | ||
(error ',error-type ,@error-arguments))))) | ||
|
||
(define-test numbers-and-words | ||
(let ((number 5) | ||
(word 'dolphin)) | ||
(true-or-false? ____ (equal '(1 3 5) `(1 3 5))) | ||
(true-or-false? ____ (equal '(1 3 5) `(1 3 number))) | ||
(assert-equal _____ `(1 3 ,number)) | ||
(assert-equal _____ `(word ,word ,word word)))) | ||
|
||
(define-test splicing | ||
(let ((axis '(x y z))) | ||
(assert-equal '(the axis are ____) `(the axis are ,axis)) | ||
(assert-equal '(the axis are ____) `(the axis are ,@axis))) | ||
(let ((coordinates '((43.15 77.6) (42.36 71.06)))) | ||
(assert-equal ____ `(the coordinates are ,coordinates)) | ||
(assert-equal ____ `(the coordinates are ,@coordinates)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
;;; Copyright 2013 Google Inc. | ||
;;; | ||
;;; Licensed under the Apache License, Version 2.0 (the "License"); | ||
;;; you may not use this file except in compliance with the License. | ||
;;; You may obtain a copy of the License at | ||
;;; | ||
;;; http://www.apache.org/licenses/LICENSE-2.0 | ||
;;; | ||
;;; Unless required by applicable law or agreed to in writing, software | ||
;;; distributed under the License is distributed on an "AS IS" BASIS, | ||
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
;;; See the License for the specific language governing permissions and | ||
;;; limitations under the License. | ||
|
||
(define-test setf | ||
;; SETF is a macro used to assign values to places. A place is a concept; | ||
;; it is an abstract "somewhere" where a value is stored. | ||
(let ((a 10) | ||
(b (list 1 20 30 40 50)) | ||
;; We use COPY-SEQ to create a copy of a string, because using SETF to | ||
;; modify literal data (strings, lists, etc.) is undefined behaviour. | ||
(c (copy-seq "I am Tom."))) | ||
;; A place may be a variable. | ||
(setf a 1000) | ||
(assert-equal 1000 a) | ||
;; A place may be a part of some list. | ||
(setf (first b) 10) | ||
(assert-equal '(10 20 30 40 50) b) | ||
;; A place may be a character in a string. | ||
;; The #\x syntax denotes a single character, 'x'. | ||
(setf (char c 5) #\B | ||
(char c 7) #\b) | ||
(assert-equal "I am Bob." c) | ||
;; There are other kinds of places that we will explore in the future. | ||
)) | ||
|
||
(define-test case | ||
;; CASE is a simple pattern-matching macro, not unlike C's "switch". | ||
;; It compares an input against a set of values and evaluates the code for | ||
;; the branch where a match is found. | ||
(let* ((a 4) | ||
(b (case a | ||
(3 :three) | ||
(4 :four) | ||
(5 :five)))) | ||
(assert-equal :four b)) | ||
;; CASE can accept a group of keys. | ||
(let* ((c 4) | ||
(d (case c | ||
((0 2 4 6 8) :even-digit) | ||
((1 3 5 7 9) :odd-digit)))) | ||
(assert-equal :even-digit d))) | ||
|
||
(defun match-special-cases (thing) | ||
;; T or OTHERWISE passed as the key matches any value. | ||
;; NIL passed as the key matches no values. | ||
;; These symbols need to passed in parentheses. | ||
(case thing | ||
((t) :found-a-t) | ||
((nil) :found-a-nil) | ||
(t :something-else))) | ||
|
||
(define-test special-cases-of-case | ||
;; You need to fill in the blanks in MATCH-SPECIAL-CASES. | ||
(assert-equal :found-a-t (match-special-cases t)) | ||
(assert-equal :found-a-nil (match-special-cases nil)) | ||
(assert-equal :something-else (match-special-cases 42))) | ||
|
||
(define-test your-own-case-statement | ||
;; We use FLET to define a local function. | ||
(flet ((cartoon-dads (input) | ||
(case input | ||
;; Fill in the blanks with proper cases. | ||
(:bart :homer) | ||
(:stewie :peter) | ||
(:stan :randy) | ||
(:this-one-doesnt-happen :fancy-cat) | ||
(t :unknown)))) | ||
(assert-equal (cartoon-dads :bart) :homer) | ||
(assert-equal (cartoon-dads :stewie) :peter) | ||
(assert-equal (cartoon-dads :stan) :randy) | ||
(assert-equal (cartoon-dads :space-ghost) :unknown))) | ||
|
||
(define-test limits-of-case | ||
;; So far, we have been comparing objects using EQUAL, one of the Lisp | ||
;; comparison functions. CASE compares the keys using EQL, which is distinct | ||
;; from EQUAL. | ||
;; EQL is suitable for comparing numbers, characters, and objects for whom we | ||
;; want to check verify they are the same object. | ||
(let* ((string "A string") | ||
(string-copy (copy-seq string))) | ||
;; The above means that two distinct strings will not be the same under EQL, | ||
;; even if they have the same contents. | ||
(true-or-false? nil (eql string string-copy)) | ||
(true-or-false? t (equal string string-copy)) | ||
;; The above also means that CASE might give surprising results when used on | ||
;; strings. | ||
(let ((match (case string | ||
("A string" :matched) | ||
(t :not-matched)))) | ||
(assert-equal :not-matched match)) | ||
;; We will explore this topic further in the EQUALITY-DISTINCTIONS lesson. | ||
)) | ||
|
||
(define-test cond | ||
;; COND is similar to CASE, except it is more general. It accepts arbitrary | ||
;; conditions and checks them in order until one of them is met. | ||
(let* ((number 4) | ||
(result (cond ((> number 0) :positive) | ||
((< number 0) :negative) | ||
(t :zero)))) | ||
(assert-equal :positive result))) |
Oops, something went wrong.