O químico louco e o programador inteligente


12

História de fundo

Você acorda tonto em um laboratório de química e percebe que foi sequestrado por um velho químico louco. Como ele não pode ver muito bem por causa de sua idade, ele quer que você trabalhe para ele e só então, você pode escapar do laboratório.

Tarefa

É sua tarefa retornar as fórmulas estruturais das moléculas cuja fórmula química será fornecida como entrada. Observe que apenas os átomos de carbono ( C), oxigênio ( O) e hidrogênio ( H) serão usados ​​como entrada. Diferentemente das fórmulas químicas, a 0é um quantificador válido e a 1não pode ser omitido (por exemplo, C1H4O0é entrada válida, mas CH4não é).

Para evitar ambiguidade, assumimos que ligações duplas e triplas não aparecem nas moléculas. Todos os átomos de carbono precisam de 4 ligações simples, todos os átomos de oxigênio precisam de 2 e os átomos de hidrogênio precisam de uma. Também assumimos que os O-Otítulos também não existem. A molécula não precisa existir nem ser estável.

A entrada nunca conterá mais do que 3átomos de carbono para garantir leveza no visor da saída.

Você só deve exibir as moléculas cujos átomos de carbono estão dispostos em uma linha reta sem interrupção. Portanto, sem C-O-Cvínculos.

Você deve retornar todas as moléculas possíveis não excluídas pelas regras anteriores. Você não precisa lidar com entradas inválidas.

O exemplo a seguir exibe todas as soluções que você precisa manipular para essa molécula.

Uma rotação de 180 graus no plano da página de uma das fórmulas da molécula é considerada redundância e não precisa ser exibida.

No exemplo abaixo, mostrarei todas as fórmulas possíveis para uma molécula e aponto as que não precisam ser exibidas.

Exemplo

Entrada: C2H6O2

Primeiro, aqui estão todas as fórmulas possíveis para essa entrada (obrigado a @ Jonathan Allan)

01        H
          |
          O   H
          |   |
  H - O - C - C - H
          |   |
          H   H

02            H
              |
          H   O
          |   |
  H - O - C - C - H
          |   |
          H   H

03        H   H
          |   |
  H - O - C - C - O - H
          |   |
          H   H

04        H   H
          |   |
  H - O - C - C - H
          |   |
          H   O
              |
              H

05        H   H
          |   |
  H - O - C - C - H
          |   |
          O   H
          |
          H

12        H   H
          |   |
          O   O
          |   |
      H - C - C - H
          |   |
          H   H

13        H
          |
          O   H
          |   |
      H - C - C - O - H
          |   |
          H   H

14        H
          |
          O   H
          |   |
      H - C - C - H
          |   |
          H   O
              |
              H


15        H
          |
          O   H
          |   |
      H - C - C - H
          |   |
          O   H
          |
          H

23            H
              |
          H   O
          |   |
      H - C - C - O - H
          |   |
          H   H

24            H
              |
          H   O
          |   |
      H - C - C - H
          |   |
          H   O
              |
              H

25            H
              |
          H   O
          |   |
      H - C - C - H
          |   |
          O   H
          |
          H

34        H   H
          |   |
      H - C - C - O - H
          |   |
          H   O
              |
              H

35        H   H
          |   |
      H - C - C - O - H
          |   |
          O   H
          |
          H

45        H   H
          |   |
      H - C - C - H
          |   |
          O   O
          |   |
          H   H

E aqui estão as fórmulas que devem estar na saída se fizermos as rotações de 180 ° no plano da página:

01        H
          |
          O   H
          |   |
  H - O - C - C - H
          |   |
          H   H



03        H   H
          |   |
  H - O - C - C - O - H
          |   |
          H   H


12        H   H
          |   |
          O   O
          |   |
      H - C - C - H
          |   |
          H   H

13        H
          |
          O   H
          |   |
      H - C - C - O - H
          |   |
          H   H

14        H
          |
          O   H
          |   |
      H - C - C - H
          |   |
          H   O
              |
              H


 15      H
         |
         O   H      
         |   |
     H - C - C - H
         |   |
         O   H
         |
         H 

23            H
              |
          H   O
          |   |
      H - C - C - O - H
          |   |
          H   H



25            H
              |
          H   O
          |   |
      H - C - C - H
          |   |
          O   H
          |
          H



35        H   H
          |   |
      H - C - C - O - H
          |   |
          O   H
          |
          H

Você não precisa imprimir os rótulos das fórmulas e pode produzir uma das rotações quando existirem duas. Por exemplo, você pode gerar 02 ou 35.

Aqui estão algumas entradas válidas para testar seu código:

C3H8O2 C1H4O0 C2H6O2 C1H4O1 C2H6O2

O PC que o químico lhe forneceu para concluir sua tarefa é bastante antigo, portanto você não tem muita memória para salvar seu código, portanto esse é o e a menor quantidade de bytes ganhos!


Precisamos lidar com moléculas cíclicas?
Lucas

