T-SQL,1974年-50 = 1924字节
我知道在SQL中打高尔夫球等同于打18个洞,只不过是一个沙坑,但是我很喜欢这个挑战,而且我认为我在方法上做了一些有趣的事情。
这确实为输入和输出提供了支持。我采用了使用尾随波浪号来表示它的约定,因此V〜为5000,X〜为10000,依此类推。根据标准的现代罗马数字用法,它还应该处理高达399,999的输出。之后,它将对INT支持范围内的任何内容进行部分非标准的罗马编码。
因为都是整数运算,所以任何非整数结果都会隐式舍入。
DECLARE @i VARCHAR(MAX)
SET @i='I+V*IV+IX*MXLVII+X~C~DCCVI'
SELECT @i
DECLARE @t TABLE(i INT IDENTITY,n VARCHAR(4),v INT)
DECLARE @u TABLE(n VARCHAR(50),v INT)
DECLARE @o TABLE(n INT IDENTITY,v CHAR(1))
DECLARE @r TABLE(n INT IDENTITY,v INT,r VARCHAR(MAX))
DECLARE @s TABLE(v INT,s VARCHAR(MAX))
DECLARE @p INT,@x VARCHAR(4000)='SELECT ',@j INT=1,@m INT,@y INT,@z VARCHAR(2),@q VARCHAR(50)='+-/*~]%'
INSERT @t(n,v) VALUES('i',1),('iv',4),('v',5),('ix',9),('x',10),('xl',50),('l',50),('xc',90),('c',100),('cd',400),('d',500),('cm',900),('m',1000),('mv~',4000),('v~',5000),('mx~',9000),('x~',10000),('x~l~',40000),('l~',50000),('x~c~',90000),('c~',100000)
INSERT @u VALUES('%i[^i'+@q,-2),('%v[^vi'+@q,-10),('%x[^xvi'+@q,-20),('%l[^lxvi'+@q,-100),('%c[^clxvi'+@q,-200),('%d[^dclxvi'+@q,-1000),('%mx~%',-2010),('%x~l~%',-20060),('%x~c~%',-20110)
WHILE PATINDEX('%[+-/*]%', @i)!=0
BEGIN
SET @p=PATINDEX('%[+-/*]%', @i)
INSERT @o(v) SELECT SUBSTRING(@i,@p,1)
INSERT @r(r) SELECT SUBSTRING(@i,1,@p-1)
SET @i=STUFF(@i,1,@p,'')
END
INSERT @r(r) SELECT @i
UPDATE r SET v=COALESCE(q.v,0) FROM @r r LEFT JOIN (SELECT r.r,SUM(u.v)v FROM @u u JOIN @r r ON r.r LIKE u.n GROUP BY r.r)q ON q.r=r.r
UPDATE r SET v=r.v+q.v FROM @r r JOIN (SELECT r.n,r.r,SUM((LEN(r.r)-LEN(REPLACE(r.r,t.n,REPLICATE(' ',LEN(t.n)-1))))*t.v) v FROM @r r JOIN @t t ON CHARINDEX(t.n,r.r) != 0 AND (LEN(t.n)=1 OR (LEN(t.n)=2 AND RIGHT(t.n,1)='~')) GROUP BY r.n,r.r) q ON q.r=r.r AND q.n = r.n
SELECT @m=MAX(n) FROM @o
SELECT @x=@x+REPLICATE('(',@m)+CAST(v AS VARCHAR) FROM @r WHERE n=1
WHILE @j<=@m
BEGIN
SELECT @x=@x+o.v+CAST(r.v AS VARCHAR)+')'
FROM @o o JOIN @r r ON r.n=o.n+1 WHERE o.n=@j
SET @j=@j+1
END
INSERT @s(v,s) EXEC(@x+',''''')
UPDATE @s SET s=s+CAST(v AS VARCHAR(MAX))+' = '
SET @j=21
WHILE @j>0
BEGIN
SELECT @y=v,@z=n FROM @t WHERE i = @j
WHILE @y<=(SELECT v FROM @s)
BEGIN
UPDATE @s SET v=v-@y,s=s+@z
END
SET @j=@j-1
END
SELECT @x+' = '+UPPER(s) FROM @s
我仍然在修补基于集合的解决方案,以替换一些WHILE循环,这可能会减少字节数,并且是惯用SQL的一个更优雅的示例。通过将表别名的使用减少到最低限度,还可以获得一些字节。但是由于用这种语言基本上无法取胜,所以我主要是在这里炫耀我的唐吉x德服装。:)
顶部的SELECT @i重复输入:
I+V*IV+IX*MXLVII+X~C~DCCVI
最后的SELECT返回:
SELECT (((((1+5)*4)+9)*1047)+90706) = 125257 = C~X~X~V~CCLVII
您可以在此SQLFiddle中自己进行测试
我将返回关于其工作原理的评论,因为如果您不打算将其用于教育价值,为什么还要发布一个明显失败的答案?