I have a homework problem which is really messing with me right now, and I could use some help in how to implement it in DrRacket. I do not wish for code, just guidance, as I am very new to DrRacket.
The assignment is to implement this phrase:
"If n = 0, return the empty tiling (list of tile structs). Otherwise, place a tromino (L-shaped domino) in the center of the chessboard so that it covers the three quadrants of the chessboard that have no missing tile in them, and tile each of the quadrants."
as recursive code using the two .rkt files given. We are permitted to use any of the functions found within tromino.rkt.
We are also told that the following functions will be necessary to write our code, and so I have included a description of what each does:
(center-tile n row column)
This function produces a single tile structure that represents a properly oriented tromino placed at the center of a 2n × 2n chessboard when the chessboard has its missing tile in the specified row and column. Remember that rows and columns are numbered starting at zero. This function does quite a bit of work for you: It figures out which quadrant the missing cell is in, determines the proper orientation of the tromino to be placed at the center of the board so that that quadrant is not covered, and returns a tile structure that represents that tromino in the proper position on the board.
(missing-cell-within-quadrant n row column quadrant-row quadrant-column)
The 2n × 2n chessboard is divided into four quadrants that are indexed just as the rows and columns are. Specifically, the upper-left quadrant corresponds to
(quadrant-row, quadrant-column) set to (0, 0). The other quadrants are (0, 1) for upper right, (1, 0) for lower-left, and (1, 1) for lower-right. The function missing-cell-within-quadrant answers the following question:
What are the (row, column) coordinates within quadrant (quadrant-row, quadrant-column) of the missing or covered cell within that quadrant, after the tile produced by center-tile has been placed?
The answer is in the form of a list with two coordinates, expressed in the frame of reference of each quadrant. For instance if the missing cell in a 23 × 23 board is at row 2, column 5, then after placement of the center tile the four calls
(missing-cell-within-quadrant 3 2 5 0 0)
(missing-cell-within-quadrant 3 2 5 0 1)
(missing-cell-within-quadrant 3 2 5 1 0)
(missing-cell-within-quadrant 3 2 5 1 1)
return the following four lists, respectively:
'(3 3)
'(2 1)
'(0 3)
'(0 0)
(upgrade-tiling tiling m quadrant-row quadrant-column)
Given a tiling — that is, a list of tromino tiles — of one of the four 2m × 2m quadrants of a 2n × 2n chessboard, where m = n−1, this function transforms all the tiles in the tiling so that their coordinates refer to the full chessboard.
You are given a file, tromino.rkt, which is as follows
#lang racket
(require racket/draw)
(define thickness 6)
(define offset (floor (/ thickness 2)))
(define one 100)
(define two (* 2 one))
(define a 0)
(define b one)
(define c (- two thickness))
(define (mirror coordinates)
(map (lambda (z) (- one z thickness)) coordinates))
(define x-00 (list c c a a b b))
(define y-00 (list a c c b b a))
(define x-01 (mirror x-00))
(define y-01 y-00)
(define x-10 x-00)
(define y-10 (mirror y-00))
(define x-11 x-01)
(define y-11 y-10)
(define (make-tromino-path x y)
(let ((p (new dc-path%)))
(send p move-to (first x) (first y))
(send p line-to (second x) (second y))
(send p line-to (third x) (third y))
(send p line-to (fourth x) (fourth y))
(send p line-to (fifth x) (fifth y))
(send p line-to (sixth x) (sixth y))
(send p close)
p))
(define tromino-path-00 (make-tromino-path x-00 y-00))
(define tromino-path-01 (make-tromino-path x-01 y-01))
(define tromino-path-10 (make-tromino-path x-10 y-10))
(define tromino-path-11 (make-tromino-path x-11 y-11))
(define (tromino-path missing-row missing-column)
(cond ((and (= missing-row 0) (= missing-column 0)) tromino-path-00)
((and (= missing-row 0) (= missing-column 1)) tromino-path-01)
((and (= missing-row 1) (= missing-column 0)) tromino-path-10)
((and (= missing-row 1) (= missing-column 1)) tromino-path-11)
(else (error 'tromino-path "Called with arguments ~a, ~a (must each be either 0 or 1)"
missing-row missing-column))))
(define (draw-board n dc)
(cond ((= n 1)
(begin
(send dc set-smoothing 'unsmoothed)
(send dc set-pen "white" 0 'solid)
(send dc set-brush "white" 'solid)
(send dc draw-rectangle 0 0 two two)
(send dc set-pen "black" 0 'solid)
(send dc set-brush "black" 'solid)
(send dc draw-rectangle 0 0 one one)
(send dc draw-rectangle one one one one)))
(else
(begin
(draw-board (- n 1) dc)
(let ((side (* one (expt 2 (- n 1)))))
(send dc copy 0 0 side side side 0)
(send dc copy 0 0 (* 2 side) side 0 side))))))
(struct tile (row column missing-cell-row missing-cell-column))
(define (show-tile t)
(printf "(row ~a column ~a missing-cell-row ~a missing-cell-column ~a)\n"
(tile-row t) (tile-column t)
(tile-missing-cell-row t) (tile-missing-cell-column t)))
(define (quadrant n row column)
(let ((half (lambda (n coordinate)
(cond ((bitwise-bit-set? coordinate (- n 1)) 1)
(else 0)))))
(list (half n row) (half n column))))
(define (center-tile n row column)
(let ((q (quadrant n row column))
(base (- (expt 2 (- n 1)) 1)))
(tile (+ base (first q)) (+ base (second q)) (first q) (second q))))
(define (missing-cell-within-quadrant n row column quadrant-row quadrant-column)
(let ((q (quadrant n row column))
(base (- (expt 2 (- n 1)) 1))
(sub-coordinate (lambda (coord quad)
(cond ((= quad 1) (- coord (expt 2 (- n 1))))
(else coord)))))
(cond ((and (= (first q) quadrant-row) (= (second q) quadrant-column))
(list (sub-coordinate row (first q))
(sub-coordinate column (second q))))
(else (list (cond ((= 0 quadrant-row) base)
(else 0))
(cond ((= 0 quadrant-column) base)
(else 0)))))))
(define (upgrade-tiling tiling m quadrant-row quadrant-column)
(let* ((shift (expt 2 m))
(row-shift (* quadrant-row shift))
(column-shift (* quadrant-column shift)))
(map (lambda (t)
(tile (+ (tile-row t) row-shift)
(+ (tile-column t) column-shift)
(tile-missing-cell-row t)
(tile-missing-cell-column t)))
tiling)))
(define (make-tiling-png n tiles basename)
(cond ((or (<= n 0) (empty? tiles))
(printf "Warning: make-tiling-png called with n too small or an empty tiling. No picture produced\n"))
(else
(begin
(define side (* (expt 2 n) one))
(define bmap (make-bitmap side side))
(define dc (new bitmap-dc% (bitmap bmap)))
(draw-board n dc)
(send dc set-pen "black" 1 'solid)
(send dc set-brush "white" 'transparent)
(send dc draw-rectangle 0 0 side side)
(send dc set-pen (new pen% (color "red") (width thickness)
(style 'solid) (cap 'projecting) (join 'miter)))
(send dc set-brush "gray" 'solid)
(send dc set-smoothing 'unsmoothed)
(map (lambda (t) (send dc draw-path (tromino-path (tile-missing-cell-row t)
(tile-missing-cell-column t))
(+ offset (* one (tile-column t)))
(+ offset (* one (tile-row t)))))
tiles)
(send bmap save-file (string-append basename ".png") 'png)))))
(provide tile
tile-row
tile-column
tile-missing-cell-row
tile-missing-cell-column
show-tile
quadrant
center-tile
missing-cell-within-quadrant
upgrade-tiling
make-tiling-png)
You are also given a file, template.rkt, which is as follows:
#lang racket
(require "./tromino.rkt")
(define test-tiling (list (tile 2 5 0 1)))
(make-tiling-png 3 test-tiling "test-tiling")
**; Your code replaces the null in the following definition**
(define (tile-board n row column)
null)
(define (make-and-show-tiling n row column)
(make-tiling-png n
(tile-board n row column)
(format "tiling-~a-~a-~a" n row column)))
; Initially, these calls will produce no picture
; because tile-board returns an empty tiling
(make-and-show-tiling 1 1 1)
(make-and-show-tiling 2 0 0)
(make-and-show-tiling 3 5 2)
(make-and-show-tiling 3 6 2)
(make-and-show-tiling 4 5 10)
(make-and-show-tiling 5 24 21)
I have a very good idea of the concept behind how this works, whereby you split the 2n × 2n chessboard into 4 separate quadrants, and then place a tromino at the center of the chessboard such that every quadrant now has either one missing cell or one cell that is covered by part of the tromino. Then, call the recursive function to tile each quadrant. The end goal is to have the code run such that each call of (make-and-show-tiling) function at the end of my template.rkt file will produce a picture of the chessboard produced.
I think I am just getting super confused because I have only learnt Java and Python before this, and the format/syntax of DrRacket is so far removed from those languages. I am completely stuck so any help other than actually writing the code for me would be incredibly welcome and gratefully accepted.
Thank you in advance!!
Related
I'm trying to figure out why I'm getting the errors expected vector? and expected pair? and if there's a way to have a vector as a variable and access the vector for the rod cutting problem (similar to the knapsack problem).
#lang slideshow
; test input: (cutrod 5 #(0 1 2 3 2 2 6 1 2 3 10))
(define (square) (colorize(rectangle 20 15) "red"))
(define (rodpiece n) (apply hc-append(vector->list (make-vector n (square)))))
(define (cutrod n s)
(rodpiece n)
(cond
((null? s) '())
(else
(let
([cut (car (vector->list s))]
[rods (cdr (vector->list s))])
(cons cut (cutrod (- n (vector-ref s n)) rods))
(cutrod n rods)
n))))
Here's the C++ PrintSolution version I'm using to convert:
void PrintSolution(int n, int s[]){
while(n>0){
printf(“%d ”, s[n]);
n = n ‐ s[n];
}
}
This error happens when I try to convert the vector to a list, it says it expected a vector:
This error happens when I keep the vector as is, it says it expected a pair:
Part of the problem is that (rodpiece) returns a list, rather than a vector. You can solve this easily by changing it to:
(define (rodpiece n)
(make-vector 1
(apply hc-append
(build-list n
(lambda (x)
(square))))))
There's no need to start with a vector, but the goal is to return one.
The next problem is that you are calling (rodpiece) in a location which basically discards the return value. You want something closer to this:
(define (cutrod n s)
(let* ((sn (vector-ref s n))
(rp (rodpiece sn)))
Which determines the size of the rod piece up front, then gets the current rod piece for use shortly afterwards. You then need to check for the base case of the recursion:
(if (or (<= n 0)
(> n (vector-length s)))
rp
Where if n is zero, or is longer than the remaining vector s, you simply return the current rod piece.
The recursion itself accumulates current rod piece with the remaining rod pieces:
(vector-append rp (cutrod (- n sn) s)))))
Putting this all together, you have:
#lang slideshow
(define (square)
(colorize (rectangle 20 20) "red"))
(define (rodpiece n)
(make-vector 1
(apply hc-append
(build-list n
(lambda (x)
(square))))))
(define (cutrod n s)
(let* ((sn (vector-ref s n))
(rp (rodpiece sn)))
(if (or (<= n 0)
(> n (vector-length s)))
rp
(vector-append rp (cutrod (- n sn) s)))))
(define cut-vector #(0 1 2 3 2 2 6 1 2 3 10))
(cutrod 5 cut-vector)
(cutrod 6 cut-vector)
(cutrod 7 cut-vector)
(cutrod 9 cut-vector)
(cutrod 10 cut-vector)
I was asked to write a procedure that computes elements of Pascal's triangle by means of a recursive process. I may create a procedure that returns a single row in the triangle or a number within a particular row.
Here is my solution:
(define (f n)
(cond ((= n 1) '(1))
(else
(define (func i n l)
(if (> i n)
l
(func (+ i 1) n (cons (+ (convert (find (- i 1) (f (- n 1))))
(convert (find i (f (- n 1)))))
l))))
(func 1 n '()))))
(define (find n l)
(define (find i n a)
(if (or (null? a) (<= n 0))
'()
(if (>= i n)
(car a)
(find (+ i 1) n (cdr a)))))
(find 1 n l))
(define (convert l)
(if (null? l)
0
(+ l 0)))
This seems to work fine but it gets really inefficient to find elements of a larger row starting with (f 8). Is there a better procedure that solves this problem by means of a recursive process?
Also, how would I write it, if I want to use an iterative process (tail-recursion)?
There are several ways to optimize the algorithm, one of the best would be to use dynamic programming to efficiently calculate each value. Here is my own solution to a similar problem, which includes references to better understand this approach - it's a tail-recursive, iterative process. The key point is that it uses mutation operations for updating a vector of precomputed values, and it's a simple matter to adapt the implementation to print a list for a given row:
(define (f n)
(let ([table (make-vector n 1)])
(let outer ([i 1])
(when (< i n)
(let inner ([j 1] [previous 1])
(when (< j i)
(let ([current (vector-ref table j)])
(vector-set! table j (+ current previous))
(inner (add1 j) current))))
(outer (add1 i))))
(vector->list table)))
Alternatively, and borrowing from #Sylwester's solution we can write a purely functional tail-recursive iterative version that uses lists for storing the precomputed values; in my tests this is slower than the previous version:
(define (f n)
(define (aux tr tc prev acc)
(cond ((> tr n) '())
((and (= tc 1) (= tr n))
prev)
((= tc tr)
(aux (add1 tr) 1 (cons 1 acc) '(1)))
(else
(aux tr
(add1 tc)
(cdr prev)
(cons (+ (car prev) (cadr prev)) acc)))))
(if (= n 1)
'(1)
(aux 2 1 '(1 1) '(1))))
Either way it works as expected for larger inputs, it'll be fast for n values in the order of a couple of thousands:
(f 10)
=> '(1 9 36 84 126 126 84 36 9 1)
There are a number of soluitons presented already, and they do point out that usign dynamic programming is a good option here. I think that this can be written a bit more simply though. Here's what I'd do as a straightforward list-based solution. It's based on the observation that if row n is (a b c d e), then row n+1 is (a (+ a b) (+ b c) (+ c d) (+ d e) e). An easy easy to compute that is to iterate over the tails of (0 a b c d e) collecting ((+ 0 a) (+ a b) ... (+ d e) e).
(define (pascal n)
(let pascal ((n n) (row '(1)))
(if (= n 0) row
(pascal (- n 1)
(maplist (lambda (tail)
(if (null? (cdr tail)) 1
(+ (car tail)
(cadr tail))))
(cons 0 row))))))
(pascal 0) ;=> (1)
(pascal 1) ;=> (1 1)
(pascal 2) ;=> (1 2 1)
(pascal 3) ;=> (1 3 3 1)
(pascal 4) ;=> (1 4 6 4 1)
This made use of an auxiliary function maplist:
(define (maplist function list)
(if (null? list) list
(cons (function list)
(maplist function (cdr list)))))
(maplist reverse '(1 2 3))
;=> ((3 2 1) (3 2) (3))
Am in on the right track for programming the knapsack problem in scheme? My program doesn't have to account for objects "values" , only their weights. The goal is to take the best combination of items so that I have approximately half of the weight in my bag.
(define (split-equip wlst)
(define (sum lst)
(define (sum-h accum lst1)
(if (null? lst)
(/ accum (length lst))
(sum-h (+ (car lst1) accum) (cdr lst1))))
(sum-h 0 lst))
(define (split-equip-h)
(let ((target-w (/ (sum wlst) 2)))
I am tempted to write my program to output a list with all of the different combinations of weights possible and then traversing the list until I find the best set of weights, but not sure how to implement this.
Since this is already your second attempt at this (the first question was deleted), I'll show you a solution in Racket. You should read it like pseudo-code and translate it into the Scheme variant you have been taught.
Disclaimer: I suck at these kind of exercises. That should be another reason for you to understand and reformulate this. But the results of my code still seem correct.
Here's the code:
#lang racket
(define (knapsack lst)
(define half (/ (apply + lst) 2)) ; compute half of total
(printf "list : ~a\nhalf : ~a\n" lst half)
(define (combs lst1 (lst2 null)) ; compute all the combinations
(if (null? lst1)
(if (null? lst2)
null
(list (reverse lst2)))
(append
(combs (cdr lst1) lst2) ; case 1 -> we don't carry the iten
(combs (cdr lst1) (cons (car lst1) lst2))))) ; case 2 -> we do
(for/fold ((delta half) (res null)) ((c (in-list (combs lst)))) ; determine the best fit
(let* ((sm (apply + c)) (newdelta (abs (- half sm))))
(cond
((< newdelta delta) (values newdelta (list c)))
((= newdelta delta) (values delta (cons c res)))
(else (values delta res))))))
(time
(let-values (((delta res) (knapsack (cdr (range 0 24 3)))))
(printf "result: ~a\ndelta : ~a\n" res delta)))
and here's what it says:
list : (3 6 9 12 15 18 21)
half : 42
result: ((3 6 12 21) (3 6 15 18) (3 9 12 18) (3 18 21) (6 9 12 15) (6 15 21) (9 12 21) (9 15 18))
delta : 0
cpu time: 6 real time: 5 gc time: 0
Hope this helps. Don't hesitate to ask questions if there's something you don't get!
I'm trying to learn some functional programming and am doing project euler problems in scheme (racket) to get me started. I'm currently on problem 15 and I think I have a correct function for computing the number of paths in the lattice. Problem is that for large number of gridSize the function takes very long time to run.
(define uniqueTraverse
(lambda (x y gridSize)
(cond
((and (eq? x gridSize) (eq? y gridSize)) 1)
((eq? x gridSize) (uniqueTraverse x (+ y 1) gridSize))
((eq? y gridSize) (uniqueTraverse (+ x 1) y gridSize))
(else (+ (uniqueTraverse (+ x 1) y gridSize)
(uniqueTraverse x (+ y 1) gridSize))))))
I'm trying to figure out how to make this function tail call recursive but I don't know how to do it. I need some help getting started on how to think about optimizing functions like this using tail call optimization.
The problem is that you recompute the same results over and over again.
To solve this, you don't need tail calls - you need to remember old
results and return them without recomputing them. This technique is called memoization.
This is one solution:
#lang racket
(define old-results (make-hash))
(define uniqueTraverse
(lambda (x y gridSize)
(define old-result (hash-ref old-results (list x y) 'unknown))
(cond
; if the result is unknown, compute and remember it
[(eq? old-result 'unknown)
(define new-result
(cond
((and (eq? x gridSize) (eq? y gridSize)) 1)
((eq? x gridSize) (uniqueTraverse x (+ y 1) gridSize))
((eq? y gridSize) (uniqueTraverse (+ x 1) y gridSize))
(else (+ (uniqueTraverse (+ x 1) y gridSize)
(uniqueTraverse x (+ y 1) gridSize)))))
(hash-set! old-results (list x y) new-result)
new-result]
; otherwise just return the old result
[else old-result])))
(uniqueTraverse 0 0 2)
Memoization is one way, another is to use a different data representation.
I used the grid represented as a matrix, or vector of vectors.
Then set the value of the top row to 1 (as there is only on path on the top edge.
After that the next row ther first of the row is one, the second is the value of the entry in the column one above, plus the entry of or value before it in the row,
Recurse for each of the points in the row, and then for each row.
The answer then is the last point in the last row when you are done recursing.
For a 3x3 grid
1 1 1
1 2 3
1 3 6
6
Where the keys are very close together, (continuous, or nearly so) a vector representation is going to be more performant than a hash.
(define (make-lattice-point-square n)
(let ((lps (make-vector (+ n 1))))
(let loop ((i 0))
(if (> i n)
lps
(begin
(vector-set! lps i (make-vector (+ n 1)))
(loop (++ i)))))))
(define (lattice-ref lat x y)
;; where x is row, y is column thought it's not really important
(vector-ref (vector-ref lat y) x))
(define (lattice-set! lat x y value)
(vector-set! (vector-ref lat y) x value))
;; paths through a point are equal the the paths through the above point,
;; plus the paths through the left, those along the top and left edges
;; only have one possible path through them
(define (ways-exit-lattice n)
(let ((lps (make-lattice-point-square n)))
(letrec
((helper
(lambda (x y)
(if (or (= x 0) (= y 0))
(lattice-set! lps x y 1)
(lattice-set! lps x y
(+ (lattice-ref lps (- x 1) y)
(lattice-ref lps x (- y 1)))))))
(lattice-walker
(lambda (x y)
(cond ((and (= x n) (= y n))
(begin (helper x y) (lattice-ref lps x y)))
((= y n)
(begin
(helper x y)
(lattice-walker (++ x) 0)))
(else
(begin
(helper x y)
(lattice-walker x (++ y))))))))
(lattice-walker 0 0))))
notice all the calls to latice-walker are tail calls.
using RSR5 compliant scheme
Here is what I have done so far:
(define sumOdd
(lambda(n)
(cond((> n 0)1)
((odd? n) (* (sumOdd n (-(* 2 n) 1)
output would look something like this:
(sumOdd 1) ==> 1
(sumOdd 4) ==> 1 + 3 + 5 + 7 ==> 16
(sumOdd 5) ==> 1 + 3 + 5 + 7 + 9 ==> 25
This is what I am trying to get it to do: find the sum of the first N odd positive integers
I can not think of a way to only add the odd numbers.
To elaborate further on the sum-odds problem, you might solve it in terms of more abstract procedures that in combination accumulates the desired answer. This isn't necessarily the easiest solution, but it is interesting and captures some more general patterns that are common when processing list structures:
; the list of integers from n to m
(define (make-numbers n m)
(if (= n m) (list n) ; the sequence m..m is (m)
(cons n ; accumulate n to
(make-numbers (+ n 1) m)))) ; the sequence n+1..m
; the list of items satisfying predicate
(define (filter pred lst)
(if (null? lst) '() ; nothing filtered is nothing
(if (pred (car lst)) ; (car lst) is satisfactory
(cons (car lst) ; accumulate item (car lst)
(filter pred (cdr lst))) ; to the filtering of rest
(filter pred (cdr lst))))) ; skip item (car lst)
; the result of combining list items with procedure
(define (build-value proc base lst)
(if (null? lst) base ; building nothing is the base
(proc (car lst) ; apply procedure to (car lst)
(build-value proc base (cdr lst))))) ; and to the building of rest
; the sum of n first odds
(define (sum-odds n)
(if (negative? n) #f ; negatives aren't defined
(build-value + ; build values with +
0 ; build with 0 in base case
(filter odd? ; filter out even numbers
(make-numbers 1 n))))) ; make numbers 1..n
Hope this answer was interesting and not too confusing.
Let's think about a couple of cases:
1) What should (sumOdd 5) return? Well, it should return 5 + 3 + 1 = 9.
2) What should (sumOdd 6) return? Well, that also returns 5 + 3 + 1 = 9.
Now, we can write this algorithm a lot of ways, but here's one way I've decided to think about it:
We're going to write a recursive function, starting at n, and counting down. If n is odd, we want to add n to our running total, and then count down by 2. Why am I counting down by 2? Because if n is odd, n - 2 is also odd. Otherwise, if n is even, I do not want to add anything. I want to make sure that I keep recursing, however, so that I get to an odd number. How do I get to the next odd number, counting down from an even number? I subtract 1. And I do this, counting down until n is <= 0. I do not want to add anything to my running total then, so I return 0. Here is what that algorithm looks like:
(define sumOdd
(lambda (n)
(cond ((<= n 0) 0)
((odd? n) (+ n (sumOdd (- n 2))))
(else (sumOdd (- n 1))))))
If it helps you, here is a more explicit example of a slightly different algorithm:
(define sumOdd
(lambda (n)
(cond ((<= n 0) 0)
((odd? n) (+ n (sumOdd (- n 1))))
((even? n) (+ 0 (sumOdd (- n 1))))))) ; note that (even? n) can be replaced by `else' (if its not odd, it is even), and that (+ 0 ..) can also be left out
EDIT:
I see that the problem has changed just a bit. To sum the first N positive odd integers, there are a couple of options.
First option: Math!
(define sumOdd (lambda (n) (* n n)))
Second option: Recursion. There are lots of ways to accomplish this. You could generate a list of 2*n and use the procedures above, for example.
You need to have 2 variables, one which keep counter of how many odd numbers are still to be added and another to hold the current odd number which gets increment by 2 after being used in addition:
(define (sum-odd n)
(define (proc current start)
(if (= current 0)
0
(+ start (proc (- current 1) (+ start 2)) )))
(proc n 1))
Here is a nice tail recursive implementation:
(define (sumOdd n)
(let summing ((total 0) (count 0) (next 1))
(cond ((= count n) total)
((odd? next) (summing (+ total next)
(+ count 1)
(+ next 1)))
(else (summing total count (+ next 1))))))
Even shorter tail-recursive version:
(define (sumOdd n)
(let loop ((sum 0) (n n) (val 1))
(if (= n 0)
sum
(loop (+ sum val) (- n 1) (+ val 2)))))