高尔夫球场


28

在这个挑战中,您的任务是摄取阴离子和阳离子,并输出化合物的化学式。输入遵循以下规则:

  • 取在2个字符串(以任何顺序)表示的阴离子和阳离子,例如FNH_4,或Al
  • 要接受每个离子的电荷,可以将其作为插入符号(例如F^-1)分隔的字符串的一部分,也可以接受其他数字参数。
    • 注意:只要您的数字输入类型是带符号的,阴离子的电荷就会作为负数传递。
  • 这些符号将始终是真实的,并且收费准确。

输出应遵循以下规则:

  • 使用_了标:铁2 Ø 3Fe_2O_3
  • 阳离子优先:NaCl,而不是ClNa。
  • 中性分子:李2 O,不是LIO或LIO -
  • 可能的最低系数:Fe 2 O 3,而不是Fe 4 O 6
  • 没有下标的:NaCl,不是Na 1 Cl 1
  • 没有移位:NH 4 OH,NH未5 O.
  • 条件括号:
    • 不要在单原子离子上使用括号:MgCl 2,而不是Mg(Cl)2
    • 如果每个分子中只有一个离子:KClO 3,而不是K(ClO 3),请不要使用括号。
    • 如果有两个或多个多原子离子,请使用括号:Be 3(PO 42,不是Be 3 PO 4 2或Be 3 P 2 O 8

以下是一些其他示例输入和输出:

Input               Output
Fe^+3, O^-2         Fe_2O_3
Fe^+2, O^-2         FeO
H^+1, SO_4^-2       H_2SO_4
Al^+3, SO_4^-2      Al_2(SO_4)_3
NH_4^+1, SO_4^-2    (NH_4)_2SO_4
Hg_2^+2, PO_4^-3    (Hg_2)_3(PO_4)_2
NH_4^+1, OH^-1      NH_4OH
Hg_2^+2, O_2^-2     Hg_2O_2

由于这是,因此以字节为单位的最短答案会获胜。


3
推荐的测试用例:Fe^+2, OH^-1: Fe(OH)_2对于每个元素(OH^-1)中有1个的多原子离子。
pizzapant184 '17

1
@Adám第二离子带电:NO_3^-1。同样,另一个测试用例应该是第一个与a配对的测试用例^-2,这样就可以了(C(NH_2)_3)_2...。或者,一个或多个需要离子的情况以方括号开始。
Heimdall

1
@Adám Fe_4(Fe(CN)_6)_3代表普鲁士蓝色。
Colera Su

3
到目前为止,这可能是我在此网站上看到的最有趣的挑战标题,这对于ppcg问题来说已经很多了。感谢您的笑声
osuka_

1
@osuka_您是否在Arqade上看到“杀死家人的最快方法”?还是我的另一个PPCG挑战,“确认光明会”?
Nissa)

Answers:


4

APL(Dyalog)60 59 61字节

+2,因为必须签署收费。

匿名中缀函数。将离子(阴离子,阳离子)列表作为左参数,并将相应电荷的列表作为右参数。

{∊(⍺{⍵∧1<≢⍺∩⎕D,⎕A:1')(',⍺⋄⍺}¨m),¨(ms1)/¨'_',∘⍕¨s←⍵÷⍨∧/⍵}∘|

在线尝试!

{}∘| 函数在哪里,左参数是右参数的大小:

∧/⍵ LCM的收费

⍵÷⍨ 除以那个

s← 存储在s(对于小号 ubscripts)

'_',∘⍕¨ 格式化(字符串化)并在每个前缀前加上下划线

()/ 复制每个字母的对应值,取自:

  s≠1 是s从不同1?(给出1或0)

  m← 存储在m(为 ultiple)

(),¨ 分别在以下内容之前添加:

  ⍺{}¨m 对于每种离子,请使用离子m作为参数调用此函数:

   ⎕D,⎕Ad igits接着大写 lphabet

   ⍺∩ 离子与那个的交集

    计算该字符数

   1< 比这少一个吗?(即我们有多元素离子吗?)

   ⍵∧ 我们需要那个离子的倍数吗?

   : 如果是这样,则:

    ')(',⍺ 把弦放在离子前面

    1⌽ 向左循环旋转一个步骤()在右侧放置)

    其他

     返回未修饰的离子

ε NLIST(扁平化)


6

C,208个 205 175 169字节

argv[1]:阳离子
argv[2]:阴离子
在stdin上带电荷的离子。

#define z(b)for(i=*++v;*++i>95;);printf(b>1?*i?"(%s)_%d":"%s_%d":"%s",*v,b);
main(c,v,d,e,g,h,i)char**v,*i;{scanf("%d%d",&c,&d);for(e=c,h=-d;g=h;e=g)h=e%g;z(-d/e)z(c/e)}

OP指定的离子可以任意顺序给出。
Heimdall

6

视网膜86 80字节

感谢Neil节省了6个字节。

^
(
\^.+
)_$&$*
(1+)(\1|¶.+)+_(\1)+$
$#3$2_$#2
_1$

