![]() |
sponsored links |
|
|
sponsored links
|
|
|
|
3
10th April 05:11
External User
Posts: 1
|
aoi@nm.ru (Allecs Chime-Ingrae) writes:
Although there is a Logo primitive operation, ITEM, that does exactly what you're after here, it'll be worthwhile for you to learn how to write it yourself. First of all, you don't really want to do FIRST (BUTFIRST :LIST) k-1 times; you just want to BUTFIRST that many times. Secondly, if you are writing an operation (something that has an OUTPUT), then it has to OUTPUT in every case. Your procedure calls OUTPUT in the base case IF :K=1 [OUTPUT ...] but not in the non-base case. So, what you wanted to write (but this still isn't right; we're working toward a correct solution and this is the first step) was OUTPUT FIRST (REPEAT :K-1 [BUTFIRST :LIST]) ; WRONG! This is better, because your procedure always outputs, and because you are calling FIRST only once. But it's still wrong because FIRST needs an input, and REPEAT doesn't output. REPEAT is used for commands, such as moving the turtle or printing something, not for operations. You *could* use REPEAT in a correct, but ugly, solution: TO KTH :K :LIST REPEAT :K-1 [MAKE "LIST BUTFIRST :LIST] OUTPUT FIRST :LIST END This works because the second input to REPEAT is a complete instruction, using the MAKE command, not an expression that produces a value and doesn't use it for anything. But it's considered ugly Logo style. The standard solution looks like this: TO KTH :K :LIST IF :K=1 [OUTPUT FIRST :LIST] OUTPUT KTH :K-1 (BUTFIRST :LIST) END This is a recursive solution; KTH calls itself as a helper procedure. If your dialect of Logo provides the Berkeley Logo procedure library, you can also say TO KTH :K :LIST OUTPUT FIRST (CASCADE :K-1 "BUTFIRST :LIST) END But to solve your original problem you need more than KTH because you can't just forget about the notes that you skip over; you have to come back to them later somehow. (This is left as an exercise for the reader. :-) Yes, COUNT. P.S. I don't see why you think you need macros for this! |
|
|
6
10th April 05:11
External User
Posts: 1
|
aoi@nm.ru (Allecs Chime-Ingrae) writes:
Yeah, read _Computer Science Logo Style_. :-) http://www.cs.berkeley.edu/~bh/logo.html There's also a book called _Thinking Recursively_ by Eric Roberts. Adding the digits of a number is the same as taking its remainder on division by 9. [The remainder function distributes over addition and multiplication, so (\Sum_{i=0}^k d_i 10^i) mod 9 = \Sum_{i=0}^k ((d_i 10^i) mod 9) = \Sum_{i=0}^k ((d_i mod 9)(10^i mod 9)) = \Sum_{i=0}^k d_i because d_i <= 9 (you have to worry a little about 9 and 0, but these details you can work out for yourself :-) and 10 mod 9 = 1, so 10^i mod 9 = 1 for all i.] So this explains why there is a sum-of-digits relationship between k and 9-k. Strictly speaking, no Logo procedure, including macros, can take functions as arguments, because procedures aren't first-class data. But Logo has an equivalent feature, which is that any Logo procedure can take the *name* of a procedure, or the *text* of a procedure, as an argument, and can then APPLY or INVOKE those things with arguments, like this: to map :func :data if emptyp :data [output []] output fput (invoke :func first :data) (map :func bf :data) end ? show map "first [the rain in spain] [t r i s] ? show map [word ? ?] [j p g r] [jj pp gg rr] The UCBLogo library version of MAP is more complicated than this in various ways, but this is the essential idea. Really the only situation in which you need macros is if you want the called procedure (the macro) to be able to do a STOP, OUTPUT, or LOCAL on behalf of its caller. If the called procedure is an ordinary procedure, it can STOP itself, but it can't STOP its caller. What macros do is let the called procedure generate an instruction which is then carried out *by the caller* after the macro outputs it. |
|