Étant donné une expression, votre tâche consiste à l'évaluer. Cependant, votre réponse ne peut pas afficher plus de chiffres que nécessaire, car cela donne l'impression d'avoir des mesures plus précises que la réalité.
Le nombre de chiffres significatifs d'un nombre est le nombre de chiffres qu'il a lorsqu'il est écrit en notation scientifique, y compris les zéros à la fin si un point décimal est présent. Par exemple, 1200
a 2 chiffres significatifs parce que c'est 1.2*10^3
mais 1200.
a 4 chiffres significatifs et 1200.0
a 5 chiffres significatifs.
Lors de l'ajout de deux nombres, le résultat doit être arrondi au même nombre de places que le nombre dont le chiffre le moins significatif est le plus à gauche. Par exemple, 1200 + 3 = 1200
(arrondi à la centaine puisque 1200 est arrondi à la centaine) 1200.01 + 3 = 1203
,, et 4.59 + 2.3 = 6.9
. Notez que 5
arrondit. Cette même règle s'applique à la soustraction. 0
est arrondi à la place de ceux. Notez que l'ajout et la soustraction ne dépendent pas du nombre de chiffres significatifs. Par exemple,999 + 2.00 = 1001
parce que 999 est arrondi à la place des uns et 2,00 à la place des centièmes; celui arrondi à moins de places est 999, donc le résultat, 1001,00, devrait être arrondi à la place de ceux aussi. De même, 300 + 1 - 300 est exactement égal à 1, mais 300 est arrondi à la place des centaines, donc le résultat final devrait également être arrondi à la place des centaines, donnant 0. 300. + 1 - 300. serait égal à 1 sur la d'autre part.
Lorsque vous multipliez ou divisez deux nombres, arrondissez au nombre de chiffres significatifs du nombre avec les chiffres les moins significatifs. Par exemple, 3.839*4=20
car la valeur exacte,, 15.356
arrondie à 20
depuis 4
n'a qu'un seul chiffre significatif. De même, 100/4=30
puisque les deux nombres ont un chiffre significatif, mais 100./4.00=25.0
puisque les deux nombres ont 3 chiffres significatifs. 0
est défini comme ayant 1 chiffre significatif.
Les expressions ne contiendra *
, /
, +
et -
, (et entre parenthèses). L'ordre des opérations doit être suivi et les résultats doivent être arrondis après chaque opération. Si des parenthèses sont omises dans une chaîne d'additions ou de soustractions ou une chaîne de multiplications et de divisions, arrondissez une fois toutes les opérations terminées. Par exemple, 6*0.4*2 = 5
(un chiffre significatif), tandis que 0.4*(2*6)=0.4*10=4
et (6*0.4)*2=2*2=4
.
Entrée : une chaîne, avec une expression contenant ()*/+-
et des chiffres. Pour simplifier les choses, -
ne sera utilisé que comme opérateur de soustraction, pas pour signifier des nombres négatifs; cependant, les réponses pourraient toujours être négatives et nécessiteraient -
un préfixe.
Sortie : résultat de l'expression, évalué et arrondi au nombre correct de chiffres. Notez que 25
c'est incorrect pour 25.0
.
Cas de test :
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
Cas Edge: Considérez le problème de 501*2.0
. La valeur exacte est 1002
. L'impression 1002
donne trop de chiffres significatifs (4, quand nous avons besoin de 2) mais 1000
donne trop peu (1, quand nous avons besoin de 2). Dans ce cas, votre programme devrait 1000
quand même imprimer .
Cette source explique également les chiffres significatifs: http://www.purplemath.com/modules/rounding2.htm
999 + 2.00
.300 + 1 - 300
s'agit certainement d' une chaîne d'additions et de soustractions, il n'est donc pas nécessaire de l'arrondir jusqu'à la fin.(300 + 1) - 300
serait zéro.Réponses:
Java 11,
13251379135613361290 octets+54 octets pour corriger le cas de bord
501*2.0
(a donné le résultat1002
avant, mais maintenant correct1000
).Je comprends maintenant pourquoi ce défi était sans réponse depuis presque deux ans ..>.> Ce défi a des cas plus particuliers que la langue néerlandaise, ce qui veut dire quelque chose ..
Java est certainement pas la bonne langue pour ce genre de défis (ou tout codegolf défi d'ailleurs ..; p), mais c'est la seule langue que je connais assez bien pour même tenter un défi difficile comme celui-ci.
Format d'entrée
String
sans espaces (si cela n'est pas autorisé, vous pouvez ajouters=s.replace(" ","")
(+19 octets) en haut de la méthode).Essayez-le en ligne.
Explication:
Désolé pour le long post.
Cette partie est utilisée pour les entrées contenant des parenthèses. Il récupérera les parties séparées et utilisera les appels récursifs.
0.4*(2*6)
devient0.4*A
, oùA
est un appel récursif àc(2*6)
(8.3*0.02)+(1.*(9*4)+2.2)
devientA+B
, oùA
est un appel récursif àc(8.3*0.02)
etB
un appel récursif àc(1.*(9*4)+2.2)
→ qui devient à son tour1.*C+2.2
, oùC
est un appel récursif àc(9*4)
Cette première boucle est utilisée pour remplir les valeurs
M
etk
, oùM
est la plus grande longueur entière concernant les chiffres significatifs etk
la plus grande longueur décimale.1200+3.0
devientM=2, k=1
(12, .0
)999+2.00
devientM=3, k=2
(999, .00
)300.+1-300.
devientM=3, k=0
(300, .
)Cette deuxième boucle est utilisée pour remplir les tableaux
A
etb
ainsi que la valeurq
, oùA
est le nombre de chiffres significatifs,b
tenir les entiers avec des zéros en tête pour correspondreM
, etq
est la plus petite longueur sans tenir compte des points.1200+3.0
devientA=[2, 5] (12, 00030)
,b=[1200, 0003.0]
etq=2
(30
)999+2.00
devientA=[3, 5] (999, 00200)
,b=[999, 002.00]
etq=3
( à la fois999
et200
)300.+1-300.
devientA=[3, 3, 3] (300, 001, 300)
,b=[300., 001, 300.]
etq=1
(1
)501*2.0
devientA=[3, 4] (501, 0020)
,b=[501, 002.0]
etq=2
(20
)Utilise un moteur JavaScript pour évaluer l'entrée, qui sera enregistrée en
R
double.1200+3.0
devientR=1203.0
999+2.00
devientR=1001.0
300.+1-300.
devientR=1.0
Cela définit
m
la plus petite valeur du tableauA
.A=[2, 5]
devientm=2
A=[3, 5]
devientm=3
A=[3, 3, 3]
devientm=3
Cela modifie en
m
fonction de plusieurs facteurs.999+2.00 = 1001.0
&m=3,q=3
devientm=4
(parce quem==M
(les deux3
) →R%1==0
(1001.0
n'a pas de valeurs décimales) →(int)R/10%10<1
((int)1001.0/10
devient100
→100%10<1
) →"1001".length()>m
(4>3
) →"1001".length()-q<=1
(4-3<=1
) →m
devient ainsi la longueur de la partie entière"1001"
(4
))3.839*4 = 15.356
&m=1,q=1
restem=1
(parce quem==M
(les deux1
) →R%1!=0
(15.356
a des valeurs décimales) →R<=99
→R%10!=0
(15.356%10==5.356
) →m!=0
→m
reste donc le même (1
))4*7*3 = 84.0
&m=1,q=1
restem=1
(parce quem==M
(les deux1
) →R%1==0
(84.0
n'a pas de valeurs décimales) →(int)R/10%10>=1
((int)84/10
devient8
→8%10>=1
) →R<=99
→R%10!=0
(84%10==4
) →m!=0
→m
reste donc le même (1
))6.0+4.0 = 10.0
&m=2,q=2
devientm=3
(carm!=M
(m=2, M=1
) →R<=99
→R%10==0
(10%10==0
) →m
devient ainsi la longueur du totalR
(moins le point)"10.0".length()-1
(3
))0-8.8 = -8.8
&m=0,q=1
devientm=1
(parce quem!=M
(m=0, M=1
) →R<=99
→R%10!=0
(-8.8%10==-8.8
) →m<1
→m
devient ainsi1
)501*2.0 = 1001.0
&m=3,q=2
devientm=2
(parce quem==M
(les deux3
) →R%1==0
(1001.0
n'a pas de valeurs décimales) →(int)R/10%10<1
((int)1001.0/10
devient100
→100%10<1
) →"1001".length()>m
(4>3
) →"1001".length()-q>1
(4-2>1
) →m
devient ainsiq
(2
))Maintenant
R
est arrondi en fonction dem
.1001.0
&m=4
devient1001.0
0.258
&m=3
devient0.26
(carabs(R)<1
,m-1
(2
) au lieu dem=3
est utilisé à l'intérieurMathContext
)-8.8
&m=1
devient-9.0
1002.0
&m=2
devient1000.0
Cela modifie la partie entière de
R
si nécessaire.300.+1-300. = 1.0
&m=3,M=3
reste1.0
(parce quem>=M
→R
reste donc le même (1.0
))0.4*10 = 4.0
&m=1,M=2
reste4.0
(parce quem<M
→(10^(M-m))/10<=R
((10^1)/10<=4.0
→10/10<=4.0
→1<=4.0
) →R
reste donc le même (4.0
))300+1-300 = 1.0
&m=1,M=3
devient0.0
(parce quem<M
→(10^(M-m))/10>R
((10^2)/10>1.0
→100/10>1.0
→10>1.0
) →R
devient ainsi à0.0
cause deint(R/(10^(M-m)))*(10^(M-m))
(int(1.0/(10^2))*(10^2)
→int(1.0/100)*100
→0*100
→0
)Il est défini
R
surr
String et le modifie en fonction de plusieurs facteurs.1203.0
&m=4,k=2
devient1203.
(cark>=1
→r
devient ainsi1001.000
;r.length()>=m
(8>=4
) →r.contains(".")
→r.length()>=m
(8>=4
) → sous-chaîne de l'index0
àm+1
(5
))6.9
&m=2,k=2
reste6.9
(cark>=1
→r
devient ainsi6.900
;r.length()>=m
(5>=2
) →r.contains(".")
→r.length()>=m
(5>=2
) → sous-chaîne de l'index0
àm+1
(3
))1.0
&m=3,k=0
devient1
(cark<1
→r
devient ainsi1
;r.length()<m
(1<3
) → sous-chaîne de l'index0
àr.length()
(1
))25.0
&m=4,k=4
devient25.00
(cark>=1
→r
devient ainsi25.00000
;r.length()>=m
(8>=4
) →r.contains(".")
→r.length()>+m
(8>=4
) → sous-chaîne de l'index0
àm+1
(5
))0
&m=1,k=0
séjours0
(parce quek<1
→r
reste donc0
;r.length()>=m
(1>=1
) →!r.contains(".")
→ sous-chaîne de l'index0
àm
(1
))Cela ramène les zéros de fin à la partie entière si nécessaire.
r="12"
&R=1200.0
devientr="1200"
r="1"
&R=10.0
devientr="10"
r="8"
&R=80.0
devientr="80"
Et enfin, nous retournons le résultat, après avoir supprimé tous les points de fin.
1203.
devient1203
5.
devient5
Peut certainement être joué par quelques centaines d'octets, mais je suis juste content que cela fonctionne maintenant. Il a déjà fallu un certain temps pour comprendre chacun des cas et ce qui était demandé dans le défi. Et puis il a fallu beaucoup d'essais et d'erreurs, de tests et de retests pour arriver au résultat ci-dessus. Et en écrivant cette explication ci-dessus, j'ai pu supprimer encore ± 50 octets de code inutilisé.
la source
501*2.0
pour la sortie1000
(vous devriez1000
quand même sortir , ce que j'interprète comme "toujours", pas dans les deux cas ). Magnifique travail quand même.