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 để sửa trường hợp cạnh 501*2.0(đã cho kết quả 1002trước đó, nhưng bây giờ đúng 1000).
Bây giờ tôi đã hiểu tại sao thử thách này không được trả lời trong gần hai năm ..>.> Thử thách này có nhiều trường hợp đặc biệt hơn tiếng Hà Lan, điều đang nói điều gì đó ..
Java chắc chắn không phải là ngôn ngữ phù hợp cho những thách thức này (hoặc bất kỳ loại tiền mã hóa nào thách thức cho vấn đề đó ..; p), nhưng đó là ngôn ngữ duy nhất tôi biết đủ tốt để thậm chí thực hiện một thử thách khó khăn như thế này.
Định dạng đầu vào như Stringkhông có khoảng trắng (nếu điều đó không được phép, bạn có thể thêm s=s.replace(" ","")(+19 byte) ở đầu phương thức).
Hãy thử trực tuyến.
Giải trình:
Xin lôi vi bai đăng dai.
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)));}
Phần này được sử dụng cho đầu vào có chứa dấu ngoặc đơn. Nó sẽ nhận được các phần riêng biệt và sử dụng các cuộc gọi đệ quy.
0.4*(2*6)trở thành 0.4*A, nơi Amột cuộc gọi đệ quy đếnc(2*6)
(8.3*0.02)+(1.*(9*4)+2.2)trở thành A+B, nơi Amột cuộc gọi đệ quy đến c(8.3*0.02)và Bmột cuộc gọi đệ quy đến c(1.*(9*4)+2.2)→ lần lượt trở thành 1.*C+2.2, Ccuộc gọi đệ quy đếnc(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;
Vòng lặp đầu tiên này được sử dụng để điền vào các giá trị Mvà k, trong đó Mđộ dài số nguyên lớn nhất liên quan đến các số liệu có ý nghĩa và kđộ dài số thập phân lớn nhất.
1200+3.0trở thành M=2, k=1( 12, .0)
999+2.00trở thành M=3, k=2( 999, .00)
300.+1-300.trở thành 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];
Vòng lặp thứ hai này được sử dụng để điền vào các mảng Avà bcũng như giá trị q, trong đó Asố lượng các số liệu có ý nghĩa, bgiữ các số nguyên với các số 0 đứng đầu để khớp Mvà qlà các chấm có độ dài thấp nhất.
1200+3.0trở thành A=[2, 5] (12, 00030), b=[1200, 0003.0]và q=2( 30)
999+2.00trở thành A=[3, 5] (999, 00200), b=[999, 002.00]và q=3(cả hai 999và 200)
300.+1-300.trở thành A=[3, 3, 3] (300, 001, 300), b=[300., 001, 300.]và q=1( 1)
501*2.0trở thành A=[3, 4] (501, 0020), b=[501, 002.0]và q=2( 20)
double R=new Double(new javax.script.ScriptEngineManager().getEngineByName("JS").eval(s)+"")
Sử dụng một công cụ JavaScript để đánh giá đầu vào, sẽ được lưu Rthành hai lần.
1200+3.0 trở thành R=1203.0
999+2.00 trở thành R=1001.0
300.+1-300. trở thành R=1.0
for(int x:A)
m=x<m?x:m;
Điều này đặt mthành giá trị nhỏ nhất trong mảng A.
A=[2, 5] trở thành m=2
A=[3, 5] trở thành m=3
A=[3, 3, 3] trở thành 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
Điều này sửa đổi mdựa trên nhiều yếu tố.
999+2.00 = 1001.0& m=3,q=3trở thành m=4(vì m==M(cả hai 3) → R%1==0( 1001.0không có giá trị thập phân) → (int)R/10%10<1( (int)1001.0/10trở thành 100→ 100%10<1) → "1001".length()>m( 4>3) → "1001".length()-q<=1( 4-3<=1) → vì vậy mtrở thành độ dài của phần nguyên "1001"( 4))
3.839*4 = 15.356& m=1,q=1stay m=1(vì m==M(cả hai 1) → R%1!=0( 15.356có giá trị thập phân) → R<=99→ R%10!=0( 15.356%10==5.356) → m!=0→ vì vậy mgiữ nguyên ( 1))
4*7*3 = 84.0& m=1,q=1stay m=1(vì m==M(cả hai 1) → R%1==0( 84.0không có giá trị thập phân) → (int)R/10%10>=1( (int)84/10trở thành 8→ 8%10>=1) → R<=99→ R%10!=0( 84%10==4) → m!=0→ vì vậy mgiữ nguyên ( 1))
6.0+4.0 = 10.0& m=2,q=2trở thành m=3(vì m!=M( m=2, M=1) → R<=99→ R%10==0( 10%10==0) → vì vậy mtrở thành độ dài của tổng R(trừ dấu chấm) "10.0".length()-1( 3))
0-8.8 = -8.8& m=0,q=1trở thành m=1(vì m!=M( m=0, M=1) → R<=99→ R%10!=0( -8.8%10==-8.8) → m<1→ vì vậy mtrở thành 1)
501*2.0 = 1001.0& m=3,q=2trở thành m=2(vì m==M(cả hai 3) → R%1==0( 1001.0không có giá trị thập phân) → (int)R/10%10<1( (int)1001.0/10trở thành 100→ 100%10<1) → "1001".length()>m( 4>3) → "1001".length()-q>1( 4-2>1) → vì vậy mtrở thành q( 2))
R=new BigDecimal(R).round(new MathContext((R<0?-R:R)<1?m-1:m)).doubleValue();
Bây giờ Rđược làm tròn dựa trên m.
1001.0& m=4trở thành1001.0
0.258& m=3trở thành 0.26(bởi vì abs(R)<1, m-1( 2) thay vì m=3được sử dụng bên trong MathContext)
-8.8& m=1trở thành-9.0
1002.0& m=2trở thành1000.0
m<M&(p=Math.pow(10,M-m))/10>R?(int)(R/p)*p:R;
Điều này sửa đổi phần nguyên Rnếu cần thiết.
300.+1-300. = 1.0& m=3,M=3stay 1.0(vì m>=M→ vì vậy Rgiữ nguyên ( 1.0))
0.4*10 = 4.0& m=1,M=2ở lại 4.0(vì m<M→ (10^(M-m))/10<=R( (10^1)/10<=4.0→ 10/10<=4.0→ 1<=4.0) → vì vậy Rgiữ nguyên ( 4.0))
300+1-300 = 1.0& m=1,M=3trở thành 0.0(vì m<M→ (10^(M-m))/10>R( (10^2)/10>1.0→ 100/10>1.0→ 10>1.0) → vì vậy Rtrở thành 0.0vì 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`
Cái này đặt Rthành rString và sửa đổi nó dựa trên nhiều yếu tố.
1203.0& m=4,k=2trở thành 1203.(vì k>=1→ vì vậy rtrở thành 1001.000; r.length()>=m( 8>=4) → r.contains(".")→ r.length()>=m( 8>=4) → chuỗi con từ chỉ mục 0đến m+1( 5))
6.9& m=2,k=2stay 6.9(vì k>=1→ vì vậy rtrở thành 6.900; r.length()>=m( 5>=2) → r.contains(".")→ r.length()>=m( 5>=2) → chuỗi con từ chỉ mục 0đến m+1( 3))
1.0& m=3,k=0trở thành 1(vì k<1→ vì vậy rtrở thành 1; r.length()<m( 1<3) → chuỗi con từ chỉ mục 0đến r.length()( 1))
25.0& m=4,k=4trở thành 25.00(vì k>=1→ vì vậy rtrở thành 25.00000; r.length()>=m( 8>=4) → r.contains(".")→ r.length()>+m( 8>=4) → chuỗi con từ chỉ mục 0đến m+1( 5))
0& m=1,k=0stay 0(vì k<1→ so rstay 0; r.length()>=m( 1>=1) → !r.contains(".")→ chuỗi con từ chỉ mục 0đến m( 1))
for(i=r.length();i++<l;)
r+=0;
Điều này đặt các số 0 ở cuối một lần nữa trở lại phần nguyên nếu cần thiết.
r="12"& R=1200.0trở thànhr="1200"
r="1"& R=10.0trở thànhr="10"
r="8"& R=80.0trở thànhr="80"
return r.replaceAll(z+"$","");
Và cuối cùng chúng tôi trả lại kết quả, sau khi chúng tôi xóa bất kỳ dấu chấm nào.
1203. trở thành 1203
5. trở thành 5
Chắc chắn có thể bị đánh gôn bởi vài trăm byte, nhưng tôi rất vui vì giờ nó đã hoạt động. Phải mất một thời gian để hiểu từng trường hợp và những gì được hỏi trong thử thách. Và sau đó phải mất rất nhiều thử và sai, thử nghiệm và kiểm tra lại để có kết quả như trên. Và trong khi viết lời giải thích này ở trên, tôi đã có thể loại bỏ ± 50 byte mã không sử dụng khác ..
999 + 2.00.