Szalony chemik i sprytny programista

12

Historia

Budzisz się z zawrotami głowy w laboratorium chemicznym i zdajesz sobie sprawę, że zostałeś porwany przez starego szalonego chemika. Ponieważ nie widzi bardzo dobrze ze względu na swój wiek, chce, abyś dla niego pracował i tylko wtedy możesz uciec z laboratorium.

Zadanie

Twoim zadaniem jest zwrócenie wzorów strukturalnych cząsteczek, których wzór chemiczny zostanie podany jako dane wejściowe. Należy pamiętać, że tylko atomy węgla ( C), tlenu ( O) i wodoru ( H) zostaną użyte jako wsad. W przeciwieństwie do wzorów chemicznych, a 0jest poprawnym kwantyfikatorem i 1nie można go pominąć (np. C1H4O0Jest poprawnym wejściem, ale CH4nie jest).

Aby zapobiec dwuznaczności, zakładamy, że podwójne i potrójne wiązania nie pojawiają się w cząsteczkach. Wszystkie atomy węgla potrzebują 4 pojedynczych wiązań, wszystkie atomy tlenu potrzebują 2, a atomy wodoru potrzebują jednego. Zakładamy również, że O-Oobligacje również nie istnieją. Cząsteczka nie musi istnieć ani być stabilna.

Wejście nigdy nie będzie zawierać więcej niż 3atomy węgla, aby zapewnić lekkość na wyświetlaczu wyjścia.

Powinieneś wyświetlać tylko te cząsteczki, których atomy węgla są ułożone w linii prostej bez zakłóceń. Ergo, bez C-O-Cobligacji.

Musisz zwrócić wszystkie możliwe cząsteczki, których nie wykluczają poprzednie zasady. Nie musisz obsługiwać nieprawidłowych danych wejściowych.

Poniższy przykład pokazuje wszystkie rozwiązania, z którymi musisz sobie poradzić dla tej cząsteczki.

Obrót o 180 stopni w płaszczyźnie strony jednego ze wzorów cząsteczki jest uważany za redundancję i nie musi być wyświetlany.

W poniższym przykładzie pokażę wszystkie możliwe formuły dla cząsteczki, a następnie wskażę te, które nie muszą być wyświetlane.

Przykład

Wejście: C2H6O2

Po pierwsze, oto wszystkie możliwe formuły dla tego wkładu (dziękuję @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

A oto wzory, które powinny znaleźć się na wyjściu, jeśli weźmiemy obrót o 180 ° w płaszczyźnie strony:

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

Nie musisz generować etykiet formuł i możesz wygenerować jeden z obrotów, jeśli istnieją dwa. Na przykład możesz wyprowadzić albo 02 albo 35.

Oto kilka poprawnych danych wejściowych do testowania kodu:

C3H8O2 C1H4O0 C2H6O2 C1H4O1 C2H6O2

Komputer, który dał ci chemik do wykonania zadania, jest dość stary, więc nie masz na nim dużo pamięci do zapisania kodu, więc jest to i najmniejsza ilość bajtów wygrywa!


źródło
Czy musimy obsługiwać cząsteczki cykliczne?
Łukasza
@Luke Podane przeze mnie dane wejściowe nie mogą być cykliczne, więc nie musisz tego robić. Ale jeśli chcesz poradzić sobie z cząsteczkami zawierającymi 4 C lub więcej, możesz to zrobić i zdobyć dodatkowy wynik :) Nawiasem mówiąc, dziękuję za edycję! angielski nie jest moim ojczystym językiem ^^
1
Sugerowana produkcja nie zawiera wielu potencjalnych cząsteczek: masz tam dwie kopie propan-1,2-diolu, ale brakuje przynajmniej propan-1,1-diolu, propan-1,3-diolu, propanu -2,2-diol, duża liczba eterów alkoholowych i różne związki, w których dwa atomy tlenu łączą się ze sobą. Ponadto, jak określony jest format wyjściowy? Mogę sobie wyobrazić cząsteczki, w których niektóre wiązania muszą zostać narysowane dłużej niż inne, aby dopasować wszystko (np. Dimetylopropan, który najwyraźniej jest prawdziwą substancją chemiczną ).
2
1. Czy możliwe jest posiadanie 2 grup OH na tym samym węglu? Wydaje się, że wykluczyłeś to z przykładów, ale nigdzie nie widzę w specyfikacji, która mówi, że nie musimy tego brać pod uwagę (wiem, że w rzeczywistości związki te istnieją w równowadze z aldehydami). 2. Dlaczego HOCH2CH2OH z brakuje obu grup OH wskazujących w dół na przykład? Czy to nie jest wymagane wyjście?
Level River St
1
3. Czy dopuszczalne jest, aby wyjścia z łańcuchem węglowym były pionowe, a nie poziome?
Level River St

Odpowiedzi:

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)}}

Połączone formuły dla lewych i prawych łańcuchów bocznych i zmienna wyeliminowana 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)}}

Niegolfowany w programie testowym

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]

Wynik

Odstępy są zgodne z wynikiem zapytania. Szkielet pionowy zamiast poziomy dozwolony na komentarze. Obracanie całego wyświetlacza o 90 lub 180 stopni uważa się za równoważne.

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
źródło
Fajnie, uruchomię go, kiedy wrócę do komputera :)