整数随着时间的推移来回移动


17

输入:

一个整数。

输出:

  1. 首先将整数转换为等效的罗马数字。
  2. 然后,将该罗马数字的每个大写字母转换为其ASCII / UNICODE十进制值。
  3. 并输出这些总和。

例:

1991 -> MCMXCI -> 77+67+77+88+67+73 -> 449
^ input                                ^ output

罗马数字:
在此处输入图片说明
这是一个可能有用的罗马数字转换器。

挑战规则:

  • 标准的罗马数字规则适用,因此没有其他替代形式 IIIIVIIII替代IVIX*。
  • 罗马数字超过1000的马克龙线是¯(UNICODE nr。175)。因此,一线算作+175,两线算作+350
  • 您可以使用任何类型的输入和输出类型,只要它代表整数即可。
  • 测试用例将在 1 - 2,147,483,647

*罗马数字规则(引自维基百科):

数字是通过组合符号并加上值而形成的,所以II两个(两个)和XIII十三(一个十和三个)也是如此。因为每个数字都有一个固定值,而不是代表10、100等的倍数,所以根据位置,不需要像207或1066这样的“位置保持”零。这些数字写成CCVII(两百,五和二)和MLXVI(一千,五十,十,五和一)。

符号从左到右按值的顺序排列,从最大开始。但是,在某些特定情况下,为避免连续重复四个字符(例如IIIIXXXX),通常按如下方式使用减法表示法:

  • I放在前面VX表示少一,所以四是IV(一小于五)而九是IX(一小于十)
  • X放在前面LC表示减去十,所以四十是XL(十小于五十),九十是XC(十小于一百)
  • C放在前面DM表示少一百个,因此四百个CD(一百个小于五百)和九百个CM(一百个小于一千)
    例如,MCMIV一千零九十四个,1904年(M一千个,CM是九百零四IV)。

现代使用罗马数字的一些例子包括:
1954年为MCMLIV;1990年为MCMXC; 2014年作为MMXIV
SOURCE

通用规则:

  • 这是,因此最短答案以字节为单位。
    不要让代码高尔夫球语言阻止您发布使用非代码高尔夫球语言的答案。尝试针对“任何”编程语言提出尽可能短的答案。
  • 适用标准规则于您的答案,因此允许您使用STDIN / STDOUT,具有正确参数的函数/方法,完整程序。你的来电。
  • 默认漏洞是禁止的。
  • 如果可能的话,请添加一个带有测试代码的链接。
  • 另外,如有必要,请添加说明。

测试用例:

100          ->   67
1            ->   73
4            ->   159
22           ->   322
5000         ->   261
2016         ->   401
1000000000   ->   427
1991         ->   449
9999         ->   800
1111111111   ->   2344
2147483647   ->   5362


1
@马丁9999- > M(X)CMXCIX- > 77+263+67+77+88+67+73+88- > 8002147483647- > ((MMCXLV)MMCDLXXX)MMMDCXLVII- > 427+427+417+438+426+436 + 252+252+242+243+251+263+263+263 + 77+77+77+68+67+88+76+86+73+73- > 5362。因此,我已经纠正了第二个问题,但是9999正确。
凯文·克鲁伊森

1
测试用例2222222222不在给定范围内。我也同意5362
尼尔

1
标题听起来有点像Stack Overflow C问题。
user6245072'8

3
标题中的“第四”是双关语吗?如果不是,则应为“第四”。
Monty Harder

Answers:


4

数学,181 173 166 151字节

打高尔夫球

