TL;DR
何やら流行っていそうだったので。
途中で少しダルくなって命名がテキトーですが。。。
calculateMyNumber.scm
(use gauche.sequence)
;; マイナンバーのチェック計算
;; dataPair = ("11桁の数値文字列" . チェックデジット)
(define (calculateMyNumber dataPair)
;; チェックデジットの判定
(define (judgeDigit modValue checkDigit)
(cond ((= modValue 0) (= checkDigit 0))
((= modValue 1) (= checkDigit 0))
(else (= checkDigit (- 11 modValue))) ))
;; Pn * Qn を返す
(define (getPn*Qn pn n)
(if (< 6 n)
(* pn (- n 5))
(* pn (+ n 1))))
(judgeDigit (mod (fold + 0 (map-with-index (lambda (n x) (getPn*Qn (digit->integer x) (+ n 1)))
(reverse (string->list (car dataPair)))))
11)
(string->number (cdr dataPair))))
;; 妥当な形式か(数値文字列か、桁数は正しいか)?
(define (validMyNumber? value)
(if (string? value)
(if (= (string-length value) 12)
(string->number value)
#f)
#f))
(define (verifiMyNumber numberString)
(if (validMyNumber? numberString)
(calculateMyNumber ((lambda (value)
(cons (substring value 0 11)
(substring value 11 12)))
numberString))
#f))
(for-each (lambda (x) (print x " : " (verifiMyNumber x)))
'("123456789010"
"123456789011"
"123456789012"
"123456789013"
"123456789014"
"123456789015"
"123456789016"
"123456789017"
"123456789018"
"123456789019"
"023456789013"))
結果.txt
123456789010 : #f
123456789011 : #f
123456789012 : #f
123456789013 : #f
123456789014 : #f
123456789015 : #f
123456789016 : #f
123456789017 : #f
123456789018 : #t
123456789019 : #f
023456789013 : #t
もっとサラリとしたコードが書きたい。
- 修正
- 合計を計算するのに名前付きletでループする必要なんてなかったんや
- 少し気持ちがスッキリした。
- せっかくだからGaucheの便利な
map-with-index
を選ぶぜ - インデントしてみると合計の余りを出すための 11 がなんかシュール
- 合計を計算するのに名前付きletでループする必要なんてなかったんや
- さらに修正
- もちっとコードを整理
- 無名関数呼び出しにしたり、名前を変えたり、見た目を調整したり
- もちっとコードを整理