Skip to content

Tavola periodica degli elementi - Codice Golf

Dopo un'ampia raccolta di informazioni, abbiamo risolto questa difficoltà che spesso hanno molti dei nostri lettori. Vi lasciamo la risposta e vogliamo esservi di grande aiuto.

Soluzione:

C, 452

Una buona funzione hash aiuta. Potrebbero essercene di migliori. (Miglioramenti suggeriti da @ugoren et al.)

h;main(c){char*p="Sn)Cu&V$U#Mo#Rf#Sg&Cs#Y+FTa%Rb)S'Nd#GaK&Mg'Zr$PtPm%ReUuo#SmDy(Ac$Lu%W&CaRa(Cf)EuB#Ds%Md$Uus*NpIn$H&YbIr*BeEs*Tc#I(FlRuC#ThSrBh/NaCoLrKr&Nb$CePb$Ne'Am)At*PdLa#Tl%HgMt,CrTbBk$Rh&Rn4TeZn$HfAg%Fm)Xe$AlScFePo$As'HeO#LvN&DbGe#Ho&Mn$Cd+Ni$Rg$HsBr$AuSi#Pr&Uup#Se*Ti#Tm$Er$Sb&PPu&Cm$GdBa'Cn&UutLiFr#Ar#Bi#NoOs%Pa4Cl";while((c=getchar())>64)h=(h+c%32+74)*311%441;while(h)if(*p<65?h-=*p++-34,0:1)for(h--;*++p>96;);do putchar(*p++);while(*p>96);}

Ungolfed con commenti:

int h;
main(c) {

  /* Hashed element symbols. Characters #$% etc. are used as padding: */
  char *p="Sn)Cu&V$U#Mo#Rf#Sg&Cs#Y+FTa%Rb)S'Nd#GaK&Mg'Zr$PtPm%ReUuo#SmDy(Ac$Lu%W&C"
          "aRa(Cf)EuB#Ds%Md$Uus*NpIn$H&YbIr*BeEs*Tc#I(FlRuC#ThSrBh/NaCoLrKr&Nb$CeP"
          "b$Ne'Am)At*PdLa#Tl%HgMt,CrTbBk$Rh&Rn4TeZn$HfAg%Fm)Xe$AlScFePo$As'HeO#Lv"
          "N&DbGe#Ho&Mn$Cd+Ni$Rg$HsBr$AuSi#Pr&Uup#Se*Ti#Tm$Er$Sb&PPu&Cm$GdBa'Cn&Uu"
          "tLiFr#Ar#Bi#NoOs%Pa4Cl";

  /* This hash function gives a unique result for each element: */
  while((c=getchar())>64) h=(h+c%32+74)*311%441;

  /* Find the corresponding position in the hashed data */
  while(h) {
    if(*p<65?h-=*p++-34,0:1) {      /* Step over an abbreviation */
      for(h--;*++p>96;);            /* Skip padding */
    }
  }

  /* Output first uppercase character and all following lowercase characters: */
  do {
    putchar(*p++);
  } while(*p>96);
}

Ho usato la forza bruta per trovare questo hash; è stato l'unico con una dimensione di hash di ≤512 che non ha avuto collisioni. Non ho però controllato le grafie alternative e potrebbero esserci funzioni migliori con algoritmi diversi (per esempio usando XOR invece di addizione).

La funzione hash mappa le stringhe di testo in valori da 0 a 440. "Tin" ha valore zero, quindi "Sn" è all'inizio della tabella. Le 7 posizioni successive sono vuote. Per mantenere il codice compatto, questo è indicato dal valore ASCII 34+7=41 (")"). Seguono "Rame" (8), quattro celle vuote (34+4=38="&") e "Vanadio" (13). Dopo aver calcolato un hash, il programma scorre la tabella sottraendo 1 per ogni lettera maiuscola seguita da 0 o più lettere minuscole e sottraendo (VALORE ASCII)-34 per ogni carattere non alfabetico. Quando il valore raggiunge lo zero, abbiamo trovato il risultato corretto.

CJam, 337297293232220201 200 byte

