Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Coding challenge: Can you make this function more elegant?
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 1 - 25 of 41 - Collapse all  -  Translate all to Translated (View all originals)   Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
jrwats  
View profile  
 More options Dec 8 2008, 8:29 pm
Newsgroups: comp.lang.lisp
From: jrwats <jrw...@gmail.com>
Date: Mon, 8 Dec 2008 17:29:26 -0800 (PST)
Local: Mon, Dec 8 2008 8:29 pm
Subject: Coding challenge: Can you make this function more elegant?
Destructively moves the "best" element (according to the predicate
function passed in) to the front of a list.  Feel free to improve the
code by using other functions, recursion, etc, but it must only visit
each element once.  i.e. you can't just find the best and call (remove
best lst :test #'equal :count 1) and then cons best onto lst.

(defun nbest-to-front (lst pred)
  (let ((best lst)
        (par nil))
    (do* ((prev lst (cdr prev))
          (chk (cdr prev) (cdr prev)))
         ((endp chk))
      (if (funcall pred (car chk) (car best))
          (setq best chk par prev)))
    (if par
        (setf (cdr par) (cdr best)))
    (setf lst (cons (car best) lst)))) ;; last line is redundant if
par = nil, but I'd like lst returned...

The alternative I thought of to that last line is:
(when par
      (setf (cdr par) (cdr best))
      (setf lst (cons (car best) lst)))
    lst))

becase I'd like the list returned, and the latter uses more lines, I
stuck with the first.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
anonymous.c.lis...@gmail.com  
View profile  
 More options Dec 8 2008, 8:44 pm
Newsgroups: comp.lang.lisp
From: anonymous.c.lis...@gmail.com
Date: Mon, 8 Dec 2008 17:44:09 -0800 (PST)
Local: Mon, Dec 8 2008 8:44 pm
Subject: Re: Coding challenge: Can you make this function more elegant?
On Dec 8, 8:29 pm, jrwats <jrw...@gmail.com> wrote:

>  i.e. you can't just find the best and call (remove
> best lst :test #'equal :count 1) and then cons best onto lst.

Why? That seems to be easiest way to do it.

easiest = most elegant.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
jrwats  
View profile  
 More options Dec 8 2008, 9:19 pm
Newsgroups: comp.lang.lisp
From: jrwats <jrw...@gmail.com>
Date: Mon, 8 Dec 2008 18:19:59 -0800 (PST)
Local: Mon, Dec 8 2008 9:19 pm
Subject: Re: Coding challenge: Can you make this function more elegant?

>     (setf lst (cons (car best) lst))))
>      ;; last line is redundant if par = nil, but I'd like lst returned...

Actually - this is buggy and will duplicate the front element if par
(parent) = nil

> The alternative I thought of to that last line is:
> (when par
>       (setf (cdr par) (cdr best))
>       (setf lst (cons (car best) lst)))
>     lst))

Not an alternative - requirement...

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
jrwats  
View profile  
 More options Dec 8 2008, 9:21 pm
Newsgroups: comp.lang.lisp
From: jrwats <jrw...@gmail.com>
Date: Mon, 8 Dec 2008 18:21:32 -0800 (PST)
Local: Mon, Dec 8 2008 9:21 pm
Subject: Re: Coding challenge: Can you make this function more elegant?
On Dec 8, 5:44 pm, anonymous.c.lis...@gmail.com wrote:
> On Dec 8, 8:29 pm, jrwats <jrw...@gmail.com> wrote:

> >  i.e. you can't just find the best and call (remove
> > best lst :test #'equal :count 1) and then cons best onto lst.

> Why? That seems to be easiest way to do it.

Maybe - I wasn't sure if there was a better method of doing this that
I wasn't seeing...

> easiest = most elegant.

I concur.  Was also hoping for something a little more terse.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kenny  
View profile  
 More options Dec 8 2008, 9:53 pm
Newsgroups: comp.lang.lisp
From: Kenny <kentil...@gmail.com>
Date: Mon, 08 Dec 2008 21:53:45 -0500
Local: Mon, Dec 8 2008 9:53 pm
Subject: Re: Coding challenge: Can you make this function more elegant?

