I converted
-(float) addNewValue:(float) newVal atTime:(double) time {
to
func addNewValue(newVal: CFloat, atTime time: CDouble) -> CFloat {}
There are no errors but I don't know why it works. Why do Float and Double become CFloat and CDouble?
There are also no errors with:
func addNewValue(newVal: Float, atTime time: Double) -> Float {}
So which am I supposed to use?
Full code
let maxPeriod:Double = 1.5
let minPeriod:Double = 0.1
let invalidEntry = -100
let maxPeriodsToStore = 20
let averageSize:Int = 20
class Detector {
let session = AVCaptureSession()
var camera : AVCaptureDevice?
var upVals = [averageSize]
var downVals = [averageSize]
var upValIndex: Int?
var downValIndex: Int?
var lastVal: Float?
var periodStart: Float?
var periods = [maxPeriodsToStore]
var periodTimes = [maxPeriodsToStore]
var periodIndex: Int?
var started: Bool?
var freq: Float?
var average: Float?
var wasDown: Bool?
func reset() {
for var i:Int = 0; i < maxPeriodsToStore; i++ {
periods[i] = invalidEntry
}
for var i:Int = 0; i < averageSize; i++ {
upVals[i] = invalidEntry
downVals[i] = invalidEntry
}
freq = 0.5
periodIndex = 0
downValIndex = 0
upValIndex = 0
}
// SO Question is regarding this function
func addNewValue(newVal: Float, atTime time: Double) -> Float {
// we keep track of the number of values above and below zero
if newVal > 0 {
upVals[upValIndex!] = newVal
upValIndex!++
if upValIndex >= averageSize {
upValIndex = 0
}
}
if newVal < 0 {
downVals[downValIndex!] -= newVal
downValIndex!++
if downValIndex! >= averageSize as! Int {
downValIndex = 0
}
}
// work out the average value above zero
var count: Float
var total: Float
for var i=0; i < averageSize; i++ {
if upVals[i] != invalidEntry {
count++
total += upVals[i]
}
}
var averageUp = total/count
// and the average value below zero
count=0;
total=0;
for var i=0; i < averageSize; i++ {
if downVals[i] != invalidEntry {
count++
total+=downVals[i]
}
}
var averageDown = total/count
// is the new value a down value?
if newVal < (-0.5*averageDown) {
wasDown = true
}
// is the new value an up value and were we previously in the down state?
if (newVal >= (0.5*averageUp) && (wasDown) != nil) {
wasDown = false
// work out the difference between now and the last time this happenned
if (time - periodStart) < maxPeriod && (time - periodStart) > minPeriod {
periods[periodIndex]=time-periodStart
periodTimes[periodIndex]=time
periodIndex++
if periodIndex >= maxPeriodsToStore {
periodIndex = 0
}
}
// track when the transition happened
periodStart = time
}
// return up or down
if newVal < (-0.5*averageDown) {
return -1
} else if newVal > (0.5*averageUp) {
return 1
}
return 0
}
So which am I supposed to use?
Float and Double. The terms CFloat and CDouble are merely typealiases (synonyms) for these, so there is no point using them; they are there merely for compatibility.
Because Swift is an entirely different language than C.
Objective-C (which is an extension of the C language) can use C-types like float and double, but Swift has to define their own interpretations of these.
More information can be found in the Primitive Types section of this Apple documentation.
Related
I was practicing data structure algorithm and made a Union - Find solution for the question.
The problem is, I think the code seems ok, but when I run it on Xcode playground, it shows different answers for the same input.
For example, I put an array [4, 6, 15, 35] in the function largestComponentSize, then it shows 2, 3, or 4 as the answer. I don't understand what's happening behind.
class Solution {
var uf = UnionFind()
func largestComponentSize(_ nums: [Int]) -> Int {
var maxNum:Int = 0
var numFactorMap = [Int:Int]()
var factorAdded = Set<Int>()
for num in nums {
var pFactors = getPrimeFactors(num)
numFactorMap[num] = pFactors[0]
for (i, val) in pFactors.enumerated() {
if !factorAdded.contains(val) {
uf.addSet(val)
factorAdded.insert(val)
}
if i > 0 {
uf.union(pFactors[i-1], val)
}
}
}
var groupCountMap = [Int:Int]()
for num in nums {
var groupId = uf.find(numFactorMap[num]!)!
if groupCountMap.keys.contains(groupId) {
groupCountMap[groupId]! += 1
} else {
groupCountMap[groupId] = 1
}
maxNum = max(maxNum, groupCountMap[groupId]!)
}
return maxNum
}
func getPrimeFactors(_ num: Int) -> [Int] {
var ans:Set<Int> = []
if num == 1 {
return []
}
var crrNum = num
var deno = 2
while crrNum >= deno {
if crrNum % deno == 0 {
ans.insert(deno)
crrNum = crrNum / deno
} else {
deno = deno + 1
}
}
return Array(ans)
}
class UnionFind {
var index = [Int: Int]()
var parent: [Int]
var size: [Int]
init() {
parent = []
size = []
}
func addSet(_ ele: Int) {
index[ele] = parent.count
parent.append(parent.count)
size.append(1)
}
func getSetSize(_ ele: Int) -> Int {
if let found = find(ele) {
return size[found]
}
return 0
}
func find(_ ele: Int) -> Int? {
if let indexOfEle = index[ele] {
if parent[indexOfEle] == indexOfEle {
return indexOfEle
} else {
if let found = find(parent[indexOfEle]) {
parent[indexOfEle] = found
}
return parent[indexOfEle]
}
} else {
return nil //never come here
}
}
func union(_ first: Int, _ second: Int) {
guard let indexOfFirst = index[first], let indexOfSecond = index[second] else {
return
}
if parent[indexOfFirst] == parent[indexOfSecond] {
return
}
var indexOfLarger = indexOfFirst
var indexOfSmaller = indexOfSecond
if size[indexOfFirst] < size[indexOfSecond] {
indexOfLarger = indexOfSecond
indexOfSmaller = indexOfFirst
}
parent[indexOfSmaller] = indexOfLarger
size[indexOfLarger] += size[indexOfSmaller]
return
}
}
}
var sol = Solution()
var nums = [4, 6, 15, 35]
var ans = sol.largestComponentSize(nums)
Thank you for your help in advance!
I just tried it on Xcode playground.
Hi this is my first question posted here. I have a class which updates an array from a stream of audio samples which I periodically need to process within another class. This is the code that updates the array and removes the oldest element when it reaches a maximum size:
public func update(sample: Sample) {
lastPeak = abs(sample.val) > abs(lastPeak) ? sample.val : lastPeak
if let last = lastSample {
if last.val * sample.val < 0 && abs(lastPeak) > minPeakSize { // this is a zero crossing
let offset = Double(sample.index) + Double(round((sample.val/(last.val - sample.val)) * 100) / 100)
let crossing = ZeroCrossing(
index: sample.index,
previousPeak: lastPeak,
indexWithOffset: offset
)
self.crossings.array.append(crossing) \\ <-- ARRAY UPDATE
lastPeak = 0
while crossings.array.count > crossingsMaxSize {
crossings.array.remove(at: 0) \\ <--ARRAY RESIZE
}
}
}
lastSample = sample
I then pass the array to a method within a separate class and occasionally get an index out of range error.
mutating func run(crossings: Crossings, octave: Int = 2) -> CorrelationResult? {
var result: CorrelationResult? = nil
if crossings.array.count > 4 {
var lastIndex: UInt = 0
if let lastCrossing = crossings.array.last {
lastIndex = lastCrossing.index
}
var startPoint = 0
var completeSet = false
for (i, crossing) in crossings.array.reversed().enumerated() { \\ <-- INDEX OUT OF RANGE
if lastIndex > crossing.index {
if lastIndex - crossing.index > windowSizeForOctave[octave] && crossing.previousPeak < 0 {
startPoint = crossings.array.count - i
completeSet = true
break
}
}
}
The array is wrapped within a struct
struct Crossings {
var locked = false
var array = [ZeroCrossing]()
}
struct ZeroCrossing {
var index: UInt
let previousPeak: Float
let indexWithOffset: Double
}
When the error occurs the array contains 500 elements and i = 0. Is there a safe way to pass arrays between classes (and I assume threads) without blocking updates to the original array?
#propertyWrapper
struct smallNumber {
private var num: Int
private var maximum: Int
var projectedValue: Bool
var wrappedValue: Int {
get { return num }
set {
if num > maximum {
num = maximum
projectedValue = true
}
else {
num = newValue
projectedValue = false
}
}
}
init() {
num = 0
maximum = 12
projectedValue = false
}
init(wrappedValue: Int) {
maximum = 12
projectedValue = false
num = min(wrappedValue, maximum)
}
init(wrappedValue: Int, maximum: Int) {
self.maximum = maximum
projectedValue = false
num = max(wrappedValue, maximum)
}
}
struct Rectangle {
#smallNumber var height: Int
#smallNumber var width: Int
var area: Int {
get {
return height * width
}
}
}
var x = Rectangle()
x.height = 9
x.width = 89
//x.width = 78
print(x.$height, x.$width, x.area)
Hi, I am learning swift and I am having trouble in the above code. In the swift reference(Projected Values), it's written that if we set the value of x greater than 12 then projectedValue becomes true. But after running the above code x.$width prints false. After removing the comment at 2nd last line x.$width prints true. Can someone explain me how is it working?
You copied the code incorrectly.
You have
if num > maximum {
but need
if newValue > maximum {
I'm trying to convert a char in int, in C it works, but in Swift I've got some problem. It's not the same in C, using ascii I've got no problem.
This func is a piece of my atoi func.
I tried with binaryInt and UnicodeScalar, but didn't get success
func scanNumber(_ strArray: [Character], _ index: Int, _ flag: Int) -> Int {
var resalt = 0
while ((strArray[index] >= "0") && (strArray[index] <= "9")) {
// flag mean plus or minus sign in strArray, if flag = 2 it's like a ["-", "1", "2", "3"]
if flag != 2 {
resalt *= 10
resalt = resalt + Int(strArray[index]) //error
} else {
resalt *= 10
resalt = resalt - Int(strArray[index]) //error
}
}
return resalt
}
Int(strArray[index]) return:
Initializer 'init(_:)' requires that 'Character' conform to 'BinaryInteger'
Here is a solution using asciiValue
func scanNumber(_ strArray: [Character], _ index: Int, _ flag: Int) -> Int {
var resalt = 0
var arrayIndex = index
while (arrayIndex < strArray.count && (strArray[arrayIndex] >= "0") && (strArray[arrayIndex] <= "9")) {
guard let ascii = strArray[arrayIndex].asciiValue else {
return resalt
}
resalt *= 10
if flag != 2 {
resalt += Int(ascii) - 48
} else {
resalt -= Int(ascii) - 48
}
arrayIndex += 1
}
return resalt
}
I also fixed the loop
With a Character you can create a String. And with a String you can create an Int.
let char: Character = "1"
if let number = Int(String(char)) {
// use number
}
I am trying to write a program to find the practical numbers, from an input from 1 to n.
Practical numbers : https://en.wikipedia.org/wiki/Practical_number
My code is running correctly but it is extremely slow - takes over 20 minutes when it should take 10 seconds. This happens when calculating numbers around 50 - it gets stuck at 44.
It is written in Swift
import Foundation
func getInteger() -> Int {
var firstNum:Int = 0
while true {
// get value from user. Using optional input since readLine returns an optional string.
let input = readLine()
// ensure string is not nil
if let unwrappedInput = input {
if let unwrappedInt = Int(unwrappedInput) {
firstNum = unwrappedInt
break
}
else { // the input doesn't convert into an int
print("`\(unwrappedInput)` is not an integer. Please enter an integer")
}
}
else { // did not enter anything
print("Please enter an integer")
}
}
return firstNum
}
func addOne(signArray: [Int]) -> [Int] { // finds the combinations
var signArray2 = [Int]()
for i in 0...signArray.count-1 {
signArray2.append (signArray[i])
}
for i in 0...signArray2.count-1 {
if signArray2[i] == 1 {
signArray2[i] = 0
}
else {
signArray2[i] = 1
break
}
}
return signArray2
}
func signEval (signArray: [Int], divArray: [Int], inNum: Int) -> Bool {// changes 2nd
var counts = 0
for i in 0...divArray.count-1 {
if signArray[i] == 0 {
counts = divArray[i] + counts }
if counts == inNum {
return true
}
}
return false
}
print("Please enter a number to find the summable numbers up to that number:")
var input2 = getInteger()// if num = 1 print 1 if num = 2 print 1 and 2 else print >2 1, 2
var inNum = 0
var numHalf = 0.0
var numRound = 0.0
var numCheck = false
var numCheck2 = false
var numQuarter = 0.0
var numSixth = 0.0
var divArray:[Int] = []
var theirArray = [Int]()
var signArray = [Int]()// array of 0s and 1s
var summableArray:[Int] = [1,2] // need to check if num is bigger than 2!
for input in 1...input2 {
numHalf = Double (input) / 2.0
numRound = round(numHalf)
if numRound == numHalf {
numCheck = true }
if input > 2 && numCheck == false { // odd numbers greater than one are not summable
}
else { // these are possible summable nums
numQuarter = Double (input) / 4.0
numRound = round(numQuarter)
if numRound == numQuarter {
numCheck = true
}
else {
numCheck = false
}
numSixth = Double(input) / 6.0
numRound = round(numSixth)
if numRound == numSixth {
numCheck2 = true }
else { numCheck2 = false}
if numCheck == true || numCheck2 == true {
theirArray = []
divArray = []
signArray = []
summableArray = []
for i in 1...input {
theirArray.append (i)
}
for i in 1...input { // creates an array of all the diviors of inputted number
if input%i == 0 {
divArray.append (i)
}
}
for j in 1...divArray.count {//
signArray.append(0)
}
for i in 1...input{
let x: Int = Int(pow(Double(2),Double(input-1)))// int 2 to the power of input -1
var Boolcheck = false
for q in 1...x-1 { // i to 2^n -1 (sequence to check)
Boolcheck = (signEval(signArray: signArray, divArray: divArray, inNum: i))// checks
signArray = addOne(signArray: signArray)// adding the ones to the array
if Boolcheck == true {
summableArray.append(i)// creates array of mini summable numbers
break
}
}
if summableArray.count == input {
print ("\(input)")
}
}
}
}
}