Drop Digits from an Integer

Drop digits from an integer

The simplest solution is actually just outputting the input - as long as the input is between 0 and 21,474,834.


The given equation gives the same value as is input. The first few operations give us:

5 * (4 * (5x + 6) + 9)
= 20 * (5x + 6) + 45
= 100x + 165

"Removing the last two digits" is equivalent to dividing by 100 and truncating the decimal part (we can use floor as the input is non-negative), which gives:

floor((100x + 165) / 100) = floor(x + 1.65) = x + 1

Subtracting 1 then just gives x, the input.


This won't necessarily give the same input if the computation would overflow. An int in Java is a signed 32 bit integer, so the largest value we can store is 231-1 = 2,147,483,647. If the largest intermediate value in the equation goes over this, we won't get the right answer:

100x + 165 <= 2147483647

Gives the maximum x for which this approach will give the same value as an approach which performs each operation, as 21,474,834.


All this said, your (updated) code is a good solution and is perfectly readable. You should consider introducing error checks (your quote says the input must be >=0, this is worth enforcing).

Adding a comment explaining that "an integer division by 100 is used to trim the last two digits" is also probably a good idea, as another developer reading your code later may assume you've made a mistake (didn't realise it would truncate). Whenever you rely on unusual behaviour, document it.

Removing digits from an integer

Can anyone explain what the error means?

The precedence in your first line is off - infix functions (like /) usually have a higher precedence than normal ones, so print (...) / 100 is equivalent to (print ...) / 100, which is obviously problematic. You can wrap everything in brackets, or use the $ function:

print $ ((((i * 5) + 6) * 4 + 9) * 5) / 100 - 1

Now as you've constrained i to be an Int, this will still give an error: / is only defined for instances of the Fractional typeclass, and Int isn't. You want integer division, div or quot, which operates only on Integrals (of which Int is an instance) and perform truncation as you want:

print $ ((((i * 5) + 6) * 4 + 9) * 5) `div` 100 - 1

