Skip to content

Instantly share code, notes, and snippets.

@sooop
Last active Aug 30, 2017
Embed
What would you like to do?
오일러 프로젝트 59번 - Swift 풀이
#!/usr/bin/swift
import Foundation
func timeit(_ f: () -> ()) {
let s = Date()
f()
let e = String(format:"time: %.4fms", s.timeIntervalSinceNow * -1000)
print(e)
}
// 키를 반복하면서 문자열에 적용하기 위해 사용한다.
struct Repeater<A>: Sequence, IteratorProtocol {
let data:[A]
var index: Int = 0
init(elements: [A]) {
self.data = elements
}
mutating func next() -> A? {
guard !data.isEmpty else { return nil }
let r = data[index]
index = (index + 1) % data.count
return r
}
}
extension Array where Element == Int {
func convertedString() -> String {
return String(flatMap(chr))
}
}
func chr(_ n: Int) -> Character? {
guard let m = Unicode.Scalar(n) else { return nil }
return Character(m)
}
func guessKey(codes: [Int]) -> [Int] {
var memo = Dictionary<Int, Int>()
let spc = " ".utf8.map{ Int($0) }.first!
codes.forEach{ memo[$0] = (memo[$0] ?? 0) + 1 }
let sortedCodes:[(Int, Int)] = memo.sorted{ $0.1 > $1.1 }
return sortedCodes[..<3].map{ $0.0 ^ spc }
}
func decode(codes: [Int], key: [Int]) -> String {
let x = zip(codes, Repeater(elements:key)).flatMap{ chr($0.0 ^ $0.1) }
return String(x)
}
func main() {
let codes:[Int] = {
guard let url = URL(string:"http://euler.synap.co.kr/files/cipher1.txt"),
let contents = try? String(contentsOf:url)
else { return [] }
return contents.split(separator:",").flatMap{ Int($0) }
}()
let keys = guessKey(codes:codes)
// print(keys.convertedString())
let products = keys.lazy.flatMap{ x in
keys.flatMap{ y in keys.map{ z in [x, y, z]}}}
for k in products {
let decoded = decode(codes: codes, key:k)
if decoded.components(separatedBy:"the").count > 2 {
print(decoded)
print(decoded.utf8.map{Int($0)}.reduce(0, +))
break
}
}
}
timeit(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment