If Statement, having a condition meet on specific numbers while variable increments - swift

Simple problems which I just can't seem to figure out in my small head. I have a variable which will be updated and increment sequentially i.e 0, 1, 2, 3, 4.. and so on just to be clear. I am trying to implement a condition for when the numbers are 1 and 2 beep and for 3 and 4 do this, this should alternate. let me show you using code.
func doSomething(number : Int) {
//number is increment sequentially: 0, 1, 2, 3, 4...
let number : Int = number
if number is 1, 2, 5, 6, 9, 10... {
//play a sound
} else if number is 3, 4, 7, 8, 11, 12... {
//vibrate
}
}
My concern isn't what happens inside the if statements but the logic in the condition of the if statement.

Here's a total alternative: don't increment a number. The numbers are not needed; they are a red herring. What you want is to perform a certain "next" action each time we need a new action. So let's write a state machine where each successive change of state behaves as you describe.
struct StateMachine {
enum TickTock {
case tick
case tock
}
private var tickTock = TickTock.tock
private var alternator = false
mutating func nextState() {
self.alternator = !self.alternator
if self.alternator {
self.tickTock = self.tickTock == .tick ? .tock : .tick
}
print(self.tickTock)
}
}
So the only thing you have to do is keep a StateMachine instance on hand and call its nextState every time you need to perform a new action.
Here's a test and its output (don't be misled by the loop; there are no actual numbers in this story, it's just a test bed):
var machine = StateMachine()
for _ in 0..<20 {
machine.nextState()
}
/*
tick
tick
tock
tock
tick
tick
tock
tock
tick
tick
tock
tock
tick
tick
tock
tock
tick
tick
tock
tock
*/
If every time we print "tick" you make a sound, and every time we print "tock" you vibrate, you'll be doing exactly what your spec requires.

if (number % 4) == 1 || (number % 4) == 2 {
ding()
} else {
wiggle()
}

if ((number + 1) / 2) % 2 == 1 {
// play a sound
} else {
// vibrate
}

This is similar to #rmaddy's answer but it uses one fewer operation:
if (number + 1) & 2 == 2 {
// play a sound
} else {
// vibrate
}
How does this work?
This works by observing that when counting in binary:
1 001
2 010
3 011
4 100
5 101
6 110
7 111
the two's digit (second digit from the right) changes in the following pattern: 0 1 1 0 0 1 1 0 0 .... By adding one, we shift the pattern to 1 1 0 0 1 1 0 0 .... So, then to check the 2's digit do a bitwise AND (&) with 2 and check if that is 2.
I would do it this way if I were programming it in assembly, but for Swift I like #matt's solution.

Related

Reactive Extensions Do operator fires more times than I expect

Can anyone tell me what causes this seemingly odd Do behavior in the following code? I would expect the Do handler to be called once per OnNext.
using System;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using NUnit.Framework;
[TestFixture]
public class WhyDoesDoActSoWierd
{
[Test]
public void ButWhy()
{
var doCount = 0;
var observable = new Subject<int>();
var stream = observable.Do( x => doCount++ );
var subs =
(from x in stream
where x % 2 == 1
from y in stream
where y % 2 == 0
&& y == x + 1
select new { x, y })
.Subscribe( x => Console.WriteLine( "{0}, {1}", x.x, x.y ) );
observable.OnNext( 1 );
// doCount == 1
observable.OnNext( 2 );
// doCount == 3
observable.OnNext( 3 );
// doCount == 5
observable.OnNext( 4 );
// doCount == 8
observable.OnNext( 5 );
// doCount == 11
observable.OnNext( 6 );
// doCount == 15
Assert.AreEqual( 6, doCount );
}
}
The behaviour here is perfectly normal. The reason is that you don't just have one subscription, you have many. And because of the cartesian product between the two observables in the query you have a larger number of Do than you might otherwise expect.
Let's look at an alternative (but similar) query to yours.
var doCountX = 0;
var doCountY = 0;
Action dump = () =>
Console.WriteLine("doCountX = {0}, doCountY = {1}", doCountX, doCountY);
var observable = new Subject<int>();
var streamX = observable.Do(x => doCountX++);
var streamY = observable.Do(x => doCountY++);
var query =
from x in streamX
from y in streamY
select new { x, y };
query.Subscribe(z => Console.WriteLine("{0}, {1}", z.x, z.y));
dump();
for (var i = 1; i <= 6; i++)
{
observable.OnNext(i);
dump();
}
The output from this is:
doCountX = 0, doCountY = 0
doCountX = 1, doCountY = 0
1, 2
doCountX = 2, doCountY = 1
1, 3
2, 3
doCountX = 3, doCountY = 3
1, 4
2, 4
3, 4
doCountX = 4, doCountY = 6
1, 5
2, 5
3, 5
4, 5
doCountX = 5, doCountY = 10
1, 6
2, 6
3, 6
4, 6
5, 6
doCountX = 6, doCountY = 15
There's the initial dump of doCountX = 0, doCountY = 0 which is to be expected as this call to dump() occurs before any calls to OnNext.
But when we get the first call to OnNext we don't get a value produced by the query because the second streamY observable hasn't yet been subscribed to.
It's only when OnNext is called the second time do we get a value from the query which happens to be the first OnNext value paired with the second. Now this also creates a new subscriptions to streamY, waiting for the next value.
So we've now got the first two values from streamX waiting for the next value from the sequence. So when OnNext(3) is called we get two results.
Each time this happens you can see the number of Do calls incrementing doCountY just keep going up.
In fact, given this very plain SelectMany query the formula is:
doCountY = n * (n - 1) / 2
So with 6 values produced via OnNext you get doCountY equal to 6 * 5 / 2 or 15.
Running with 10 values gives 10 * 9 / 2 or 45 values.
So a SelectMany in fact does many more subscriptions than you might think. This is often why you would generally only use it to chain together observables that only produce a single value each to prevent the exponential explosion of subscriptions.
Does it make sense now?
As an aside to Enigmativity's well fleshed-out answer, there are 2 things going on here:
Observables like Enumerables compose lazily.
Just like you wouldn't expect any combinator in an enumerable query to be evaluated until your move through the enumerator, you should expect that consumers will see the all combinators evaluated for that pipeline, as many times as the number of observers subscribing to the pipeline.
In short, x <- stream, y <- stream already makes it twice.
The comprehension is rewritten as:
stream1.Where(x => x % 2 == 1)
.SelectMany(x => stream2
.Where(y => y % 2 == 0 && y == x + 1)
.Select(y => new { x, y })
);
For every value of x received, you will make a subscription to all the values of the stream which match the predicate - which becomes a lot. Query comprehensions are generally de-sugared as SelectMany/Join/GroupBy - most of Rx you'll practically end up using might be better expressed in terms of other operators - such as Merge or Zip or even Join.
There's a question which is extremely similar to the one you've just asked:
Is Reactive Extensions evaluating too many times?
There's a bit of a discussion on why this is the expected behavior in Rx.

Extracting least significant bits - why is the % operator relevant?

I need help to understand the below code which I found in a tutorial explaining about Steganography and LSB. However, I couldn't understand why the code writer used the modulo operator (%).For example, to insert the new data in the red pixels, he used % 2, for green % 5 and so on. The snippet for the code is below:
for i, x in enumerate(data):
if counter < len(message_bit):
if i % 2 == 0:
r= int(str("{0:b}".format(x[0]))[:-1] + message_bit[counter], 2) # red
x = (r, x[1], x[2])
counter += 1
elif i % 5 == 0:
g = int(str("{0:b}".format(x[1]))[:-1] + message_bit[counter], 2) # green
x = (x[0], g, x[2])
counter += 1
elif i % 11 == 0:
pass
else:
b = int(str("{0:b}".format(x[2]))[:-1] + message_bit[counter], 2) #blue
x = (x[0], x[1], b)
counter += 1
new_data.append(x)
The modulo operator is used for calculating the remainder of integer division. For example, for incrementing i, i % 3 would give you the cyclic results 0, 1, 2, 0, 1, 2, etc. A conventional way would be to use this cyclic relationship to embed a bit in a different color plane.
if i % 3 == 0:
# embed in the red
elif i % 3 == 1:
# embed in the greed
else:
# embed in the blue
While this code's author achieves the same decision, the results show no clear pattern and the embedding is not uniform across all color planes.
i = 0
i % 2 == 0 is true -> embed in RED
i = 1
i % 2 == 0 is false
i % 5 == 0 is false
i % 11 == 0 is false
else -> embed in BLUE
i = 2
same as i = 0 -> embed in RED
i = 3
same as i = 1 -> embed in BLUE
i = 4
same as i = 0 -> embed in RED
i = 5
i % 2 == 0 is false
i % 5 == 0 is true -> embed in GREEN
continuing with this logic....
i = 6 -> embed in RED
i = 7 -> embed in BLUE
i = 8 -> embed in RED
i = 9 -> embed in BLUE
i = 10 -> embed in RED
i = 11 -> SKIP
and so on and so forth
Since every other i is even, you'll embed half of your bits in red. Since i % 5 == 0 and i % 11 == 0 are rarely true, you'll embed the majority of the rest of your bits in blue. And only approximately 1/10th of them will go into green (specifically when i is 5, 15, 25, ...).
I don't know where you found this code, but in the only place I could find it, there was no explanation by the poster. So one can only guess about the choice of this weird pattern. However, based on the quality of the rest of the code, I find it likely that the author misunderstood what he should be doing, which resulted in that weird pattern. The fact that both the embedding and extraction routines follow the logic means the program works and the author didn't think past that.
Extracting least significant bits - why is the % operator relevant?
well, if you choose a number that is 2^n you will return the n least significant bits, typically this is done with bitwise and and a mask eg...
m % 4 or (m % 2**2) will return the least significant 2 bits; in the range if 0-3 inclusively.
this is the same as something like m & 3... ie m & (2**n)-1

Counting threshold hits

