Is there a way to show where a large number lies in a range of a smaller number? - swift

I'm not quite sure how to word this question, but perhaps an example will help...
Is there an operator which will show the placement of, say, 25, on a number range from 1-7?
For example:
25/7 returns 4
21/7 returns 7
22/7 returns 1
4/7 returns 4
etc.
Example of code:
var dayOfMonth: Int = 28
var aNumber: Int
aNumber = (dayOfMonth ) % 7
func dayOfTheWeek(day: Int) {
switch day {
case 0:
print("Monday")
case 1:
print("Tuesday")
case 2:
print("Wednesday")
case 3:
print("Thursday")
case 4:
print("Friday")
case 5:
print("Saturday")
case 6:
print("Sunday")
default:
print("Error")
}
}
dayOfTheWeek(day: aNumber)

I think you're looking for the modulo operator, spelt % in Swift. With the difference that 21 % 7 is 0, not 7.
m % n could be thought of as "the remainder after dividing m by n"

Related

How to get the binary inverse of a number in Swift?

If we have a given number, say 9 (binary representation is 1001). How can we most efficiently get it's inverse 6 (binary representation is 0110)? i.e replacing 0 with 1 and 1 with 0.
I have written a code of order O(1) complexity? But can there be a better way? Does Swift provide an elegant way of handling this?
Note negate function ~9 results in -10. This is not what I am seeking.
func inverse(of givenNumber: Int) -> Int // eg. 9
{
let binaryRepresentation = String(givenNumber, radix: 2) // "1001"
let binaryRepresentationLength = binaryRepresentation.count // 4
let maxValueInLength = (1 << binaryRepresentationLength) - 1 // 15, i.e., 1111
let answer = givenNumber ^ maxValueInLength // 6, i.e., 0110
return answer
}
Edit 1: givenNumber > 0
For positive numbers you can use the following:
func intInverse<T: FixedWidthInteger>(of givenNumber: T) -> T
{
assert(!T.isSigned || givenNumber & (T(1) << (givenNumber.bitWidth - 1)) == 0)
let binaryRepresentationLength = givenNumber.bitWidth - givenNumber.leadingZeroBitCount
let maxValueInLength = givenNumber.leadingZeroBitCount > 0 ? (~(~T(0) << binaryRepresentationLength)) : ~0
let answer = givenNumber ^ maxValueInLength
return answer
}
Which is identical to your algorithm but doesn't require stringifying the number. It doesn't work for negative numbers, but then neither does your algorithm because your algorithm sticks a - on the front of the number.
Probably the easiest way to extend this to cover negative numbers is to invert all the bits to get the binaryRepresentationLength
EDIT
I changed the way the exclusive or mask is created because the old one crashed for unsigned values with the top bit set and for signed values with the second highest bit set.
The code becomes much simpler using the property binade of a floating-point value.
func inverse(of givenNumber: Int) -> Int // eg. 9
{
let maxValueInLength = Int((Double(givenNumber).binade * 2) - 1) // 15, i.e., 1111
let answer = givenNumber ^ maxValueInLength // 6, i.e., 0110
return answer
}

Generating a simple algebraic expression in swift

