Recursive Binary Tree in swift - swift

This algorithm correctly searches a tree and returns true if the searchValue is in the tree, I understand the base case, but I'm a little lost on the else statement, I'm not understanding what the || does in this scenario, is it returning both of those or just one in certain cases?
func search(node: Node?, searchValue: Int) -> Bool {
if(node == nil){
return false
}
if(node?.value == searchValue){
return true
} else {
return search(node: node?.leftChild, searchValue: searchValue) || search(node: node?.rightChild, searchValue: searchValue)
}
}

Related

Enum pattern matching as a parameter to a function call

I've setup a playground with an example:
enum CarType : Equatable {
case wheeled(wheels: Int)
case flying
public static func ==(lhs: CarType, rhs: CarType) -> Bool {
return lhs.enumName == rhs.enumName
}
var enumName: String {
let stuff = "\(self)".split(separator: "(").first!
return String(describing: stuff)
}
}
var typesPresentAtMyParty = [CarType.wheeled(wheels:4), .wheeled(wheels:4), .flying]
let aKnownType = CarType.flying
if case aKnownType = typesPresentAtMyParty[2] {
print("Was the type")
}
func isPresent(type: CarType, inArray: [CarType]) -> Bool {
return inArray.filter {
if case type = $0 {
return true
}
return false
}.first != nil
}
func isWheeled(inArray: [CarType]) -> Bool {
return inArray.filter {
if case .wheeled = $0 {
return true
}
return false
}.first != nil
}
isPresent(type: .flying, inArray: typesPresentAtMyParty)
isPresent(type: .wheeled, inArray: typesPresentAtMyParty)
The last line here does not compile. While i can do if case .wheeled = $0 ignoring associated type as a check, i cannot find a way of doing the same in a function call isPresent(type: CarType, inArray: [CarType]), when sending isPresent(type: .wheeled, inArray: typesPresentAtMyParty)
Is there a way of writing a function that takes only the valid pattern matching part of the enum as a parameter?
It is not possible to pass partially constructed enums to a function. Partially constructed enums are not valid values, and they only work in pattern matching because the compiler has a concrete value to work with - the one from the right side of the pattern.
These being said, you could easily rewrite your functions to better, more swiftier versions.
Firstly, you don't need isPresent, you can simply use contains:
typesPresentAtMyParty.contains { $0 == .flying }
typesPresentAtMyParty.contains { if case . wheeled = $0 { return true } else { return false } }
Similarly, isWheeled can be shortened (and renamed, for better semantics):
func isWheeled(_ carType: CarType) -> Bool {
if case . wheeled = carType { return true } else { return false }
}
which can pe passed to contains:
let hasWeeled = typesPresentAtMyParty.contains(where: isWheeled)

How to make the closures shorter?

How to make the closures shorter? I want to know the simple programming of the closures.
let closures = { (fillBefore: Bool, fillAfter: Bool) -> String in
if fillBefore && fillAfter {
return kCAFillModeBoth
} else if !fillBefore && fillAfter {
return kCAFillModeBackwards
} else if fillBefore && !fillAfter {
return kCAFillModeForwards
} else {
return kCAFillModeRemoved
}
}
anim?.fillMode = closures((item?.fillBefore)!, (item?.fillAfter)!)
How to make the closures shorter?
Based on your case, I think that at some point you have to evaluate both of booleans, so I would assume that there is no "shorter" code for handling it.
However, you might be looking for a "neater" approach, so I would suggest to evaluate them as pair of booleans (tuple), with a switch statement:
let closure = { (fillBefore: Bool, fillAfter: Bool) -> String in
switch (fillBefore, fillAfter) {
case (true, true):
return kCAFillModeBoth
case (false, true):
return kCAFillModeBackwards
case (true, false):
return kCAFillModeForwards
default: // on your case, it would be the same as (false, false)
return kCAFillModeRemoved
}
}
let myClosure = closure(false,false)
myClosure // removed

How to compare to optional arrays? [duplicate]

This question already has an answer here:
Why is Equatable not defined for optional arrays
(1 answer)
Closed 6 years ago.
I'd like a function to compare [String]? with [String]? where either, both or neither are nil. If both are nil then the function returns true
Is there notation where I can avoid checking a value is equal to nil?
This:
func compare_colours(a1:[String]?, a2:[String]?) -> Bool {
return a1 == a2
}
isn't valid in Swift because I'd need to add ! first:
return a1! == a2!
if let a1Unwrapped = a1{
if let a2Unwrapped = a2{
return a1Unwrapped == a2Unwrapped
}
}
if (a1 == nil && a2 == nil){
return true
}
return false
I prefer using guard over if statements so I can avoid the pyramid of doom:
func compare_colours(a1:[String]?, a2:[String]?) -> Bool {
if a1 == nil && a2 == nil { return true }
guard let unwrapped1 = a1 else { return false }
guard let unwrapped2 = a2 else { return false }
return unwrapped1 == unwrapped2
}
You don't need to check for nil. Instead you can check to see if the Optional enum is .None:
switch (a1, a2) {
case (.None, .None): print("Both unset Optional")
}
Either way you have to do the same basic thing, check for nil/.None. For more details on how this works you can read this answer: https://stackoverflow.com/a/33209762/887210
Or just use the optional as an empty and you can match all scenarios.
func compare_colours(a1:[String]?, a2:[String]?) -> Bool {
return a1 ?? [""] == a2 ?? [""]
}

How to check for palindrome in Swift using recursive definition

I like many of the features in Swift, but using manipulating strings are still a big pain in the ass.
func checkPalindrome(word: String) -> Bool {
print(word)
if word == "" {
return true
} else {
if word.characters.first == word.characters.last {
return checkPalindrome(word.substringWithRange(word.startIndex.successor() ..< word.endIndex.predecessor()))
} else {
return false
}
}
}
This code fails miserably whenever the string's length is an odd number. Of course I could make it so the first line of the block would be if word.characters.count < 2, but is there a way in Swift to get substrings and check easily?
Update
I like many of the suggestions, but I guess the original question could be misleading a little, since it's a question about String more than getting the right results for the function.
For instance, in Python, checkPalindrome(word[1:-1]) would work fine for the recursive definition, whereas Swift code is much less graceful since it needs other bells and whistles.
return word == String(word.reversed())
func isPalindrome(myString:String) -> Bool {
let reverseString = String(myString.characters.reversed())
if(myString != "" && myString == reverseString) {
return true
} else {
return false
}
}
print(isPalindrome("madam"))
I have used the below extension to find whether the number is Palindrome or Not.
extension String {
var isPalindrome: Bool {
return self == String(self.reversed())
}
}
Sometimes having a front end for a recursion can simplify life. I sometimes do this when the arguments which are most convenient to use are not what I want in the user interface.
Would the following meet your needs?
func checkPalindrome(str: String) -> Bool {
func recursiveTest(var charSet: String.CharacterView) -> Bool {
if charSet.count < 2 {
return true
} else {
if charSet.popFirst() != charSet.popLast() {
return false
} else {
return recursiveTest(charSet)
}
}
}
return recursiveTest(str.characters)
}
just add on more condition in if
func checkPalindrome(word: String) -> Bool {
print(word)
if (word == "" || word.characters.count == 1){
return true
}
else {
if word.characters.first == word.characters.last {
return checkPalindrome(word.substringWithRange(word.startIndex.successor() ..< word.endIndex.predecessor()))
} else {
return false
}
}
}
extension StringProtocol where Self: RangeReplaceableCollection {
var letters: Self { filter(\.isLetter) }
var isPalindrome: Bool {
let letters = self.letters
return String(letters.reversed()).caseInsensitiveCompare(letters) == .orderedSame
}
}
"Dammit I'm Mad".isPalindrome // true
"Socorram-me subi no onibus em marrocos".isPalindrome // true
You can also break your string into an array of characters and iterate through them until its half comparing one by one with its counterpart:
func checkPalindrome(_ word: String) -> Bool {
let chars = Array(word.letters.lowercased())
for index in 0..<chars.count/2 {
if chars[index] != chars[chars.count - 1 - index] {
return false
}
}
return true
}
And the recursive version fixing the range issue where can't form a range with endIndex < startIndex:
func checkPalindrome<T: StringProtocol>(_ word: T) -> Bool {
let word = word.lowercased()
.components(separatedBy: .punctuationCharacters).joined()
.components(separatedBy: .whitespacesAndNewlines).joined()
if word == "" || word.count == 1 {
return true
} else {
if word.first == word.last {
let start = word.index(word.startIndex,offsetBy: 1, limitedBy: word.endIndex) ?? word.startIndex
let end = word.index(word.endIndex,offsetBy: -1, limitedBy: word.startIndex) ?? word.endIndex
return checkPalindrome(word[start..<end])
} else {
return false
}
}
}
checkPalindrome("Dammit I'm Mad")
I think if you make an extension to String like this one then it will make your life easier:
extension String {
var length: Int { return characters.count }
subscript(index: Int) -> Character {
return self[startIndex.advancedBy(index)]
}
subscript(range: Range<Int>) -> String {
return self[Range<Index>(start: startIndex.advancedBy(range.startIndex), end: startIndex.advancedBy(range.endIndex))]
}
}
With it in place, you can change your function to this:
func checkPalindrome(word: String) -> Bool {
if word.length < 2 {
return true
}
if word.characters.first != word.characters.last {
return false
}
return checkPalindrome(word[1..<word.length - 1])
}
Quick test:
print(checkPalindrome("aba")) // Prints "true"
print(checkPalindrome("abc")) // Prints "false"
extension String {
func trimmingFirstAndLastCharacters() -> String {
guard let startIndex = index(self.startIndex, offsetBy: 1, limitedBy: self.endIndex) else {
return self
}
guard let endIndex = index(self.endIndex, offsetBy: -1, limitedBy: self.startIndex) else {
return self
}
guard endIndex >= startIndex else {
return self
}
return String(self[startIndex..<endIndex])
}
var isPalindrome: Bool {
guard count > 1 else {
return true
}
return first == last && trimmingFirstAndLastCharacters().isPalindrome
}
}
We first declare a function that removes first and last characters from a string.
Next we declare a computer property which will contain the actual recursive code that checks if a string is palindrome.
If string's size is less than or equal 1 we immediately return true (strings composed by one character like "a" or the empty string "" are considered palindrome), otherwise we check if first and last characters of the string are the same and we recursively call isPalindrome on the current string deprived of the first and last characters.
Convert the string into an Array. When the loop is executed get the first index and compare with the last index.
func palindrome(string: String)-> Bool{
let char = Array(string)
for i in 0..<char.count / 2 {
if char[i] != char[char.count - 1 - i] {
return false
}
}
return true
}
This solution is not recursive, but it is a O(n) pure index based solution without filtering anything and without creating new objects. Non-letter characters are ignored as well.
It uses two indexes and walks outside in from both sides.
I admit that the extension type and property name is stolen from Leo, I apologize. 😉
extension StringProtocol where Self: RangeReplaceableCollection {
var isPalindrome : Bool {
if isEmpty { return false }
if index(after: startIndex) == endIndex { return true }
var forward = startIndex
var backward = endIndex
while forward < backward {
repeat { formIndex(before: &backward) } while !self[backward].isLetter
if self[forward].lowercased() != self[backward].lowercased() { return false }
repeat { formIndex(after: &forward) } while !self[forward].isLetter
}
return true
}
}
Wasn't really thinking of this, but I think I came up with a pretty cool extension, and thought I'd share.
extension String {
var subString: (Int?) -> (Int?) -> String {
return { (start) in
{ (end) in
let startIndex = start ?? 0 < 0 ? self.endIndex.advancedBy(start!) : self.startIndex.advancedBy(start ?? 0)
let endIndex = end ?? self.characters.count < 0 ? self.endIndex.advancedBy(end!) : self.startIndex.advancedBy(end ?? self.characters.count)
return startIndex > endIndex ? "" : self.substringWithRange(startIndex ..< endIndex)
}
}
}
}
let test = ["Eye", "Pop", "Noon", "Level", "Radar", "Kayak", "Rotator", "Redivider", "Detartrated", "Tattarrattat", "Aibohphobia", "Eve", "Bob", "Otto", "Anna", "Hannah", "Evil olive", "Mirror rim", "Stack cats", "Doom mood", "Rise to vote sir", "Step on no pets", "Never odd or even", "A nut for a jar of tuna", "No lemon, no melon", "Some men interpret nine memos", "Gateman sees name, garageman sees nametag"]
func checkPalindrome(word: String) -> Bool {
if word.isEmpty { return true }
else {
if word.subString(nil)(1) == word.subString(-1)(nil) {
return checkPalindrome(word.subString(1)(-1))
} else {
return false
}
}
}
for item in test.map({ $0.lowercaseString.stringByReplacingOccurrencesOfString(",", withString: "").stringByReplacingOccurrencesOfString(" ", withString: "") }) {
if !checkPalindrome(item) {
print(item)
}
}
A simple solution in Swift:
func isPalindrome(word: String) -> Bool {
// If no string found, return false
if word.count == 0 { return false }
var index = 0
var characters = Array(word) // make array of characters
while index < characters.count / 2 { // repeat loop only for half length of given string
if characters[index] != characters[(characters.count - 1) - index] {
return false
}
index += 1
}
return true
}
func checkPalindrome(_ inputString: String) -> Bool {
if inputString.count % 2 == 0 {
return false
} else if inputString.count == 1 {
return true
} else {
var stringCount = inputString.count
while stringCount != 1 {
if inputString.first == inputString.last {
stringCount -= 2
} else {
continue
}
}
if stringCount == 1 {
return true
} else {
return false
}
}
}

Defining `Comparable` for optional types in Swift 1.2

import SwiftyJSON
public typealias FeedItem = JSON
extension FeedItem {
var id: Int { get { return self["id"].intValue } }
}
public func <(lhs: FeedItem, rhs: FeedItem) -> Bool {
return lhs.id < rhs.id
}
public func ==(lhs: FeedItem, rhs: FeedItem) -> Bool {
return lhs.id == rhs.id
}
extension FeedItem:Comparable {}
extension Optional : Comparable {}
public func < <T>(l:T?, r:T?) -> Bool {
if let a=l,b=r {
return a < b
} else if (l==nil) && (r != nil) { return true }
else { return false }
}
public func == <T>(l:T?, r:T?) -> Bool {
if let a=l, b=r {
return a==b
} else {
return false
}
}
First, it should read extension Optional<T where T:Comparable>: Comparable but swift 1.2 does not allow that. Anyway I can express the constraint more explicitly rather than expecting the reader to realize the fact by noticing return a < b and return a==b ?
Second (and apparently more important): the code above works when I use < and > but minElement and maxElement both return nil when a nil is present in their input no matter what and min and max fall into infinite recursion:
let items: [FeedItem?] = [ nil, .Some(JSON(["id":2])), .Some(JSON(["id":1])) ]
println(items[0]?.id) // nil
println(items[1]?.id) // Optional(2)
println(items[2]?.id) // Optional(1)
println(items[0] < items[1]) // true
println(items[1] < items[2]) // false
println(items[2] < items[1]) // true
println(minElement(items)) // nil
println(maxElement(items)) // nil
println( min(items[0],items[2]) ) // nil
println( min(items[2],items[1]) ) // crashes due to infinite recursion
I'm no debug (or swift) expert but from what I can gather in XCode I believe the
if let a=l,b=r {
return a < b
}
part somehow misses the point that a and b are not Optionals but FeedItems. I expect the a < b should call the < operator on FeedItem and not the one on Optional but apparently this is exactly what happens; i.e. a < b resolves to the same function it is called from (that is, the < for Optionals) and thus a recursion happens. I might be wrong though.
Insights ?