progs/catastrophic/catastrophic.swift
author Christian Urban <christian.urban@kcl.ac.uk>
Fri, 29 Nov 2024 18:59:32 +0000
changeset 976 e9eac62928f5
parent 767 bdd12391d345
permissions -rw-r--r--
updated
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
767
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
     1
// A case of catastrophic backtracking in Swift
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
     2
//---------------------------------------------
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
     3
// example provided by Martin Mikusovic
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
     4
//
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
     5
// regex: (a*)*b
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
     6
// strings: aa...a
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
     7
//
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
     8
// compile with
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
     9
//
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    10
// swiftc catastrophic.swift
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    11
//
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    12
// run with for example
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    13
//
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    14
// time ./catastrophic 20
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    15
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    16
import Foundation
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    17
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    18
let args = CommandLine.arguments
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    19
if args.count >= 2, let count = Int(args[1]) {
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    20
    let s = String(repeating: "a", count: count)
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    21
    calculateTime {
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    22
        let _ = s ~= "(a*)*b"
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    23
    }
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    24
} else {
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    25
    print("Please enter a valid number argument.")
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    26
}
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    27
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    28
func calculateTime(block: () -> ()) {
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    29
    let start = DispatchTime.now()
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    30
    block()
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    31
    let end = DispatchTime.now()
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    32
    let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    33
    let timeInterval = Double(nanoTime) / 1_000_000_000
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    34
    print("\(timeInterval) s")
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    35
}
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    36
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    37
extension String {
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    38
    static func ~=(lhs: String, rhs: String) -> Bool {
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    39
        guard let regex = try? NSRegularExpression(pattern: rhs) else { return false }
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    40
        let range = NSRange(location: 0, length: lhs.utf16.count)
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    41
        return regex.firstMatch(in: lhs, options: [], range: range) != nil
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    42
    }
bdd12391d345 updated
Christian Urban <christian.urban@kcl.ac.uk>
parents:
diff changeset
    43
}