Xây dựng một quang phổ kế!


8

Thử thách

Cho khối lượng phân tử có độ phân giải cao của một phân tử hữu cơ, tạo ra công thức phân tử của phân tử.

Giải trình

Đầu vào sẽ là một số duy nhất đến ba chữ số chính xác, khối lượng phân tử tương đối của phân tử.

Ở đây, khối lượng phân tử được định nghĩa là tổng khối lượng của các nguyên tử trong hợp chất. Vì bạn chỉ tìm thấy các công thức phân tử của các hợp chất hữu cơ, nên khối lượng nguyên tử bạn cần biết là:

  • C , Carbon: 12.011
  • H , hydro: 1.008
  • Ô , Oxy: 15.999
  • N , Nitơ: 14,007

Công thức của bạn chỉ nên chứa carbon, hydro, oxy hoặc nitơ.

Khi viết công thức, cần có dạng:

CaHbOcNd

Trong trường hợp các yếu tố này phải được theo thứ tự đó ( C -> H -> O -> N, vì vậy C2O8N4H6nên có C2H6O8N4) và a, b, cdlà những con số của phần tử trước đó trong phân tử (tức là C2phương tiện rằng có hai nguyên tử cacbon trong phân tử).

Nếu a, b, choặc dđược không, yếu tố đó không nên được đưa vào công thức (ví dụ C2H6O2N0nên C2H6O2). Cuối cùng, nếu a, b, choặc dlà một, bạn không nên bao gồm các số trong công thức (ví dụ C1H4nên CH4).

Đầu vào sẽ luôn hợp lệ (tức là sẽ có một phân tử có khối lượng đó). Nếu đầu vào không rõ ràng (nhiều phân tử có cùng khối lượng), bạn chỉ phải xuất một trong các phân tử. Làm thế nào bạn chọn phân tử này là tùy thuộc vào bạn.

Ví dụ làm việc

Giả sử đầu vào là 180.156, chỉ có một sự kết hợp của các yếu tố có thể có khối lượng phân tử này:

12.011*6 + 1.008*12 + 15.999*6 + 14.007*0 = 180.156

Vì vậy, có:

  • 6 nguyên tử cacbon
  • 12 hydrogens
  • 6 Oxy
  • 0 Nitrogen

Do đó, đầu ra của bạn phải là:

C6H12O6

Thêm ví dụ

Input -> Output

28.054 -> C2H4
74.079 -> C3H6O2
75.067 -> C2H5O2N
18.015 -> H2O

Chiến thắng

Mã ngắn nhất trong byte thắng.


2
Nếu đầu vào không rõ ràng thì sao?
NoOneIsHãy là

@NoOneIsHãy AFAIK đầu vào không nên mơ hồ, nhưng dù sao tôi cũng sẽ thêm nó vào quy tắc.
Beta Decay

Có thể lấy đầu vào là int (nghĩa là không có giai đoạn - ethene 28054)
Stephen

4
12.011là khối lượng nguyên tử tương đối của carbon, là trung bình có trọng số của khối lượng đồng vị tương đối của các đồng vị. Trong một quang phổ kế, nơi phân biệt các đồng vị khác nhau, bạn sẽ thấy chính xác 12. Tương tự cho các nguyên tử khác.
Leaky Nun

2
Đối với một thử nghiệm thú vị, lưu ý rằng đầu vào 672.336có 24 giải pháp khả thi, bao gồm dung dịch nitơ tinh khiết và dung dịch hydro tinh khiết.
Greg Martin

Câu trả lời:


2

Toán học, 108 byte

Print@@Join@@({Characters@"CHON",#}ᵀ/.a_/;Last@a<2:>Table@@a)&/@{12011,1008,15999,14007}~FrobeniusSolve~#&

Hàm thuần túy mong đợi đầu vào là một số nguyên (gấp 1000 lần khối lượng phân tử tương đối); nó in tất cả các câu trả lời có thể cho STOUD (và trả về một mảng Nulls).

Việc nâng vật nặng được thực hiện bởi nội dung {12011,1008,15999,14007}~FrobeniusSolve~#, tìm thấy tất cả các tổ hợp số nguyên không âm của các trọng số được mã hóa bằng với đầu vào. {Characters@"CHON",#}ᵀđặt mỗi sự kết hợp như vậy trong một hình thức giống như {{"C", 0}, {"H", 1}, {"O", 2}, {"N", 3}}. ( thực ra là ký tự Mathicala riêng 3 byte U + F3C7.)

Các quy tắc chuyển đổi /.a_/;Last@a<2:>Table@@athay đổi cặp của mẫu {x, 0}để {}và cặp của mẫu {x, 1}để {x}(và spits ra lỗi như nó cố gắng để áp dụng cho toàn bộ biểu hiện cũng). Sau đó Print@@Join@@in kết quả ở dạng chính xác, tránh việc phải truyền các số nguyên dưới dạng chuỗi và nối.


Kết quả của 672336 là gì? :)
Beta Decay

Các dường như là ký tự sai. Nên .
Martin Ender

Vâng, phải lựa chọn giữa dễ đọc và dễ cắt / dán.
Greg Martin

2

Python 2 , 242 byte

b=[12011,1008,15999,14007]
def p(m):
 if m in b:x=[0,]*4;x[b.index(m)]=1;return x
 elif m<1:return 0
 else:
  for i in range(4):
   x=p(m-b[i])
   if x:x[i]+=1;return x
  return 0
print''.join(a+`n`*(n>1)for n,a in zip(p(input()),'CHON')if n)

Hãy thử trực tuyến!
Hàm đệ quy, đầu vào là một số nguyên (gấp 1000 lần khối lượng phân tử tương đối) nhờ Stephen S cho ý tưởng


Máy tính của tôi mất 40 segs để lần lượt 672336vào C33H115O3N8với mã sửa đổi này . Nó chứa một bảng tra cứu các lần truy cập / không thể giảm số lượng cuộc gọi đệ quy và tối ưu hóa để đếm một yếu tố nhiều lần (nếu khối lượng đủ cao)


Tại sao 180156thời gian chờ khi tất cả các trường hợp thử nghiệm rất nhanh? (không có bộ nhớ cache)
Beta Decay

@BetaDecay hmm, có thể 18015thay thế?
Rod

Không, 18015H2O, khôngC6H12O6
Beta Decay

1

JavaScript (ES6), 159 158 byte

Không chính xác nhanh ...

w=>[...Array(w**4|0)].some((_,n)=>![12011,1008,15999,14007].reduce((p,c,i)=>p-c*(x[i]=n%w|!(n/=w)),w*1e3,x=[]))&&x.map((v,i)=>('CHON'[i]+v).slice(0,v)).join``

Bản giới thiệu


Phiên bản nhanh hơn, 174 173 byte

w=>[...Array(w**3|0)].some((_,n)=>r=(d=w*1e3-14007*(a=n/w/w%w|0)-15999*(b=n/w%w|0)-12011*(c=n%w|0))%1008|d<0?0:[c,d/1008,b,a])&&r.map((v,i)=>('CHON'[i]+v).slice(0,v)).join``

Tất cả các trường hợp thử nghiệm

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.