aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMyoungjin JEON <jeongoon@gmail.com>2020-09-16 17:29:56 +1000
committerMyoungjin JEON <jeongoon@gmail.com>2020-09-16 17:29:56 +1000
commitf62dcb1f5ff22001b1ac0824cd76f49717c383ac (patch)
tree82665c065905f0b94b2af1c267035a91ba5a7875
parentfca5d7df3072bc6d574b2dc71c2a80ee5a82359b (diff)
downloadperlweeklychallenge-club-f62dcb1f5ff22001b1ac0824cd76f49717c383ac.tar.gz
perlweeklychallenge-club-f62dcb1f5ff22001b1ac0824cd76f49717c383ac.tar.bz2
perlweeklychallenge-club-f62dcb1f5ff22001b1ac0824cd76f49717c383ac.zip
[ch-067/jeongoon] Lisp solution added; [ch-078/jeongoon] Lisp solution added.
-rw-r--r--challenge-067/jeongoon/common-lisp/ch-1.lsp66
-rw-r--r--challenge-067/jeongoon/common-lisp/ch-2.lsp88
-rw-r--r--challenge-078/jeongoon/common-lisp/ch-1.lsp35
-rw-r--r--challenge-078/jeongoon/common-lisp/ch-2.lsp42
-rw-r--r--challenge-078/jeongoon/haskell/ch-2.hs2
5 files changed, 232 insertions, 1 deletions
diff --git a/challenge-067/jeongoon/common-lisp/ch-1.lsp b/challenge-067/jeongoon/common-lisp/ch-1.lsp
new file mode 100644
index 0000000000..304a37b356
--- /dev/null
+++ b/challenge-067/jeongoon/common-lisp/ch-1.lsp
@@ -0,0 +1,66 @@
+;; a non-recursive combination modified for challenge
+(defun make-vector-range (min max)
+ (let* ((range (loop for i from min to max collect i))
+ (size (length range)))
+ (make-array (list size) :initial-contents range)))
+
+(defun combinations (n m)
+ ;; a non-recursive method for making combinations
+ (when (>= m n)
+ (let* ((initial-room-size (- m n))
+ (room (make-array (list n) :initial-element initial-room-size))
+ (num (make-array (list n)
+;; :initial-contents (make-vector-range 0 (1- n))))
+ :initial-contents (make-vector-range 1 n)))
+ (next-cursor (1- n))
+ (combi (list (coerce num 'list)))) ;; coerce makes a copy of array
+ (loop named moving-element do
+ (if (> (aref room next-cursor) 0)
+ ;; still current element move to right
+ (let ((ref-room (aref room next-cursor))
+ (ref-num (aref num next-cursor)))
+ (setf (aref room next-cursor) (1- ref-room))
+ (setf (aref num next-cursor) (1+ ref-num))
+ (nconc combi (list (coerce num 'list))))
+ ;; else
+ ;; no more room left on the right for current element
+ ;; have to move cursor to point next avaiable one.
+ (let*
+ ((cursor-moved
+ (loop named moving-cursor for i from next-cursor above 0
+ do
+ (when (> (aref room (1- i)) 0)
+ (setq next-cursor (1- i))
+ (return-from moving-cursor t)))))
+ (if cursor-moved
+ (let ((room-size (1- (aref room next-cursor)))
+ (base-num (aref num next-cursor)))
+ (loop for i from next-cursor below n
+ for p from 1 do
+ (progn
+ (setf (aref room i) room-size)
+ (setf (aref num i) (+ base-num p))))
+ (nconc combi (list (coerce num 'list)))
+ (setq next-cursor (1- n)))
+ ;; else : "no more movement" means we found all combinations
+ (return-from moving-element combi))))))))
+
+(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))
+
+(defun print-usage ()
+ (format t "Usage: sbcl --script ch-1.lsp <$m> <$n>"
+ (first *cmdline*)))
+
+(when (< (length *cmdline*) 3) (print-usage) (quit))
+(defparameter *maximum-natnum* (parse-integer (second *cmdline*)))
+(defparameter *num-selection* (parse-integer (third *cmdline*)))
+
+(format t "~a~%" (combinations *num-selection* *maximum-natnum*))
diff --git a/challenge-067/jeongoon/common-lisp/ch-2.lsp b/challenge-067/jeongoon/common-lisp/ch-2.lsp
new file mode 100644
index 0000000000..45807ce99a
--- /dev/null
+++ b/challenge-067/jeongoon/common-lisp/ch-2.lsp
@@ -0,0 +1,88 @@
+;; from ch-077/ch-1.lsp
+
+(defun flat-once (list-of-list)
+ (let ((all '()))
+ (map nil #'(lambda (ls) (setq all (append all ls))) list-of-list)
+ all))
+
+;; get a list of vectors
+;; each vector has all the possible cases and this function will
+;; product the all the cases by going through
+;; this function is a non-recursive implementation of product the cases
+(defun product-cases (cases-map &optional validate-func)
+ (let* ((num-cases (length cases-map))
+ (cases-vec (make-array (list num-cases) :initial-contents cases-map))
+ (pos (make-array (list num-cases) :initial-element 0))
+ (csr (1- num-cases)) ;; pointing the last case
+ (all-cases (list 'remove-me)))
+
+ (loop named processing-cases do
+ (if (< (aref pos csr) (length (aref cases-vec csr)))
+ ;; still have next step at the current cursor
+ (let* ((cur-cases-combi
+ (mapcar
+ (lambda (sub-case cur-sub-case-idx)
+ (coerce (aref sub-case cur-sub-case-idx) 'list))
+ cases-map (coerce pos 'list))))
+
+ (when (or (null validate-func)
+ (funcall validate-func cur-cases-combi))
+ ;; flatten and collect the case
+ (nconc all-cases (list (flat-once cur-cases-combi))))
+ ;; try next case
+ (setf (aref pos csr) (1+ (aref pos csr))))
+ ;; else -- try to go higher order
+ (let* ((new-csr
+ (loop named finding-new-cursor
+ for c from (1- csr) downto 0
+ if (< (aref pos c) (1- (length (aref cases-vec c))))
+ do (return-from finding-new-cursor c))))
+ (if (null new-csr)
+ (return-from processing-cases)
+ (progn
+ (setf (aref pos new-csr) (1+ (aref pos new-csr)))
+ (loop for i from (1+ new-csr) below num-cases
+ do (setf (aref pos i) 0))
+ (setq csr (1- num-cases)))))))
+ (cdr all-cases)))
+
+
+(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))
+
+(defun print-usage ()
+ (format t "Usage: sbcl --script ch-1.lsp <$S> # ex) 35"
+ (first *cmdline*)))
+
+(when (< (length *cmdline*) 2) (print-usage) (quit))
+(defparameter *numbers-to-change* (second *cmdline*))
+(defparameter *letter-phone-hash* (make-hash-table))
+;; generating letter phone dial pad to lookup
+(mapcar (lambda (c v) (setf (gethash (intern (string c)) *letter-phone-hash*) v))
+ (coerce "0123456789*#" 'list)
+ '("" "_,@" "abc" "def" "ghi" "jkl" "mno" "pqrs" "tuv" "wxyz" " " ""))
+
+(defvar cases-map
+ (loop for num-char in (coerce *numbers-to-change* 'list)
+ collect (let* ((sym (intern (string num-char)))
+ (candi-lst (coerce (gethash sym *letter-phone-hash*) 'list)))
+ (make-array (list (length candi-lst))
+ :initial-contents
+ ;; product-case function will get
+ ;; a list of vectors, each vector has to get
+ ;; all the lists which contain a possible case
+ ;; which canbe a simple character or a list
+ ;; e.g) #(("a case") ("b case")) or
+ ;; #((1 2 3) (4 5))
+ (map 'list (lambda (a-char) (list a-char)) candi-lst)))))
+
+;;(format t "~a~%" cases-map)
+(format t "[~{\"~a\"~^, ~}]~%" (map 'list (lambda (a-case) (coerce a-case 'string))
+ (product-cases cases-map)))
diff --git a/challenge-078/jeongoon/common-lisp/ch-1.lsp b/challenge-078/jeongoon/common-lisp/ch-1.lsp
new file mode 100644
index 0000000000..2b72d9be22
--- /dev/null
+++ b/challenge-078/jeongoon/common-lisp/ch-1.lsp
@@ -0,0 +1,35 @@
+;; tested with: sbcl --script ch-1.lsp 9 10 7 5 6 1
+
+(defun leader-element (numbers)
+ (if (null numbers) '(0)
+ ;; else
+ (let* ((rnumbers (reverse numbers))
+ (cur-leader (1- (apply #'min numbers)))) ;; pseudo first leader
+ (reverse
+ (loop for leader in
+ (map 'list (lambda (c) ;; (c)andidate
+ (if (<= cur-leader c)
+ (progn (setq cur-leader c) c) nil)) rnumbers)
+ if (not (null leader)) collect leader)))))
+
+(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))
+
+(defun print-usage ()
+ (format t "Usage: sbcl --script ch-1.lsp <integer> ..." (first *cmdline*)))
+(when (< (length *cmdline*) 1) (print-usage) (quit))
+
+(defparameter *numbers*
+ (remove-if #'null ;; filtering non-integer values ...
+ (map 'list (lambda (n-str) (parse-integer n-str :junk-allowed t))
+ (rest *cmdline*))))
+
+(format t "@A = ~a~%" *numbers*)
+(format t "@B = ~a~%" (leader-element *numbers*))
diff --git a/challenge-078/jeongoon/common-lisp/ch-2.lsp b/challenge-078/jeongoon/common-lisp/ch-2.lsp
new file mode 100644
index 0000000000..d258c61b0e
--- /dev/null
+++ b/challenge-078/jeongoon/common-lisp/ch-2.lsp
@@ -0,0 +1,42 @@
+(defun left-rotate (lst n)
+ (loop for e in lst
+ for i from 0
+ if (< i n) collect e into backs
+ else collect e into fronts
+ finally (return (concatenate 'list fronts backs))))
+
+(defun map-left-rotate (lst n-list)
+ (map 'list (lambda (n) (funcall #'left-rotate lst n)) n-list))
+
+(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))
+
+(defun print-usage ()
+ (format t "Usage: sbcl --script ch-1.lsp <integer> ... / <unsigned integer> ..."
+ (first *cmdline*)))
+(when (< (length *cmdline*) 5) (print-usage) (quit))
+
+(defparameter *sep* nil)
+(defparameter *a-array* '())
+(defparameter *b-array* '())
+
+;; ref: http://clhs.lisp.se/Body/05_abc.htm
+(setf (values *a-array* *b-array*)
+ (loop for arg in (rest *cmdline*)
+ for n = (parse-integer arg :junk-allowed t)
+ if (null n) do (when (null *sep*) (setq *sep* arg))
+ else if (null *sep*) collect arg into a-array
+ else collect n into b-array
+ finally (return (values a-array b-array))))
+
+(format t "@A = ~a~%" *a-array*)
+(format t "@B = ~a~%" *b-array*)
+(loop for rotated in (map-left-rotate *a-array* *b-array*)
+ do (format t "~a~%" rotated))
diff --git a/challenge-078/jeongoon/haskell/ch-2.hs b/challenge-078/jeongoon/haskell/ch-2.hs
index 04a6c6d5a8..1083b9bbd7 100644
--- a/challenge-078/jeongoon/haskell/ch-2.hs
+++ b/challenge-078/jeongoon/haskell/ch-2.hs
@@ -3,7 +3,7 @@ import Data.List
import Data.Char (isNumber)
import Data.Maybe (catMaybes)
--- tested with: runhaskell 7 4 2 6 3 / 1 3 4
+-- tested with: runhaskell ch-2.hs 7 4 2 6 3 / 1 3 4
-- use any non-digit value as a separator between @A and @B
unsafe_mapLeftRotate ls rotates =