rawValue ++max is deprecated swift 3 - swift

I have this problem I can not solve. paste my code
static let count: Int = {
var max: Int = 0
while let _ = PDFList(rawValue: ++max) {}
return max
}()
}
I tried to write this but it does not work
rawValue: (max += 1)) {}
if you help me please. Thank you

+= is not an expression like ++, it's a statement. That is, it doesn't evaluate to a value that can be used in assignment, as a parameter, etc.
You have to split it apart, then use max directly:
static let count: Int = {
var max = 0
while let _ = PDFList(rawValue: max) { max += 1 }
return max
}()
This is more clear, IMO:
static let count: Int = {
var max = 0
while PDFList(rawValue: max) != nil { max += 1 }
return max
}()

The functional way to do this is:
static let count: Int = {
let max = (1 ... Int.max)
.first { PDFList(rawValue: $0) == nil }
return max!
}()
The original code never checks 0 and I am not sure whether that's correct. If it's not correct, change the lower bound of the range to 0.

Related

How to solve a problem with using the method of branches and borders?

All words of the ternary language consist of only 3 letters: a, b, and c and all have a strictly specified length N. Words that do not contain two identical subsequences of letters in a row are considered correct. For example, abcacb is the correct word, and ababc is not the correct one, since the ab subsequences go there.
I tried to solve the problem with a complete enumeration of all possible combinations and a function that looked for a repeating sequence. However, this turned out to be the wrong decision. The problem needs to be solved somehow using the branch and bound method. I have absolutely no idea how this problem can be solved by this method. I would be very happy if someone provides examples or explains to me. I have already spent six days to solve this problem and am very tired.
My wrong solution:
import Foundation
func findRepetition(_ p: String) -> [String:Int] {
var repDict: [String:Int] = [:]
var p = p
while p.count != 0 {
for i in 0...p.count-1 {
repDict[String(Array(p)[0..<i]), default: 0] += 1
}
p = String(p.dropFirst())
}
return repDict
}
var correctWords = [String]()
var wrongWords = [String]()
func getRepeats(_ p: String) -> Bool {
let p = p
var a = findRepetition(p)
for i in a {
var substring = String(Array(repeating: i.key, count: 2).joined())
if p.contains(substring) {
wrongWords.append(p)
return false
}
}
correctWords.append(p)
return true
}
var counter = 0
func allLexicographicRecur (_ string: [String.Element], _ data: [String], _ last: Int, _ index: Int){
var length = string.count-1
var data = data
for i in 0...length {
data[index] = String(string[i])
if index == last {
if getRepeats(data.joined()) {
counter += 1
}
}else{
allLexicographicRecur(string, data, last, index+1)
}
}
}
func threeLanguage(_ l: Int) {
var alphabet = "abc"
var data = Array(repeating: "", count: l)
allLexicographicRecur(alphabet.sorted(), data, l-1, 0)
print("The specified word length: \(l), the number of correct words: \(counter)\n")
print("Correct words:\n\(correctWords)\n")
print("Wrong words:\n\(wrongWords)")
}
threeLanguage(3)
Example:
abca is the right word.
abab is wrong (ab).
aaaa is also wrong (a).
abcabc is also incorrect (abc).
If I correctly understood your problem, you need to separate you input string to parts N-length and check parts by your rules. Smth like this
let constant: Int = 3
extension String {
private func components(withLength length: Int) -> [String] {
return stride(from: 0, to: count, by: length).map {
let start = index(startIndex, offsetBy: $0)
let end = index(start, offsetBy: length, limitedBy: endIndex) ?? endIndex
return String(self[start ..< end])
}
}
var numberOfValidWords: Int {
var numberOfIncorrectWords = 0
let length = count - constant
let array = components(withLength: constant)
for component in array {
let computedLength = replacingOccurrences(of: component, with: "").count
if computedLength != length {
print("as is lengths are not equal, this part is met in string several times")
numberOfIncorrectWords += 1
continue
}
}
return array.count - numberOfIncorrectWords
}
}
Hope it will be helpful

How to remove duplicate characters from a string in Swift

ruby has the function string.squeeze, but I can't seem to find a swift equivalent.
For example I want to turn bookkeeper -> bokepr
Is my only option to create a set of the characters and then pull the characters from the set back to a string?
Is there a better way to do this?
Edit/update: Swift 4.2 or later
You can use a set to filter your duplicated characters:
let str = "bookkeeper"
var set = Set<Character>()
let squeezed = str.filter{ set.insert($0).inserted }
print(squeezed) // "bokepr"
Or as an extension on RangeReplaceableCollection which will also extend String and Substrings as well:
extension RangeReplaceableCollection where Element: Hashable {
var squeezed: Self {
var set = Set<Element>()
return filter{ set.insert($0).inserted }
}
}
let str = "bookkeeper"
print(str.squeezed) // "bokepr"
print(str[...].squeezed) // "bokepr"
I would use this piece of code from another answer of mine, which removes all duplicates of a sequence (keeping only the first occurrence of each), while maintaining order.
extension Sequence where Iterator.Element: Hashable {
func unique() -> [Iterator.Element] {
var alreadyAdded = Set<Iterator.Element>()
return self.filter { alreadyAdded.insert($0).inserted }
}
}
I would then wrap it with some logic which turns a String into a sequence (by getting its characters), unqiue's it, and then restores that result back into a string:
extension String {
func uniqueCharacters() -> String {
return String(self.characters.unique())
}
}
print("bookkeeper".uniqueCharacters()) // => "bokepr"
Here is a solution I found online, however I don't think it is optimal.
func removeDuplicateLetters(_ s: String) -> String {
if s.characters.count == 0 {
return ""
}
let aNum = Int("a".unicodeScalars.filter{$0.isASCII}.map{$0.value}.first!)
let characters = Array(s.lowercased().characters)
var counts = [Int](repeatElement(0, count: 26))
var visited = [Bool](repeatElement(false, count: 26))
var stack = [Character]()
var i = 0
for character in characters {
if let num = asciiValueOfCharacter(character) {
counts[num - aNum] += 1
}
}
for character in characters {
if let num = asciiValueOfCharacter(character) {
i = num - aNum
counts[i] -= 1
if visited[i] {
continue
}
while !stack.isEmpty, let peekNum = asciiValueOfCharacter(stack.last!), num < peekNum && counts[peekNum - aNum] != 0 {
visited[peekNum - aNum] = false
stack.removeLast()
}
stack.append(character)
visited[i] = true
}
}
return String(stack)
}
func asciiValueOfCharacter(_ character: Character) -> Int? {
let value = String(character).unicodeScalars.filter{$0.isASCII}.first?.value ?? 0
return Int(value)
}
Here is one way to do this using reduce(),
let newChar = str.characters.reduce("") { partial, char in
guard let _ = partial.range(of: String(char)) else {
return partial.appending(String(char))
}
return partial
}
As suggested by Leo, here is a bit shorter version of the same approach,
let newChar = str.characters.reduce("") { $0.range(of: String($1)) == nil ? $0.appending(String($1)) : $0 }
Just Another solution
let str = "Bookeeper"
let newChar = str.reduce("" , {
if $0.contains($1) {
return "\($0)"
} else {
return "\($0)\($1)"
}
})
print(str.replacingOccurrences(of: " ", with: ""))
Use filter and contains to remove duplicate values
let str = "bookkeeper"
let result = str.filter{!result.contains($0)}
print(result) //bokepr

How can I find how many useful digits are in any given a number N

A digit in the number is useful if the number is divisible by that digit.
I have been working on this for 2 days now.
Here is what I have:
func selfDivide(integer: Int) -> Int {
var numString = String(integer)
for character in numString.characters {
if character % numString == 0 {
return character
}
}
}
I'm thinking I have to find a way to use % between that string and character.
The error that I get is:
Binary operator '%' cannot be applied to characters of type 'Character' and 'String'
Here is more Swifty way using extension (Swift 4+):
public extension Int {
/// returns number of digits in Int number
public var digitCount: Int {
get {
return numberOfDigits(in: self)
}
}
/// returns number of useful digits in Int number
public var usefulDigitCount: Int {
get {
var count = 0
for digitOrder in 0..<self.digitCount {
/// get each order digit from self
let digit = self % (Int(truncating: pow(10, digitOrder + 1) as NSDecimalNumber))
/ Int(truncating: pow(10, digitOrder) as NSDecimalNumber)
if isUseful(digit) { count += 1 }
}
return count
}
}
// private recursive method for counting digits
private func numberOfDigits(in number: Int) -> Int {
if number < 10 && number >= 0 || number > -10 && number < 0 {
return 1
} else {
return 1 + numberOfDigits(in: number/10)
}
}
// returns true if digit is useful in respect to self
private func isUseful(_ digit: Int) -> Bool {
return (digit != 0) && (self % digit == 0)
}
}
Usage:
print(333444.digitCount)
print(333444.usefulDigitCount)
I would recommend doing all of the work with Int instead of converting to String. You can use % 10 to get the digits and / 10 to remove the last digit.
func selfDivide(number: Int) -> Int {
var num = number
var count = 0
while num != 0 {
let digit = abs(num % 10)
if digit != 0 && number % digit == 0 {
count += 1
}
num = num / 10
}
return count
}
Same answer provided as an extension to Int:
extension Int {
var usefulDigits: Int {
var num = self
var count = 0
while num != 0 {
let digit = abs(num % 10)
if digit != 0 && self % digit == 0 {
count += 1
}
num = num / 10
}
return count
}
}
Examples:
print(100.usefulDigits) // 1
print(123.usefulDigits) // 2
print(222.usefulDigits) // 3
print(299.usefulDigits) // 0
print(Int.max.usefulDigits) // 4
print(Int.min.usefulDigits) // 7
In a single iteration of the while loop, the function will calculate out the last digit of number and check whether the last digit of number if not equals to 0 as well as the number is divisible by the digit or not, if the result is true then the count is incremented by 1. The last line removes the last digit from the number. Same process is repeated until the number is greater than 0. At last the number of useful digits is returned finally.
extension Int {
func usefulNumCount() -> Int {
var count = 0
var num = abs(self)
while num > 0 {
let remainder = num % 10
if remainder != 0 && self % remainder == 0 {
count += 1
}
num = num / 10
}
return count
}
}
This only makes sense to me with unsigned integers.
Please let me know if you have further sense to knock into me; I tend to need it.
public extension UnsignedInteger {
/// The digits that make up this number.
/// - Parameter radix: The base the result will use.
func digits(radix: Self = 10) -> [Self] {
sequence(state: self) { quotient in
guard quotient > 0
else { return nil }
let division = quotient.quotientAndRemainder(dividingBy: radix)
quotient = division.quotient
return division.remainder
}
.reversed()
}
func usefulDigitCount(radix: Self = 10) -> Int {
digits(radix: radix).filter(isMultiple).count
}
}
In Swift 5
extension BinaryInteger {
var digits: [Int] {
return String(describing: self).compactMap { Int(String($0)) }
}
}
extension Int {
public var digitCount: Int {
get {
return self.digits.count
}
}
}
extension Int {
var usefulDigits: Int {
var count = 0
for digit in self.digits {
if digit != 0 && self % digit == 0 {
count += 1
}
}
return count
}
}

EXC_I386_GPFLT in Swift code using Xcode Playground

I ran the same code in Xcode 7beta/rc Playground project and got an error:
Execution was interrupted, reason: EXC_BAD_ACCESS(code=EXC_I386_GPFLT)
in
let n: Int = Int(Process.arguments[1])!
How do I solve in Playground project since other solutions don't seem to be related?
Binary tree: http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&lang=swift&id=1
class TreeNode {
var left, right : TreeNode?
var item : Int
init(_ left: TreeNode?, _ right: TreeNode?, _ item: Int) {
self.left = left
self.right = right
self.item = item
}
func check() -> Int {
guard let left = left, let right = right else {
return item
}
return item + left.check() - right.check()
}
}
func bottomUpTree(item: Int, _ depth: Int) -> TreeNode {
if depth > 0 {
return
TreeNode(
bottomUpTree(2*item-1, depth-1),
bottomUpTree(2*item, depth-1),
item
)
}
else {
return
TreeNode(nil,nil,item)
}
}
let n: Int = Int(Process.arguments[1])!
let minDepth = 4
let maxDepth = n
let stretchDepth = n + 1
let check = bottomUpTree(0,stretchDepth).check()
print("stretch tree of depth \(stretchDepth)\t check: \(check)")
let longLivedTree = bottomUpTree(0,maxDepth)
var depth = minDepth
while depth <= maxDepth {
let iterations = 1 << (maxDepth - depth + minDepth)
var check = 0
for i in 0..<iterations {
check += bottomUpTree(i,depth).check()
check += bottomUpTree(-i,depth).check()
}
print("\(iterations*2)\t trees of depth \(depth)\t check: \(check)")
depth += 2
}
print("long lived tree of depth \(maxDepth)\t check: \(longLivedTree.check())")
Process.arguments holds the value that is passed as arguments for a command-line application.
But you're using it in a Playground: there's no access to command line input from a Playground (they are Sandboxed), so Process.arguments is nil and your app crashes when you're doing Process.arguments[1].
The solution is to use this in an actual application, not in a Playground.
You can use a custom "readLine()" function and a global input variable, each element in the input array is presenting a line:
import Foundation
var currentLine = 0
let input = ["5", "5 6 3"]
func readLine() -> String? {
if currentLine < input.endIndex {
let line = input[currentLine]
currentLine += 1
return line
} else {
return nil
}
}
let firstLine = readLine() // 5
let secondLine = readLine() // 5 6 3
let thirdLine = readLine() // nil

Generating a random number in Swift

I read in https://www.hackingwithswift.com/read/35/2/generating-random-numbers-in-ios-8-and-earlier that the best way to generate a random number is to use
let r = arc4random_uniform(UInt32(_names.count))
let name : String = _names[Int(r)]
but it seems odd that I have to cast twice to be able to get a random number, what should I do to avoid casting?
It really depends on how much casting you want to avoid. You could simply wrap it in a function:
func random(max maxNumber: Int) -> Int {
return Int(arc4random_uniform(UInt32(maxNumber)))
}
So then you only have to do the ugly casting once. Everywhere you want a random number with a maximum number:
let r = random(max: _names.count)
let name: String = _names[r]
As a side note, since this is Swift, your properties don't need _ in front of them.
I really like using this extension
extension Int {
init(random range: Range<Int>) {
let offset: Int
if range.startIndex < 0 {
offset = abs(range.startIndex)
} else {
offset = 0
}
let min = UInt32(range.startIndex + offset)
let max = UInt32(range.endIndex + offset)
self = Int(min + arc4random_uniform(max - min)) - offset
}
}
Now you can generate a random Int indicating the range
let a = Int(random: 1...10) // 3
let b = Int(random: 0..<10) // 6
let c = Int(random: 0...100) // 31
let d = Int(random: -10...3) // -4
Swift 4.2 and above
You can initial a random element:
let randomInt = Int.random(in: 0...1)
let randomDouble = Double.random(in: 0...1)
Also You can take a random element from a collection like
let randomInt = (0...9).randomElement()
Also there is another handy method that you can use on array for shuffling that you may need:
let shuffled = [1, 2, 3, 4].shuffled()
you can use gameplaykit
let random = GKRandomDistribution(lowestValue: 0, highestValue: 100)
let r = random.nextInt()
Modified answer from Luca written as extension in Swift 4
/// Returns random number within given range, upper bound included, eg. -1...0 = [-1, 0, 1]
extension CountableClosedRange where Bound == Int
{
var random: Int
{
let range = self
let offset: Int = range.lowerBound < 0 ? abs(range.lowerBound) : 0
let min = UInt32(range.lowerBound + offset)
let max = UInt32(range.upperBound + offset)
let randomNumber = Int(min + arc4random_uniform(max - min + 1)) - offset
return randomNumber
}
}
/// Returns random number within given range, upper bound not included, eg. -1...0 = [-1, 0]
extension CountableRange where Bound == Int
{
var random: Int
{
let range = self
let offset: Int = range.lowerBound < 0 ? abs(range.lowerBound) : 0
let min = UInt32(range.lowerBound + offset)
let max = UInt32(range.upperBound + offset)
let randomNumber = Int(min + arc4random_uniform(max - min)) - offset
return randomNumber
}
}
Examples:
(0...10).random
(0..<10).random
Or you could use
let name : String = _names[ Int(arc4random()) % _names.count ]