cperilla
10/29/2013 - 2:51 PM

This one was kinda bitchy and the solution I came with for the second feels a bit hacky compared to one I did for the first one. http://26

This one was kinda bitchy and the solution I came with for the second feels a bit hacky compared to one I did for the first one.

http://2600hertz.wordpress.com/2010/03/20/the-mystery-spiral/ http://community.topcoder.com/stat?c=problem_statement&pm=6093

;; Author: Carlos Perilla <deepspawn AT valkertown.org>
;; Date: 28-10-2013
;; http://2600hertz.wordpress.com/2010/03/20/the-mystery-spiral/
;; http://community.topcoder.com/stat?c=problem_statement&pm=6093
(define (square x) (* x x) )

(define (spiral-point x y size)
  (let [(max (square size))
        (p (+ (* size 2) (* (- size 2) 2)))]
    (cond [(= y 0) (- max x)]
          [(= x 0) (+  (- max p) y)]
          [(= x (- size 1)) (-  max size (- y 1))]
          [(= y (- size 1)) (+ (- max p 1) size x)]
          [else (spiral-point (- x 1) (- y 1) (- size 2))])))

(define (spiral size)
  (print)
  (let ((half-size (quotient size 2)))
    (do ([i 0 (+ i 1)])
        ([= i size])
      (do ([j 0 (+ j 1)])
          ([= j size])
        (let [(point-value (spiral-point j i size))]
          (display (format "~a"
                           point-value
                           ))
          (if (verify-spiral (- half-size j) 
                             (- half-size i)
                             point-value)
              (display "  ") 
              (display "* "))
          ))
      (print))))


(define (verify-spiral x y value)
  (let [(test-point (get-spiral-index value))]
    (and (= x (car test-point)) (= y (cdr test-point)))))

(define (shift a  b) (if (>=  a b) (- a b) 1))
(define (get-spiral-index number)
  (let* ((root (ceiling (sqrt number)))
         (ring-size (if (= (remainder root 2) 0) (+ root 1) root))
         (ring-side (- ring-size 2))
         (ring-half (quotient ring-size 2))
         (ring-max (square ring-size))
         (corner0 ring-max)
         (corner1 (- corner0 ring-size))
         (corner2 (- corner1 ring-side))
         (corner3 (- corner2 ring-size))
         (corner4 (- corner3 ring-side))
         (coord-x (- (remainder (shift number 1) ring-size) ring-half))
         (coord-y (- (remainder (shift number 2) ring-size) ring-half))
         (coord-x2 (- ring-half (remainder (shift number 3) ring-size)))
         (coord-y2 (- ring-half (remainder (shift number 4) ring-size))))
    (cond
     [(= number ring-max) (cons ring-half ring-half)]
     [(> number corner1)  (cons coord-x  ring-half)]
     [(> number corner2)  (cons (- ring-half) coord-y)]
     [(> number corner3)  (cons coord-x2 (- ring-half))]
     [(> number corner4)  (cons ring-half coord-y2) ]
     )))
(quotient 3 2)
(remainder (shift 2 4) 3)
(spiral 15)