leu:E2f^3b2+4%_"53N5903CVCT4":i3/=~Ef+b%]53b"gØâ^ÃP·^À4ξ^ß^E5^W^Ma{áª^B¤±´oòæ»^XÊQÑ»4žDÙÝòÙ 0^ÝþKa6^Ó£,Ûkû¥¡ùh^E"256b7b6a/0a3**<)[email protected]/,(" ¬^GH/N¿·%^U^RU1²Bd
òë^м~í^ÌéáU"256b25b'Af+2/='J-'Q/"UU"*)_5=)*E%2

Il codice precedente utilizza la notazione caret, poiché contiene caratteri di controllo.

Al costo di 24 byte aggiuntivi (per un totale di 224), questi caratteri possono essere evitati.

leu:E2f^3b2+4%_"53N5903CVCT4":i3/=~Ef+b%]53b
"' [email protected]]jO4G)=b{[email protected]/oCN)*|BRxvNRL+LO7NI(pLs4[d87$Q%8Rt+' M5JU"
{32f-95b}:B~7b6a/0a3**<)[email protected]/,(
"&y.$h*z^trQPUc]l8F h$=18C^r|vD~S"
B25b'Af+2/='J-'Q/"UU"*)_5=)*E%2

È possibile provare questo codice nell'interprete CJam.

Casi di prova

$ base64 -d > elements.cjam <<< bGV1OkUyZl4zYjIrNCVfIjUzTjU5MDNDVkNUNCI6aTMvPX5FZitiXCVdNTNiImfY4oNQt4A0zr6fBTUXDWF74aoCpLG0b/LmuxjKUdG7NMW+RNnd8tmgMJ3+S2E2k6Ms22v7paH5aAUiMjU2YjdiNmEvMGEzKio8KTVtZEA1YS8sKCIgrAdIL06/tyUVElUxskJkCvLrkLx+7Yzp4VUiMjU2YjI1YidBZisyLz0nSi0nUS8iVVUiKlwpXzU9KSpFJTI8PyhcZWw=
$ cksum elements.cjam 
952664534 200 elements.cjam
$ for e in Carbon NiTROGen Sodium Gold Silver Tin; do LANG=en_US cjam elements.cjam <<< $e; echo; done
C                                                                                                       
N                                                                                                       
Na                                                                                                      
Au                                                                                                      
Ag                                                                                                      
Sn

Come funziona

Il primo passo è leggere il nome dell'elemento da STDIN e applicare una funzione hash piuttosto elaborata, che mappa tutti i nomi degli elementi nell'intervallo [0, 225]:

l eu :E          " Read a line from STDIN, convert to uppercase and save in E.            ";
2 f^             " XOR each character code with 2.                                        ";
3 b              " Convert to integer; consider the resulting array a base 3 number.      ";
2 + 4 %          " Add 2 and take the result modulo 4. Result: R                          ";
"53N5903CVCT4":i " Push [53 51 78 53 57 48 51 67 86 67 84 52].                            ";
3 / =            " Retrieve the chunk of length 3 that corresponds to R. Result: C        ";
~ E f+           " Add C[2] to all character codes of E.                                  ";
b                " Convert to integer; consider the resulting array a base C[1] number.   ";
 %              " Take the integer modulo C[0]. Result: M                                ";
] 53 b           " Push H := 53 * R + M.                                                  ";

Molti simboli di elementi sono formati dal primo e dal secondo, dal primo e dal terzo, dal primo e dal quarto, dal primo e dal quinto o dal primo e dal decimo (che è solo il primo) carattere del nome inglese dell'elemento. Rappresenteremo questi elementi con i numeri da 0 a 4 rispettivamente. Tutti gli elementi rimanenti (rappresentati da 5) richiederanno una tabella di ricerca.

La tabella risultante può essere spinta come segue:

"gØâ^ÃP·^À4ξ^ß^E5^W^Ma{áª^B¤±´oòæ»^XÊQÑ»4žDÙÝòÙ 0^ÝþKa6^Ó£,Ûkû¥¡ùh^E"256b7b6a/0a3**

La matrice dei codici dei caratteri viene convertita dalla base 256 alla base 7 e i 6 vengono sostituiti da serie di tre 0.

Questa è la tabella decisionale D:

[4 0 0 0 1 0 0 0 0 0 0 3 0 2 0 1 0 0 0 0 0 0 0 0 4 1 1 0 0 0 0 2 0 4 0 5 2 0 0 3 4 0 0 0 0 4 0 1 0 0 3 1 0 0 2 1 1 1 0 0 0 1 0 5 5 0 0 2 0 0 0 5 5 0 0 0 5 0 3 0 0 0 0 5 0 0 0 0 0 0 0 0 5 2 3 0 1 0 5 0 4 0 0 0 0 4 0 5 0 0 0 0 0 5 0 0 0 2 5 1 4 1 5 0 0 0 5 0 0 5 1 1 0 0 0 0 0 0 2 0 5 0 0 0 3 1 0 2 0 0 0 2 0 0 0 5 0 0 0 0 1 0 0 0 0 0 4 0 2 2 5 2 0 0 5 1 0 0 0 0 4 0 5 0 0 3 5 0 0 5 0 1 0 0 0 2 0 0 0 0 0 5 0 4 0 0 0 0 0 0 0 0 3 0 4 0 0 1 2 2 0 0 0 0 0]

L'azione necessaria per l'elemento con hash 1 ad esempio, corrisponde al primo elemento di questa matrice. Anche gli elementi della matrice che non corrispondono all'hash di nessun elemento sono nulli, il che consente di eseguire l'azione necessaria per l'elemento (0 0 0) ↦ 6 compressione.

Ora interpretiamo D per l'hash H.