(q=Select[ToCharacterCode@#,64<#<99&]&/@StringSplit[RomanNumeral[#],"_"];p=PadLeft;l=Length;Total[p[q,4]+p[{350,350*Mod[l@q,2],175,0}[[-l@q;;]],4],2])&

不打高尔夫球

(
q = Select[
     ToCharacterCode@#,
     64<#<99&
    ]&/@StringSplit[RomanNumeral@#,"_"];
p=PadLeft;
l=Length;
Total[
   p[q,4]+
   p[{350,350*Mod[l@q,2],175,0}[[-l@q;;]],4]
   ,2]
)&

Mathematica的 RomanNumeral实现给出(IX)CMXCIX为9999,因此程序对该数字返回971。

如所写,类型((...))(...)...的罗马数字返回长度为4((...))的罗马数字的ASCII代码嵌套列表。返回一个长度为3的列表,(...)...返回一个长度为2的列表,...返回一个长度为1的列表。最后一行将这些规则转换为适合每个长度的宏数列表,将这些宏添加到其中,然后对整个嵌套列表求和,以返回输出。


1
欢迎来到PPCG!
betseg '16

@betseg谢谢!这是一个有趣的第一个问题。
HiggstonRainbird '16

10

Python 3中,281 278 273 269字节

我在codegolf的第一次尝试,现在就开始。试图做到这一点而没有查看链接的问题,所以它可能很糟糕:)

def f(n):d=len(str(n))-1;l=10**d;return 0if n<1else(n<l*4and[73,88,67,77,263,242,252,438,417,427][d]+f(n-l))or(l<=n//9and[161,155,144,340,505,494,690,855,844][d]+f(n-9*l))or(n<l*5and[159,164,135,338,514,485,688,864,835][d]+f(n-4*l))or[86,76,68][d%3]+(d//3*175)+f(n-5*l)

多亏了GáborFekete,小了8个字节

取消高尔夫:

def f(n):
d = len(str(n)) - 1 # number of digits minus one
l = 10 ** d         # largest power of 10 that is not larger than parameter
if n == 0:
    return 0
elif n < 4 * l: # starts with X, C, M, ...
    return [
        ord('I'),
        ord('X'),
        ord('C'),
        ord('M'),
        ord('X') + 175, 
        ord('C') + 175, 
        ord('M') + 175, 
        ord('X') + 350, 
        ord('C') + 350, 
        ord('M') + 350
    ][d] + f(n - l)
elif n // 9 * 10 >= 10 * l: # starts with IX, XC, ...
    return [
        ord('I') + ord('X'), 
        ord('X') + ord('C'), 
        ord('C') + ord('M'),
        ord('M') + ord('X') + 175,
        ord('X') + ord('C') + 350,
        ord('C') + ord('M') + 350,
        ord('M') + ord('X') + 525,
        ord('X') + ord('C') + 700,
        ord('C') + ord('M') + 700
    ][d] + f(n - 9*l)
elif n < 5 * l: # starts with IV, XL, CD, ... 
    return [
        ord('I') + ord('V'),
        ord('X') + ord('L'),
        ord('C') + ord('D'),
        ord('M') + ord('V') + 175,
        ord('X') + ord('L') + 350,
        ord('C') + ord('D') + 350,
        ord('M') + ord('V') + 525,
        ord('X') + ord('L') + 700,
        ord('C') + ord('D') + 700
    ][d] + f(n - 4 * l)
else: # starts with V, L, D, ...
    return [
        ord('V'), 
        ord('L'), 
        ord('D'),
        ord('V') + 175, 
        ord('L') + 175, 
        ord('D') + 175,
        ord('V') + 350, 
        ord('L') + 350, 
        ord('D') + 350
    ][d] + f(n - 5 * l)

您可以打高尔夫球更换一些字节return 0 if n==0 elsereturn 0if n<1else
的Gabor菲克特

f函数名称为时,您的高尔夫球版本中有调用g
加博尔·费克特(GáborFekete)

更改n//9*10>=10*ln//9>=l保存更多内容。
加博尔·费克特(GáborFekete)

固定的功能名称,我更改了它以检查是否正确打了高尔夫球,却忘记将其改回。
jDomantas '16


3

Mathematica,198个字节

Tr[Tr@Flatten[ToCharacterCode/@#]+Length@#*Tr@#2&@@#&/@Partition[Join[SplitBy[Select[Characters@#/."\&"->1,MemberQ[Join["A"~CharacterRange~"Z",{1}],#]&],LetterQ]/. 1->175,{{0}}],2]]&@RomanNumeral@#&

不幸的是,尽管我敢肯定内置的功能可以用得更多,但内置的功能并没有多大帮助。

注意:9999 -> 971根据此处进行评估。


2

批处理,373字节

@echo off
set/an=%1,t=0,p=1
call:l 73 159 86 161
call:l 88 164 76 155
call:l 67 135 68 144
call:l 77 338 261 340
call:l 263 514 251 505
call:l 242 485 243 494
call:l 252 688 436 690
call:l 438 864 426 855
call:l 417 835 418 844
call:l 427 0 0 0
echo %t%
exit/b
:l
set/ad=n/p%%10,p*=10,c=d+7^>^>4,d-=9*c,t+=%4*c,c=d+3^>^>3,d-=5*c,t+=%3*c+%2*(d^>^>2)+%1*(d^&3)

通过根据用于值1,4,5个9使用查找表转换所述数的每个数字作品M(V)M(X)(M(V))(M(X))。如果你喜欢(IV)(IX)((IV))((IX))再使用call:l 77 509 261 511,并call:l 252 859 436 861分别。


1

JavaScript(ES6),183个字节

f=(n,a=0)=>n<4e3?[256077,230544,128068,102535,25667,23195,12876,10404,2648,2465,1366,1183,329].map((e,i)=>(d=e>>8,c=n/d|0,n-=c*d,r+=c*(e%256+a*-~(i&1))),r=0)|r:f(n/1e3,a+175)+f(n%1e3)

注:不仅喜欢(IV)M(V),但也喜欢(VI)(V)M; 实际上,它只会在数字的开头使用M。


1

Python,263个字节

def g(m):x=0;r=[73,86,88,76,67,68,77,261,263,251,242,243,252,436,438,426,417,418,427,0,0];return sum([b%5%4*r[i+(i*1)]+((b==9)*(r[i+(i*1)]+r[(i+1)*2]))+((b==4)*(r[i+(i*1)]+r[i+1+(i*1)]))+((b in [5,6,7,8])*r[i+1+(i*1)])for i,b in enumerate(map(int,str(m)[::-1]))])

欢迎使用PPCG,不错的第一答案!

1

R,115字节

所以...我发布解决方案是因为我发现这个问题很有趣。我尽了最大努力,因为R具有处理不带包装的罗马数字的能力:您只能在1和之间输入数字3899,如as.roman文档所述

这就是为什么我在循环中在1到之间指定范围来作弊:是output(的长度。 实际上,根据该网站,最长的罗马数字是(14个字符),对应于。11 14foras.roman(3899)MMMDCCCXCIX
MMDCCCLXXXVIII2888

此外,您无法计算length此函数的输出。

a=scan();v=0;for(i in 1:14){v=c(v,as.numeric(charToRaw(substring(as.character(as.roman(a)),1:14,1:14)[i])))};sum(v)

如果有人发现解决上述问题的解决方案,请随时发表评论。


0

Python 3,315个字节

def p(n=int(input()),r=range):return sum([f*g for f,g in zip([abs(((n-4)%5)-1)]+[t for T in zip([((n+10**g)//(10**g*5))%2for g in r(10)],[(n%(10**g*5))//(10**g*4)+max((n%(10**g*5)%(10**g*4)+10**(g-1))//(10**g),0)for g in r(1,10)])for t in T],[73,86,88,76,67,68,77,261,263,251,242,243,252,436,438,426,417,418,427])])

非高尔夫版本:

def p(n=int(input()),r=range):
    return sum([f*g for f,g in zip(
        [abs(((n-4)%5)-1)]+
        [t for T in zip(
            [((n+10**g)//(10**g*5))%2for g in r(10)],
            [(n%(10**g*5))//(10**g*4)+max((n%(10**g*5)%(10**g*4)+10**(g-1))//(10**g),0)for g in r(1,10)]
        )for t in T],
        [73,86,88,76,67,68,77,261,263,251,242,243,252,436,438,426,417,418,427])])

说明: 此版本使用不同的方法,它计算数字中出现罗马数字的次数。

[abs(((n-4)%5)-1)]I罗马数字中s 的数量。

[((n+10**g)//(10**g*5))%2for g in r(10)]是数字中的V,L,D,(V),(L),(D),((V)),((L)),((D))s数。

[(n%(10**g*5))//(10**g*4)+max((n%(10**g*5)%(10**g*4)+10**(g-1))//(10**g),0)for g in r(1,10)]是数字X,C,M,(X),(C),(M),((X)),((C)),((M))中的数字。

然后,将出现的内容与字符的值相乘并返回其总和。

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.