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

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

Project Euler(with Scheme) Problem 38〜39

続けています。継続はアレなり。



Problem 38

意外にも、キレイに解けた。

(define (string-onlyhead str)
  (define (sub char ind)
    (if (>= ind (string-length str)) #t
        (and (not (char=? char (string-ref str ind))) (sub char (+ ind 1)))))
  (sub (string-ref str 0) 1))

(define (string-unique? str)
  (if (<= (string-length str) 1) #t
      (and (not (char=? #\0 (string-ref str 0))) (string-onlyhead str) (string-unique? (substring str 1 (string-length str))))))

(define (get-string seed)
  (define (sub ind str)
    (if (>= (string-length str) 9) str
        (sub (+ ind 1) (string-append str (number->string (* seed ind))))))
  (sub 1 ""))

(define (solve maxstart)
  (define (sub max ind)
    (if (= ind 0) max
        (let ((st (get-string ind)))
          (if (and (string-unique? st) (= 9 (string-length st)) (> (string->number st) max))
              (sub (string->number st) (- ind 1))
              (sub max (- ind 1))))))
  (sub 0 maxstart))

;n>2という条件から、10000以下を調べればよい
(display (solve 10000))
(newline)

Schemeの文字列って使いやすいかも!!!

Problem 39

これもキレイに関数を組み立てられた。howhave。

(define (nijo? n)
  (define (sub seed)
    (cond ((> (* seed seed) n) #f)
          ((= (* seed seed) n) #t)
          (#t (sub (+ seed 1)))))
  (sub 1))

(define (nijo n) (* n n))

(define (howhave p)
  (define (sub1 smaller ans)
    (define (sub2 middle)
      (let* ((bigger (- p (+ smaller middle)))
             (sahen (+ (nijo smaller) (nijo middle)))
             (uhen (nijo bigger)))
        (cond ((> sahen uhen) #f)
              ((= sahen uhen) #t)
              (#t (sub2 (+ middle 1))))))
    (if (> (* smaller 3) p) ans
        (sub1 (+ smaller 1) (+ ans (if (sub2 smaller) 1 0)))))
  (sub1 1 0))

(define (solve endp)
  (define (sub nowp maxp maxcount)
    (let ((nowhave (howhave nowp)))
      (cond ((> nowp endp) maxp)
            ((> nowhave maxcount) (sub (+ nowp 1) nowp nowhave))
            (#t (sub (+ nowp 1) maxp maxcount)))))
  (sub 1 0 0))

(display (solve 1000))
(newline)

いつもSchemeで2重ループにあたる関数を書くときには2つのループ変数を引数に含む関数で書いてたけど、
このhowhaveみたいに2重のdefineにして書く方がキレイそう!!!!気付きだ!!!!!!!!!!!!


ProjectEulerをSchemeで解き始めてから、書き方が少しずつ上手くなっているのが分かる。
最初に基礎的なことをやってりゃはじめから出来てたのかもだけど、関係なし!頑張る!!!!