Ctrl+P again to print, arrows/tab to navigate results, enter to confirm

    Type checking timeouts

    If your solution fails due to a timeout (and it isn't doing something that's inherently slow, e.g. factorizing), it's probably too complex for the type checker to understand. To troubleshoot, try undoing some optimizations (particularly joining strings with flatMap) and adding explicit type annotations and/or as-casts to things you suspect the compiler's hung up on.

    [!TIP] Oftentimes, the compiler will give a useful type checking error after you remove optimizations. In this case, you can usually put those optimizations back after fixing the error.

    Substrings

    let str = "Hello! World"
    str.prefix(6)      // "Hello!"
    str.suffix(5)      // "World"
    ""+([]+str)[3...5] // "lo!"
    

    Splitting

    The split function can take a closure that tells it what characters to split on. Split on spaces using:

    i.split{$0==" "}
    

    If the string doesn't contain newlines, this will also work:

    i.split{$0<"!"}
    

    Typecasting

    String

    String(i)
    

    can be

    "\(i)"
    

    Array

    Array(i)
    

    can be

    []+i
    

    Looping

    for i in 0...100{print(i)}
    (0...100).map{print($0)}
    

    Depending on how many times you use the loop variable, it might be shorter to use for-in instead of map in certain cases. Try them both!

    Conditional printing

    Usually the same length, but depending on specific situation one can be shorter than the other

    if a>0{print(a)}
    a>0 ?print(a):()
    

    Argument labels

    By wrapping a function or initializer reference in an immediately-executed closure, you can call it without argument labels:

    String(repeating:"h",count:3)
    {String.init}()("h",3)
    
    ["a","b","c"].joined(separator:" ")
    {["a","b","c"].joined}()(" ")
    

    This trick works for most functions/initializers with lengthy argument labels, as long as the function isn't generic and doesn't rely solely on the labels for overload resolution.

    Key paths

    "hello".map{$0.asciiValue!}
    "hello".map(\.asciiValue!)
    

    Type inference

    Type placeholders

    In cases where the compiler can't infer the full type, it can often infer part of the type:

    let f={($0 as[String]).map{$0+"hello"}}
    let g={$0.map{$0+"hello"}} // error: cannot infer type of closure parameter '$0' without a type annotation
    let h={($0 as[_]).map{$0+"hello"}}
    

    This syntax works for generic parameters; Array, Dictionary, and Optional sugar ([_], [_:_], _?); tuple types; and function types.

    Inference via literals

    let f={($0,$1,$2)as(Int,String,Double)}
    let g={($0+0,$1+"",$2+0.0)}
    

    Joining strings

    If you don't need a separator or don't care about trailing whitespace, you can use flatMap instead of map/joined:

    [1,2,3].map{"\($0)"}.joined()
    ""+[1,2,3].flatMap{"\($0)"}
    
    {[1,2,3].map{"\($0)"}.joined}()(" ")
    [1,2,3].map{"\($0) "}.joined()
    ""+[1,2,3].flatMap{"\($0) "}
    

    It's very easy to time-out the type checker with this trick, so use it with care.