函数程序设计实验九:检查信用卡号是否合法

{-
Have you ever wondered how websites validate your credit card number when you shop online? They don’t check a massive database of numbers, and they don’t use magic. In fact, most credit providers rely on a checksum formula for distinguishing valid numbers from random collection of digits (or typing mistakes).

In this lab, you will implement a validation algorithm for credit cards. The algorithm follows these steps:

•Double the value of every second digit beginning with the rightmost.
•Add the digits of the doubled values and the undoubled digits from the original number.
•Calculate the modulus of the sum divided by 10.
If the result equals 0, then the number is valid. Here is an example of the results of each step on the number 4012888888881881.

•In order to start with the rightmost digit, we produce a reversed list of digits. Then, we double every second digit.
Result: [1,16,8,2,8,16,8,16,8,16,8,16,2,2,0,8].

•We sum all of the digits of the resulting list above. Note that we must again split the elements of the list into their digits (e.g. 16 becomes [1, 6]).
Result: 90.

•Finally, we calculate the modulus of 90 over 10.
Result: 0.

Since the final value is 0, we know that the above number is a valid credit card number. If we make a mistake in typing the credit card number and instead provide 4012888888881891, then the result of the last step is 2, proving that the number is invalid.
-}
import Data.Char
import System.IO
import Text.Printf

main::IO()
main= do
    txt <- readFile "cards200.txt"
    let (a,b)=cal (lines txt)
    putStr (printf "%d %d\n" a b)

cal::[String]->(Int,Int)
cal []=(0,0)
cal (x:xs)=
    if ((work (reverse x))==0)
        then (a+1,b)
        else (a,b+1)
    where (a,b)=cal xs

work::String->Int
work []=0
work [x]=(ord x)-(ord '0')
work (x1:x2:xs)=mod (((ord x1)-(ord '0'))+2*((ord x2)-(ord '0'))+(work xs)) 10

下面是cards200.txt的内容,运行代码得到答案22 178

5206755864819202
1379105492196115
5409512986423649
2705286724993610
4590339523768086
7227568698917515
7017537213343686
5441960412536408
1985650308674803
8930251924100163
6223821112224859
7265593269397063
3873657458334911
6913844637722625
2580746846641936
9050852716481811
5612958052562645
2663399291059011
8310304087166965
1151264385941225
3037176896346992
5604814434307028
7419257683131694
9503791528055374
9773495582143088
9448254169209493
3286837130875257
5007595642145928
2516351799318459
6337164871156274
7865007097015627
7372821206158307
4403647737415034
6954778118722210
3133156447719746
3997982917486623
4197606313324053
1728915124175897
2307878742690360
4074800821417823
4923217108878892
2771780062982413
9712263452110514
5650879658145762
1070047600975341
9318877123032305
4885886478753273
9221770746792896
8671449317320096
7368330615081774
3445945555212665
4853120512616008
3482350040120767
5323020530158064
5127315771284171
9729917795762335
9740300357540071
6725967401435715
7441317791240209
2454679651614971
3757488578117189
9257701133688982
7943503683782367
3604145491277744
9692694573414683
9077904010926086
2254791611686848
8027692968023945
2387176678104505
4961766440144563
2361230366122325
1526360654060322
8532325537255486
9231587386310271
1050747991021243
6668415865402539
4230790983717850
2435868087432919
8731404774948976
6371097759555152
9088139380127694
6967169793427582
3323325291563746
7007432325793545
7089483373601483
2430093874132130
3040751512996411
2693410760829446
6969371237742025
3942376263955089
3957390287372100
4862957622459158
4786602026579134
8450154277222308
4035343388074620
7498124220380695
7192995180898233
1131325310492906
2766691510698965
8095276139394176
9966549280223171
1411727368920347
5814685899773800
6518673629107513
5311876803771658
2116396666698721
9584980921175563
9370712578393090
2623803399559228
2554069289606635
5837823785098656
8549705982880789
2321128508863864
6842918893399230
9035413026416668
1654972532148536
3495573138029854
5817622134680768
1994722602621796
6443360793014405
8773037480460291
8046374745587669
3055562327207629
4558242953142855
6321379289576506
8971922515616254
8221106232869586
4826456615481474
8785249860573600
8536198896418796
2546645020349068
1880532328690795
4119406265665946
8114992846616615
3932961417889762
9702577117219397
3740846640578505
8411547908222939
7042976242346668
3588880107998642
5280273948390678
2196210961268405
6383121641303595
6715029217563466
3931215413446217
1923673735577072
2571238980362941
4484030303881053
3072982904243882
4172209610262246
7154260346716014
6879206404517582
8712980866003596
5109365647181395
6763248796711187
2186440548023804
9875044991010591
5678343677212736
1102626697179283
1699532544698937
5360056499731896
5071425690624400
3433800222275108
9530890376641214
5657952597408996
6519460026092261
6842369154112005
1039393918892464
3166139313516959
2032768426604030
4697010054853566
1513388324083947
3391936421212877
1817541281516339
7486119192490819
9880925640870413
2178511677268005
7101269239389344
9660472023939684
5714348578916462
5549457487224650
8018512530038654
4462286733742177
8962508293240515
6295710317245944
2246734149999346
3802409610686262
5193144313232365
2038650110016923
4814070532760728
9898057381020684
7925852131711347
5937749020573882
9956226752602246
6791120971542523
3308122545548043
5862103172486367
6250429168206121
4306760688620767
1863851343341223