Skip to main content
Commonmark migration
Source Link

#JavaScript (ES6),  100 99 98  78 bytes

JavaScript (ES6),  100 99 98  78 bytes

Takes input as a string. Returns a float.

s=>+(0+s).replace(/\d/g,(d,i)=>j&&+d+((n=s[i+!++s[i]])<2&&i?--j:n>7&&j--),j=1) 

Try it online!

###How?

How?

We first prepend a leading \$0\$ to the input string, so that we're guaranteed to have a digit before a possible leading \$8\$ or \$9\$, that must trigger the rounding right away.

The flag \$j\$ is set to \$1\$ as long as we are looking for a digit on which we can do a satisfying rounding, and set to \$0\$ afterwards.

Because a leading \$0\$ was added to the string that we're walking through but \$s\$ was left unchanged, \$d\$ contains the current character and \$s[i]\$ is pointing to the next character.

We use the following code to load the next digit in \$n\$, skipping a possible decimal separator:

n = s[i + !++s[i]] 

Although strings are immutable in JavaScript, the expression ++s[i] will return \$s[i]+1\$ if it contains a numeric value, even though \$s[i]\$ is not actually incremented. Therefore, the expression !++s[i] is evaluated to \$false\$ (coerced to \$0\$) for all digits (including \$0\$) and to \$true\$ (coerced to \$1\$) for the decimal separator ".".

