불포화도


11

불포화도

이것은 특히 어려운 코드 퍼즐은 아니지만 여러 가지 방법으로 해결하는 데 관심이 있습니다.

불포화도는 원자 사이의 이중 화학 결합의 수 및 / 또는 화합물의 고리의 수입니다.

XaYbZc 형태의 화합물의 분자식이 제공됩니다 (여기서 a, b 및 c는 화합물의 X, Y 또는 Z의 원자 수임) 주기율표에서 (C, H, N, F, Cl, Br 이외의 원소는 공식에 포함되지 않기 때문에 무시 될 수 있음). 화합물은 하나 이상의 탄소 원자를 함유 할 것이다. 불포화도를 계산하고 표시해야합니다.

예를 들어, 화합물 벤젠 (아래 그림)은 3 개의 이중 결합 (원자 사이에 이중 선으로 표시됨)과 단일 고리 (루프에 연결된 많은 원자)를 가지므로 DoU가 4입니다.

벤젠 고리

LibreTexts에 의해 정의 된 대로 :

DoU = (2C + 2 + N-X-H) / 2

어디:

  • C 탄소 원자의 수
  • N 질소 원자의 수
  • X 할로겐 원자의 수 ( F, Cl, Br, I)
  • H 수소 원자의 수

테스트 사례 :

C6H6 --> 4
C9H2O1 --> 0
C9H9N1O4 --> 6
U1Pt1 --> Not a valid input, no carbon
Na2O1 --> Not a valid input, no carbon
C1H1 --> 1.5, although in practice this would be one, but is a part of a compound rather than a compound in entirety. 
N1H3 would return 0 - though in practice it isn't an organic compound (in other words it contains no carbon) so the formula wouldn't apply and it isn't a valid input

CH에 대한 설명 은 여기를 참조하십시오

본질적으로, 화합물에 상기 원소들 (C, H, N, F, Cl, Br, I) 중 어느 것이 있는지, 그리고 얼마나 많은지 식별해야합니다. 그런 다음 위 공식을 사용하여 불포화도를 계산하십시오.

C, H, N, F, Cl, Br 및 I 만 DoU 수식에 유효한 입력입니다. 이 퍼즐의 목적 상, 다른 원소는 완전히 무시 될 수 있습니다 (예 : 화합물이 C6H6Mn 인 경우 결과는 여전히 4 임). 위의 화합물이 없으면 답은 0입니다.

투입되는 모든 화합물은 화학적으로 가능하고 하나 이상의 탄소 원자를 함유하며 존재하는 것으로 알려져 있다고 가정 할 수 있습니다. 입력이 유효하지 않으면 프로그램은 0 또는 -1을 출력하거나 결과를 생성하지 않을 수 있습니다.

규칙

표준 IO 규칙허점이 적용됩니다. 입력은 표준 문자열이어야하며 입력이 비어 있지 않다고 가정 할 수 있습니다. 이것은 codegolf이므로 바이트 단위의 가장 짧은 코드가 이깁니다.


제안 된 테스트 사례 : 산화 나트륨 : Na2O및 메틸 리딘 : CHCCl4He. 이것들은 몇 가지 해결책을 깨뜨릴 수있는 코너 사례입니다. 그건 그렇고, Mathematica 이외의 다른 사람에게 (아마도) 중요하지는 않지만 화합물이 존재할 수 있다고 가정 할 수 있습니까?
Stewie Griffin

이해가 안됩니다 C9H2O1 --> 0. 9가 아니어야합니까? (2*9+2+0-0-2)/2
DLosc

마지막 단락에 따르면 코드가 유효하지 않은 입력을 처리 할 수 ​​있어야합니까? 그건 그렇고, 화합물의 모든 단일 원소가 C1H1에서와 같이 후행 '1'을 보장합니까?
Keyu Gan

@KeyuGan 그렇습니다.
Archie Roques

답변:


2

자바 스크립트 (ES6) 117 112 바이트

