Skip to content

Instantly share code, notes, and snippets.

@pazworld
Last active December 20, 2015 01:59
Show Gist options
  • Save pazworld/6053193 to your computer and use it in GitHub Desktop.
Save pazworld/6053193 to your computer and use it in GitHub Desktop.
「数を作る」をSchemeで(横へな9参考) ref: http://qiita.com/pazworld/items/226324031ed86a6b284c
;; 与えられた整数リストから4つを使った全組み合わせを返す
(define (combi4 unselected selected)
(define (delete-one x ls) ;; xを1つだけ削除したリストを返す
(cond
((null? ls) '())
((= x (car ls)) (cdr ls))
(else (cons (car ls) (delete-one x (cdr ls))))))
(define (if6append9 x f) ;; xが6以外ならf(x)を、6ならf(6)とf(9)を連結して返す
(if (= x 6)
(append (f 6) (f 9))
(f x)))
(define (nextlevel x results) ;; 数を1つ組み合わせて次の桁へ進む
(append
(if6append9
x
(lambda (y)
(combi4 (delete-one x unselected)
(cons y selected)))) results))
(if (= 4 (length selected))
(list selected)
(fold nextlevel '() unselected)))
;; リストの全組み合わせからn番目の整数を返す
(define (solve2 n ls)
(define (list->num ls) ;; [1,1,0,9] -> 1109
(fold (lambda (x s) (+ x (* s 10))) 0 ls))
(define (take-n x over ls) ;; n番目があればその値、なければoverに指定された値を返す
(if (> x (length ls))
over
(car (drop ls (- x 1)))))
(take-n n '- (filter
(lambda (x) (>= x 1000))
(sort (delete-duplicates
(map list->num
(combi4 ls '()))) <))))
;; 文字列を与えると問題を解く
(define (solve s)
(define (char->number c)
(- (char->integer c) (char->integer #\0)))
(define (colon-idx)
(string-search-forward ":" s))
(define (get-n)
(string->number (string-head s (colon-idx))))
(define (get-numlist)
(map
char->number
(string->list
(substring s (+ 1 (colon-idx)) (string-length s)))))
(solve2 (get-n) (get-numlist)))
;; テスト
(define (test data expected)
(define (eq a b) ;; 数値または-を比較する
(if (symbol? a) (eq? a b) (= a b)))
(format #t "~A: ~A -> ~A~%"
(if (eq expected (solve data)) "ok" "ng")
data expected))
(define (tests)
(begin
(test "13:01167" 1109)
(test "1:1234" 1234)
(test "13:01167" 1109)
(test "1:1234" 1234)
(test "2:1234" 1243)
(test "7:1234" 2134)
(test "24:1234" 4321)
(test "25:1234" '-)
(test "2:1116" 1119)
(test "2:0116" 1019)
(test "3:6666" 6696)
(test "16:6666" 9999)
(test "10:01267" 1097)
(test "14:111167" 1671)
(test "1:1111" 1111)
(test "2:1111" '-)
(test "1:666633" 3366)
(test "72:666611" 9999)
(test "73:666622" '-)
(test "1:666600" 6006)
(test "52:666600" 9999)
(test "53:666600" '-)
(test "25:06688" 8086)
(test "93:02566" 6502)
(test "11:06688" 6809)
(test "169:01268" 9801)
(test "174:01268" 9821)
(test "66:012288" 8201)))
(tests)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment