Dada una expresión, su tarea es evaluarla. Sin embargo, su respuesta no puede mostrar más dígitos de los necesarios, ya que esto da la impresión de tener mediciones más precisas que la realidad.
El número de cifras significativas que tiene un número es cuántos dígitos tiene cuando se escribe en notación científica, incluidos los ceros al final si está presente un punto decimal. Por ejemplo, 1200
tiene 2 cifras significativas porque es 1.2*10^3
pero 1200.
tiene 4 cifras significativas y 1200.0
tiene 5 cifras significativas.
Al sumar dos números, el resultado debe redondearse al mismo número de lugares que el número cuyo dígito menos significativo se encuentra más a la izquierda. Por ejemplo, 1200 + 3 = 1200
(redondeado al lugar de las centenas ya que 1200 se redondea al lugar de las centenas) 1200.01 + 3 = 1203
, y 4.59 + 2.3 = 6.9
. Tenga en cuenta que se 5
redondea. Esta misma regla se aplica a la resta. 0
se redondea al lugar de las unidades. Tenga en cuenta que sumar y restar no dependen del número de dígitos significativos. Por ejemplo,999 + 2.00 = 1001
porque 999 se redondea al lugar de las unidades y 2.00 se redondea al lugar de las centésimas; el redondeado a menos lugares es 999, por lo que el resultado, 1001.00, también debe redondearse al lugar de las unidades. Del mismo modo, 300 + 1 - 300 es exactamente igual a 1, pero 300 se redondea al lugar de las centenas, por lo que el resultado final también se debe redondear al lugar de las centenas, dando 0. 300. + 1 - 300. sería igual a 1 en el otra mano
Al multiplicar o dividir dos números, redondea al número de dígitos significativos del número con los dígitos menos significativos. Por ejemplo, 3.839*4=20
debido a que el valor exacto 15.356
, se redondea a 20
como 4
solo tiene una cifra significativa. Del mismo modo, 100/4=30
dado que ambos números tienen una cifra significativa, pero 100./4.00=25.0
dado que ambos números tienen 3 cifras significativas. 0
se define para tener 1 figura significativa.
Expresiones solamente contendrá *
, /
, +
, y -
, (y entre paréntesis). Se debe seguir el orden de las operaciones y los resultados se deben redondear después de cada operación. Si los paréntesis se dejan fuera en una cadena de sumas o restas o en una cadena de multiplicaciones y divisiones, entonces redondea después de completar todas las operaciones. Por ejemplo, 6*0.4*2 = 5
(una cifra significativa), while 0.4*(2*6)=0.4*10=4
y (6*0.4)*2=2*2=4
.
Entrada : una cadena, con una expresión que contiene ()*/+-
y dígitos. Para simplificar las cosas, -
solo se utilizará como un operador de resta, no para significar números negativos; Sin embargo, las respuestas aún podrían ser negativas y requerirían -
como prefijo.
Salida : El resultado de la expresión, evaluada y redondeada al número correcto de dígitos. Tenga en cuenta que 25
es incorrecto para 25.0
.
Casos de prueba :
3 + 0.5 --> 4
25.01 - 0.01 --> 25.00
4*7*3 --> 80
(4*7)*3 --> 90
(8.0 + 0.5)/(2.36 - 0.8 - 0.02) --> 5.7
6.0 + 4.0 --> 10.0
5.0 * 2.0 --> 10.0
1/(2.0 * (3.0 + 5.0)) --> 0.06
0.0020 * 129 --> 0.26
300 + 1 - 300 --> 0
0 - 8.8 --> -9
3*5/2*2 --> 20
Caso de borde: considere el problema de 501*2.0
. El valor exacto es 1002
. La impresión 1002
da demasiadas cifras significativas (4, cuando necesitamos 2) pero 1000
da muy pocas (1, cuando necesitamos 2). En este caso, su programa debería imprimir de 1000
todos modos.
Esta fuente también explica dígitos significativos: http://www.purplemath.com/modules/rounding2.htm
999 + 2.00
,.300 + 1 - 300
es una cadena de sumas y restas, por lo que no necesita redondearse hasta el final.(300 + 1) - 300
Sería cero.Respuestas:
Java 11,
13251379135613361290 bytes+54 bytes para arreglar el caso de borde
501*2.0
(dio resultado1002
antes, pero ahora correcto1000
).Ahora entiendo por qué este desafío no tuvo respuesta durante casi dos años ...>.> Este desafío tiene casos más especiales que el idioma holandés, que dice algo ...
Java ciertamente no es el idioma adecuado para este tipo de desafíos (o cualquier codegolf desafío para el caso ...; p), pero es el único lenguaje que conozco lo suficientemente bueno como para incluso intentar un desafío difícil como este.
Formato de entrada como
String
sin espacios (si eso no está permitido, puede agregars=s.replace(" ","")
(+19 bytes) en la parte superior del método).Pruébalo en línea.
Explicación:
Perdón por la larga publicación.
Esta parte se usa para entradas que contienen paréntesis. Obtendrá las partes separadas y usará llamadas recursivas.
0.4*(2*6)
se convierte0.4*A
, dondeA
es una llamada recursiva ac(2*6)
(8.3*0.02)+(1.*(9*4)+2.2)
se convierteA+B
, dondeA
es una llamada recursivac(8.3*0.02)
yB
una llamada recursiva ac(1.*(9*4)+2.2)
→ que a su vez se convierte1.*C+2.2
, dondeC
es una llamada recursiva ac(9*4)
Este primer ciclo se usa para completar los valores
M
yk
, dondeM
es la mayor longitud entera con respecto a cifras significativas yk
la mayor longitud de decimales.1200+3.0
se convierte enM=2, k=1
(12, .0
)999+2.00
se convierte enM=3, k=2
(999, .00
)300.+1-300.
se convierte enM=3, k=0
(300, .
)Este segundo bucle se usa para llenar las matrices
A
yb
también el valorq
, dondeA
es la cantidad de cifras significativas,b
mantener los enteros con ceros a la izquierda para coincidirM
, yq
es la longitud más baja sin tener en cuenta los puntos.1200+3.0
se convierteA=[2, 5] (12, 00030)
,b=[1200, 0003.0]
yq=2
(30
)999+2.00
se convierteA=[3, 5] (999, 00200)
,b=[999, 002.00]
yq=3
(ambos999
y200
)300.+1-300.
se convierteA=[3, 3, 3] (300, 001, 300)
,b=[300., 001, 300.]
yq=1
(1
)501*2.0
se convierteA=[3, 4] (501, 0020)
,b=[501, 002.0]
yq=2
(20
)Utiliza un motor de JavaScript para evaluar la entrada, que se guardará
R
como doble.1200+3.0
se convierteR=1203.0
999+2.00
se convierteR=1001.0
300.+1-300.
se convierteR=1.0
Esto establece
m
el valor más pequeño en la matrizA
.A=[2, 5]
se conviertem=2
A=[3, 5]
se conviertem=3
A=[3, 3, 3]
se conviertem=3
Esto se modifica en
m
función de múltiples factores.999+2.00 = 1001.0
& sem=3,q=3
convierte enm=4
(porquem==M
(ambos3
) →R%1==0
(1001.0
no tiene valores decimales) →(int)R/10%10<1
(se(int)1001.0/10
convierte en100
→100%10<1
) →"1001".length()>m
(4>3
) →"1001".length()-q<=1
(4-3<=1
) → entonces sem
convierte en la longitud de la parte entera"1001"
(4
))3.839*4 = 15.356
&m=1,q=1
permanecem=1
(porquem==M
(ambos1
) →R%1!=0
(15.356
tiene valores decimales) →R<=99
→R%10!=0
(15.356%10==5.356
) →m!=0
→ así quem
permanece igual (1
))4*7*3 = 84.0
&m=1,q=1
permanecem=1
(porquem==M
(ambos1
) →R%1==0
(84.0
no tiene valores decimales) →(int)R/10%10>=1
(se(int)84/10
convierte en8
→8%10>=1
) →R<=99
→R%10!=0
(84%10==4
) →m!=0
→ así quem
permanece igual (1
))6.0+4.0 = 10.0
& sem=2,q=2
convierte enm=3
(porquem!=M
(m=2, M=1
) →R<=99
→R%10==0
(10%10==0
) → sem
convierte en la longitud del totalR
(menos el punto)"10.0".length()-1
(3
))0-8.8 = -8.8
& sem=0,q=1
conviertem=1
(porquem!=M
(m=0, M=1
) →R<=99
→R%10!=0
(-8.8%10==-8.8
) →m<1
→ sem
convierte en1
)501*2.0 = 1001.0
& sem=3,q=2
convierte enm=2
(porquem==M
(ambos3
) →R%1==0
(1001.0
no tiene valores decimales) →(int)R/10%10<1
(se(int)1001.0/10
convierte en100
→100%10<1
) →"1001".length()>m
(4>3
) →"1001".length()-q>1
(4-2>1
) → sem
convierte enq
(2
)Ahora
R
se redondea segúnm
.1001.0
y sem=4
convierte1001.0
0.258
& sem=3
convierte en0.26
(porqueabs(R)<1
,m-1
(2
) en lugar dem=3
se usa dentroMathContext
)-8.8
y sem=1
convierte-9.0
1002.0
y sem=2
convierte1000.0
Esto modifica la parte entera de
R
si es necesario.300.+1-300. = 1.0
&m=3,M=3
permanece1.0
(porquem>=M
→ entoncesR
permanece igual (1.0
))0.4*10 = 4.0
&m=1,M=2
permanece4.0
(porquem<M
→(10^(M-m))/10<=R
((10^1)/10<=4.0
→10/10<=4.0
→1<=4.0
) →R
permanece igual (4.0
))300+1-300 = 1.0
& sem=1,M=3
convierte en0.0
(porquem<M
→(10^(M-m))/10>R
((10^2)/10>1.0
→100/10>1.0
→10>1.0
) → entonces seR
convierte en0.0
debido aint(R/(10^(M-m)))*(10^(M-m))
(int(1.0/(10^2))*(10^2)
→int(1.0/100)*100
→0*100
→0
)Este conjuntos
R
ar
como secuencia, y lo modifica basa en varios factores.1203.0
& sem=4,k=2
convierte1203.
(porquek>=1
→ entonces ser
convierte en1001.000
;r.length()>=m
(8>=4
) →r.contains(".")
→r.length()>=m
(8>=4
) → subcadena del índice0
am+1
(5
))6.9
&m=2,k=2
permanece6.9
(porquek>=1
→ entonces ser
convierte en6.900
;r.length()>=m
(5>=2
) →r.contains(".")
→r.length()>=m
(5>=2
) → subcadena del índice0
am+1
(3
))1.0
& sem=3,k=0
convierte1
(porquek<1
→ ser
convierte en1
;r.length()<m
(1<3
) → subcadena del índice0
ar.length()
(1
))25.0
& sem=4,k=4
convierte25.00
(porquek>=1
→ entonces ser
convierte en25.00000
;r.length()>=m
(8>=4
) →r.contains(".")
→r.length()>+m
(8>=4
) → subcadena del índice0
am+1
(5
))0
& sem=1,k=0
queda0
(porquek<1
→ así ser
queda0
;r.length()>=m
(1>=1
) →!r.contains(".")
→ subcadena del índice0
am
(1
))Esto hace que los ceros finales vuelvan a la parte entera si es necesario.
r="12"
y seR=1200.0
convierter="1200"
r="1"
y seR=10.0
convierter="10"
r="8"
y seR=80.0
convierter="80"
Y finalmente devolvemos el resultado, después de haber eliminado los puntos finales.
1203.
se convierte1203
5.
se convierte5
Definitivamente se puede jugar un par de cientos de bytes, pero me alegra que esté funcionando ahora. Ya tomó un tiempo entender cada uno de los casos y lo que se preguntaba en el desafío. Y luego se necesitaron muchas pruebas y errores, pruebas y pruebas para llegar al resultado anterior. Y mientras escribía esta explicación arriba pude eliminar otros ± 50 bytes de código no utilizado ...
fuente
501*2.0
genere1000
(debería emitir de1000
todos modos , lo que interpreto como "todavía", de ninguna manera ). Magnífico trabajo de todos modos.