I'm looking to create a function that returns a solve for x math equation that can be preformed in ones head (Clearly thats a bit subjective but I'm not sure how else to phrase it).
Example problem: (x - 15)/10 = 6
Note: Only 1 x in the equation
I want to use the operations +, -, *, /, sqrt (Only applied to X -> sqrt(x))
I know that let mathExpression = NSExpression(format: question) converts strings into math equations but when solving for x I'm not sure how to go about doing this.
I previously asked Generating random doable math problems swift for non solving for x problems but I'm not sure how to convert that answer into solving for x
Edit: Goal is to generate an equation and have the user solve for the variable.
Since all you want is a string representing an equation and a value for x, you don't need to do any solving. Just start with x and transform it until you have a nice equation. Here's a sample: (copy and paste it into a Playground to try it out)
import UIKit
enum Operation: String {
case addition = "+"
case subtraction = "-"
case multiplication = "*"
case division = "/"
static func all() -> [Operation] {
return [.addition, .subtraction, .multiplication, .division]
}
static func random() -> Operation {
let all = Operation.all()
let selection = Int(arc4random_uniform(UInt32(all.count)))
return all[selection]
}
}
func addNewTerm(formula: String, result: Int) -> (formula: String, result: Int) {
// choose a random number and operation
let operation = Operation.random()
let number = chooseRandomNumberFor(operation: operation, on: result)
// apply to the left side
let newFormula = applyTermTo(formula: formula, number: number, operation: operation)
// apply to the right side
let newResult = applyTermTo(result: result, number: number, operation: operation)
return (newFormula, newResult)
}
func applyTermTo(formula: String, number:Int, operation:Operation) -> String {
return "\(formula) \(operation.rawValue) \(number)"
}
func applyTermTo(result: Int, number:Int, operation:Operation) -> Int {
switch(operation) {
case .addition: return result + number
case .subtraction: return result - number
case .multiplication: return result * number
case .division: return result / number
}
}
func chooseRandomNumberFor(operation: Operation, on number: Int) -> Int {
switch(operation) {
case .addition, .subtraction, .multiplication:
return Int(arc4random_uniform(10) + 1)
case .division:
// add code here to find integer factors
return 1
}
}
func generateFormula(_ numTerms:Int = 1) -> (String, Int) {
let x = Int(arc4random_uniform(10))
var leftSide = "x"
var result = x
for i in 1...numTerms {
(leftSide, result) = addNewTerm(formula: leftSide, result: result)
if i < numTerms {
leftSide = "(" + leftSide + ")"
}
}
let formula = "\(leftSide) = \(result)"
return (formula, x)
}
func printFormula(_ numTerms:Int = 1) {
let (formula, x) = generateFormula(numTerms)
print(formula, " x = ", x)
}
for i in 1...30 {
printFormula(Int(arc4random_uniform(3)) + 1)
}
There are some things missing. The sqrt() function will have to be implemented separately. And for division to be useful, you'll have to add in a system to find factors (since you presumably want the results to be integers). Depending on what sort of output you want, there's a lot more work to do, but this should get you started.
Here's sample output:
(x + 10) - 5 = 11 x = 6
((x + 6) + 6) - 1 = 20 x = 9
x - 2 = 5 x = 7
((x + 3) * 5) - 6 = 39 x = 6
(x / 1) + 6 = 11 x = 5
(x * 6) * 3 = 54 x = 3
x * 9 = 54 x = 6
((x / 1) - 6) + 8 = 11 x = 9
Okay, let’s assume from you saying “Note: Only 1 x in the equation” that what you want is a linear equation of the form y = 0 = β1*x + β0, where β0 and β1 are the slope and intercept coefficients, respectively.
The inverse of (or solution to) any linear equation is given by x = -β0/β1. So what you really need to do is generate random integers β0 and β1 to create your equation. But since it should be “solvable” in someone’s head, you probably want β0 to be divisible by β1, and furthermore, for β1 and β0/β1 to be less than or equal to 12, since this is the upper limit of the commonly known multiplication tables. In this case, just generate a random integer β1 ≤ 12, and β0 equal to β1 times some integer n, 0 ≤ n ≤ 12.
If you want to allow simple fractional solutions like 2/3, just multiply the denominator and the numerator into β0 and β1, respectively, taking care to prevent the numerator or denominator from getting too large (12 is again a good limit).
Since you probably want to make y non-zero, just generate a third random integer y between -12 and 12, and change your output equation to y = β1*x + β0 + y.
Since you mentioned √ could occur over the x variable only, that is pretty easy to add; the solution (to 0 = β1*sqrt(x) + β0) is just x = (β0/β1)**2.
Here is some very simple (and very problematic) code for generating random integers to get you started:
import func Glibc.srand
import func Glibc.rand
import func Glibc.time
srand(UInt32(time(nil)))
print(rand() % 12)
There are a great many answers on this website that deal with better ways to generate random integers.

Number of Cycles from list of values, which are mix of positives and negatives in Spark and Scala