Can we use loop and rotatef? (hint)

kt


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
anonymous.c.lis...@gmail.com  
View profile  
 More options Dec 8 2008, 11:49 pm
Newsgroups: comp.lang.lisp
From: anonymous.c.lis...@gmail.com
Date: Mon, 8 Dec 2008 20:49:36 -0800 (PST)
Local: Mon, Dec 8 2008 11:49 pm
Subject: Re: Coding challenge: Can you make this function more elegant?
On Dec 8, 9:53 pm, Kenny <kentil...@gmail.com> wrote:

Why would I do that?

(sort list pred)

And it gets all the others in the right order as a bonus!


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
jrwats  
View profile  
 More options Dec 9 2008, 12:33 am
Newsgroups: comp.lang.lisp
From: jrwats <jrw...@gmail.com>
Date: Mon, 8 Dec 2008 21:33:12 -0800 (PST)
Local: Tues, Dec 9 2008 12:33 am
Subject: Re: Coding challenge: Can you make this function more elegant?

> Can we use loop and rotatef? (hint)

> kt

Hmmm... a welcome hint:

(defun nmove-best-to-front2 (lst pred)
  (loop for i on lst do
       (if (funcall pred (car i) (car lst))
         (rotatef (car lst) (car i)))))

I'll have to remember this rotatef voodoo...

However... it's still doing swapping on each best find.  I'd imagine
it's markedly slower when using a list sorted reverse of the given
predicate (descending?).  It doesn't change the runtime O(n), but ah
what the heck, slime is open, I'll run it now:

scratch that - way to slow...

CL-USER> (time (test-nmove-best-to-front2 1000000))
Evaluation took:
  2.446 seconds of real time
  2.424151 seconds of total run time (2.396150 user, 0.028001 system)
  99.10% CPU
  3,827,875,897 processor cycles
  0 bytes consed
NIL
CL-USER> (time (test-nmove-best-to-front 1000000))
Evaluation took:
  0.048 seconds of real time
  0.040003 seconds of total run time (0.040003 user, 0.000000 system)
  83.33% CPU
  49,030,586 processor cycles
  0 bytes consed

How about this:

(defun nmove-best-to-front3 (lst pred)
  (let ((best (car lst))
        (best-lst lst))
    (loop for i on (cdr lst) do
         (if (funcall pred (car i) best)
             (setq best (car i) best-lst i)))
    (rotatef (car lst) (car best-lst))))

CL-USER> (time (test-nmove-best-to-front3 1000000))
Evaluation took:
  2.902 seconds of real time
  2.876180 seconds of total run time (2.856178 user, 0.020002 system)
  99.10% CPU
  3,792,683,484 processor cycles
  0 bytes consed
NIL

Hmm... that didn't help... what's going on?


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
jrwats  
View profile  
 More options Dec 9 2008, 12:36 am
Newsgroups: comp.lang.lisp
From: jrwats <jrw...@gmail.com>
Date: Mon, 8 Dec 2008 21:36:53 -0800 (PST)
Local: Tues, Dec 9 2008 12:36 am
Subject: Re: Coding challenge: Can you make this function more elegant?

> Can we use loop and rotatef? (hint)

> kt

Hmmm... a welcome hint:

(defun nmove-best-to-front2 (lst pred)
  (loop for i on lst do
       (if (funcall pred (car i) (car lst))
         (rotatef (car lst) (car i)))))

I'll have to remember this rotatef voodoo...

However... it's still doing swapping on each best find.  I'd imagine
it's markedly slower when using a list sorted reverse of the given
predicate (descending?).  It doesn't change the runtime O(n), but ah
what the heck, slime is open, I'll run it now:

scratch that - way to slow...

CL-USER> (time (test-nmove-best-to-front2 1000000))
Evaluation took:
  2.446 seconds of real time
  2.424151 seconds of total run time (2.396150 user, 0.028001 system)
  99.10% CPU
  3,827,875,897 processor cycles
  0 bytes consed