Note the backticks (`), which allow a normal function to be used infix. You could write this as:

print $ (div ((((i * 5) + 6) * 4 + 9) * 5) 100) - 1

But then the brackets are making things really hard to read.


Are there any other solutions better than truncating by a divisor?

In general probably not, but as mentioned on your other question, this particular equation will always give you the same result as your input, so you can just write:

main = getLine >>= print

How can I remove digits at arbitrary positions?

Converting to a string and removing characters is likely your best bet. Something like the following will work, although it's arguably a bit dense:

removeDigits :: [Int] -> Int -> Int
removeDigits indices x = read . reverse . filterIndices indices . reverse . show $ x

filterIndices :: [Int] -> [a] -> [a]
filterIndices inds elems = map snd . filter ((`notElem` inds) . fst) . zip [1..] $ elems

Note this treats the last digit as the "1st" digit - it's a bit more natural to refer to digits with.


An (in my opinion) easier to read representation of your existing code is:

transform = (subtract 1) . (`quot` 100) . (*5) . (+9) . (*4) . (+6) . (*5)

With this way of writing it, composition overrides the arithmetic precedence laws, letting us write it how it's read ("times 5, add 6, times 4, ..."). We have to use subtract 1, as -1 is interpreted as the literal value -1, not as a unary function.

How to remove a particular digit from an integer using javascript

Try this :

// Input
let number = 789012345;

// Convert number into a string
let numberStr = number.toString();

// Replace the 0 with empty string
const res = numberStr.replace(numberStr[3], '');

// Convert string into a number.
console.log(Number(res));

Removing numbers from integer

I actually think that dealing with a string of numbers is preferable, not only from a code readability point of view, but also possibly from a performance view. That being said, if we absolutely cannot use strings here, then it is still possible to work directly with the integer input.

We can examine each tens digit of the input number using num % 10. Should that digit be even, we can add it to the output number, otherwise do not add it. Note that at each iteration we need to scale the digit by 10 to the correct exponent.

Here is a working code snippet:

int length = (int) (Math.log10(num) + 1);    // finds the number of digits

int output = 0;
int counter = 0;
for (int i=0; i < length; ++i) {
if ((num % 10) % 2 == 0) {
output += (num % 10) * Math.pow(10, counter);
++counter;
}
num = num / 10;
}

System.out.println(output);

2826

Demo

How to delete specific digit from integer?

This does not require arrays nor loops:

int n = 1237534;

String newNum = String.valueOf(n);
char c = '3';
StringBuilder sb1 = new StringBuilder( newNum );
StringBuilder sb2 = new StringBuilder( newNum );

int newGuess1 = Integer.parseInt(sb1.deleteCharAt(newNum.indexOf(c)).toString());
int newGuess2 = Integer.parseInt(sb2.deleteCharAt(newNum.indexOf(c, newNum.indexOf(c)+1)).toString());

System.out.println( newGuess1 > newGuess2 ? newGuess1: newGuess2 );

Remove a digit from a number(integer) in python

UPDATE: It seems to be counterintuitive, but string-based solution is much faster then int-based. Here're my code and results in seconds for 103-, 226-digit and 472-digit numbers. I decided not to test 102139-digit number on my laptop :)

import timeit, math

digits = [100, 200, 500, 1_000, 2_000, 5_000, 10_000, 50_000, 100_000]

def print_str(n):
s = str(n)
for i in range(len(s)):
#print(i)
n2 = int(s[:i] + s[i+1:])


def print_int(a):
p = 1
while p <= a:
n2 = a//p//10*p + a%p
p *= 10

if __name__ == '__main__':
number = 1
for i in digits:
n = 17**math.ceil(math.log(10**i, 17))
str_ = timeit.timeit('print_str(n)', setup='from __main__ import print_str, n', number=number)
int_ = timeit.timeit('print_int(n)', setup='from __main__ import print_int, n', number=number)
print("{:8d}\t{:15.6f}\t{:15.6f}".format(len(str(n)), str_/number*1000, int_/number*1000))

Results (in milliseconds for particular number length):

$ time python3 main.py
101 0.169280 0.185082
201 0.502591 0.537000
501 3.917680 3.195815
1001 13.768999 22.781801
2001 114.404890 120.546628
5001 1066.541904 1625.172070
10002 8033.144731 8802.031382
50001 937385.167088 1045865.986814
100002 7800950.456252 8189620.010314

First column - number of digits, second one - time in milliseconds for the str-based solution, and third - for the int-based.

But how is it possible?

It could be understood if we remember how endless integer numbers are constructed in Python. Under the hood there's an array of 15- or 30-bit integers which being joined produces the result number. So when you divide this number you have to walk through the whole array and modify every every digit. Also take in account complexity - sometimes you have to add or subtract from more significant digit, that complicates process.

When you use strings, you only copy bytes from one place to another. It's extremely fast procedure made with internal cpu instruction.

But what if we do not need conversion to int? For example, we want to print a number, so having it in a string form is better? How will it enfaster process?

Here're results - also in ms for different length

 $ time python3 main.py
101 0.051510 0.124668
201 0.091741 0.442547
501 0.357862 2.562110
1001 0.787016 15.229156
2001 2.545076 111.917518
5001 4.993472 1334.944235

UPD: Bencharks of updated versions:

$ time python3 main2.py

digits str1 str2 int1 int2
101 0.047 0.101 0.110 0.073
201 0.091 0.315 0.380 0.145
501 0.338 2.049 2.540 0.778
1001 1.342 16.878 16.032 1.621
2001 1.626 85.277 97.809 5.553
5001 4.903 1039.889 1326.481 32.490
10002 15.987 7856.753 9512.209 129.280
20001 72.205 60363.860 68219.334 487.088

real 2m29.403s
user 2m27.902s
sys 0m0.577s

Remove nth digit from an integer without converting to string

% and / are your friends here! Using modulus and division we can get pieces of the number that we want.

We use modulus to eliminate the most significant digits, and division to eliminate the least significant digits. We can use division because the remainder gets truncated.

Then we put the two pieces we got from these two operations together. However, we need to shift the digits we got from the division to have room for the least significant digits.

Take 987654321 / 10000, this will give you 98765 (let's call this x)

Take 987654321 % 100, this will give you 21 (let's call this y)

x * 100 + y = 9876521.

More generally, if you want to remove a to bth digits from the number n (where a < b),

n % 10^(a-1) + ((n / 10^(b)) * 10^(a-1))

Remove digits from number without reversing the number

A different approach could be to track the position of the digit you want to add to the result (by multiplying it by 10position). This way, you won't have to reverse the number when you're done:

long removeDigit(long number, int digit) {
long result = 0L;
long multiplier = 1L;
while (number > 0L) {
int currDigit = (int) number % 10;
if (currDigit != digit) {
result += multiplier * currDigit;
multiplier *= 10;
}
number /= 10;
}
return result;
}


Related Topics



Leave a reply



Submit