Reputation: 137
I'm Haruo. My pleasure is solving SPOJ in Common Lisp(CLISP). Today I solved Classical/Balk! but in SBCL not CLISP. My CLISP submit failed due to runtime error (NZEC).
I hope my code becomes more sophisticated. Today's problem is just a chance. Please the following my code and tell me your refactoring strategy. I trust you.
Haruo
Upvotes: 1
Views: 424
Reputation: 139401
Take for example get-x-depth-for-yz-grid
.
(defun get-x-depth-for-yz-grid (planes//yz-plane grid)
(let ((planes (get-planes-including-yz-grid-in planes//yz-plane grid)))
(unless (evenp (length planes))
(error "error in get-x-depth-for-yz-grid"))
(sort planes (lambda (p1 p2) (< (caar p1) (caar p2))))
(do* ((rest planes (cddr rest)) (res 0))
((null rest) res)
(incf res (- (caar (second rest)) (caar (first rest)))))))
style -> ERROR can be replaced by ASSERT.
possible bug -> SORT is possibly destructive -> make sure you have a fresh list consed!. If it is already fresh allocated by get-planes-including-yz-grid-in
, then we don't need that.
bug -> SORT returns a sorted list. The sorted list is possibly not a side-effect. -> use the returned value
style -> DO replaced with LOOP.
style -> meaning of CAAR unclear. Find better naming or use other data structures.
(defun get-x-depth-for-yz-grid (planes//yz-plane grid)
(let ((planes (get-planes-including-yz-grid-in planes//yz-plane grid)))
(assert (evenp (length planes)) (planes)
"error in get-x-depth-for-yz-grid")
(setf planes (sort (copy-list planes) #'< :key #'caar))
(loop for (p1 p2) on planes by #'cddr
sum (- (caar p2) (caar p1)))))
Upvotes: 4
Reputation: 4360
->
macro will confuse sbcl’s type inference. You should have (-> x)
expand into x
, and (-> x y...)
into (let (($ x)) (-> y...))
loop
and use it in more places. dolist
with extra mutation is not greatdestructuring-bind
instead of eg (rest (rest ))
. You’re also inconsistent as sometimes you’d write (cddr...)
for that instead.block*
suffers from many problems:
(let (foo) (setf foo...))
which trips up sbcl type inference.block*
implies that the various bindings are scoped in a way that they may refer to those previously defined things but actually all initial value may refer to any variable or function name and if that variable has not been initialised then it evaluates to nil.get-x-y-and-z-ranges
really needs to use loop
. I think it’s wrong too: the lists are different lengths.first
, etc. Maybe even a struct(!)(sort foo)
might destroy foo
. You need to do (setf foo (sort foo))
.do
. Use loop
.:key
in a few places.defvar
but I think you mean defparameter
*t*
is a stupid nameUpvotes: 3