Have an RDD with List of values, which are mix of positives and negatives.
Need to compute number of cycles from this data.
For example,
val range = List(sampleRange(2020,2030,2040,2050,-1000,-1010,-1020,Starting point,-1030,2040,-1020,2050,2040,2020,end point,-1060,-1030,-1010)
the interval between each value in above list is 1 second. ie., 2020 and 2030 are recorded in 1 second interval and so on.
how many times it turns from negative to positive and stays positive for >= 2 seconds.
If >= 2 seconds it is a cycle.
Number of cycles: Logic
Example 1: List(1,2,3,4,5,6,-15,-66)
No. of cycles is 1.
Reason: As we move from 1st element of list to 6th element, we had 5 intervals which means 5 seconds. So one cycle.
As we move to 6th element of list, it is a negative value. So we start counting from 6th element and move to 7th element. The negative values are only 2 and interval is only 1. So not counted as cycle.
Example 2:
List(11,22,33,-25,-36,-43,20,25,28)
No. of cycles is 3.
Reason: As we move from 1st element of list to 3rd element, we had 2 intervals which means 2 seconds. So one cycle As we move to 4th element of list, it is a negative value. So we start counting from 4th element and move to 5th, 6th element. we had 2 intervals which means 2 seconds. So one cycle As we move to 7th element of list, it is a positive value. So we start counting from 7th element and move to 8th, 9th element. we had 2 intervals which means 2 seconds. So one cycle.
range is a RDD in the use case. It looks like
scala> range
range: Seq[com.Range] = List(XtreamRange(858,890,899,920,StartEngage,-758,-790,-890,-720,920,940,950))
You can encode this "how many times it turns from negative to positive and stays positive for >= 2 seconds. If >= 2 seconds it is a cycle." pretty much directly into a pattern match with a guard. The expression if(h < 0 && ht > 0 && hht > 0) checks for a cycle and adds one to the result then continues with the rest of the list.
def countCycles(xs: List[Int]): Int = xs match {
case Nil => 0
case h::ht::hht::t if(h < 0 && ht > 0 && hht > 0) => 1 + countCycles(t)
case h::t => countCycles(t)
}
scala> countCycles(range)
res7: Int = 1
A one liner
range.sliding(3).count{case f::s::t::Nil => f < 0 && s > 0 && t > 0}
This generates all sub-sequences of length 3 and counts how many are -ve, +ve, +ve
Generalising cycle length
def countCycles(n:Int, xs:List[Int]) = xs.sliding(n+1)
.count(ys => ys.head < 0 && ys.tail.forall(_ > 0))
The below code would help you resolve you query.
object CycleCheck {
def main(args: Array[String]) {
var data3 = List(1, 4, 82, -2, -12, "startingpoint", -9, 32, 76,45, -98, 76, "Endpoint", -24)
var data2 = data3.map(x => getInteger(x)).filter(_ != "unknown").map(_.toString.toInt)
println(data2)
var nCycle = findNCycle(data2)
println(nCycle)
}
def getInteger(obj: Any) = obj match {
case n: Int => obj
case _ => "unknown"
}
def findNCycle(obj: List[Int]) : Int = {
var cycleCount =0
var sign = ""
var signCheck="+"
var size = obj.size - 1
var numberOfCycles=0
var i=0
for( x <- obj){
if (x < 0){
sign="-"
}
else if (x > 0){
sign="+"
}
if(signCheck.equals(sign))
cycleCount=cycleCount+1
if(!signCheck.equals(sign) && cycleCount>1){
cycleCount = 1
numberOfCycles=numberOfCycles+1
}
if(size==i && cycleCount>1)
numberOfCycles= numberOfCycles+1
if(cycleCount==1)
signCheck = sign;
i=i+1
}
return numberOfCycles
}
}

Check a multiple in Swift?

I am trying to find the odd numbers and a multiple of 7 between a 1 to 100 and append them into an array. I have got this far:
var results: [Int] = []
for n in 1...100 {
if n / 2 != 0 && 7 / 100 == 0 {
results.append(n)
}
}
Your conditions are incorrect. You want to use "modular arithmetic"
Odd numbers are not divisible by 2. To check this use:
if n % 2 != 0
The % is the mod function and it returns the remainder of the division (e.g. 5 / 2 is 2.5 but integers don't have decimals, so the integer result is 2 with a remainder of 1 and 5 / 2 => 2 and 5 % 2 => 1)
To check if it's divisible by 7, use the same principle:
if n % 7 == 0
The remainder is 0 if the dividend is divisible by the divisor. The complete if condition is:
if n % 2 != 0 && n % 7 == 0
You can also use n % 2 == 1 because the remainder is always 1. The result of any mod function, a % b, is always between 0 and b - 1.
Or, using the new function isMultiple(of:, that final condition would be:
if !n.isMultiple(of: 2) && n.isMultiple(of: 7)
Swift 5:
Since Swift 5 has been released, you could use isMultiple(of:) method.
In your case, you should check if it is not multiple of ... :
if !n.isMultiple(of: 2)
Swift 5 is coming with isMultiple(of:) method for integers , so you can try
let res = Array(1...100).filter { !$0.isMultiple(of:2) && $0.isMultiple(of:7) }
Here is an efficient and concise way of getting the odd multiples of 7 less than or equal to 100 :
let results: [Int] = Array(stride(from: 7, through: 100, by: 14))
You can also use the built-in filter to do an operation on only qualified members of an array. Here is how that'd go in your case for example
var result = Array(1...100).filter { (number) -> Bool in
return (number % 2 != 0 && number % 7 == 0)
}
print(result) // will print [7, 21, 35, 49, 63, 77, 91]
You can read more about filter in the doc but here is the basics: it goes through each element and collects elements that return true on the condition. So it filters the array and returns what you want

map function in Swift converting String to Int?

let digitNames = [
0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",
5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]
let strings = numbers.map {
(var number) -> String in
var output = ""
while number > 0 {
output = digitNames[number % 10]! + output
number /= 10
}
return output
}
// strings is inferred to be of type [String]
// its value is ["OneSix", "FiveEight", "FiveOneZero"]
I was hoping if there is anyone that could explain how this code works (it is taken from apple's developer page for swift under "closures). I'm not too sure especially what the code in the "while" loop means :/ how exactly is the number converted to string?
map function is Higher Order Level function and it is used to do some operation on single elements of array and return a transformed array generated after your operations.
numbers.map will traverse each element of array and transform the elements by doing some operation and returned a transformed array .
output = digitNames[number % 10]! + output
1) for first element in array 16 in first iteration of while loop number % 10 will return 6 as a reminder of 16 after dividing by 10 so digitName[6] will assign output to Six
let strings = numbers.map {
(var number) -> String in
var output = ""
while number > 0 {
output = digitNames[number % 10]! + output //16
number /= 10
}
return output
}
2) It divides number by 10 and which will give 1 now number will be 1
3) while number > 0 { checks if number is greater than 0 yes it is 1
4) Again iterate now this time digitNames[number % 10]! return One and by appending previous output it will become One append output(which is Six).So OneSix
Your first element become OneSix.This will done for each element and after all elements map return String array.So finally String become
["OneSix", "FiveEight", "FiveOneZero"]