DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #163 - Significant Figures

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!

Top comments (14)

Collapse
 
idanarye profile image
Idan Arye

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?

Collapse
 
schwepmo profile image
schwepmo

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

Collapse
 
savagepixie profile image
SavagePixie

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.

Thread Thread
 
schwepmo profile image
schwepmo

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

Collapse
 
savagepixie profile image
SavagePixie

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

Collapse
 
schwepmo profile image
schwepmo

Well actually, no. See my response :D

Thread Thread
 
idanarye profile image
Idan Arye

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.

Thread Thread
 
schwepmo profile image
schwepmo

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.

Collapse
 
rburmorrison profile image
Ryan Burmeister-Morrison

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
Collapse
 
candidateplanet profile image
lusen / they / them 🏳️‍🌈🥑

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)
Collapse
 
savagepixie profile image
SavagePixie • Edited

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
Collapse
 
amcmillan01 profile image
Andrei McMillan

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
Collapse
 
rburmorrison profile image
Ryan Burmeister-Morrison

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