T-SQL, 1974 - 50 = 1924 bayt
SQL'de golf oynamanın bir kum takozundan başka bir şey olmadan 18 delik oynamaya eşdeğer olduğunu biliyorum, ancak bunun meydan okumasını sevdim ve bence metodolojik olarak birkaç ilginç şey yapmayı başardım.
Bu, giriş ve çıkış için vinculum'u desteklemez. Onu temsil etmek için bir izleyen tilde kullanma kuralını kabul ettim, bu yüzden V ~ 5000, X ~ 10000, vb. Bundan sonra, INT'nin desteklediği aralıktaki herhangi bir şeyin kısmen standart olmayan Roma kodlamasını yapacak.
Tamamen matematik olduğu için, tamsayı olmayan sonuçlar dolaylı olarak yuvarlanır.
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
Hala bayt sayısını azaltabilir ve deyimsel SQL daha zarif bir örnek olabilir WHILE döngü bazı değiştirmek için set tabanlı bir çözüm ile müdahalesi. Ayrıca, tablo diğer adlarının kullanımını en aza indirgeyerek elde edilecek bazı baytlar da vardır. Ancak bu dilde kazanılamayacağı için, çoğunlukla sadece Don Kişot kıyafetimi göstermek için buradayım. :)
Üstteki SELECT @ i girişi tekrarlar:
I+V*IV+IX*MXLVII+X~C~DCCVI
Ve sonunda SEÇ:
SELECT (((((1+5)*4)+9)*1047)+90706) = 125257 = C~X~X~V~CCLVII
Ve bu SQLFiddle'da kendiniz test edebilirsiniz
Ve nasıl çalıştığına dair bazı yorumlar eklemek için geri döneceğim, çünkü eğitim değerinden faydalanmayacaksanız neden açık bir şekilde kaybeden bir cevap yayınlamalısınız?