Can you explain the output of the following Swift Projected Value? - swift5

#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 {

Related

Union-find: largest component size by common factor algorithm gives different results on every run

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.

Can property wrapper have default parameter values?

Is it possible to implement property wrapper that is initialized by either explicit values or predefined defaults? So that, given example:
#propertyWrapper
struct Wrapper<Value> {
private(set) var value: Value!
private var x: Int
private var y: Int
var wrappedValue: Value {
get { value }
set { value = newValue }
}
init(wrappedValue value: Value,
withX x: Int = 10,
withY y: Int = 20) {
self.x = x
self.y = y
self.wrappedValue = value
}
}
is able to be initialized in any of the following ways
#Wrapper
var allDefaults = ...
#Wrapper(withX: 30)
var explicitX = ...
#Wrapper(withY: 40)
var explicitY = ...
#Wrapper(withX: 50, withY: 60)
var allExplicit = ...
The above example works in swift 5.1 only in case all of the optional parameters are explicitly initialized, as in last #Wrapper example.
In any other case this results in error: Abort trap: 6
This is a compiler bug that has been resolved: SR-11480

Practical number algorithm too slow

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)")
}
}
}
}
}

Subscript of a struct doesn't set values when created as an implicitly unwrapped optional

Why can't I change the the "numbers" array using subscripts when "Foo" is an implicitly unwrapped optional?
struct Foo {
var numbers = [0,0,0]
subscript(index: Int) -> Int {
get { return self.numbers[index] }
set { self.numbers[index] = newValue }
}
}
var fooA:Foo!
fooA = Foo()
fooA[1] = 1 // does not change numbers array
fooA[1] // returns 0
fooA.numbers[1] = 1 // this works
fooA[1] // returns 1
var fooB:Foo!
fooB = Foo()
fooB![1] = 1 // this works
fooB![1] // returns 1
For some reason it works when I make "Foo" a class (called "Goo" below)
class Goo {
var numbers = [0,0,0]
subscript(index: Int) -> Int {
get { return self.numbers[index] }
set { self.numbers[index] = newValue }
}
}
var goo:Goo!
goo = Goo()
goo[1] = 1 // this works
goo[1] // returns 1
it looks like a bug (or i miss something important), check this
struct Foo {
var numbers = [0,0,0]
subscript(index: Int) -> Int {
get {
return self.numbers[index]
}
set {
numbers[index] = newValue
}
}
}
var fooA:Foo! = Foo()
// here is the difference
fooA?[1] = 1
fooA[1] // 1
fooA.numbers[1] = 1
fooA[1] // 1
more 'complex' experiment
struct Foo {
var numbers = [0,0,0]
subscript(index: Int) -> Int {
get {
return numbers[index]
}
set {
print(numbers[index],newValue)
numbers[index] = newValue
print(numbers[index])
}
}
}
var fooA:Foo! = Foo()
fooA[1] = 1
fooA[1] // 0
// but prints
// 0 1
// 1
for more 'fun'
var fooA:Foo! = Foo()
if var foo = fooA {
foo[1] = 1
print(foo)
}
prints
"Foo(numbers: [0, 1, 0])\n"

Why CFloat and CDouble?? func addNewValue(newVal: CFloat, atTime time: CDouble) -> CFloat {}

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.