Java 11, 1325 1379 1356 1336 1290 byte
import java.math.*;String c(String s)throws Exception{String r="",T=r,a[],b[],z="\\.";int i=0,l,A[],M=0,m=s.length(),j,f=0,q=m;if(s.contains("(")){for(;i<m;){var c=s.charAt(i++);if(f<1){if(c==40){f=1;continue;}r+=c;}else{if(c==41&T.replaceAll("[^(]","").length()==T.replaceAll("[^)]","").length()){r+="x"+s.substring(i);break;}T+=c;}}return c(r.replace("x",c(T)));}else{for(a=s.split("[\\+\\-\\*/]"),A=new int[l=a.length];i<l;f=b.length>1&&(j=b[1].length())>f?j:f)M=(j=(b=a[i++].split(z))[0].length())>M?j:M;for(b=a.clone(),i=0;i<l;A[i]=b[i].contains(".")?j=b[i].length()-1:b[i].replaceAll("0*$","").length(),i++)for(q=(j=b[i].replace(".","").length())<q?j:q,j=a[i].split(z)[0].length();j++<M;)b[i]=0+b[i];double R=new Double(new javax.script.ScriptEngineManager().getEngineByName("JS").eval(s)+""),p;for(int x:A)m=x<m?x:m;m=m==M&R%1==0&(int)R/10%10<1&(j=(r=R+"").split(z)[0].length())>m?j-q>1?q:j:R>99?m:R%10==0?r.length()-1:m<1?1:m;R=new BigDecimal(R).round(new MathContext((R<0?-R:R)<1?m-1:m)).doubleValue();r=(m<M&(p=Math.pow(10,M-m))/10>R?(int)(R/p)*p:R)+"";l=r.length()-2;r=(r=f<1?r.replaceAll(z+"0$",""):r+"0".repeat(f)).substring(0,(j=r.length())<m?j:r.contains(".")?(j=r.replaceAll("^0\\.0+","").length())<m?m-~j:m+1:m);for(i=r.length();i++<l;)r+=0;return r.replaceAll(z+"$","");}}
+54 byte untuk memperbaiki kasus tepi 501*2.0(memberi hasil 1002sebelumnya, tetapi sekarang benar 1000).
Saya sekarang mengerti mengapa tantangan ini tidak dijawab selama hampir dua tahun ..>.> Tantangan ini memiliki kasus yang lebih khusus daripada bahasa Belanda, yang mengatakan sesuatu ..
Jawa tentu bukan bahasa yang tepat untuk tantangan semacam ini (atau codegolf apa pun) tantangan dalam hal ini;
Masukkan format Stringtanpa spasi (jika tidak diizinkan, Anda dapat menambahkan s=s.replace(" ","")(+19 byte) di bagian atas metode ini).
Cobalah online.
Penjelasan:
Maaf untuk posting lama.
if(s.contains("(")){
for(;i<m;){
var c=s.charAt(i++);
if(f<1){
if(c==40){
f=1;
continue;}
r+=c;}
else{
if(c==41&T.replaceAll("[^(]","").length()==T.replaceAll("[^)]","").length()){
r+="x"+s.substring(i);
break;}
T+=c;}}
return c(r.replace("x",c(T)));}
Bagian ini digunakan untuk input yang mengandung tanda kurung. Ini akan mendapatkan bagian-bagian yang terpisah dan menggunakan panggilan rekursif.
0.4*(2*6)menjadi 0.4*A, di mana Apanggilan rekursif untukc(2*6)
(8.3*0.02)+(1.*(9*4)+2.2)menjadi A+B, di mana Aadalah panggilan rekursif ke c(8.3*0.02)dan Bpanggilan rekursif ke c(1.*(9*4)+2.2)→ yang pada gilirannya menjadi 1.*C+2.2, di mana Cadalah panggilan rekursif untukc(9*4)
for(a=s.split("[\\+\\-\\*/]"),A=new int[l=a.length];
i<l;
f=b.length>1&&(j=b[1].length())>f?j:f)
M=(j=(b=a[i++].split(z))[0].length())>M?j:M;
Loop pertama ini digunakan untuk mengisi nilai-nilai Mdan k, di mana Madalah bilangan bulat-panjang terbesar mengenai angka-angka penting dan kpanjang desimal terbesar.
1200+3.0menjadi M=2, k=1( 12, .0)
999+2.00menjadi M=3, k=2( 999, .00)
300.+1-300.menjadi M=3, k=0( 300, .)
for(b=a.clone(),i=0;
i<l;
A[i]=b[i].contains(".")?j=b[i].length()-1:b[i].replaceAll("0*$","").length(),i++)
for(q=(j=b[i].replace(".","").length())<q?j:q,
j=a[i].split(z)[0].length();
j++<M;)
b[i]=0+b[i];
Loop kedua ini digunakan untuk mengisi array Adan bjuga nilai q, di mana Ajumlah angka signifikan, bpegang bilangan bulat dengan nol terkemuka untuk mencocokkan M, dan qmerupakan titik-titik pengabaian dengan panjang terendah.
1200+3.0menjadi A=[2, 5] (12, 00030),, b=[1200, 0003.0]dan q=2( 30)
999+2.00menjadi A=[3, 5] (999, 00200),, b=[999, 002.00]dan q=3(keduanya 999dan 200)
300.+1-300.menjadi A=[3, 3, 3] (300, 001, 300),, b=[300., 001, 300.]dan q=1( 1)
501*2.0menjadi A=[3, 4] (501, 0020),, b=[501, 002.0]dan q=2( 20)
double R=new Double(new javax.script.ScriptEngineManager().getEngineByName("JS").eval(s)+"")
Menggunakan mesin JavaScript untuk mengevaluasi input, yang akan disimpan dalam Rdua kali lipat.
1200+3.0 menjadi R=1203.0
999+2.00 menjadi R=1001.0
300.+1-300. menjadi R=1.0
for(int x:A)
m=x<m?x:m;
Ini menetapkan mnilai terkecil dalam array A.
A=[2, 5] menjadi m=2
A=[3, 5] menjadi m=3
A=[3, 3, 3] menjadi m=3
m=m==M // If `m` equals `M`
&R%1==0 // and `R` has no decimal values (apart from 0)
&(int)R/10%10<1 // and floor(int(R)/10) modulo-10 is 0
&(j=(r=R+"").split(z)[0].length())>m?
// and the integer-length of R is larger than `m`:
j-q>1? // If this integer-length of `R` minus `q` is 2 or larger:
q // Set `m` to `q` instead
: // Else:
j // Set `m` to this integer-length of `R`
:R>99? // Else-if `R` is 100 or larger:
m // Leave `m` the same
:R%10==0? // Else-if `R` modulo-10 is exactly 0:
r.length()-1 // Set `m` to the total length of `R` (minus the dot)
:m<1? // Else-if `m` is 0:
1 // Set `m` to 1
: // Else:
m; // Leave `m` the same
Ini memodifikasi mberdasarkan beberapa faktor.
999+2.00 = 1001.0& m=3,q=3menjadi m=4(karena m==M(keduanya 3) → R%1==0( 1001.0tidak memiliki nilai desimal) → (int)R/10%10<1( (int)1001.0/10menjadi 100→ 100%10<1) → "1001".length()>m( 4>3) → "1001".length()-q<=1( 4-3<=1) → jadi mmenjadi panjang bagian integer "1001"( 4))
3.839*4 = 15.356& m=1,q=1tetap m=1(karena m==M(keduanya 1) → R%1!=0( 15.356memiliki nilai desimal) → R<=99→ R%10!=0( 15.356%10==5.356) → m!=0→ jadi mtetap sama ( 1))
4*7*3 = 84.0& m=1,q=1tetap m=1(karena m==M(keduanya 1) → R%1==0( 84.0tidak memiliki nilai desimal) → (int)R/10%10>=1( (int)84/10menjadi 8→ 8%10>=1) → R<=99→ R%10!=0( 84%10==4) → m!=0→ jadi mtetap sama ( 1))
6.0+4.0 = 10.0& m=2,q=2menjadi m=3(karena m!=M( m=2, M=1) → R<=99→ R%10==0( 10%10==0) → jadi mmenjadi panjang total R(minus titik) "10.0".length()-1( 3))
0-8.8 = -8.8& m=0,q=1Menjadi m=1(karena m!=M( m=0, M=1) → R<=99→ R%10!=0( -8.8%10==-8.8) → m<1→ sehingga mmenjadi 1)
501*2.0 = 1001.0& m=3,q=2menjadi m=2(karena m==M(keduanya 3) → R%1==0( 1001.0tidak memiliki nilai desimal) → (int)R/10%10<1( (int)1001.0/10menjadi 100→ 100%10<1) → "1001".length()>m( 4>3) → "1001".length()-q>1( 4-2>1) → jadi mmenjadi q( 2))
R=new BigDecimal(R).round(new MathContext((R<0?-R:R)<1?m-1:m)).doubleValue();
Sekarang Rdibulatkan berdasarkan m.
1001.0& m=4menjadi1001.0
0.258& m=3menjadi 0.26(karena abs(R)<1, m-1( 2) alih-alih m=3digunakan di dalam MathContext)
-8.8& m=1menjadi-9.0
1002.0& m=2menjadi1000.0
m<M&(p=Math.pow(10,M-m))/10>R?(int)(R/p)*p:R;
Ini memodifikasi bagian integer Rjika perlu.
300.+1-300. = 1.0& m=3,M=3tetap 1.0(karena m>=M→ jadi Rtetap sama ( 1.0))
0.4*10 = 4.0& m=1,M=2tetap 4.0(karena m<M→ (10^(M-m))/10<=R( (10^1)/10<=4.0→ 10/10<=4.0→ 1<=4.0) → jadi Rtetap sama ( 4.0))
300+1-300 = 1.0& m=1,M=3menjadi 0.0(karena m<M→ (10^(M-m))/10>R( (10^2)/10>1.0→ 100/10>1.0→ 10>1.0) → jadi Rmenjadi 0.0karena int(R/(10^(M-m)))*(10^(M-m))( int(1.0/(10^2))*(10^2)→ int(1.0/100)*100→ 0*100→ 0)
r=(...)+""; // Set `R` to `r` as String (... is the part explained above)
l=r.length()-2; // Set `l` to the length of `R` minus 2
r=(r=k<1? // If `k` is 0 (no decimal values in any of the input-numbers)
r.replaceAll(z+"0$","")
// Remove the `.0` at the end
: // Else:
r+"0".repeat(f)
// Append `k` zeroes after the current `r`
).substring(0, // Then take the substring from index `0` to:
(j=r.length())<m? // If the total length of `r` is below `m`:
j // Leave `r` the same
:r.contains(".")? // Else-if `r` contains a dot
(j=r.replaceAll("^0\\.0+","").length())<m?
// And `R` is a decimal below 1,
// and its rightmost decimal length is smaller than `m`
m-~j // Take the substring from index 0 to `m+j+1`
// where `j` is this rightmost decimal length
: // Else:
m+1 // Take the substring from index 0 to `m+1`
: // Else:
m); // Take the substring from index 0 to `m`
Ini set Runtuk rsebagai String, dan memodifikasi itu didasarkan pada beberapa faktor.
1203.0& m=4,k=2menjadi 1203.(karena k>=1→ begitu rmenjadi 1001.000; r.length()>=m( 8>=4) → r.contains(".")→ r.length()>=m( 8>=4) → substring dari indeks 0ke m+1( 5))
6.9& m=2,k=2tetap 6.9(karena k>=1→ jadi rmenjadi 6.900; r.length()>=m( 5>=2) → r.contains(".")→ r.length()>=m( 5>=2) → substring dari indeks 0ke m+1( 3))
1.0& m=3,k=0menjadi 1(karena k<1→ begitu rmenjadi 1; r.length()<m( 1<3) → substring dari indeks 0ke r.length()( 1))
25.0& m=4,k=4menjadi 25.00(karena k>=1→ begitu rmenjadi 25.00000; r.length()>=m( 8>=4) → r.contains(".")→ r.length()>+m( 8>=4) → substring dari indeks 0ke m+1( 5))
0& m=1,k=0tetap 0(karena k<1→ begitu rtetap 0; r.length()>=m( 1>=1) → !r.contains(".")→ substring dari indeks 0ke m( 1))
for(i=r.length();i++<l;)
r+=0;
Ini menempatkan nol trailing kembali ke bagian integer jika perlu.
r="12"& R=1200.0menjadir="1200"
r="1"& R=10.0menjadir="10"
r="8"& R=80.0menjadir="80"
return r.replaceAll(z+"$","");
Dan akhirnya kami mengembalikan hasilnya, setelah kami menghapus titik-titik jejak.
1203. menjadi 1203
5. menjadi 5
Pasti bisa bermain golf dengan beberapa ratus byte, tapi saya senang ini berfungsi sekarang. Sudah butuh beberapa saat untuk memahami masing-masing kasus dan apa yang ditanyakan dalam tantangan. Dan kemudian butuh banyak trial-and-error, pengujian dan pengujian ulang untuk mendapatkan hasil di atas. Dan ketika menulis penjelasan ini di atas saya bisa menghapus ± 50 byte kode yang tidak terpakai lagi ..
999 + 2.00,.