プログラミングを上達させたい

情報学専攻の大学院→放送局でCMの営業など@大阪→舞台俳優&IT営業@東京

Project Euler(with Scheme) Problem 11

仕事や風邪の影響でダウンしていたが、それ以上にこの問題をSchemeで解くのが面倒で時間がかかってしまった。
そんなProblem11。

Problem 11

;(define N (read))
;(define M (read))
(define N 20)
(define M 20)
;20*20の数字を入れるのみにした

(define (n-input-vec n)
  (define (n-element-input i)
    (if (= i 0) '()
        (let* ((num (read)))
          (cons num (n-element-input (- i 1))))))
  (list->vector (n-element-input n)))

(define nums (make-vector N))

(define (input-vecvec)
  (define (sub i)
    (if (= i N) (display "input OK")
        (let* ((a (vector-set! nums i (n-input-vec M))))
          (sub (+ i 1)))))
  (sub 0))

(input-vecvec)
;(display nums)
(newline)

(define (vecvecref i j)
  (vector-ref (vector-ref nums i) j))
;(display (vecvecref 2 3))
(define (seki4 basei basej di dj)
  (define (sub count i j seki)
    (cond ((or (< i 0) (< j 0) (> i 19) (> j 19)) 0)
           ((= count 4) seki)
           (#t (sub (+ count 1) (+ i di) (+ j dj) (* (vecvecref i j) seki)))))
  (sub 0 basei basej 1))

(define (generate n)
  (if (= n -1) '()
      (cons n (generate (- n 1)))))
(define (this-p-max i j)
  (max (seki4 i j 1 0) (seki4 i j 0 1) (seki4 i j 1 1) (seki4 i j 1 -1)))
(define (this-i-max i jlist)
  (if (null? jlist) 0
      (max (this-p-max i (car jlist)) (this-i-max i (cdr jlist)))))
(define (this-i-j-max ilist jlist)
  (if (null? ilist) 0
      (max (this-i-max (car ilist) jlist) (this-i-j-max (cdr ilist) jlist))))
(display (let ((lists (generate 19)))
           (this-i-j-max lists lists)))
(newline)

手続き型ではループをバンバン書いてすぐ解ける問題だが、Schemeで書こうとするとエレガントに書くとかそういう以前に、そもそも解けるコードが作れなかった。
vectoer-set!とかset!とかが上手く挙動しないし。
というか破壊系の関数をどう自然に入れたらよいのかもよく分かってないし!
結果として無理矢理関数っぽく書くことになった。
しかし、上記コードの後半の「目的に向け少しずつ関数を育てていく感じ」はとても好き。「〜〜max」という関数が3つ並ぶ感じ。

もうこういう、配列に保存させる系の問題が来ませんように!!!!