clux / magic-forest

CPU bound benchmarking of languages using the magic forest problem

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

swift is a pain

clux opened this issue · comments

So tried swift for the first time today on Arch. Easiest installation I found was by installing these 3 from the AUR:

  • ncurses5-compat-libs
  • icu55
  • swift-bin

and compiling a forest.swift with swiftc -O forest.swift -o swiftforest.
Thus we can run the full ./swiftforest 395 295 300, or if you are less patient 95 105 100 because it's pretty slow in my first iteration (which look a lot like the scala and kotlin versions):

Dumping it here because I cba getting 3 AUR packages into an already annoying arch docker images at the moment:

struct Forest {
    var goats = 0
    var wolves = 0
    var lions = 0

    func isValid() -> Bool {
        return self.goats >= 0 && self.wolves >= 0 && self.lions >= 0
    }
    func isStable() -> Bool {
        return (self.goats == 0 && (self.wolves == 0 || self.lions == 0)) ||
               (self.wolves == 0 && self.lions == 0)
    }
}

extension Forest: Equatable {
    static func == (lhs: Forest, rhs: Forest) -> Bool {
        return
            lhs.goats == rhs.goats &&
            lhs.wolves == rhs.wolves &&
            lhs.lions == rhs.lions
    }
}

extension Array where Element : Equatable {
    var unique: [Element] {
        var xs: [Element] = []
        forEach { item in
            if !xs.contains(item) {
                xs += [item]
            }
        }
        return xs
    }
}

func mutate(forests: [Forest]) -> [Forest] {
    var next : [Forest] = []
    for f in forests {
        next.append(Forest(goats: f.goats - 1, wolves: f.wolves - 1, lions: f.lions + 1))
        next.append(Forest(goats: f.goats - 1, wolves: f.wolves + 1, lions: f.lions - 1))
        next.append(Forest(goats: f.goats + 1, wolves: f.wolves - 1, lions: f.lions - 1))
    }
    let res = next.filter({ $0.isValid() }).unique
    //for f in res {
    //    print(f)
    //}
    return res
}

func solve(f: Forest) -> [Forest] {
    var forests : [Forest] = [f]
    while !forests.isEmpty && !forests.contains(where: { $0.isStable() }) {
        forests = mutate(forests: forests)
    }
    return forests.filter({ $0.isStable() })
}

let initial = Forest(
    goats: Int(CommandLine.arguments[1])!,
    wolves: Int(CommandLine.arguments[2])!,
    lions: Int(CommandLine.arguments[3])!
)
print("Initial:", initial)
for s in solve(f: initial) {
    print("Solution:", s)
}

Any suggestions for performance improvements or installation tricks welcome. Quick bench on Linux is slower than everything currently in this repo. Over a minute to run the 300 set.