Running solo and would like some help. If you had a series of numbers and wanted to keep count of how many times values cross barriers, how would you do this?
series = [1, 6, 2, 4, 1, 9, 2]
series.hit_counts(upper=7, middle=5, lower=3) #returns 3
Details
1 -> 6 = +1 (Going from 1 to 6 hits the lower and middle threshold)
6 -> 2 = +0 (The high value, 6, never reached the upper threshold although it crosses the middle)
2 -> 4 = +0 (2 is below the lower threshold but has not hit the middle)
4 -> 1 = +0 (The series still has not reached the middle threshold)
1 -> 9 = +1 (The series hit the middle threshold)
9 -> 2 = +1 (The series has hit the high and middle thresholds)
hit_counts: Counts how many times values reach either the upper or lower threshold then cross the middle threshold.
Upper limit: 7
Middle limit: 5
Lower limit: 3
The method in question would return 3. Any ideas would be appreciated.
I've taken a different approach to solving your problem.
Code
INF = Float::INFINITY
def score(series, limits)
last =
case series.first
when (-INF..limits[:LOWER]) then :LOWER
when (limits[:UPPER]..INF) then :UPPER
else :MIDDLE
end
series[1..-1].count do |n|
if limits[last] <= n
score = (last == :LOWER && n >= limits[:MIDDLE])
last =
case n
when (-INF..limits[:MIDDLE]-1) then :LOWER
when (limits[:UPPER]..INF) then :UPPER
else :MIDDLE
end
else
score = (last == :UPPER && n <= limits[:MIDDLE])
last =
case n
when (-INF..limits[:LOWER]) then :LOWER
when (limits[:MIDDLE]+1..INF) then :UPPER
else :MIDDLE
end
end
score
end
end
Examples
limits = { LOWER: 3, MIDDLE: 5, UPPER: 7 }
series = [1, 6, 2, 4, 1, 9, 2]
p score(series,limits) #=> 3
series = [1,5,12,8,10,4,13,3,1,4,6,4,6,9,1]
p score(series, limits) #=> 5
#BroiSatse gets the same results for these two test sequences.
Explanation
I've changed the rules to what I believe is a somewhat simpler problem that has the same scoring:
Let levels = {LOWER: 3, MIDDLE: 5, UPPER: 7}
A player starts at one of the three levels, :LOWER, :MIDDLE or :UPPER. If f = series.first, that level, held by the variable last, is:
:LOWER if f <= limits[:LOWER]
:UPPER if f >= limits[:UPPER],
:MIDDLE otherwise
`
The player will move among levels (or remain at the current level), scoring 1 when moving from :LOWER to :MIDDLE or :UPPER, or when moving from :UPPER to :MIDDLE or :LOWER.
For each i > 0, let f = series[i]. The player is located at last. The rules for moving and scoring are as follows:
if limits[last] <= f (moving to a non-decreasing value) the player moves to (and last becomes):
:LOWER if f < limits[:MIDDLE]
:UPPER if f >= limits[:UPPER]
:MIDDLE otherwise
A point is scored if the player moves from :LOWER to either :MIDDLE or :UPPER.
`
if f < limits[last] (moving to a decreasing value) the player moves to (and last becomes):
:LOWER if f <= limits[:LOWER]
:UPPER if f > limits[:MIDDLE]
:MIDDLE otherwise
A point is scored if the player moves from :UPPER to either :MIDDLE or :LOWER.
The process is repeated for each subsequent element in the sequence.
The code merely implements these rules in a straightforward way.
Assuming I understand what you want here, you can try sth like:
class Array
def hit_counts(upper=7, middle=5, lower=3)
limit_broken = false
each_cons(2).count do |a,b|
limit_broken = true unless (lower..upper).cover? a
current_range = Range.new(*[a,b].sort)
if limit_broken && current_range.cover?(middle)
limit_broken = false
true
else
false
end
end
end
end

Reverse Range in Swift

