Getting a specific number from a bigger number? - lua

a = (any random number)
Is there a way could I get the third number (12345) without converting it into a string?
If not, what would be a good way to get it by converting it into a string?

You can use the sub function
function getDigit(value,digitPlace)
return tonumber(tostring(value):sub(digitPlace,digitPlace))
end
This will get the third digit of a as a number:
a = 12345
print(getDigit(a,3))

You can get that using simple maths.
function getDigitInt(value, digit)
-- get rid of the sign
value = math.abs(value)
-- how many digits does the number have?
local numDigits = math.floor(math.log(value, 10)) + 1
-- does the requested digit exist?
if digit > numDigits or digit < 1 then
print("digit does not exist")
return
end
-- return the requested digit
return math.floor(value / 10^(numDigits - digit)) % 10
end
-- test
for i = 0, 8 do print(getDigitInt(1234567, i)) end
Add more error handling as needed. Also this can only handle integers of course. But I'm sure you will find out how to apply this idea to decimals as well.

You can convert the number into array and find the any place easily like blow
public int GetDigitsPlace(int number, int digitPlace) {
string t = number.ToString();
int[] nArr = new int[t.Length];
for(int i = 0; i < nArr.Length; i++) {
nArr[i] = int.Parse(t[i]);
}
return nArr[digitPlace];
}

Related

How to calculate this String text ="2+3-5+1" using Split method? [duplicate]

This question already has answers here:
Calculate string value in javascript, not using eval
(12 answers)
Closed 4 months ago.
When the text was '2+3+5+1', the logic was easy
Split('+') so the string is converted to an array.
loop over the array and calculate the sum.
check the code below
void main() {
const text = '2+3+5+1';
final array = text.split('+');
int res =0;
for (var i=0; i<= array.length -1; i++){
res+=int.parse(array[i]);;
}
print(array);
print(res);
}
Now this String "2+3-5+1" contains minus.
how to get the right response using split method?
I am using dart.
note: I don't want to use any library (math expression) to solve this exercice.
Use the .replace() method.
text = text.replace("-", "+-");
When you run through the loop, it will calculate (-).
You can split your string using regex text.split(/\+|\-/).
This of course will fail if any space is added to the string (not to mention *, / or even decimal values).
const text = '20+3-5+10';
const arr = text.split(/\+|\-/)
let tot = 0
for (const num of arr) {
const pos = text.indexOf(num)
if (pos === 0) {
tot = parseInt(num)
} else {
switch (text.substr(text.indexOf(num) - 1, 1)) {
case '+':
tot += parseInt(num)
break
case '-':
tot -= parseInt(num)
break
}
}
}
console.log(tot)
I see 2 maybe 3 options, definitely there are hundreds
You don't use split and you just iterate through the string and just add or subtract on the way. As an example
You have '2+3-5+1'. You iterate until the second operator (+ or -) on your case. When you find it you just do the operation that you have iterated through and then you just keep going. You can do it recursive or not, doesn't matter
"2+3-5+1" -> "5-5+1" -> "0+1" -> 1
You use split on + for instance and you get [ '2', '3-5', '1' ] then you go through them with a loop with 2 conditions like
if(isNaN(x)) res+= x since you know it's been divided with a +
if(!isNaN(x)) res+= x.split('-')[0] - x.split('-')[1]
isNaN -> is not a number
Ofc you can make it look nicer. If you have parenthesis though, none of this will work
You can also use regex like split(/[-+]/) or more complex, but you'll have to find a way to know what operation follows each digit. One easy approach would be to iterate through both arrays. One of numbers and one of operators
"2+3-5+1".split(/[-+]/) -> [ '2', '3', '5', '1' ]
"2+3-5+1".split(/[0-9]*/).filter(x => x) -> [ '+', '-', '+' ]
You could probably find better regex, but you get the idea
You can ofc use a map or a switch for multiple operators

How can I get the expected output in Dart?

