Swift 3: func largestNumber - swift

I do not have good skills at development so don't laugh at me. But now I make some tests to improve my skills at coding and I have some question. At Apple dev guide I can't find an answer.
So Swift 3 title "Given an integer n, return the largest number that contains exactly n digits"
All I know is it is
func largestNumber(n: Int) -> Int {
Example:
For n = 2, the output should be
largestNumber(n) = 99
Tell me please how to code it.

All the comments at the time of writing on your question have taken the view that you are asking a coding question - i.e. how do I write this in Swift - rather than an algorithm question - i.e. what is the mathematical/algorithmic solution to this problem?
As others have pointed out SO is not for getting things written for you - code or algorithms - but giving you some pointers to explore is another matter. So tackling the second problem, here are some things to explore:
If you don't know what a logarithm is find out.
Consider that log10(10) = 1, log10(100) = 2, etc. there is a pattern here. Can you relate those logarithm values to the solution to your problem in some way?
Having done that what might the log10 of the maximum Int value tell you?
Could you use what you've determined so far to test the parameter n of your largestNumber function to make sure you can produce a valid answer (i.e. one which is less than or equal to the maximum Int value)?
You state that largestNumber(2) = 99, write 99 as a formula containing a power of 10? How about 999? Spot a pattern?
Once you've an algorithm you can then code it in Swift (or Objective-C, Basic, Java, FORTRAN, Ada, Jovial, Go, Haskell, etc., etc., etc...)
HTH

I think this would work for you
func largestNumber(digits: Int) -> Int{
var numStr = "0"
for i in 0..<digits {
//since the biggest digit in the decimal system is 9 we append that to our String
numStr += "9"
}
//convert String to Int
return Int(numStr) ?? 0
}

Here is the answer:
function largestNumber(n) {
var sum="";
for (i=0; i<n; i++)
{
sum+="9";
console.log(sum);
}
return parseInt(sum);
}

Related

Manage apps crashes when numbers are out of max possible in swift language

please can you help as I am in a corner....
My apps developped on Xcode with swift is calculating figures which can be out of Int max number and the apps crashes! How can I manage so that the apps manage before crashing? Example: I ask for an Int and calculate "factors" : 30! = 30 x 29 x 28x 27 x...1 but it is clearly over intmax
Thanks for you help
Regards
K
You can use Double to solve this problem.
For example to calculate this function calculate the factor of any Int (works for 170, then it's considered as Inf)
func factor(integer : Int) -> Double{
var result : Double = 1
for newFactor in 1...integer{
result = result * Double(newFactor)
print("index",newFactor,"value:",result)
}
return result
}
you should use overflow operator just like:
var overflowNum = UInt8.max;
overflowNum = overflowNum &* 10;
this will be overflowed and finally the value is between the UInt8.min and the Uint8.max
just like the real big number you've got to mod with UInt8.max.

Iterating through all but the last index of an array

I understand that in Swift 3 there have been some changes from typical C Style for-loops. I've been working around it, but it seems like I'm writing more code than before in many cases. Maybe someone can steer me in the right direction because this is what I want:
let names : [String] = ["Jim", "Jenny", "Earl"]
for var i = 0; i < names.count - 1; i+=1 {
NSLog("%# loves %#", names[i], names[i+1])
}
Pretty simple stuff. I like to be able to get the index I'm on, and I like the for-loop to not run if names.count == 0. All in one go.
But it seems like my options in Swift 3 aren't allowing me this. I would have to do something like:
let names : [String] = ["Jim", "Jenny", "Earl"]
if names.count > 0 {
for i in 0...(names.count - 1) {
NSLog("%# loves %#", names[i], names[i+1])
}
}
The if statement at the start is needed because my program will crash in the situation where it reads: for i in 0...0 { }
I also like the idea of being able to just iterate through everything without explicitly setting the index:
// Pseudocode
for name in names.exceptLastOne {
NSLog("%# loves %#", name, name.plus(1))
}
I feel like there is some sort of syntax that mixes all my wants, but I haven't come across it yet. Does anyone know of a way? Or at least a way to make my code more compact?
UPDATE: Someone suggested that this question has already been asked, citing a SO post where the solution was to use something to the degree of:
for (index, name) in names.enumerated {}
The problem with this when compared to Hamish's answer is that I only am given the index of the current name. That doesn't allow me to get the value at index without needing to do something like:
names[index + 1]
That's just one extra variable to keep track of. I prefer Hamish's which is:
for i in names.indices.dropLast() {
print("\(names[i]) loves \(names[i + 1])")
}
Short, simple, and only have to keep track of names and i, rather than names, index, and name.
One option would be to use dropLast() on the array's indices, allowing you to iterate over a CountableRange of all but the last index of the array.
let names = ["Jim", "Jenny", "Earl"]
for i in names.indices.dropLast() {
print("\(names[i]) loves \(names[i + 1])")
}
If the array has less than two elements, the loop won't be entered.
Another option would be to zip the array with the array where the first element has been dropped, allowing you to iterate through the pairs of elements with their successor elements:
for (nameA, nameB) in zip(names, names.dropFirst()) {
print("\(nameA) loves \(nameB)")
}
This takes advantage of the fact that zip truncates the longer of the two sequences if they aren't of equal length. Therefore if the array has less than two elements, again, the loop won't be entered.

How to obtain the exponent value of a number?

Basically I would like to know if it is possible to get the exponent value in a number, ex:
number = 2.6e3
I want to get the value 3 of the exponent. I have been searching for quite a while now and have not found the answer to this. I am new to programming so I may not know exactly what to look for (which methods, etc).
Any help is much appreciated! Thanks!
Assuming I am interpreting your question correctly this is what you want to do:
B = A^X where A and B are known values. Solve for X.
1000 = 10^X (In this case, X = 3.)
The below code will work for any base. It requires either Foundation or UIKit. The function arguments "value" and "base" are B, A respectively. Try the code out in the Xcode Playground!
func getExponentForValueAndBase(value: Double, base: Double) -> Double {
return log(value)/log(base)
}
getExponentForValueAndBase(1000, base: 10) // = 3
Assuming this is your question: Given a number as an integer, find the interger value of the log base 10 of it.
import Foundation
func log(Int number) -> Int
{
return floor(log10(number))
}

What type to use for timeIntervalSince1970 in ms?

I need time since Epoch in ms for an API request, so I'm looking to have a function that converts my myUIDatePicker.date.timeIntervalSince1970 into milliseconds by multiplying by 1000. My question is what should the return value be?
Right now I have
func setTimeSinceEpoch(datePicker: UIDatePicker) -> Int {
return Int(datePicker.date.timeIntervalSince1970 * 1000)
}
Will this cause any issues? I need an integer, not a floating point, but will I have issues with overflow? I tested it out with print statements and it seems to work but I want to find the best way of doing this.
Looking at Apple Docs:
var NSTimeIntervalSince1970: Double { get }
There is a nice function called distantFuture. Even if you use this date in you func the result will be smaller then the max Int.
let future = NSDate.distantFuture() // "Jan 1, 4001, 12:00 AM"
print((Int(future.timeIntervalSince1970) * 1000) < Int.max) // true
So, until 4001 you're good to go. It will work perfectly on 64-bits systems.
Note: If your system supports iPhone 5 (32-bits) it's going to get an error on pretty much any date you use. Int in Iphone 5 corresponds to Int32.
Returning an Int64 is a better approach. See this.

In swift which loop is faster `for` or `for-in`? Why?

Which loop should I use when have to be extremely aware of the time it takes to iterate over a large array.
Short answer
Don’t micro-optimize like this – any difference there is could be far outweighed by the speed of the operation you are performing inside the loop. If you truly think this loop is a performance bottleneck, perhaps you would be better served by using something like the accelerate framework – but only if profiling shows you that effort is truly worth it.
And don’t fight the language. Use for…in unless what you want to achieve cannot be expressed with for…in. These cases are rare. The benefit of for…in is that it’s incredibly hard to get it wrong. That is much more important. Prioritize correctness over speed. Clarity is important. You might even want to skip a for loop entirely and use map or reduce.
Longer Answer
For arrays, if you try them without the fastest compiler optimization, they perform identically, because they essentially do the same thing.
Presumably your for ;; loop looks something like this:
var sum = 0
for var i = 0; i < a.count; ++i {
sum += a[i]
}
and your for…in loop something like this:
for x in a {
sum += x
}
Let’s rewrite the for…in to show what is really going on under the covers:
var g = a.generate()
while let x = g.next() {
sum += x
}
And then let’s rewrite that for what a.generate() returns, and something like what the let is doing:
var g = IndexingGenerator<[Int]>(a)
var wrapped_x = g.next()
while wrapped_x != nil {
let x = wrapped_x!
sum += x
wrapped_x = g.next()
}
Here is what the implementation for IndexingGenerator<[Int]> might look like:
struct IndexingGeneratorArrayOfInt {
private let _seq: [Int]
var _idx: Int = 0
init(_ seq: [Int]) {
_seq = seq
}
mutating func generate() -> Int? {
if _idx != _seq.endIndex {
return _seq[_idx++]
}
else {
return nil
}
}
}
Wow, that’s a lot of code, surely it performs way slower than the regular for ;; loop!
Nope. Because while that might be what it is logically doing, the compiler has a lot of latitude to optimize. For example, note that IndexingGeneratorArrayOfInt is a struct not a class. This means it has no overhead over declaring the two member variables directly. It also means the compiler might be able to inline the code in generate – there is no indirection going on here, no overloaded methods and vtables or objc_MsgSend. Just some simple pointer arithmetic and deferencing. If you strip away all the syntax for the structs and method calls, you’ll find that what the for…in code ends up being is almost exactly the same as what the for ;; loop is doing.
for…in helps avoid performance errors
If, on the other hand, for the code given at the beginning, you switch compiler optimization to the faster setting, for…in appears to blow for ;; away. In some non-scientific tests I ran using XCTestCase.measureBlock, summing a large array of random numbers, it was an order of magnitude faster.
Why? Because of the use of count:
for var i = 0; i < a.count; ++i {
// ^-- calling a.count every time...
sum += a[i]
}
Maybe the optimizer could have fixed this for you, but in this case it hasn’t. If you pull the invariant out, it goes back to being the same as for…in in terms of speed:
let count = a.count
for var i = 0; i < count; ++i {
sum += a[i]
}
“Oh, I would definitely do that every time, so it doesn’t matter”. To which I say, really? Are you sure? Bet you forget sometimes.
But you want the even better news? Doing the same summation with reduce was (in my, again not very scientific, tests) even faster than the for loops:
let sum = a.reduce(0,+)
But it is also so much more expressive and readable (IMO), and allows you to use let to declare your result. Given that this should be your primary goal anyway, the speed is an added bonus. But hopefully the performance will give you an incentive to do it regardless.
This is just for arrays, but what about other collections? Of course this depends on the implementation but there’s a good reason to believe it would be faster for other collections like dictionaries, custom user-defined collections.
My reason for this would be that the author of the collection can implement an optimized version of generate, because they know exactly how the collection is being used. Suppose subscript lookup involves some calculation (such as pointer arithmetic in the case of an array - you have to add multiple the index by the value size then add that to the base pointer). In the case of generate, you know what is being done is to sequentially walk the collection, and therefore you could optimize for this (for example, in the case of an array, hold a pointer to the next element which you increment each time next is called). Same goes for specialized member versions of reduce or map.
This might even be why reduce is performing so well on arrays – who knows (you could stick a breakpoint on the function passed in if you wanted to try and find out). But it’s just another justification for using the language construct you should probably be using regardless.
Famously stated: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil" Donald Knuth. It seems unlikely that you are in the %3.
Focus on the bigger problem at hand. After it is working, if it needs a performance boost, then worry about for loops. But I guarantee you, in the end, bigger structural inefficiencies or poor algorithm choice will be the performance problem, not a for loop.
Worrying about for loops is oh so 1960s.
FWIW, a rudimentary playground test shows map() is about 10 times faster than for enumeration:
class SomeClass1 {
let value: UInt32 = arc4random_uniform(100)
}
class SomeClass2 {
let value: UInt32
init(value: UInt32) {
self.value = value
}
}
var someClass1s = [SomeClass1]()
for _ in 0..<1000 {
someClass1s.append(SomeClass1())
}
var someClass2s = [SomeClass2]()
let startTimeInterval1 = CFAbsoluteTimeGetCurrent()
someClass1s.map { someClass2s.append(SomeClass2(value: $0.value)) }
println("Time1: \(CFAbsoluteTimeGetCurrent() - startTimeInterval1)") // "Time1: 0.489435970783234"
var someMoreClass2s = [SomeClass2]()
let startTimeInterval2 = CFAbsoluteTimeGetCurrent()
for item in someClass1s { someMoreClass2s.append(SomeClass2(value: item.value)) }
println("Time2: \(CFAbsoluteTimeGetCurrent() - startTimeInterval2)") // "Time2 : 4.81457495689392"
The for (with a counter) is just incrementing a counter. Very fast. The for-in uses an iterator (call object to pass the next element). This is much slower. But finally you want to access the element in both cases wich will then make no difference in the end.