Is there a way to work with reverse ranges in Swift?
For example:
for i in 5...1 {
// do something
}
is an infinite loop.
I know I can use 1..5 instead, calculate j = 6 - i and use j as my index. I was just wondering if there was anything more legible?
Update For latest Swift 3 (still works in Swift 4)
You can use the reversed() method on a range
for i in (1...5).reversed() { print(i) } // 5 4 3 2 1
Or stride(from:through:by:) method
for i in stride(from:5,through:1,by:-1) { print(i) } // 5 4 3 2 1
stide(from:to:by:) is similar but excludes the last value
for i in stride(from:5,to:0,by:-1) { print(i) } // 5 4 3 2 1
Update For latest Swift 2
First of all, protocol extensions change how reverse is used:
for i in (1...5).reverse() { print(i) } // 5 4 3 2 1
Stride has been reworked in Xcode 7 Beta 6. The new usage is:
for i in 0.stride(to: -8, by: -2) { print(i) } // 0 -2 -4 -6
for i in 0.stride(through: -8, by: -2) { print(i) } // 0 -2 -4 -6 -8
It also works for Doubles:
for i in 0.5.stride(to:-0.1, by: -0.1) { print(i) }
Be wary of floating point compares here for the bounds.
Earlier edit for Swift 1.2: As of Xcode 6 Beta 4, by and ReverseRange don't exist anymore :[
If you are just looking to reverse a range, the reverse function is all you need:
for i in reverse(1...5) { println(i) } // prints 5,4,3,2,1
As posted by 0x7fffffff there is a new stride construct which can be used to iterate and increment by arbitrary integers. Apple also stated that floating point support is coming.
Sourced from his answer:
for x in stride(from: 0, through: -8, by: -2) {
println(x) // 0, -2, -4, -6, -8
}
for x in stride(from: 6, to: -2, by: -4) {
println(x) // 6, 2
}
There's something troubling about the asymmetry of this:
for i in (1..<5).reverse()
...as opposed to this:
for i in 1..<5 {
It means that every time I want to do a reverse range, I have to remember to put the parentheses, plus I have to write that .reverse() on the end, sticking out like a sore thumb. This is really ugly in comparison to C-style for loops, which are symmetrical counting up and counting down. So I tended to use C-style for loops instead. But in Swift 2.2, C-style for loops are going away! So I've had to scurry around replacing all my decrementing C-style for loops with this ugly .reverse() construct — wondering all the while, why on earth isn't there a reverse-range operator?
But wait! This is Swift — we're allowed to define our own operators!! Here we go:
infix operator >>> {
associativity none
precedence 135
}
func >>> <Pos : ForwardIndexType where Pos : Comparable>(end:Pos, start:Pos)
-> ReverseRandomAccessCollection<(Range<Pos>)> {
return (start..<end).reverse()
}
So now I'm allowed to say:
for i in 5>>>1 {print(i)} // 4, 3, 2, 1
This covers just the most common case that occurs in my code, but it is far and away the most common case, so it's all I need at present.
I had a kind of internal crisis coming up with the operator. I would have liked to use >.., as being the reverse of ..<, but that's not legal: you can't use a dot after a non-dot, it appears. I considered ..> but decided it was too hard to distinguish from ..<. The nice thing about >>> is that it screams at you: "down to!" (Of course you're free to come up with another operator. But my advice is: for super symmetry, define <<< to do what ..< does, and now you've got <<< and >>> which are symmetrical and easy to type.)
Swift 3 version (Xcode 8 seed 6):
infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound) ->
ReversedRandomAccessCollection<CountableRange<Bound>>
where Bound : Comparable, Bound.Stride : Integer {
return (minimum..<maximum).reversed()
}
Swift 4 version (Xcode 9 beta 3):
infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound)
-> ReversedRandomAccessCollection<CountableRange<Bound>>
where Bound : Comparable & Strideable {
return (minimum..<maximum).reversed()
}
Swift 4.2 version (Xcode 10 beta 1):
infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound)
-> ReversedRandomAccessCollection<Range<Bound>>
where Bound : Strideable {
return (minimum..<maximum).reversed()
}
It appears that the answers to this question have changed a bit as we've progressed through the betas. As of beta 4, both the by() function and the ReversedRange type have been removed from the language. If you're looking to make a reversed range, your options are now as follows:
1: Create a forward range, and then use the reverse() function to reverse it.
for x in reverse(0 ... 4) {
println(x) // 4, 3, 2, 1, 0
}
for x in reverse(0 ..< 4) {
println(x) // 3, 2, 1, 0
}
2: Use the new stride() functions that were added in beta 4, which includes functions to specify the starting and ending indexes, as well as the amount to iterate by.
for x in stride(from: 0, through: -8, by: -2) {
println(x) // 0, -2, -4, -6, -8
}
for x in stride(from: 6, to: -2, by: -4) {
println(x) // 6, 2
}
Note that I've also included the new exclusive range operator in this post as well. .. was replaced with ..<.
Edit: From the Xcode 6 beta 5 release notes, Apple added the following suggestion for handling this:
ReverseRange has been removed; use lazy(x..
Here's an example.
for i in lazy(0...5).reverse() {
// 0, 1, 2, 3, 4, 5
}
Xcode 7, beta 2:
for i in (1...5).reverse() {
// do something
}
Swift 3, 4+: you can do it like this:
for i in sequence(first: 10, next: {$0 - 1}) {
guard i >= 0 else {
break
}
print(i)
}
result: 10, 9, 8 ... 0
You can customise it any way you like. For more info read func sequence<T> reference
This could be another way of doing this.
(1...5).reversed().forEach { print($0) }
Reverse() function is used for reverse number.
Var n:Int // Enter number
For i in 1...n.reverse()
{
Print(i)
}

Simplest way to add bits mod n?

Given a bunch of integers, I want to convert them to base n and for each bit, add the bits up and mod them by n.
Example: Let n = 3, and suppose I want to add the bits mod 3 in 4, 4, 4, 2. These numbers in base 3 is 11, 11, 11, 02. The least significant bit adds up to 1 + 1 + 1 + 2 = 5 = 2 mod 3. The second least significant bit adds up to 1 + 1 + 1 + 0 = 3 = 0 mod 3. The answer is then 02 base 3 = 2. Alternatively, if we didn't convert to base 3 before the addition, and just did it in binary, we have 100, 100, 100, 010. The resulting bits from least significant to most significant is: 0 + 0 + 0 + 0 = 0 mod 3, 0 + 0 + 0 + 1 = 1 mod 3, 1 + 1 + 1 + 0 = 0 mod 3, so the answer is 010 = 2.
The case where n = 2 is pretty easy, you can just XOR everything. Is there a way to generalize this?
Here's a ditty in ruby:
#! /usr/bin/env ruby
def naryxor(n, terms)
puts "Calculating the #{n}-ary XOR of #{terms.join(", ")}..."
raise "Negative terms are forbidden" if terms.any? { |i| i < 0 }
xor = [] # "Digits" of our n-ary xor result
done = false
while not done
done = true # Assume we're done until proven otherwise
xor.insert(0, 0) # Insert a new total digit at the front
terms = terms.select { |i| i > 0 }.collect do |i|
done = false # Not all remaining terms were zero
digit = i % n # Find the least n-ary digit
rest = (i - digit) / n # shift it off
xor[0] += digit # add it to our xor
rest # Replace this integer with its remainder
end
xor[0] %= n # Take the mod once, after summing.
end
xor[1..-1] # Drop untouched leading digit
end
raise "Usage: ./naryxor.rb arity term term..." if ARGV.size <= 1
puts naryxor(ARGV[0].to_i, ARGV[1..-1].collect(&:to_i)).join("")
Running it:
$ ./naryxor.rb 3 4 4 4 2
Calculating the 3-ary XOR of 4, 4, 4, 2...
02
This is just expands the n-ary representations of the passed integers and does the dumb thing. If n were taken to be a power of two, we could do some more interesting bit-twiddles to avoid the integer divisions, but you gave no such guarantee.
I don't think there's a mathematical property that leads to an efficient general short-cut. The reason XOR works for base 2 is because XOR has the convenient property of being an addition with carry discard.
A simple recursive function can apply the algorithm, e.g. taking advantage of Scala's BigInt class for base conversion:
def sums(radix: Int, digits: List[List[String]]): String =
if(digits exists { _.nonEmpty }) // there's at least 1 bit left to add
(digits.flatMap { _.headOption } // take the 1st bit of all numbers
.map { BigInt(_, radix) } // convert to int representation
.sum
.toInt % radix // modulo by base
).toString +
sums(radix, digits map { _.drop(1) }) // do next most significant bit
else
"" // base case: no digits left to add
def sum(radix: Int, ns: List[Int]): Int =
BigInt(
sums(
radix,
ns // use BigInt to convert from int representation to string
.map { BigInt(_) }
.map { _.toString(radix).split("").drop(1).toList.reverse }
)
.reverse,
radix
).toInt
scala> sum(3, List(4,4,4,2))
res0: Int = 2
Your question is tagged 'performance' but doesn't lay out any additional constraints about memory or runtime to inform an improved approach.

Resources