I am trying to get the output as below:
The problem is from URI-1098 Sequence IJ 4.
My Code is:
void main() {
double x = 0;
double y = 1;
for(double i = x; i<=2; i+= .2){
for(double j=y; j <= y + 2; j++){
if(i==0 || i==1 || i==2){
print('I=${i.toStringAsFixed(0)} J=${j.toStringAsFixed(0)}');
}else{
print('I=${i.toStringAsFixed(1)} J=${j.toStringAsFixed(1)}');
}
}
y += 0.2;
}
}
And my output is:
I=0 J=1
I=0 J=2
I=0 J=3
I=0.2 J=1.2
I=0.2 J=2.2
I=0.2 J=3.2
I=0.4 J=1.4
I=0.4 J=2.4
I=0.4 J=3.4
I=0.6 J=1.6
I=0.6 J=2.6
I=0.6 J=3.6
I=0.8 J=1.8
I=0.8 J=2.8
I=0.8 J=3.8
I=1 J=2
I=1 J=3
I=1 J=4
I=1.2 J=2.2
I=1.2 J=3.2
I=1.2 J=4.2
I=1.4 J=2.4
I=1.4 J=3.4
I=1.4 J=4.4
I=1.6 J=2.6
I=1.6 J=3.6
I=1.6 J=4.6
I=1.8 J=2.8
I=1.8 J=3.8
I=1.8 J=4.8
I=2.0 J=3.0
I=2.0 J=4.0
I=2.0 J=5.0
I am not getting desired outputs for the last 3 lines of the output. Can anyone kindly show the the error in my logic.
Thanking you all in advance.
You're using doubles.
That's the issue here. You are adding 0.2 repeatedly to a value starting at 0, but 0.2 is not precisely representable as a double. The 0.2 literal really represents the double value 0.200000000000000011102230246251565404236316680908203125 which is close to 0.2, but not exactly there.
The values you get by adding 0.2 to itself ten times loses some precision along the way. It hits 1.0 precisely, but then the next addition needs to drop some bits so the next value is actually below 1.2. The final result is 1.9999999999999997779553950749686919152736663818359375 which is not == 2.0, so your check for == 2.0 doesn't trigger. When you ask for the value with one decimal, it does round to "2.0", so you can't tell unless you print the actual value.
There are multiple ways to get around the problem.
One is to not use doubles. If you keep the numbers as integers by multiplying them by ten, then you just need a way to create the string to print. That could be
String toPrint(int value) {
var string = value.toString();
var lead = string.substring(0, string.length - 1);
if (string.endsWith('0')) return lead;
return "$lead.${string.substring(string.length - 1)}";
}
Alternatively, you can keep using doubles, but do .toStringAsFixed(1) and then check whether the last digit is zero. If it is, cut off the last two characters before printing.

Dart: How to iterate digits of integer?

How to iterate digits of integer? for example sum of digits here, it works, but is any way to right way?
int sumOfDigits(int num) {
int sum = 0;
String numtostr = num.toString();
for (var i = 0; i < numtostr.length; i++) {
sum = sum + int.parse(numtostr[i]);
}
return sum;
}
If you're looking for a shorter way to do this, you can combine split, map and reduce
int sum = num.split('').map((e) => int.parse(e)).reduce((t, e) => t + e);
You can even do this:
int sum = num.split('').map(int.parse).reduce((t, e) => t + e);
Thank you #julemand101
It's fairly inefficient to create a string, then split the string, and parse the individual digits back to integers.
How about something like:
Iterable<int> digitsOf(int number) sync* {
do {
yield = number.remainder(10);
number ~/= 10;
} while (number != 0);
}
This iterates the digits of the (non-negative) number in base 10, from least significant to most significant, without allocating any strings along the way.
If you want the digits in the reverse order, you can either create a list from the iterable above and reverse it, or use a different approach:
Iterable<int> digitsHighToLow(int number) sync* {
var base = 1;
while (base * 10 < number) {
base = base * 10;
}
do {
var digit = number ~/ base;
yield digit;
number = (number - digit * base) * 10;
} while (number != 0);
}
(again, only works on non-negative numbers, you'll have to figure out what you want for negative numbers, either throw, or try negating the number, it's the same digits after all, or something else).

Convert a number to Human readable format (e.g. 1.5k, 5m, 1b) in Dart?

