12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- ;; https://projecteuler.net/problem=22
- ;; Names scores
- ;; Problem 22
- ;; Using names.txt (right click and 'Save Link/Target As...'), a 46K
- ;; text file containing over five-thousand first names, begin by
- ;; sorting it into alphabetical order. Then working out the
- ;; alphabetical value for each name, multiply this value by its
- ;; alphabetical position in the list to obtain a name score.
- ;; For example, when the list is sorted into alphabetical order,
- ;; COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name
- ;; in the list. So, COLIN would obtain a score of 938 × 53 = 49714.
- ;; What is the total of all the name scores in the file?
- (import
- (except (rnrs base) let-values map)
- (only (guile) lambda* λ)
- (srfi srfi-1)
- (lib fileio)
- (contract)
- (prefix (lib math) math:))
- (define-with-contract read-names
- (require (string? file-name))
- (ensure (list? <?>)
- (not (null? <?>)))
- (λ (file-name)
- (let* ([file-content
- (get-string-from-file
- (string-join (list (dirname (current-filename)) "names.txt")
- "/"))])
- (map
- (λ (name-with-quotes)
- (string-trim-both name-with-quotes
- (λ (char) (char=? char #\"))))
- (string-split file-content
- (λ (char)
- (char=? char #\,)))))))
- (define-with-contract letter-score
- (require (char? letter))
- (ensure (integer? <?>)
- (positive? <?>))
- (λ (letter)
- (+ (- (char->integer letter)
- (char->integer #\A))
- 1)))
- (define-with-contract name-score
- (require (string? name))
- (ensure (integer? <?>)
- (positive? <?>))
- (λ (name)
- (math:sum (map letter-score (string->list name)))))
- (let* ([file-name (second (command-line))]
- [sorted-names (sort (read-names file-name)
- string-ci<)])
- (let iter ([index 0]
- [remaining-names sorted-names]
- [sum 0])
- (cond
- [(null? remaining-names) sum]
- [else
- (iter (+ index 1)
- (cdr remaining-names)
- (+ sum (* (name-score (first remaining-names))
- (+ index 1))))]))
- (display
- (simple-format
- #f "~s\n"
- (let iter ([index 0]
- [remaining-names sorted-names]
- [sum 0])
- (cond
- [(null? remaining-names) sum]
- [else
- (iter (+ index 1)
- (cdr remaining-names)
- (+ sum (* (name-score (first remaining-names))
- (+ index 1))))])))))
|