Ціле число йде назад і назад через час


17

Вхід:

Ціле число.

Вихід:

  1. Спочатку перетворіть ціле число в його еквівалентний римський число.
  2. Потім перетворіть кожну велику літеру цього римського числа в їх десятичне значення ASCII / UNICODE.
  3. І виведіть суму цих.

Приклад:

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

Римські цифри: Ось, можливо, корисний перетворювач римських чисел .
введіть тут опис зображення

Правила виклику:

  • Застосовуються стандартні римські чисельні правила, тому немає альтернативних форм на зразок IIIIабо VIIIIзамість IVі IX. *
  • Лінії Макрона над римськими цифрами минулої тисячі є ¯(UNICODE № 175). Отже, один рядок вважається як, +175а два як +350.
  • Вам дозволяється використовувати будь-який тип вводу та виводу, якщо вони представляють цілі числа.
  • Тестові випадки будуть в діапазоні 1 - 2,147,483,647.

* Римські чисельні правила (цитата з Вікіпедії):

Числа утворюються комбінуванням символів та додаванням значень, тому IIдва (два) і XIIIтринадцять (десять і три). Оскільки кожна цифра має фіксоване значення, а не представляє кратні десять, сто тощо, відповідно до позиції, немає необхідності в "нумерації місце" нулів, як у числах, як 207 або 1066; ці числа записуються якCCVII (дві сотні, п’ять і дві) і MLXVI(тисяча, п'ятдесят, десять, п’ять і одна).

Символи розміщуються зліва направо в порядку значення, починаючи з найбільшого. Однак у кількох конкретних випадках, щоб уникнути повторення чотирьох символів (наприклад, IIIIабо XXXX), віднімання часто застосовується таким чином:

  • Iставиться перед Vабо Xвказує один менше, тому чотири є IV(один менше п'яти) і дев'ять - IX(один менше десяти)
  • Xставиться перед Lабо Cвказує на десять менше, тому сорок - це XL(десять менше п’ятдесяти), а дев'яносто - це XC(десять менше сотні)
  • Cставиться перед Dабо Mвказує на сто менше, тому чотириста - це CD(сто менше п'ятисот), а дев'ятсот - це CM(сто менше тисячі)
    Наприклад, MCMIVце тисяча дев'ятсот чотири, 1904 ( Mце тисяча, CMє дев'ятсот і IVчотири).

Деякі приклади сучасного використання римських цифр включають:
1954 як MCMLIV; 1990 як MCMXC; 2014 рік як MMXIV
ДЖЕРЕЛО

Загальні правила:

  • Це , тому найкоротша відповідь у байтах виграє.
    Не дозволяйте мовам коду-гольфу відштовхувати вас від публікації відповідей з мов, що не кодують гольф. Спробуйте придумати якомога коротшу відповідь на "будь-яку" мову програмування.
  • Для вашої відповіді застосовуються стандартні правила , тому вам дозволяється використовувати 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
@martin 9999-> M(X)CMXCIX-> 77+263+67+77+88+67+73+88-> 800і 2147483647-> ((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було правильно.
Kevin Cruijssen

1
Тестовий випадок 2222222222не в заданому діапазоні. І я згоден з цим 5362.
Ніл

1
Назва заголовку звучить як питання переповнення стека C.
user6245072

3
Чи слово "четвертий" у заголовку є каламбуром? Якщо ні, то це повинно бути "вперед".
Monty Harder

Відповіді:


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]
)&

Математика RomanNumeralРеалізація дає (IX) CMXCIX для 9999, і тому програма повертає 971 для цього числа.

Як написано, римська цифра типу ((...)) (...) ... повертає вкладений список кодів ASCII для римських цифр довжиною 4, ((...)) ... повертає список довжиною 3, (...) ... повертає список довжини 2, і ... повертає список довжини 1. Заключний рядок перетворює ці правила у відповідну кількість макронів для кожного розділу list, додає ці макрони, а потім підсумовує весь вкладений список, щоб повернути результат.


1
Ласкаво просимо до PPCG!
betseg

@betseg Дякую! Це було першою проблемою весело.
HiggstonRainbird

10

Пітон 3, 281 278 273 269 ​​байт

Моя перша спроба кодегольфа, ось ми і підемо. Намагався це зробити, не дивлячись на пов’язане питання, так що це, мабуть, страшно :)

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)

На 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 elseзreturn 0if n<1else
Габор Фекете

Ваша версія для гольфу має дзвінки fв неї, коли ім'я функції g.
Gábor Fekete

Змініть, n//9*10>=10*lщоб n//9>=lзберегти ще кілька.
Габор Фекете

Ім'я виправленої функції, я змінив це, щоб перевірити, чи правильно граю в нього, і забув змінити його.
jDomantas


3

Математика, 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

Пітон, 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 «s потенціалу для боротьби з римськими цифрами без пакетів: Ви можете тільки ввести числа між 1і 3899, як as.roman" s документація пояснює.

Ось чому я обдурив трохи, даючи діапазон між 1до в петлі: це довжина від виходу «s ( ) . Фактично, за даними цього веб-сайту , найдовший римський номер (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)]- число Is в римській цифрі.

[((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))s в числі.

Потім він помножує події на значення символу і повертає його суму.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.