loading...

Daily Challenge #163 - Significant Figures

thepracticaldev profile image dev.to staff ・1 min read

Setup

Write a function that takes a number and returns the number of significant figures in a given number.

Significant Figures are the meaningful digits in a measured or computed value.
All non-zero digits are significant
4.357 has 4 significant figures
152.63 has 5 significant figures

Zeroes at the beginning of a number are not significant
0215 has 3 significant figures
0.6 has 1 significant figure

Trailing zeroes in a number with a decimal point are significant
78.200 has 5 significant figures
20.0 has 3 significant figures

Trailing zeroes in a number without a decimal point are not significant
1200 has 2 significant figures
345000 has 3 significant figures

All zeroes between significant figures are significant
90.09 has 4 significant figures
5050 has 3 significant figures

Constraints:
The type of the given number will be string.
You must return the number of significant figures as type int.
No blank strings will be given.

Tests

1
003
3000
404
050030210
0.1
0.0

Good luck and have fun!


This challenge comes from ljgecko1230 on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Posted on by:

thepracticaldev profile

dev.to staff

@thepracticaldev

The hardworking team behind dev.to ❤️

Discussion

pic
Editor guide
 

Trailing zeroes in a number with a decimal point are significant
78.200 has 5 significant figures
20.0 has 3 significant figures

Trailing zeroes in a number without a decimal point are not significant
1200 has 2 significant figures
345000 has 3 significant figures

Shouldn't it be the other way around?

 

I just checked on Wikipedia and it is right the way that it is stated in the task. This is because if you add zeros after the decimal point, you imply that your number was "measured" with a higher precision.

Example: a normal ruler vs. a precision measuring devices

If you use the normal ruler you can only be certain your measured distance is 1.5cm

With a precision ruler you can be certain, that your measured distance is something like 1.500cm

 

Oh, so it's a measurement thing.

Interestingly enough, technically, according to Wikipedia we have no way of knowing whether any zero to the right of the last non-zero digit is significant or not, regardless of the presence of decimals. So the exercise is still not quite right.

I feel like the exercise is fine. It defines a definite rule for deciding on which trailing zeros are significant and which aren't.

 

Yes, but I suppose it's changed to avoid the obvious string -> number -> string conversion that would take care of non-significant zeros.

 

Well actually, no. See my response :D

Still doesn't explain why "Trailing zeroes in a number without a decimal point" are not significant, considering how each such zero increases the number by an order of magnitude and how appending .0 suddenly makes these zeroes significant.

Check the Wikipedia article it explains that aswell. Short answer is, that trailing zeros are somewhat ambiguous and that you have to specify it by some rule, which is done by the task description.

 

Nim submission.

import strutils

proc significantFigures(n: float): int = formatFloat(n)
  .replace(".")
  .strip(chars={'0'})
  .len()

when isMainModule:
  assert significantFigures(1) == 1
  assert significantFigures(003) == 1
  assert significantFigures(3000) == 1
  assert significantFigures(404) == 3
  assert significantFigures(050030210) == 7
  assert significantFigures(0.1) == 1
  assert significantFigures(0.0) == 0
 

Trailing zeroes in a number with a decimal point are significant
78.200 has 5 significant figures
20.0 has 3 significant figures

According to that 0.0 should be 1.

 

Good point! I didn’t account for trailing 0’s. I’ll update it later.

 

in python

note: added the 11 and 1.1 test cases because the subtracting-from-both-ends solution can have edge cases around there

def sigfig(num):
  # ignore 0's on the far left
  ldx = 0
  while num[ldx] == '0' and ldx < len(num):
    ldx += 1

  # ignore 0's on the far right if no decimal place
  rdx = len(num) - 1
  if num.find('.') > 0:
    return (rdx - ldx) # the +1 from below is cancelled out by needing to subtract the '.'
  else:
    while num[rdx] == '0' and rdx > -1:
      rdx -= 1
    return (rdx - ldx) + 1

print(sigfig('11'), 2)
print(sigfig('1.1'), 2)
print(sigfig('1'), 1)
print(sigfig('003'), 1)
print(sigfig('3000'), 1)
print(sigfig('404'), 3)
print(sigfig('050030210'), 7)
print(sigfig('0.1'), 1)
print(sigfig('0.0'), 1)
 

js solution :)

function get_significant_num(str) {
  var total_significant_nums = 0;

  if (typeof str === 'string') {

    str = str.trim().replace(/^(0)+/, '');

    if (/\./.test(str)) {
      total_significant_nums = str.match(/\d+/g).join('').length;
    } else {
      str = str.replace(/0+$/, '');
      total_significant_nums = str.length;
    }

  }

  return total_significant_nums;
}


console.log(get_significant_num('20.0'));//3
console.log(get_significant_num('78.200'));//5
console.log(get_significant_num('0.6'));//1
console.log(get_significant_num('0215'));//3
console.log(get_significant_num('4.357'));//4
console.log(get_significant_num('345000'));//3
console.log(get_significant_num('050030210'));//7
 

I think this should do the trick, I'll test it later.

JavaScript

const significant = str => str.includes('.')
   ? str.replace(/^0+/, '').length - 1
   : str.replace(/^0+|0+$/g, '').length