Redondeo satisfactorio
Sabes cuando estás en la clase de ciencias y te piden redondear a 2 higos, pero tu respuesta es 5.2501...
? Deberías redondear a 5.3
, ¡pero eso es tan insatisfactorio! Al redondear a 5.3
, se obtiene un total de 0.05, que es una gran cantidad en comparación con 0.1 (el valor posicional al que está redondeando). Así que ayúdame a redondear de una manera satisfactoria.
Para redondear de manera satisfactoria, debe redondear en el primer dígito que encuentre que produce un error relativamente pequeño, menos de la mitad del error máximo posible al redondear. Básicamente, debe redondear cada vez que encuentre 0, 1, 8 o 9. Si eso nunca sucede, devuelva la entrada como está. No redondee los ceros a la izquierda o unos, eso simplemente no se siente satisfactorio.
Entrada
Una cadena o valor flotante que representa un número decimal no negativo.
Salida
El mismo número decimal redondeado satisfactoriamente, en formato de cadena o flotante.
Ejemplos
Input -> Output
0 -> 0
0.5 -> 0.5
0.19 -> 0
0.8 -> 1
5.64511 -> 5.645
18.913 -> 20
88.913 -> 100
36.38299 -> 36.4
621 -> 620
803.22 -> 1000
547.4726 -> 547.4726
Este es un desafío de código de golf , por lo que gana el código más corto.
fuente
036.40000
consideran cadenas como una salida válida?.0
dará una parte para enteros? Además,0
no es positivo.19
redondea20
pero0.19
redondea0
? ¿Por qué?Respuestas:
JavaScript (ES6),
100 99 9878 bytesToma la entrada como una cadena. Devuelve un flotador.
Pruébalo en línea!
¿Cómo?
Primero anteponemos un0 0 inicial a la cadena de entrada, para garantizar que tengamos un dígito antes de un posible 8 o 9 9 , que debe activar el redondeo de inmediato.
La banderaj se establece en 1 siempre que estemos buscando un dígito en el que podamos realizar un redondeo satisfactorio, y luego se establece en 0 0 .
Debido a que se agregó un0 0 inicial a la cadena por la que estamos caminando pero s se modificó, re contiene el carácter actual y s [ i ] apunta al siguiente carácter.
Usamos el siguiente código para cargar el siguiente dígito ennorte , omitiendo un posible separador decimal:
Aunque las cadenas son inmutables en JavaScript, la expresións [ i ] + 1 si contiene un valor numérico, aunque s [ i ] no se incremente realmente. Por lo tanto, la expresión Fa l s e (forzada a 0 0 ) para todos los dígitos (incluido 0 0 ) y a t r u e (forzada a 1 ) para el separador decimal
++s[i]
devolverá!++s[i]
se evalúa como"."
.Cuando se produce el redondeo, producimosnorte es 0 0 o 1 (y no es el dígito inicial de la entrada original) y norte es 8 o 9 9 . Por lo tanto, j se establece en 0 0 en ambos casos, pero agregamos 0 0 a re en el primer caso (redondeando hacia abajo) y 1 en el segundo caso (redondeando hacia arriba).
d + --j
si el siguiente dígitod + j--
sifuente
Rubí ,
7977696765 bytesPruébalo en línea!
Explicación
->n
Tomar entrada como una cadenaz=n+".0"
Cree una cadena temporalz
que garantice que contiene un punto y un dígito relevante.i=z=~/\./
Determine la posición del punto decimalz
y asigne ai
.z[i]=''
Suelta el punto para que no se interponga más adelante.z=~/(?!^)[01]|8|9/
Determine la posición de no arranque0-1
o cualquiera8-9
, lo que ocurra primero.(...)-i
Esta diferencia será el número de decimales para mantener, negativo si redondearemos a la izquierda del punto.n.to_f.round ...
Convierte a flotador y haz el redondeo.fuente
Jalea , 34 bytes
Pruébalo en línea!
-1 gracias a Jonathan Allan .
fuente
ŒV
? Creo queV
también funcionará._>¥0ɓVær
como el mío (perdí el uso de la diádica rápida, ¡así que gracias también!)Gelatina ,
3029 bytes-1 gracias a Erik the Outgolfer (uso de dyadic quick
¥
de su respuesta)Un enlace monádico que acepta una lista de caracteres que produce un flotante.
Pruébalo en línea! O ver el conjunto de pruebas .
Cómo
Primero tenga en cuenta que la cadena de entrada está hecha exclusivamente de los caracteres
0123456789.
que tienen ordinales[48,49,50,51,52,53,54,55,56,57,46]
, que tienen restos cuando se divide por ocho de[0,1,2,3,4,5,6,7,0,1,6]
. Los únicos personajes que están entre-1
e1
inclusivo son0
,1
,8
, y9
.Además, si restamos ocho de los ordinales (
[40,41,42,43,44,45,46,47,48,49,38]
), lo mismo (bastante obvio) es válido. Si dividimos a la mitad estos ([20,20.5,21,21.5,22,22.5,23,23.5,24,24.5,19]
), los únicos caracteres que tienen restos cuando se dividen entre ocho, que están entre-1
e1
inclusive, son8
y9
.fuente
Retina 0.8.2 , 75 bytes
Pruébalo en línea! El enlace incluye casos de prueba. Explicación:
Manejar el caso de un líder
8
o9
.Si hay un no líder
0
o1
, entonces ponlo a cero y el resto de la cadena. Además, si hay un8
o9
, déjelo, pero ponga a cero el resto de la cadena. (Pero deje el punto decimal sin cambios en cualquier caso).Si todavía hay un
8
o a9
en este punto, ponlo a cero e incrementa el dígito anterior (posiblemente antes del punto decimal).Elimine los ceros finales si van después de un punto decimal, pero solo elimine el punto decimal si no hay otros dígitos intermedios.
fuente
C (gcc) ,
111102 bytesPruébalo en línea!
fuente
C # (compilador interactivo de Visual C #) , 280 bytes
Pruébalo en línea!
Puede ser más corto si usé dobles en lugar de decimales, pero usé decimales para preservar la precisión, o de lo contrario un número como 547.4726 sería 547.472595214844.
C # (compilador interactivo de Visual C #) , 268 bytes
Pruébelo en línea (versión menos precisa)
fuente