When the rounding occurs, we yield d + --j if the next digit \$n\$ is \$0\$ or \$1\$ (and it's not the leading digit of the original input) and d + j-- if \$n\$ is \$8\$ or \$9\$. Therefore, \$j\$ is set to \$0\$ in both cases but we add \$0\$ to \$d\$ in the first case (rounding down) and \$1\$ in the second case (rounding up).

#JavaScript (ES6),  100 99 98  78 bytes

Takes input as a string. Returns a float.

s=>+(0+s).replace(/\d/g,(d,i)=>j&&+d+((n=s[i+!++s[i]])<2&&i?--j:n>7&&j--),j=1) 

Try it online!

###How?

We first prepend a leading \$0\$ to the input string, so that we're guaranteed to have a digit before a possible leading \$8\$ or \$9\$, that must trigger the rounding right away.

The flag \$j\$ is set to \$1\$ as long as we are looking for a digit on which we can do a satisfying rounding, and set to \$0\$ afterwards.

Because a leading \$0\$ was added to the string that we're walking through but \$s\$ was left unchanged, \$d\$ contains the current character and \$s[i]\$ is pointing to the next character.

We use the following code to load the next digit in \$n\$, skipping a possible decimal separator:

n = s[i + !++s[i]] 

Although strings are immutable in JavaScript, the expression ++s[i] will return \$s[i]+1\$ if it contains a numeric value, even though \$s[i]\$ is not actually incremented. Therefore, the expression !++s[i] is evaluated to \$false\$ (coerced to \$0\$) for all digits (including \$0\$) and to \$true\$ (coerced to \$1\$) for the decimal separator ".".

When the rounding occurs, we yield d + --j if the next digit \$n\$ is \$0\$ or \$1\$ (and it's not the leading digit of the original input) and d + j-- if \$n\$ is \$8\$ or \$9\$. Therefore, \$j\$ is set to \$0\$ in both cases but we add \$0\$ to \$d\$ in the first case (rounding down) and \$1\$ in the second case (rounding up).

JavaScript (ES6),  100 99 98  78 bytes

Takes input as a string. Returns a float.

s=>+(0+s).replace(/\d/g,(d,i)=>j&&+d+((n=s[i+!++s[i]])<2&&i?--j:n>7&&j--),j=1) 

Try it online!

How?

We first prepend a leading \$0\$ to the input string, so that we're guaranteed to have a digit before a possible leading \$8\$ or \$9\$, that must trigger the rounding right away.

The flag \$j\$ is set to \$1\$ as long as we are looking for a digit on which we can do a satisfying rounding, and set to \$0\$ afterwards.

Because a leading \$0\$ was added to the string that we're walking through but \$s\$ was left unchanged, \$d\$ contains the current character and \$s[i]\$ is pointing to the next character.

We use the following code to load the next digit in \$n\$, skipping a possible decimal separator:

n = s[i + !++s[i]] 

Although strings are immutable in JavaScript, the expression ++s[i] will return \$s[i]+1\$ if it contains a numeric value, even though \$s[i]\$ is not actually incremented. Therefore, the expression !++s[i] is evaluated to \$false\$ (coerced to \$0\$) for all digits (including \$0\$) and to \$true\$ (coerced to \$1\$) for the decimal separator ".".

When the rounding occurs, we yield d + --j if the next digit \$n\$ is \$0\$ or \$1\$ (and it's not the leading digit of the original input) and d + j-- if \$n\$ is \$8\$ or \$9\$. Therefore, \$j\$ is set to \$0\$ in both cases but we add \$0\$ to \$d\$ in the first case (rounding down) and \$1\$ in the second case (rounding up).

added an explanation
Source Link
Arnauld
  • 205.5k
  • 21
  • 187
  • 670

#JavaScript (ES6),  100 99 98  78 bytes

Takes input as a string. Returns a float.

s=>+(0+s).replace(/\d/g,(d,i)=>j&&+d+((n=s[i+!++s[i]])<2&&i?--j:n>7&&j--),j=1) 

Try it online!

###How?

We first prepend a leading \$0\$ to the input string, so that we're guaranteed to have a digit before a possible leading \$8\$ or \$9\$, that must trigger the rounding right away.

The flag \$j\$ is set to \$1\$ as long as we are looking for a digit on which we can do a satisfying rounding, and set to \$0\$ afterwards.

Because a leading \$0\$ was added to the string that we're walking through but \$s\$ was left unchanged, \$d\$ contains the current character and \$s[i]\$ is pointing to the next character.

We use the following code to load the next digit in \$n\$, skipping a possible decimal separator:

n = s[i + !++s[i]] 

Although strings are immutable in JavaScript, the expression ++s[i] will return \$s[i]+1\$ if it contains a numeric value, even though \$s[i]\$ is not actually incremented. Therefore, the expression !++s[i] is evaluated to \$false\$ (coerced to \$0\$) for all digits (including \$0\$) and to \$true\$ (coerced to \$1\$) for the decimal separator ".".

When the rounding occurs, we yield d + --j if the next digit \$n\$ is \$0\$ or \$1\$ (and it's not the leading digit of the original input) and d + j-- if \$n\$ is \$8\$ or \$9\$. Therefore, \$j\$ is set to \$0\$ in both cases but we add \$0\$ to \$d\$ in the first case (rounding down) and \$1\$ in the second case (rounding up).

#JavaScript (ES6),  100 99 98  78 bytes

Takes input as a string. Returns a float.

s=>+(0+s).replace(/\d/g,(d,i)=>j&&+d+((n=s[i+!++s[i]])<2&&i?--j:n>7&&j--),j=1) 

Try it online!

#JavaScript (ES6),  100 99 98  78 bytes

Takes input as a string. Returns a float.

s=>+(0+s).replace(/\d/g,(d,i)=>j&&+d+((n=s[i+!++s[i]])<2&&i?--j:n>7&&j--),j=1) 

Try it online!

###How?

We first prepend a leading \$0\$ to the input string, so that we're guaranteed to have a digit before a possible leading \$8\$ or \$9\$, that must trigger the rounding right away.

The flag \$j\$ is set to \$1\$ as long as we are looking for a digit on which we can do a satisfying rounding, and set to \$0\$ afterwards.

Because a leading \$0\$ was added to the string that we're walking through but \$s\$ was left unchanged, \$d\$ contains the current character and \$s[i]\$ is pointing to the next character.

We use the following code to load the next digit in \$n\$, skipping a possible decimal separator:

n = s[i + !++s[i]] 

Although strings are immutable in JavaScript, the expression ++s[i] will return \$s[i]+1\$ if it contains a numeric value, even though \$s[i]\$ is not actually incremented. Therefore, the expression !++s[i] is evaluated to \$false\$ (coerced to \$0\$) for all digits (including \$0\$) and to \$true\$ (coerced to \$1\$) for the decimal separator ".".

When the rounding occurs, we yield d + --j if the next digit \$n\$ is \$0\$ or \$1\$ (and it's not the leading digit of the original input) and d + j-- if \$n\$ is \$8\$ or \$9\$. Therefore, \$j\$ is set to \$0\$ in both cases but we add \$0\$ to \$d\$ in the first case (rounding down) and \$1\$ in the second case (rounding up).

saved 20 bytes
Source Link
Arnauld
  • 205.5k
  • 21
  • 187
  • 670

#JavaScript (ES6),  100 99 98  9878 bytes

Takes input as a string. Returns a float.

s=>+(s>'2'?0+s:s).replace(/.(\.?)([0189])(.*)\d/g,(a,b,c,d,i)=>[+a[0]+=>j&&+d+(c>1)]+(b||0n=s[i+!++s[i]])+d.replace(/\d/g,0<2&&i?--j:n>7&&j--),j=1) 

Try it online!Try it online!

#JavaScript (ES6),  100 99  98 bytes

Takes input as a string. Returns a float.

s=>+(s>'2'?0+s:s).replace(/.(\.?)([0189])(.*)/,(a,b,c,d)=>[+a[0]+(c>1)]+(b||0)+d.replace(/\d/g,0)) 

Try it online!

#JavaScript (ES6),  100 99 98  78 bytes

Takes input as a string. Returns a float.

s=>+(0+s).replace(/\d/g,(d,i)=>j&&+d+((n=s[i+!++s[i]])<2&&i?--j:n>7&&j--),j=1) 

Try it online!

saved 1 byte
Source Link
Arnauld
  • 205.5k
  • 21
  • 187
  • 670
Loading
saved 1 byte
Source Link
Arnauld
  • 205.5k
  • 21
  • 187
  • 670
Loading
added 2 characters in body
Source Link
Arnauld
  • 205.5k
  • 21
  • 187
  • 670
Loading
Source Link
Arnauld
  • 205.5k
  • 21
  • 187
  • 670
Loading