El químico loco y el programador inteligente

12

Trasfondo

Te despiertas mareado en un laboratorio de química y te das cuenta de que te ha secuestrado un viejo químico loco. Como no puede ver muy bien debido a su edad, quiere que trabajes para él y solo así podrás escapar del laboratorio.

Tarea

Es su tarea devolver las fórmulas estructurales de las moléculas cuya fórmula química se dará como entrada. Tenga en cuenta que solo los átomos de carbono ( C), oxígeno ( O) e hidrógeno ( H) se utilizarán como entrada. A diferencia de las fórmulas químicas, a 0es un cuantificador válido y a 1no se puede omitir (por ejemplo, C1H4O0es una entrada válida, pero CH4no lo es).

Para evitar la ambigüedad, suponemos que los enlaces dobles y triples no aparecen en las moléculas. Todos los átomos de carbono necesitan 4 enlaces simples, todos los átomos de oxígeno necesitan 2 y los átomos de hidrógeno necesitan uno. También asumimos que los O-Obonos no existen también. La molécula no tiene que existir ni ser estable.

La entrada nunca contendrá más que 3átomos de carbono para garantizar la ligereza en la pantalla de salida.

Solo debe mostrar las moléculas cuyos átomos de carbono están dispuestos en línea recta sin interrupción. Ergo, sin C-O-Cataduras.

Debe devolver todas las moléculas posibles no excluidas por las reglas anteriores. No necesita manejar entradas inválidas.

El siguiente ejemplo muestra todas las soluciones que debe manejar para esa molécula.

Una rotación de 180 grados en el plano de la página de una de las fórmulas de la molécula se considera redundante y no es necesario mostrarla.

En el siguiente ejemplo, mostraré todas las fórmulas posibles para una molécula, luego señalaré las que no es necesario mostrar.

Ejemplo

Entrada: C2H6O2

Primero, aquí están todas las fórmulas posibles para esta entrada (Gracias 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

Y aquí están las fórmulas que deberían estar en la salida si sacamos las rotaciones de 180 ° en el plano de la 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

No necesita generar las etiquetas de las fórmulas y puede generar cualquiera de las rotaciones cuando existen dos. Por ejemplo, puede generar 02 o 35.

Aquí hay algunas entradas válidas para probar su código:

C3H8O2 C1H4O0 C2H6O2 C1H4O1 C2H6O2

La PC que el químico le dio para completar su tarea es bastante antigua, por lo que no tiene mucha memoria para guardar su código, por lo tanto, este es el y gana la menor cantidad de bytes.


fuente
¿Necesitamos manejar moléculas cíclicas?
Lucas
@Luke Las entradas que le di no pueden ser cíclicas, por lo que no necesita manejar eso. Pero si desea manejar moléculas que contienen 4 C o más, puede hacerlo y obtener un puntaje de bonificación :) ¡Gracias por la edición por cierto! el inglés no es mi lengua materna ^^
1
Al resultado que ha sugerido le faltan muchas moléculas potenciales: tiene dos copias de propan-1,2-diol allí, pero le faltan al menos propan-1,1-diol, propan-1,3-diol, propan -2,2-diol, una gran cantidad de éteres de alcohol y varios compuestos donde los dos átomos de oxígeno se conectan entre sí. Además, ¿cómo se especifica el formato de salida? Me imagino moléculas en las que algunos de los enlaces necesitan ser estirados más tiempo que otros para que quepan en todo (por ejemplo, dimetilpropano, que aparentemente es un químico real ).
2
1. ¿Es posible tener 2 grupos OH en el mismo carbono? Parece que lo ha excluido de los ejemplos, pero no veo en ninguna parte de la especificación que diga que no tenemos que considerarlo (sé que en realidad estos compuestos existen en equilibrio con aldehídos) 2. ¿Por qué está el HOCH2CH2OH con ambos grupos OH apuntando hacia abajo que faltan en el ejemplo? ¿No es una salida requerida?
Level River St
1
3. ¿Es aceptable tener las salidas con la cadena de carbono vertical en lugar de horizontal?
Level River St

Respuestas:

3

Rubí, 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 cadenas laterales izquierda y derecha y variable eliminada h

Rubí, 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)}}

Sin golf en el programa de prueba

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]

Salida

El espaciado es según el resultado de la pregunta. Backbone vertical en lugar de horizontal permitido por comentarios. Las rotaciones de toda la pantalla a través de 90 o 180 grados se consideran 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
Level River St
fuente