aboutsummaryrefslogtreecommitdiff
path: root/challenge-088/jeongoon/common-lisp/ch-2.lsp
diff options
context:
space:
mode:
authorKang-min Liu <gugod@gugod.org>2020-12-02 08:27:20 +0900
committerKang-min Liu <gugod@gugod.org>2020-12-02 08:27:20 +0900
commit70adebf80e38d1e8e718f2e76cd74dee1bb001b1 (patch)
tree09f6806cada5e26f8200d25811720b047ed3fe14 /challenge-088/jeongoon/common-lisp/ch-2.lsp
parente1de20d977c235d63cf724ab65badac1a79d3b90 (diff)
parent885407d513a3e813981cfde43fddc20b6cb1ee30 (diff)
downloadperlweeklychallenge-club-70adebf80e38d1e8e718f2e76cd74dee1bb001b1.tar.gz
perlweeklychallenge-club-70adebf80e38d1e8e718f2e76cd74dee1bb001b1.tar.bz2
perlweeklychallenge-club-70adebf80e38d1e8e718f2e76cd74dee1bb001b1.zip
Merge remote-tracking branch 'manwar/master'
Diffstat (limited to 'challenge-088/jeongoon/common-lisp/ch-2.lsp')
-rw-r--r--challenge-088/jeongoon/common-lisp/ch-2.lsp105
1 files changed, 105 insertions, 0 deletions
diff --git a/challenge-088/jeongoon/common-lisp/ch-2.lsp b/challenge-088/jeongoon/common-lisp/ch-2.lsp
new file mode 100644
index 0000000000..8c926259de
--- /dev/null
+++ b/challenge-088/jeongoon/common-lisp/ch-2.lsp
@@ -0,0 +1,105 @@
+;; tested with:
+;; echo "[a b c][d e f][g h i] | sbcl --script ch-2.lsp
+
+(defun get-command-line ()
+ (or
+ #+CLISP *args*
+ #+SBCL *posix-argv*
+ #+LISPWORKS system:*line-arguments-list*
+ #+CMU extensions:*command-line-words*
+ nil))
+
+(defparameter *cmdline* (get-command-line))
+(defparameter *rows-list* '())
+(defvar row '())
+(defvar wrd nil)
+
+;; read from stdin
+(loop for line = (read-line *standard-input* nil)
+ while line
+ do(loop for ch in (coerce line 'list)
+ do(if (char= ch #\[)
+ Nil ;; ignore
+ (if (or (char= ch #\]) (char= ch #\Newline))
+ (progn
+ (when (not (null wrd))
+ (let ((word-str (coerce wrd 'string)))
+ (if (null row)
+ (setq row (list word-str))
+ (nconc row (list word-str))))
+ (setq wrd '()))
+ (when (not (null row))
+ (if (null *rows-list*)
+ (setq *rows-list* (list row))
+ (nconc *rows-list* (list row)))
+ (setq row '())))
+ (if (char= ch #\Space)
+ ;; add a word to row
+ (when (not (null wrd))
+ (let ((word-str (coerce wrd 'string)))
+ (if (null row)
+ (setq row (list word-str))
+ (nconc row (list word-str))))
+ (setq wrd '()))
+ ;; else: add a char to word
+ (progn
+ (if (null wrd)
+ (setq wrd (list ch))
+ (nconc wrd (list ch)))))))))
+
+(defparameter *num-rows* (length *rows-list*))
+(defparameter *num-cols* (length (first *rows-list*)))
+
+;; convert it into 2 dimensional array
+(defvar *matrix* (make-array (list *num-rows* *num-cols*)
+ :initial-contents *rows-list*))
+
+;; confirm input
+(format t "given matrix:~%")
+(dotimes (r *num-rows*)
+ (setq row (loop for c from 0 below *num-cols*
+ collect (aref *matrix* r c)))
+ (format t "[~{~a~^ ~}]~%" row))
+
+;; ( solution ... )
+;; this solution is only for reading
+;; so I haven't check for any side effect
+(defun get-spiral-array (mat) ;; take 2 dimensional array
+ (let* ((num-rows (array-dimension mat 0))
+ (num-cols (array-dimension mat 1))
+ (sarray '())) ;; result
+ (loop for o from 0
+ for row-end = (1- (+ o num-rows))
+ for col-end = (1- (+ o num-cols))
+ do (progn
+ ;; north
+ (let ((north-side (loop for c from o upto col-end
+ collect (aref mat o c))))
+ (if (null sarray)
+ (setq sarray north-side)
+ (nconc sarray north-side)))
+ ;; east
+ (let ((east-side (loop for r from (1+ o) upto row-end
+ collect (aref mat r col-end))))
+ (when (not (null east-side))
+ (nconc sarray east-side)
+ ;; south
+ (let ((south-side
+ (loop for c from (1- col-end) downto o
+ collect (aref mat row-end c))))
+ (when (not (null south-side))
+ (nconc sarray south-side)
+ ;; west
+ (let ((west-side
+ (loop for r from (1- row-end) above o
+ collect (aref mat r o))))
+ (when (not (null west-side))
+ (nconc sarray west-side))))))))
+ ;; go inner
+ do (progn (setq num-rows (- num-rows 2)
+ num-cols (- num-cols 2)))
+ while (and (< 0 num-rows) (< 0 num-cols)))
+
+ sarray)) ;; return
+
+(format t "[~{~a~^ ~}]~%" (get-spiral-array *matrix*))