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
バイトカウントを減らし、慣用的なSQLのよりエレガントな例になる可能性のあるWHILEループの一部を置き換えるためのセットベースのソリューションをいじっています。また、テーブルエイリアスの使用を最小限に抑えることで得られるバイトもいくつかあります。しかし、この言語では基本的に勝てないので、私はほとんどここにいるだけで、ドン・キホーテの衣装を誇示します。:)
上部の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で自分でテストできます
そして、私はそれがどのように機能するかについてのコメントを追加するために戻ってきます。なぜなら、あなたが教育的価値のためにそれを悪用するつもりがないのに、明らかに失った答えを投稿するからです。