I'm looping over two variables to maximize a function, returning x and
y that maximize f. Any way to do it without the setf in the body?
; Here's a function you can paste to the REPL.
(defun f (x y)
(- (+ (* 9 x) (* 4 y))
(* x x)
(* y y))
; And here's what I'm trying to do:
(let ((best-x -1)
(best-y -1)
(max nil))
(loop :for x :below 10 :do
(loop :for y :below 10 :do
(let ((n (f x
y)))
(if (or (null max) (> n
max))
(setf best-x
x
best-y
y
max n)))))
(values best-x best-y))
Frank Buss <fb@frank-buss.de> writes:
Looks like you are searching for a functional way of doing this. In Haskell you could write it like this (I'm a Haskell newbie, I'm sure this can be written better, but at least it works)
f (x,y) = 9*x + 4*y - x*x - y*y
best = foldr1 max values
where values = [(f(x,y), (x,y)) | x<-[0..9], y<-[0..9]]
max t1 t2 = if (fst t1) >= (fst t2) then t1 else t2
let f x y = 9*x+4*y-x*x-y*y in
foldl1' max [(f x y,(x,y)) | x <- [0..9], y<-[0..9]]
is a little simpler. Uses the max built-in and foldl1' which operates
left to right and is strict.
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 74 |
| Nodes: | 6 (0 / 6) |
| Uptime: | 40:46:56 |
| Calls: | 1,028 |
| Calls today: | 2 |
| Files: | 1,332 |
| D/L today: |
11 files (17,272K bytes) |
| Messages: | 272,641 |