< ) 5 md     " Push D[:H-1] (D[H-1] / 5) (D[H-1] % 5).                                    ";
@ 5a / , (   " Count the number of 5's in D[:H-1] (by splitting at [5]). Result: I        ";

Successivamente, si spinge la tabella di ricerca. Se aggiungiamo j ai simboli a carattere singolo e sostituiamo Uu con Q ogni simbolo sarà lungo esattamente due caratteri. Può essere spinto come segue:

" ¬^GH/N¿·%^U^RU1²Bd
òë^м~í^ÌéáU"256b25b'Af+2/

L'array di codici dei caratteri viene convertito da base 256 a base 25, il codice dei caratteri di A viene aggiunto a tutte le cifre (con il processo di fusione in Carattere) e il risultato viene diviso in parti di lunghezza pari a due.

Questa è la tabella di ricerca L:

["QP" "YB" "PD" "SN" "QO" "QT" "QS" "SB" "KJ" "TM" "FE" "PB" "AU" "WJ" "CN" "SG" "RF" "CM" "CU" "HG" "NA" "RG" "AG"]

Ora si procede a calcolare i nomi potenziali degli elementi.

=                " Push L[I].                                                             ";
'J - 'Q / "UU" * " Remove J's and replace Q's with runs of two U's.                       ";
 ) _ 5 = ) *    " Push S := (D[H-1] % 5 + 1) * ((D[H-1] % 5 + 1 == 5) + 1).              ";
E %              " Push every Sth character of E.                                         ";
2 <              " Discard all but the first two characters.                              ";

La pila ora contiene

B M N

dove B è il valore booleano D[H-1] / 5, M è il nome recuperato dalla tabella di ricerca e N è il nome dell'elemento formato dalla selezione dei caratteri da E.

Abbiamo quasi finito:

?                " If B, push M; else, push N.                                            ";
(               " Extract the first character from the string.                           ";
el               " Convert the rest to lowercase.                                         ";

JavaScript ES6, 690 708 byte

for(n=prompt()[l='toLowerCase'](i=0);!(c='HHeLiBeBCNFNeNaMgAlSiPSClArKCaScTiVCrMnFeCoNiCuZnGaGeAsSeBrKrRbSrYZrNbMoTcRuRhPdAgCdInSnSbTeIXeCsBaLaCePrNdPmSmEuGdTbDyHoErTmYbLuHfTaWReOsIrPtAuHgTlPbBiPoAtRnFrRaAcThPaUNpPuAmCmBkCfEsFmMdNoLrRfDbSgBhHsMtDsRgCnUutFlUupLvUusUuo'.match(x=/[A-Z][a-z]*/g)['HyHeLitBeryBorCarNitFluNeonSoMagAlSiliPhSuChlArgPotCalcScTitVChrManIroCobNicCoppZinGalGeArsSelBrKRubStYttrZirNioMoTecRuthenRhoPaSilvCadInTinAnTelIoXCaeBaLanCePraNeodPromSaEuGadTerDyHoErThuYtteLuHafTaTuRheOsIriPlaGoMerThaLeBiPolAsRadoFrRadiAcThoProtUrNepPluAmCuBerkCaliEiFeMenNoLawRutherDuSeaBohHasMeiDaRoCopeUnuntFleUnunpLivUnunsUnuno'.match(x).map(a=>a[l]()).indexOf(n.slice(0,i++))]);)
alert(c)

Il primo array contiene i simboli e il secondo array contiene le lettere minime necessarie per capire a quale elemento ci si riferisce. Grazie a core1024 e edc65 per averci aiutato ad accorciarlo. Test su http://jsfiddle.net/xjdev4m6/2/. Leggermente più leggibile:

n=prompt().toLowerCase()
e='HyHeLitBeryBorCarNitFluNeonSoMagAlSiliPhSuChlArgPotCalcScTitVChrManIroCobNicCoppZinGalGeArsSelBrKRubStYttrZirNioMoTecRuthenRhoPaSilvCadInTinAnTelIoXCaeBaLanCePraNeodPromSaEuGadTerDyHoErThuYtteLuHafTaTuRheOsIriPlaGoMerThaLeBiPolAsRadoFrRadiAcThoProtUrNepPluAmCuBerkCaliEiFeMenNoLawRutherDuSeaBohHasMeiDaRoCopeUnuntFleUnunpLivUnunsUnuno'.match(x=/[A-Z][a-z]*/g).map(a=>a.toLowerCase())
s='HHeLiBeBCNFNeNaMgAlSiPSClArKCaScTiVCrMnFeCoNiCuZnGaGeAsSeBrKrRbSrYZrNbMoTcRuRhPdAgCdInSnSbTeIXeCsBaLaCePrNdPmSmEuGdTbDyHoErTmYbLuHfTaWReOsIrPtAuHgTlPbBiPoAtRnFrRaAcThPaUNpPuAmCmBkCfEsFmMdNoLrRfDbSgBhHsMtDsRgCnUutFlUupLvUusUuo'.match(x)
for(i=0;i<7;i++){
  if(c=s[e.indexOf(n.slice(0,i))]){
    alert(c,i=8) // i=8 breaks out of the loop so the result is only alerted once
  }
}

Qui puoi vedere le recensioni e le valutazioni dei lettori

Se hai ancora qualche perplessità e capacità di perfezionare la nostra affermazione, puoi fare un riferimento e lo esamineremo volentieri.



Utilizzate il nostro motore di ricerca

Ricerca
Generic filters

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.