NIL
CL-USER> (time (test-nmove-best-to-front 1000000))
Evaluation took:
  0.048 seconds of real time
  0.040003 seconds of total run time (0.040003 user, 0.000000 system)
  83.33% CPU
  49,030,586 processor cycles
  0 bytes consed

How about this:

(defun nmove-best-to-front3 (lst pred)
  (let ((best (car lst))
        (best-lst lst))
    (loop for i on (cdr lst) do
         (if (funcall pred (car i) best)
             (setq best (car i) best-lst i)))
    (rotatef (car lst) (car best-lst))))

CL-USER> (time (test-nmove-best-to-front3 1000000))
Evaluation took:
  2.902 seconds of real time
  2.876180 seconds of total run time (2.856178 user, 0.020002 system)
  99.10% CPU
  3,792,683,484 processor cycles
  0 bytes consed
NIL

Hmm... that didn't help... what's going on?


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
jrwats  
View profile  
 More options Dec 9 2008, 12:44 am
Newsgroups: comp.lang.lisp
From: jrwats <jrw...@gmail.com>
Date: Mon, 8 Dec 2008 21:44:03 -0800 (PST)
Local: Tues, Dec 9 2008 12:44 am
Subject: Re: Coding challenge: Can you make this function more elegant?
On Dec 8, 9:33 pm, jrwats <jrw...@gmail.com> wrote:

OK - one more post.  To recap:

(defun nmove-best-to-front (lst pred)
  (let ((best lst)
        (parent nil))
    (do* ((prev lst (cdr prev))
          (cur (cdr prev) (cdr prev)))
         ((endp cur))
      (if (funcall pred (car cur) (car best))
          (setf best cur parent prev)))
    (when parent
      (setf (cdr parent) (cdr best))
      (setf lst (cons (car best) lst)))
    lst))

(defun nmove-best-to-front2 (lst pred)
  (loop for i on (cdr lst) do
       (if (funcall pred (car i) (car lst))
           (rotatef (car lst) (car i)))))

(defun nmove-best-to-front3 (lst pred)
  (let ((best (car lst))
        (best-lst lst))
    (loop for i on (cdr lst) do
         (if (funcall pred (car i) best)
             (setq best (car i) best-lst i)))
    (rotatef (car lst) (car best-lst))))