0유효하지 않은 입력을 반환 합니다.

s=>s.split(/(\d+)/).reduce((p,c,i,a)=>p+[0,k=a[i+1]/2,2*k,-k][n='NCFHIClBr'.search(c||0)+1,s|=n==2,n>2?3:n],1)*s

테스트 사례

대체 버전, 103 바이트

챌린지 소개에서 잘못 제안한대로 입력이 유효한 것으로 확인 된 경우 다음을 수행 할 수 있습니다.

s=>s.split(/(\d+)/).reduce((p,c,i,a)=>p+[0,k=a[i+1]/2,2*k,-k][n='NCFHIClBr'.search(c||0)+1,n>2?3:n],1)

데모


2

파이썬 (3) , 142 (151) 148 바이트

import re
l=dict(re.findall("(\D+)(\d+)",input()))
m=lambda k:int(l.get(k,0))
print(m("C")and m("C")+1+(m("N")-sum(map(m,"F I H Cl Br".split())))/2)

오류가 발생하면 0을 반환합니다.

@HyperNeutrino 덕분에 바이트가 줄었습니다.

온라인으로 사용해보십시오!


죄송합니다-테스트 사례가 업데이트되었습니다!
Archie Roques


@HyperNeutrino 테스트 사례는 불분명했습니다. 이제 유효하지 않은 입력에 대한 출력이 없습니다.
MooseOnTheRocks 2016 년


dict거기의 좋은 사용 !
DLosc

0

, 70 67 바이트

`C\d`Na&1+/2*VaR+XDs._R['C'NC`H|F|I|Cl|Br`].s["+2*"'+'-]RXU.XX"+0*"

화학식을 명령 줄 인수로 사용합니다. 0유효하지 않은 입력에 대한 출력 . 온라인으로 사용해보십시오!

설명

일련의 정규식 대체를 사용하여 화학식을 수학 공식으로 바꾸고이를 회피하고 최종 값을 얻기 위해 몇 가지 조정을합니다.

대체품 (약간 골 판이없는 버전) :

aR+XDs._R"C ""+2*"R"N "'+R`(H|F|I|Cl|Br) `'-RXU.XX"+0*"

a                    Cmdline arg
 R+XD                 Replace runs of 1 or more digits (\d+)
     s._               with a callback function that prepends a space
                       (putting a space between each element and the following number)
 R"C "                Replace carbon symbol
      "+2*"            with +2* (add 2* the number of carbon atoms to the tally)
 R"N "                Replace nitrogen symbol
      '+               with + (add the number of nitrogen atoms to the tally)
 R`(H|F|I|Cl|Br) `    Replace hydrogen or halogen symbol
                  '-   with - (subtract the number of atoms from the tally)
 RXU.XX               Replace uppercase letter followed by another char ([A-Z].)
       "+0*"           with +0* (cancel out numbers of all other kinds of atoms)

결과 문자열을로 평가합니다 V. 이것은 우리에게 제공합니다 2C + N − X − H. 올바른 값을 얻기 위해 다음과 같이 조정합니다.

`C\d`Na&1+/2*V...

             V...  Value of expression calculated above
          /2*      multiplied by 1/2
        1+         plus 1
`C\d`Na            Is carbon in the original formula? (i.e. C followed by a digit)
       &           Logical AND: if no carbon, return 0, otherwise return the formula value

0

C (gcc) , 195197 202 바이트

아마도 가장 긴 대답 일 것입니다.

d,c,b,e,n;f(char*a){for(c=d=0;b=*a;d+=e?e-1?b-66?b-67?0:e-2?0:-n:e-3?0:-n:b-67?b-78?b/70*73/b?-n:0:n:(c=2*n):0)e=*++a>57?*a-108?*a-114?0:3:2:1,a+=e>1,n=strtol(a,&a,10);printf("%.1f",c?d/2.+1:0);}

온라인으로 사용해보십시오!

오류가 발생하면 0을 반환합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.