problem 22

Problem 22 - Project Euler

ファイルに書かれた名前を数値に変換したものの重み付け総和を求める問題です。

ファイル入力は初めてでしたが調べたらすぐ分かりました。他の言語と変わりません。ファイルハンドラ、ファイルポインタではなくてポートと呼ばれるものを介してファイルにアクセスするようです。

(use gauche.sequence)
(use srfi-13)

(define (p22)

  (define (alpha->integer c) ; A -> 1, B -> 2 ... のように大文字アルファベットを数字に変換する
    (- (char->integer c)
       (char->integer #\A)
       -1))

  (define (name->num name) ; COLIN = 3 + 15 + 12 + 9 + 14 = 53 のように名前を数字に変換する
    (fold (lambda (x y) (+ y (alpha->integer x))) 0 (string->list name)))

  (define (fold-prod idx name num) ; 重み付けして足していく
    (+ num (* (+ idx 1) (name->num name))))

  (let* ((in (open-input-file "names.txt")) ; main
         (line (read-line in)))
    (close-input-port in)
    (fold-with-index fold-prod 0 (remove string-null? (sort (string-split line #/"?,?"/)))))

)

(print (p22))

分かったこと

  • #\A や #\B などで文字を表す
  • #/.../ で正規表現を表す
  • string-split が perl で言うところの split。ただし引数の順序が逆。
  • 空文字列の判定は string-null?
  • filter の逆は remove
  • 添え字付き fold は fold-with-index
  • open-input-file で read mode のファイルオープン
  • read-line で一行読み込み
  • close-input-port で入力ポートを閉じる