m)T`()``.+\)$|\(.[a-z]?\)
¶

在线尝试!

输入以换行符分隔(为方便起见,测试套件使用逗号分隔)。

说明

^
(

我们首先(在每个分子前面加一个。在^上匹配线,因为开始m)朝向节目的结束设置多行模式所有前面的阶段。

\^.+
)_$&$*

我们用替换^[-+]n部分)_,然后是的n副本1(即,将费用转换为一元费用,并删除符号)。

(1+)(\1|¶.+)+_(\1)+$
$#3$2_$#2

此阶段执行三件事:将两个费用除以其GCD,将其转换回十进制并交换它们。通过匹配最长的正则表达式,可以很容易地在正则表达式中找到GCD,1+这使我们仅使用后向引用即可匹配两个电荷\1。为此,我们利用Retina的“捕获计数”功能,该功能告诉我们使用组的频率。因此$#2,第一笔费用除以GCD,$#3第二笔费用除以GCD(均为十进制)。

_1$

我们_1从两个部分的末端删除。

m)T`()``.+\)$|\(.[a-z]?\)

我们从以a结尾的行)(即那些有a的行_1)以及仅包含单个原子的行中删除括号。

最后,我们通过删除换行来连接两个分子。


3

Haskell101 97字节

(s#t)n m|let x#i|j<-div(lcm n m)i=l$x:[l(x:['(':x++")"|l x<':'])++'_':show j|j>1]=s#n++t#m
l=last

在线尝试!用法示例:Fe^+3, O^-2作为("Fe"#"O")3 2



2

Python 3,129字节

lambda E,e,I,i,m=lambda e,i:(len(e)>2<=i)*"("+e+(len(e)>2<=i)*")"+"_%d"%i*(i>1):m(E,i/gcd(i,I))+m(e,I/gcd(i,I))
from math import*

在线尝试!


如果我们需要处理阴离子的负电荷,则需要153个字节:

lambda E,e,I,i,a=abs,m=lambda e,i:(len(e)>2<=i)*"("+e+(len(e)>2<=i)*")"+"_%d"%i*(i>1):m(E,a(i)/gcd(a(i),a(I)))+m(e,a(I)/gcd(a(i),a(I)))
from math import*

在线尝试!


2

RPL(HP48 S / SX),294.5字节

是的,提交的内容非常荒谬,不确定其竞争力如何...

DIR
  M
    « S ROT S SWAP ABS 4 PICK ABS
      DUP2 WHILE DUP2 REPEAT MOD SWAP END DROP2
      SWAP OVER / 4 ROLL J 3 ROLLD / ROT J
      ROT 0 > IF THEN SWAP END + »
  S
    « DUP "^" POS DUP2 1 + OVER SIZE SUB OBJ🡢
      3 ROLLD 1 - 1 SWAP SUB »
  J
    IF OVER 1 ==
    THEN SWAP DROP
    ELSE DUP SIZE DUP2 DUP SUB "Z" > - 1 >
      IF
      THEN "(" SWAP + ")" +
      END
      "_" + SWAP +
    END
END

3个例程整齐地打包在一个目录中。M是主要的。它期望堆栈上的2个字符串格式化为离子,然后将一个分子字符串推入堆栈。

S将离子分解为一个数字电荷,将元素公式分解为一个字符串。例如,"PO_4^-3"将从堆栈中取出-3"PO_4"推入堆栈。

J将离子数与公式结合在一起,并确定是否将公式包装在方括号中。前一个位ELSE处理1个离子,使字符串保持原样。例如,如果1"PO_4"在堆栈上,则将它们替换为"PO_4"1"H""H"

其余的处理多种离子。如果是单个原子,则不在括号内,否则为括号。要确定是否为,我检查字符串的长度并检查最后一个字符是否为>"Z"。布尔表达式返回1表示true,0表示false。通过从字符串的长度中减去此比较的结果,当它是单个原子时,我得到1或更少,否则,更多:长度1是单个原子;长度2将以字母作为最后一个字符;对于单个原子,它是小写字母,因此>"Z",结果为1,否则为2;长度为3种或更多个手段多于1个原子并与来自长度结果将是至少2。例如,减去0或1 3"PO_4"给出"(PO_4)_3"3"Al""Al_3"

M首先使用分裂每个离子S。在第一行之后,堆栈的级别5(因此最深的埋藏对象)包含第二离子的电荷,级别4的第二离子的公式,级别3的第一离子的公式,级别2的第一离子的绝对值和级别1的绝对值第二个离子的电荷 例如,如果在堆栈上给定的离子是"Al^+3""SO_4^-2"我们得到-2"SO_4""Al"32

第二行计算2种电荷的gcd(保持电荷不变)。

第三行将每个电荷除以gcd(以计算倍数),然后使用将其与离子的公式结合J。因此,我们有两根弦,每根弦都除去了一个给定的离子(或其倍数),而第二根电荷埋在了它们的后面。例如,-2"Al_2""(SO_4)_3"(-2是电荷SO_4的)。

第四行消除电荷,如果为正,则在连接它们之前交换两个字符串(使阳离子优先出现)。因此,在上面的示例中,由于它为负数,因此按如下顺序加入它们:"Al_2(SO_4)_3"


1

JavaScript,145个字节

(c,a,p,n,g=(a,b)=>b?g(b,a%b):a)=>`(${c})_${n/-g(p,-n)}(${a})_${p/g(p,-n)}`.replace(/\(((\w+)\)(?=_1)|([A-Z][a-z]*)\))/g,"$2$3").replace(/_1/g,"")

争辩c是阳离子,a是阴离子,p是正电荷,n是负电荷。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.