4

I need Something like

var a = 1
var b = 2
var c = a + b should be 12 (Int) instead of 3.

var a = 12
var b = 34
var c = a + b should be 1234 (Int) instead of 46.

I am not figuring out how can we do this for any number?

One way is to convert two both Int to String, concatenate and covert it again that String to Int, but I don't think it's efficient.

Thank you in advance if you have a solution.

Dimple
  • 788
  • 1
  • 11
  • 27
Jigar
  • 305
  • 2
  • 14
  • `var c = a*10+b` resp. `var c = a*100+b`, you just have to check how "big" `a` is to multiply with 10, 100 and so on. – Andreas Oetjen Oct 04 '18 at 07:11
  • @AndreasOetjen that I know but, it's not a proper solution, var a= 122344 and b =9022, what about this? every time needs to write different code. – Jigar Oct 04 '18 at 07:14
  • You could use the 10th logarithm to find out the dimension of "b" (e.g. the part before the fraction), and then calculate 10 to the power of that, and multiply it with `a`. Or, much more efficient, use a switch case statement. – Andreas Oetjen Oct 04 '18 at 07:19
  • 1
    Did anyone check if any of the solutions are more efficient than the converting both int to string and back? Maybe add that also to the answer? – Rakesha Shastri Oct 04 '18 at 07:29
  • I've checked it. My solution is 3 times faster (in playground) than string concatenation. – Daniil Subbotin Oct 04 '18 at 07:39
  • In the playground, the switch/case solution is about 100 times faster than the String/Int conversation. – Andreas Oetjen Oct 04 '18 at 07:54
  • @subdan i just saw somewhere today that playground results are the most unreliable. Try it in a project. Not saying it won't be better. – Rakesha Shastri Oct 04 '18 at 10:14

4 Answers4

2

12+34 = 12*10^2 + 34 = 1200+34 = 1234

func logC(val: Double, forBase base: Double) -> Double {
    return log(val)/log(base)
}

var a = 10
var b = 0
let x = b == 10 ? 2 : b == 0 ? 1 : ceil(logC(val: Double(b), forBase: 10))
var c = Int(Double(a) * pow(10, x) + Double(b))
print(c)
Daniil Subbotin
  • 6,138
  • 5
  • 20
  • 24
  • 1
    This is nice, but I think it's not that performant, because of the `log` function – Andreas Oetjen Oct 04 '18 at 07:27
  • @AndreasOetjen That's true, it's not performant, I was surprised when I haven't found any swift function for that, Do you think it should be in Swift 5? – Jigar Oct 04 '18 at 07:37
  • You can covnert the second number to string and get its length. Or just divide by 10 until you get zero. – Sulthan Oct 04 '18 at 07:50
  • It's not working, try using `a=10` and `b=10`, and you get `110` instead of `1010`. You have to increment `x` by one: `let x = ceil(logC(val: Double(b), forBase: 10)) + 1` – Andreas Oetjen Oct 04 '18 at 07:52
  • Also, it does not work if `b=0`; in this case, you get `x=-inf` – Andreas Oetjen Oct 04 '18 at 07:58
1

You can write something like this:

extension Int {
    func concatenateDecimalDigits(in other: Int) -> Int {
        let scale: Int
        switch other {
        case 0...9:
            scale = 10
        case 10...99:
            scale = 100
        case 100...999:
            scale = 1000
        case 1000...9999:
            scale = 10000
        case 10000...99999:
            scale = 100000
        case 100000...999999:
            scale = 1000000
        //You need to add more cases if you need...
        //...
            //...
        default:
            scale = 0   //ignore invalid values
        }
        return self * scale + other
    }
}
var a = 1
var b = 2
print( a.concatenateDecimalDigits(in: b) ) //->12
a = 12
b = 34
print( a.concatenateDecimalDigits(in: b) ) //->1234
a = 122344
b = 9022
print( a.concatenateDecimalDigits(in: b) ) //->1223449022

You can write some logic to calculate scale without switch, but that does not make much difference.

Sulthan
  • 128,090
  • 22
  • 218
  • 270
OOPer
  • 47,149
  • 6
  • 107
  • 142
  • 1
    I think this is the most efficent / performant solution, without any `log` calculations. But it's not that nice-looking, as always :-) – Andreas Oetjen Oct 04 '18 at 07:28
  • By the way, this could be simplified to something like `let scales = [1, 10, 100, 1000, 10000, ...]; let scale = (scales.first { other < $0 }) ?? 0`. – Sulthan Oct 04 '18 at 08:05
  • @Sulthan, yes, that's one possible option which I have included in _some logic to calculate `scale` without `switch`_. In fact, I have chosen my code for easy-to-understand readability, not for performance nor code conciseness. – OOPer Oct 04 '18 at 08:09
1

You can do it with simple conversion like below:

var a = 1
var b = 2
var c = Int("\(a)\(b)") // Result 12

var a1 = 12
var b1 = 34
var c1 = Int("\(a1)\(b1)")  // Result 1234


var a2 = 122344
var b2 = 9022
var c2 = Int("\(a2)\(b2)") // Result 1223449022
Karamjeet Singh
  • 460
  • 1
  • 5
  • 16
  • 2
    This is not an answer, this is what @Jigar already asked: _One way is to convert two both Int to String, concatenate and covert it again that String to Int, but I don't think it's efficient._ – Andreas Oetjen Oct 04 '18 at 08:00
  • This doesn't answer the question regarding efficiency. – William Grand May 17 '23 at 13:32
0

General solution for any two Int:

You will need to calculate number of digits for calculate multiplier as:

func numberOfDigits(_ num: Int) -> Int {
    var count = 0
    var number = num
    while number > 0 {
        number = number / 10
        count += 1
    }
    return count
}

Use it as:

    let a = 11
    let b = 24

    let noOfDigit = numberOfDigits(b)
    let multiplier = pow(Double(10), Double(noOfDigit))
    let c = a * Int(multiplier) + b
    print(c)

And, in one line as:

    let c = a * Int(pow(Double(10), Double(numberOfDigits(b)))) + b
Ankit Jayaswal
  • 5,549
  • 3
  • 16
  • 36