@ Lucas As entradas que eu dei não podem ser cíclicas, então você não precisa lidar com isso. Mas se você quiser lidar com moléculas que contenham 4 C ou mais, você pode fazê-lo e obter pontuação bônus :) Obrigado pela edição, a propósito! english não é minha língua nativa ^^

1
A saída que você sugeriu está faltando muitas moléculas em potencial: você tem duas cópias de propan-1,2-diol lá, mas está faltando pelo menos propan-1,1-diol, propan-1,3-diol, propan -2,2-diol, um grande número de éteres de álcool e vários compostos nos quais os dois átomos de oxigênio se conectam. Além disso, como especificado é o formato de saída? Posso imaginar moléculas nas quais algumas das ligações precisam ser extraídas por mais tempo do que outras para encaixar tudo (por exemplo, dimetilpropano, que aparentemente é um produto químico real ).

2
1. É possível ter 2 grupos OH no mesmo carbono? Parece que você o excluiu dos exemplos, mas não vejo em nenhum lugar na especificação que diga que não precisamos considerá-lo (sei que, na realidade, esses compostos existem em equilíbrio com aldeídos) 2. Por que o HOCH2CH2OH está com ambos os grupos OH apontando para baixo faltando no exemplo? Não é uma saída necessária?
Level River St

1
3. É aceitável ter as saídas com a cadeia de carbono vertical em vez de horizontal?
Level River St

Respostas:


3

Ruby, 275

->s{(k=4<<2*c=s[1].to_i).times{|i|z=" "*8
t=("  H|O|"[i%2*2,4]+"C|"*c+"O|H   "[i>>c&2^2,4]).chars.map{|j|z+j+z}
(c*2).times{|j|t[4+j&-2][j%2*10,7]="    H - O - H    "[[i>>j/2-1&4,-7-(i>>c*2-j/2-1&4)][j%2],7]}
i*(k+1)>>c+1&k-1<i||("%b"%i).sum%16!=s[5].to_i||i%7>c*3||puts(t)}}

Fórmulas combinadas para cadeias laterais esquerda e direita e variável eliminada h

Ruby, 279

->s{(k=1<<h=2+2*c=s[1].to_i).times{|i|t=("  H|O|"[i%2*2,4]+"C|"*c+"O|H   "[i>>c&2^2,4]).chars.map{|j|(z=" "*8)+j+z}
c.times{|j|t[4+j*2][0,7]="    H - O -"[i>>j-1&4,7]
t[4+j*2][10,7]="- O - H    "[i>>h-j-3&4^4,7]}
i*(k+1)>>h/2&k-1<i||("%b"%i).sum%16!=s[5].to_i||i%7>c*3||puts(t)}}

Ungolfed in program program

f=->s{
  (k=1<<h=2+2*c=s[1].to_i).times{|i|                       #c=number of C atoms. h=number of H (calculated)
                                                           #iterate i from 0 to (k=1<<h)-1

  t=("  H|O|"[i%2*2,4]+"C|"*c+"O|H   "[i>>c&2^2,4]).       #compose a backbone string H-C...C-H. Insert O at the top where bit 0 of i set, and O at the bottom where bit c+1 of i set
  chars.map{|j|(z=" "*8)+j+z}                              #convert string to an array of characters, pad each character left and right with 8 spaces

  c.times{|j|t[4+j*2][0,7]="    H - O -"[i>>j-1&4,7]       #overwrite spaces on left with H or HO according to bits 1 up to c
             t[4+j*2][10,7]="- O - H    "[i>>h-j-3&4^4,7]} #overwrite spaces on right with H or OH according to bits h-1 down to c+1

  i*(k+1)>>h/2&k-1<i||                                     #rotate the bits of i by h/2. if this is less than i, do not output the structure (eliminates rotations by 180deg by outputtng the lexically highest)
  ("%b"%i).sum%16!=s[5].to_i||                             #if the number of 1's in i differs from the number of O's indicated in the input, do not output
  i%7>c*3||                                                #if i%7>c*3, do not output (empirical solution to avoid 90deg rotations for C=1)
  puts(t)                                                  #if the above are all false, output the current structure.
  }
}

f[gets]

Resultado

O espaçamento é de acordo com a saída da pergunta. Backbone vertical em vez de horizontal permitido por comentários. Rotações de toda a tela em 90 ou 180 graus são consideradas equivalentes.

C2H6O2
        H
        |
        O
        |
H - O - C - H
        |
    H - C - H
        |
        H



        H
        |
        O
        |
    H - C - H
        |
H - O - C - H
        |
        H





        H
        |
H - O - C - H
        |
H - O - C - H
        |
        H



        H
        |
        O
        |
    H - C - H
        |
    H - C - H
        |
        O
        |
        H



        H
        |
H - O - C - H
        |
    H - C - H
        |
        O
        |
        H



        H
        |
    H - C - H
        |
H - O - C - H
        |
        O
        |
        H



        H
        |
H - O - C - H
        |
    H - C - O - H
        |
        H





        H
        |
    H - C - H
        |
H - O - C - O - H
        |
        H





        H
        |
    H - C - O - H
        |
H - O - C - H
        |
        H

Bom eu vou executá-lo quando eu voltar para o meu computador :)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.