(defun test-nmove-best-to-front3 (n)
  (dotimes (i n)
    (let ((lst '(50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33
32 31 30 29 28 27
 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2
1)))
      (nmove-best-to-front3 lst #'<))))

(defun test-nmove-best-to-front2 (n)
  (dotimes (i n)
    (let ((lst '(50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33
32 31 30 29 28 27
 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2
1)))
      (nmove-best-to-front2 lst #'<))))

(defun test-nmove-best-to-front (n)
  (dotimes (i n)
    (let ((lst '(50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33
32 31 30 29 28 27
 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2
1)))
      (nmove-best-to-front lst #'<))))

The last post didn't make any sense and I re-tested again (after
making sure EVERYTHING was compiled).  Luckily the universe makes
sense again and rotatef isn't too expensive (even when run all all the
elements of the list

CL-USER> (time (test-nmove-best-to-front3 100000000))
Evaluation took:
  2.583 seconds of real time
  2.560160 seconds of total run time (2.540159 user, 0.020001 system)
  99.11% CPU
  4,386,136,174 processor cycles
  8,720 bytes consed
NIL
CL-USER> (time (test-nmove-best-to-front2 100000000))
Evaluation took:
  2.663 seconds of real time
  2.640165 seconds of total run time (2.624164 user, 0.016001 system)
  99.14% CPU
  3,986,463,619 processor cycles
  0 bytes consed
NIL
CL-USER> (time (test-nmove-best-to-front 100000000))
Evaluation took:
  2.984 seconds of real time
  2.964185 seconds of total run time (2.948184 user, 0.016001 system)
  99.33% CPU
  4,185,056,895 processor cycles
  0 bytes consed


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
joswig@corporate-world.li sp.de  
View profile  
 More options Dec 9 2008, 1:01 am
Newsgroups: comp.lang.lisp
From: "jos...@corporate-world.lisp.de" <jos...@corporate-world.lisp.de>
Date: Mon, 8 Dec 2008 22:01:51 -0800 (PST)
Local: Tues, Dec 9 2008 1:01 am
Subject: Re: Coding challenge: Can you make this function more elegant?
On Dec 9, 6:44 am, jrwats <jrw...@gmail.com> wrote:

a) you are NOT allowed to destructively modify literal data. das ist
verboten! fingerkloppen!
b) Common Lisp has FIRST, SECOND, THIRD, ... and REST
c) You can name a variable LIST. No need to write LST, LS, or L. Try
to use real variable names.
   No need to encrypt or compress your code.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kenny  
View profile  
 More options Dec 9 2008, 1:13 am
Newsgroups: comp.lang.lisp
From: Kenny <kentil...@gmail.com>
Date: Tue, 09 Dec 2008 01:13:27 -0500
Local: Tues, Dec 9 2008 1:13 am
Subject: Re: Coding challenge: Can you make this function more elegant?

Because you not know what rotatef is?

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kenny  
View profile  
 More options Dec 9 2008, 1:55 am
Newsgroups: comp.lang.lisp
From: Kenny <kentil...@gmail.com>
Date: Tue, 09 Dec 2008 01:55:44 -0500
Local: Tues, Dec 9 2008 1:55 am
Subject: Re: Coding challenge: Can you make this function more elegant?

No, I was not suggesting that, i was just suggesting rotatef to clean up
the final exchange and loop to clean up the do-doo.

I don't know but you have managed to get almost two orders magnitude
difference out of equivalent code, I'd head for Vegas.

Ewwww! with? finally? Helllooooooo? And is your car really so slow?
Remember, car is a machine language opcode so it should be faster than
an extra setf which is a CLOS <spit> generic function and goes through
method combination*.

OTKB:

(loop with best = lst
       for cm on (cdr lst)
       when (funcall pred (car cm) (car best))
       do (setf best cm)
       finally (rotatef (car lst) (car best)))

hth,kt

* kiddinnnnnggggggg!


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
jrwats  
View profile  
 More options Dec 9 2008, 3:31 am
Newsgroups: comp.lang.lisp
From: jrwats <jrw...@gmail.com>
Date: Tue, 9 Dec 2008 00:31:33 -0800 (PST)
Local: Tues, Dec 9 2008 3:31 am
Subject: Re: Coding challenge: Can you make this function more elegant?

> (sort list pred)

> And it gets all the others in the right order as a bonus!

For the rare case when you don't want the added cost of sorting
everything and want the "best in the front" :)

Now - why it's beneficial to destructively change the input list and
put the best in the front rather than simply returning the best
element... well that's a good question...


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Dec 9 2008, 3:34 am
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <kkylh...@gmail.com>
Date: Tue, 9 Dec 2008 08:34:28 +0000 (UTC)
Local: Tues, Dec 9 2008 3:34 am
Subject: Re: Coding challenge: Can you make this function more elegant?
On 2008-12-09, anonymous.c.lis...@gmail.com <anonymous.c.lis...@gmail.com> wrote:

No cigar:

  (setf list (sort list pred))

The identity of the first cons of the list may change under sort,
so you must always retain the return value in place of the original
list.

Sorting the list in a function like this is probably silly.

If you are going to extract the ``best'' item regularly, you will
probably maintain the list in sorted order. The efficient way to do that
is an ordered insert.  A full sort will have to scan the whole list
once, even if it's optimized for the case when the list is nearly sorted.

By keeping the list in sorted order, you will get O(1) on extracting the best
value, but insertions are O(N). Still, in the average case the , this is a
constant factor better than inserting in random order and then having to walk
the entire list to find the best item, because insertion doesn't always have to
walk the entire list.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
jrwats  
View profile  
 More options Dec 9 2008, 3:35 am
Newsgroups: comp.lang.lisp
From: jrwats <jrw...@gmail.com>
Date: Tue, 9 Dec 2008 00:35:37 -0800 (PST)
Local: Tues, Dec 9 2008 3:35 am
Subject: Re: Coding challenge: Can you make this function more elegant?

> a) you are NOT allowed to destructively modify literal data. das ist
> verboten! fingerkloppen!

blinkenlights?  SBCL only gave me warnings and then did what I told it
to do.  I laugh in the face of danger!

> b) Common Lisp has FIRST, SECOND, THIRD, ... and REST

all of those have at least 1 character extra to type!  Some even 3!
That's at least 1/2 a second of typing.

> c) You can name a variable LIST. No need to write LST, LS, or L. Try
> to use real variable names.

OK - I concede

>    No need to encrypt or compress your code.

What?  Oh I'm assuming this is in reference to car rather than first
and lst as opposed to list.  I blame lst on reading one of these
ancient books I have that used the naming convention.  I blame car
on... McCarthy... and communists.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
budden  
View profile  
 More options Dec 9 2008, 3:45 am
Newsgroups: comp.lang.lisp
From: budden <budde...@gmail.com>
Date: Tue, 9 Dec 2008 00:45:02 -0800 (PST)
Local: Tues, Dec 9 2008 3:45 am
Subject: Re: Coding challenge: Can you make this function more elegant?
CL-USER> (nbest-to-front (list 1 2 3 2 1) #'<)
(1 1 2 3 2 1)
???

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ariel Badichi  
View profile  
 More options Dec 9 2008, 5:23 am
Newsgroups: comp.lang.lisp
From: Ariel Badichi <a...@tidexsystems.com>
Date: Tue, 9 Dec 2008 02:23:42 -0800 (PST)
Local: Tues, Dec 9 2008 5:23 am
Subject: Re: Coding challenge: Can you make this function more elegant?
On Dec 9, 3:29 am, jrwats <jrw...@gmail.com> wrote:

> Destructively moves the "best" element (according to the predicate
> function passed in) to the front of a list.  Feel free to improve the
> code by using other functions, recursion, etc, but it must only visit
> each element once.  i.e. you can't just find the best and call (remove
> best lst :test #'equal :count 1) and then cons best onto lst.

Kenny Tilton posted a code snippet that is close to what I would
write, but were I to take your approach (replacing conses) and style
(Graham), I would first write a utility function, MAPL2, that is
similar to MAPL, but also passes the predecessor sublist (or NIL if
there isn't one).

Ariel


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
budden  
View profile  
 More options Dec 9 2008, 5:28 am
Newsgroups: comp.lang.lisp
From: budden <budde...@gmail.com>
Date: Tue, 9 Dec 2008 02:28:06 -0800 (PST)
Local: Tues, Dec 9 2008 5:28 am
Subject: Re: Coding challenge: Can you make this function more elegant?
Using iterate:

(in-package :iterate) ; it is likely you'll have symbol clashes if you
use-package;
                      ; btw, use http://sourceforge.net/projects/iteratekeywords/
(defun test-best-to-front (n best-to-front)
  (dotimes (i n)
    (let ((lst (list 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35
34 33
32 31 30 29 28 27
 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2
1)))
      (funcall best-to-front lst #'<))))

(defun nbest-to-front-4 (lst pred)
        (iter (for i in lst)
              (for o on lst) (:for maybe-cut-point previous o initially nil)
              (with best-i = (car lst)) (:with cut-point = nil)
              (unless (first-time-p)
                (when (funcall pred best-i i)
                  (setf best-i i cut-point maybe-cut-point)))
              (finally
               (return
                 (cond ((null cut-point) lst) ((eq cut-point lst) lst)
                       (t (let ((new-lst (cdr cut-point))) (shiftf (cdr cut-point)
(cdr new-l) lst)))
                       )))
              ))

(compile 'nbest-to-front-4)

(defun nbest-to-front-5 (lst pred) (loop with best = lst
       for cm on (cdr lst)
       when (funcall pred (car cm) (car best))
       do (setf best cm)
       finally (rotatef (car lst) (car best))))

(compile 'nbest-to-front-5)

ITER> (time (test-best-to-front 1000000 'nbest-to-front-4))
Evaluation took:
  5.239 seconds of real time
  5.212325 seconds of total run time (5.124320 user, 0.088005 system)
  [ Run times consist of 0.196 seconds GC time, and 5.017 seconds non-
GC time. ]
  99.48% CPU
  7,833,665,384 processor cycles
  400,698,840 bytes consed

NIL
ITER> (time (test-best-to-front 1000000 'nbest-to-front-5))
Evaluation took:
  5.164 seconds of real time
  5.152323 seconds of total run time (5.048316 user, 0.104007 system)
  [ Run times consist of 0.224 seconds GC time, and 4.929 seconds non-
GC time. ]
  99.77% CPU
  7,720,695,931 processor cycles
  400,698,904 bytes consed

Note that last Kenny's function don't keep the order of other
elements. Maybe it is right...
You see, speed is comparable. I agree my version is not elegant at
all. It would be no worse than Kenny's if


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ariel Badichi  
View profile  
 More options Dec 9 2008, 5:34 am
Newsgroups: comp.lang.lisp
From: Ariel Badichi <a...@tidexsystems.com>
Date: Tue, 9 Dec 2008 02:34:13 -0800 (PST)
Local: Tues, Dec 9 2008 5:34 am
Subject: Re: Coding challenge: Can you make this function more elegant?
On Dec 9, 12:28 pm, budden <budde...@gmail.com> wrote:

> ITER> (time (test-best-to-front 1000000 'nbest-to-front-4))
> ITER> (time (test-best-to-front 1000000 'nbest-to-front-5))

It is not really useful to time these functions if you are interested
in the performance of the best-to-front functions.

Ariel


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
budden  
View profile  
 More options Dec 9 2008, 5:56 am
Newsgroups: comp.lang.lisp
From: budden <budde...@gmail.com>
Date: Tue, 9 Dec 2008 02:56:23 -0800 (PST)
Local: Tues, Dec 9 2008 5:56 am
Subject: Re: Coding challenge: Can you make this function more elegant?
BTW, here is a useful abstraction of "returning the best value in
iteration". It can be used separatedly. This is a (completely non-
tested) implementation of iterate clause for that:

http://paste.lisp.org/display/71851#1

And the function would change to:
;;; iterate-keywords loaded
(defun nbest-to-front-7 (lst pred)
   (iter:iter (:for place :on lst)
              (:for elt :in lst)
              (:finding place :yielding-best-of elt :by pred :into best)
              (:finally
               (rotatef (car lst) (car best))))
        lst)
----------
4$/hour lisp freelancer. Hire me!


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
budden  
View profile  
 More options Dec 9 2008, 7:09 am
Newsgroups: comp.lang.lisp
From: budden <budde...@gmail.com>
Date: Tue, 9 Dec 2008 04:09:58 -0800 (PST)
Local: Tues, Dec 9 2008 7:09 am
Subject: Re: Coding challenge: Can you make this function more elegant?
> > ITER> (time (test-best-to-front 1000000 'nbest-to-front-4))
> > ITER> (time (test-best-to-front 1000000 'nbest-to-front-5))

Maybe, but how to fix it? You need a fresh list on any iteration.
Maybe one might use #'< and #'> alternated on the same list.

(defun test-best-to-front (n best-to-front) "n should be even!"
    (let ((lst (list 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35
34 33
32 31 30 29 28 27
 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2
1)))
    (dotimes (i (/ n 2))
      (setf lst (funcall best-to-front lst #'<))
      (setf lst (funcall best-to-front lst #'>))
) (print lst)))

I noticed I pasted a wrong version of nbest-to-front-4 here. Here is a
fix:

(defun nbest-to-front-4 (lst pred)
        (iter (for i in lst)
              (for o on lst) (for maybe-cut-point previous o initially
nil)
              (with best-i = (car lst)) (with cut-point = nil)
              (unless (first-time-p)
                (when (funcall pred best-i i)
                  (setf best-i i cut-point maybe-cut-point)))
              (finally
               (return
                 (cond ((null cut-point) lst) ((eq cut-point lst) lst)
                       (t (let ((new-lst (cdr cut-point)))
                             (shiftf (cdr cut-point) (cdr new-lst)
lst)))
                       )))
              ))

Now:
(defun nbest-to-front-5 (lst pred) (loop with best = lst
       for cm on (cdr lst)
       when (funcall pred (car cm) (car best))
       do (setf best cm)
       finally (rotatef (car lst) (car best)))
       lst)

ITER> (time (test-best-to-front 4000000 'nbest-to-front-4))

(1 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29
28 27
 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2)
Evaluation took:
  16.835 seconds of real time
  16.729045 seconds of total run time (16.693043 user, 0.036002
system)
  [ Run times consist of 0.020 seconds GC time, and 16.710 seconds non-
GC time. ]
  99.37% CPU
  25,172,015,038 processor cycles
  2,405,008 bytes consed

(1 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29
28 27 26
 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2)
ITER> (time (test-best-to-front 4000000 'nbest-to-front-5))

(50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28
27
 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2
1)
Evaluation took:
  16.331 seconds of real time
  16.317020 seconds of total run time (16.317020 user, 0.000000
system)
  99.91% CPU
  24,419,120,812 processor cycles
  2,346,928 bytes consed

I wonder where is a source of consing?


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
anonymous.c.lis...@gmail.com  
View profile  
 More options Dec 9 2008, 1:12 pm
Newsgroups: comp.lang.lisp
From: anonymous.c.lis...@gmail.com
Date: Tue, 9 Dec 2008 10:12:50 -0800 (PST)
Local: Tues, Dec 9 2008 1:12 pm
Subject: Re: Coding challenge: Can you make this function more elegant?
Because I think recursion is elegant
-----------------------
(defun recursive-best-to-front (list function)
  (let ((first nil)
        (best nil)
        (car (car list))
        (cdr (cdr list)))
    (setf best car)
    (setf first nil)
    (labels
      ((nthToFront-1 (list function)
                     (let ((car (car list))
                           (cdr (cdr list)))
                       (when car
                         (when (funcall function car best)
                           (setf best car))
                         (setf cdr (nthToFront-1 cdr function))
                         (if (eq car best)
                             (progn
                               (setf first best)
                               (setf best nil)
                               cdr)
                             (cons car cdr))
                         ))))
      (setf cdr (nthToFront-1 cdr function))
      (cons first (cons car cdr)))))
---------------------
Haven't bothered to benchmark against anything.
Probably pretty terrible.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
anonymous.c.lis...@gmail.com  
View profile  
 More options Dec 9 2008, 1:17 pm
Newsgroups: comp.lang.lisp
From: anonymous.c.lis...@gmail.com
Date: Tue, 9 Dec 2008 10:17:26 -0800 (PST)
Local: Tues, Dec 9 2008 1:17 pm
Subject: Re: Coding challenge: Can you make this function more elegant?
On Dec 9, 1:12 pm, anonymous.c.lis...@gmail.com wrote:

Ah, needs a (setf list (cons first (cons car cdr))))))
at the end there to be properly destructive, my bad.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kenny  
View profile  
 More options Dec 9 2008, 1:55 pm
Newsgroups: comp.lang.lisp
From: Kenny <kentil...@gmail.com>
Date: Tue, 09 Dec 2008 13:55:52 -0500
Local: Tues, Dec 9 2008 1:55 pm
Subject: Re: Coding challenge: Can you make this function more elegant?

And what, prithee, have you destroyed with that final proper crushing blow?

kxo


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Thomas A. Russ  
View profile  
 More options Dec 9 2008, 12:53 pm
Newsgroups: comp.lang.lisp
From: t...@sevak.isi.edu (Thomas A. Russ)
Date: 09 Dec 2008 09:53:44 -0800
Local: Tues, Dec 9 2008 12:53 pm
Subject: Re: Coding challenge: Can you make this function more elegant?

jrwats <jrw...@gmail.com> writes:
> > a) you are NOT allowed to destructively modify literal data. das ist
> > verboten! fingerkloppen!
> blinkenlights?  SBCL only gave me warnings and then did what I told it
> to do.  I laugh in the face of danger!

blinkenlights is okay.  Its the spitzensparken you need to watch out
for.  And modifying literal data gets into that realm.

--
Thomas A. Russ,  USC/Information Sciences Institute


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 1 - 25 of 41   Newer >
« Back to Discussions « Newer topic     Older topic »