[FP101x] Validasi kartu kredit dengan Swift (Lab2)
Sekarang saya sedang mengambil kelas online TUDelft’s “FP101x - Intro to Functional Programming” di edX, dan ternyata seru juga. Postingan ini ditulis karena saya ingin berbagi solusi dari latihan-latihan dari kelas FP101x yang saya kerjakan ulang dengan Swift. Bahkan sang pengajar kelas tersebut, Erik Meijer, beberapa waktu lalu nge-tweet seperti ini :
At this point, @SwiftLang is probably a better, and more valuable, vehicle for learning functional programming than Haskell.
— Erik Meijer (@headinthebox) October 17, 2015
Tapi karena sampai sekarang saya belum menemukan kode Swift di kelas FP101x, jadi saya tulis ulang kode haskell dari kelas FP101x ke Swift playground.
Validasi 💳 - Lab2.swift
Berikut kutipan dari latihan lab2.hs yang saya tulis kembali dengan Swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | // Helpers public func eval(_ digits: [Int]) -> Int { return digits.reduce(0, { result, digit in return digit + (result * 10) }) } public func evalRev(_ digits: [Int]) -> Int { var result = 0 for index in stride(from: (digits.count-1), through: 0, by: -1) { result = (result * 10) + digits[index] } return result } extension Sequence { public func all(_ validateElement: (Self.Iterator.Element) -> Bool) -> Bool { return self.reduce(true) { result, element in return result && validateElement(element) } } } // Ex. 0 func toDigits(digit: Int) -> [Int] { return [] } // Ex. 1 func toDigitsRev(digit: Int) -> [Int] { return [] } // Ex. 2 func doubleSecond(digits: [Int]) -> [Int] { return [] } // Ex. 3 func sumDigits(digits: [Int]) -> Int { return 0 } // Ex. 4 func isValid(digit: Int) -> Bool { return false } // Ex. 5 func numValid(digits: [Int]) -> Int { return digits.filter(isValid).count } |
Versi lengkapnya latihan ini bisa diunduh sebagai playground : Lab2.playground. Playground-nya sudah diformat sedemikian rupa dengan markdown, jadi lebih rapi aja gitu. Playground dibuat dengan Xcode 8.2.1 and Swift 3.0.
Versi haskell
Kalau tertarik untuk mengecek latihan aslinya dalam haskell, bisa dilihat di sini.
Pembaruan: Solusi 1.5 tahun kemudian!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | // Ex. 0 func toDigits(digit: Int) -> [Int] { if case 0..<10 = digit { return [digit] } else { return toDigits(digit / 10) + [digit % 10] } } // Ex. 1 func toDigitsRev(digit: Int) -> [Int] { return toDigits(digit).reversed() } // Ex. 2 func doubleSecond(digits: [Int]) -> [Int] { let isEven : (Int) -> Bool = { x in x % 2 == 0 } return digits.enumerated().map { index, x in isEven(index + 1) ? x * 2 : x } } // Ex. 3 // Menambahkan fungsi bantuan untuk mempermudah mendapatkan head dan tail // ref: http://chris.eidhof.nl/post/swift-tricks/ extension Array { func match() -> (head: Element, tail: [Element])? { guard !isEmpty else { return nil } return ( first!, Array(dropFirst()) ) } } func sumDigits(digits: [Int]) -> Int { guard let (head, tail) = digits.match() else { return 0 } return toDigits(head).reduce(0, +) + sumDigits(tail) } // Ex. 4 func isValid(digit: Int) -> Bool { return sumDigits(doubleSecond(toDigitsRev(digit))) % 10 == 0 } // Ex. 5 func numValid(digits: [Int]) -> Int { return digits.filter(isValid).count } |
Latihan yang sangat seru dan menantang! 💪