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