I'm missing something simple, but I've a list of lists that I want to sum.
I have this:
(map + (list (list 1 2) (list 3 4)))
and I want this:
(map + (list 1 2) (list 3 4))
Is there any simple function that breaks down a list into its components (I know each does, but not how to simple apply it here). I've also tried to consing + and map to the list of list, and then evaluating it, but without much success ;)
A month or two ago, I wrote Sokoban in Arc, and produced a small library for multidimensional lists in the process. This function should interest you:
;dims needed because ((abc)) may be a two-dimensional list containing abc or
;a one-dimensional list containing (abc)
(def muldim-map (dims f lst)
((afn (lst)
(if (no lst)
nil
(if (is dims 0)
(f lst)
(cons (muldim-map (- dims 1) f (car lst)) (self (cdr lst))))))
lst))
If I read it right, it is a function that for example, can grab the nth entry from a cell (or nth row / column from a matrix)?
You have the code out there somewhere? It is probably good to have some more examples of Arc out in the open, and there'll be things in it I can learn from.
Sorry, I misunderstood your query last night.I just realized the function actually doesn't apply in this specific instance here.
It's a version of the normal map generalized to n-dimensional lists; I forgot when writing it that normal map accepts multiple lists.
However, with that added, it would be useful if you, say, had (((1 2) (3 4)) ((5 6) (7 8))) and wanted ((6 8) (10 12)); that would end up being (apply muldim-map 2 + (list (list (list 1 2) (list 3 4)) (list (list 5 6) (list 7 8))))
(I was going to download Arc's source code and use the source of the original map as a guide to writing a version of muldim-map that could handle multiple multi-dimensional lists on the spot, but I don't believe these high school computers have software that can handle tarballs.)
However, I just realized I had another function in that library that could perform the task you described, although it would be overkill. It's called something like move-muldim-block; it takes a multi-dimensional list and returns a new multi-dimensional list with a multi-dimensional piece of that list moved elsewhere, using a combining function to determing the value of the area in which it was moved (I used it in Sokoban to simplify code that would let let me move a crate character onto a storage character and change it to the crate-on-storate character).
In other words, if lst is set to ((1 2) (3 4)) and f is some function, (move-muldim block (list 1 0) (list 1 2) (list 0 0) +) would be equivalent to (((+ 1 3) (+ 2 4)) ((f 3) (f 4))) (it moves a 1x2 block from coordinates (1 0) to coordinates (0 0)). Just take the car of the result and you have what you're looking for (in which case, we could omit the last argument and use the default value).
For this specific task, apply is a heck of a lot simpler, but I can still post the code if you're interested. I personally found it very interesting to realize that this could be done, and that muldim-move-block is a little more useful than I first thought.
Hmm. Right now I store the positions of my mobile piec elsewhere than in the world-list. Your function might be handy later on. I haven't yet decided if I want every actor of the world stored in the world (even if some of them might overlap), or store the mobile actors in a separate list.
Right now the thing about sokoban implementations that would interest me most is if you've done anything fancy to generate the output. Having an update of a 2d world scroll by ever so often makes it hard to track movement of a single character through this world. Did you work on that?
Since Arc is a language targeted for the web... have you considered the possibility of generating a web page for it, with maybe next >> and << prev links?
That might actually work, and just autorefresh the page every second or so :)
First priorities now are finishing the wandering algorithm for the animals so that they're no longer steered but steer themselves, and generalize the code I've some more so that adding more behaviours than just biting things is easy. I'll add the visuals-through webpage idea to that list :)
Sorry, not really. I just used a simple function to print out a 2-dimensional list and resized my terminal window so that the grid would be in the same place after every sequence of moves, which gives the illusion that the same grid is being redrawn.
Small mistake -- the invocation would be (move-muldim block (list 1 0) (list 1 2) (list 0 0) + f) (I hope no-one thought I'd be silly enough to set the function to find the replacement-fn by looking up the global value of f...).
Hmm. Seen flat and tried it. in Arc2 flat works recursively, turning (list (list 1 2) (list (1 2)) into (1 2 1 2), which doesn't produce the desired (2 4) when combined with map +
The apply function takes a function, any number of arguments, and a list, to wit (apply f x0 x1 x2 ... xN args). This is the same as (f x0 x1 x2 ... xN args.0 args.1 args.2 ... args.M). This allows you to construct argument lists at runtime, which can come in very handy.
Actually, in looking over the functions again, it turns out that there is already a function that does what you want: random-elt. That should do what you need it to do.
As for your problem (and no, it doesn't work on Anarki[1]), the problem is that rand-choice is a macro, not a function, and apply only works on functions. The only solution is a terrible hack:
(def mapply (macro . parms)
" Applies the macro `macro' to `parms', which are not quoted.
See also [[mac]] [[apply]] "
(eval:apply (rep macro) (join (butlast parms) (last parms))))