i'm developing an app related to social messanging and i want to convert big numbers to Human readable format (e.g. 1500 to 1.5k) and also i'm new to Dart.
Your help will be appreciated.
You can use the NumberFormat class of flutter which has some in built functions for results you want..
Check out this link for NumberFormat class of flutter
Example:
This is one way if you want to use currency..
var _formattedNumber = NumberFormat.compactCurrency(
decimalDigits: 2,
symbol: '', // if you want to add currency symbol then pass that in this else leave it empty.
).format(numberToFormat);
print('Formatted Number is: $_formattedNumber');
Example:
This example is with locale.
var _formattedNumber = NumberFormat.compactCurrency(
decimalDigits: 2,
locale: 'en_IN'
symbol: '',
).format(numberToFormat);
print('Formatted Number is: $_formattedNumber');
The output of this is code would be:
If 1000 is entered then 1K is the output
Another way is by just using NumberFormat.compact() which gives the desired output...
// In this you won't have to worry about the symbol of the currency.
var _formattedNumber = NumberFormat.compact().format(numberToFormat);
print('Formatted Number is: $_formattedNumber');
The output of above example will also be:
If 1000 is entered then 1K is the output
I tried this and is working...
Make a class and used its static method every where.
class NumberFormatter{
static String formatter(String currentBalance) {
try{
// suffix = {' ', 'k', 'M', 'B', 'T', 'P', 'E'};
double value = double.parse(currentBalance);
if(value < 1000000){ // less than a million
return value.toStringAsFixed(2);
}else if(value >= 1000000 && value < (1000000*10*100)){ // less than 100 million
double result = value/1000000;
return result.toStringAsFixed(2)+"M";
}else if(value >= (1000000*10*100) && value < (1000000*10*100*100)){ // less than 100 billion
double result = value/(1000000*10*100);
return result.toStringAsFixed(2)+"B";
}else if(value >= (1000000*10*100*100) && value < (1000000*10*100*100*100)){ // less than 100 trillion
double result = value/(1000000*10*100*100);
return result.toStringAsFixed(2)+"T";
}
}catch(e){
print(e);
}
}
}

What standard produced hex-encoded characters with an extra "25" at the front?

I'm trying to integrate with ybp.com, a vendor of proprietary software for managing book ordering workflows in large libraries. It keeps feeding me URLs that contain characters encoded with an extra "25" in them. Like this book title:
VOLATILE KNOWING%253a PARENTS%252c TEACHERS%252c AND THE CENSORED STORY OF ACCOUNTABILITY IN AMERICA%2527S PUBLIC SCHOOLS.
The encoded characters in this sample are as follows:
%253a = %3A = a colon
%252c = %2C = a comma
%2527 = %27 = an apostrophe (non-curly)
I need to convert these encodings to a format my internal apps can recognize, and the extra 25 is throwing things off kilter. The final two digits of the hex encoded characters appear to be identical to standard URL encodings, so a brute force method would be to replace "%25" with "%". But I'm leary of doing that because it would be sure to haunt me later when an actual %25 shows up for some reason.
So, what standard is this? Is there an official algorithm for converting values like this to other encodings?
%25 is actually a % character. My guess is that the external website is URLEncoding their output twice accidentally.
If that's the case, it is safe to replace %25 with % (or just URLDecode twice)
The ASCII code 37 (25 in hexadecimal) is %, so the URL encoding of % is %25.
It looks like your data got URL encoded twice: , -> %2C -> %252C
Substituting every %25 for % should not generate any problems, as an actual %25 would get encoded to %25252525.
Create a counter that increments one by one for next two characters, and if you found modulus, you go back, assign the previous counter the '%' char and proceed again. Something like this.
char *str, *newstr; // Fill up with some memory before proceeding below..
....
int k = 0, j = 0;
short modulus = 0;
char first = 0, second = 0;
short proceed = 0;
for(k=0,j=0; k<some_size; j++,k++) {
if(str[k] == '%') {
++k; first = str[k];
++k; second = str[k];
proceed = 1;
} else if(modulus == 1) {
modulus = 0;
--j; first = str[k];
++k; second = str[k];
newstr[j] = '%';
proceed = 1;
} else proceed = 0; // Do not do decoding..
if(proceed == 1) {
if(first == '2' && second == '5') {
newstr[j] = '%';
modulus = 1;
......

Resources