Tamsayı zaman içinde ileri geri gider


17

Giriş:

Bir tam sayı.

Çıktı:

  1. Önce tamsayıyı eşdeğer Romen Rakamına dönüştürün.
  2. Sonra Romen Rakamının her büyük harfini ASCII / UNICODE ondalık değerine dönüştürün.
  3. Ve bunların toplamını çıkar.

Misal:

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

Romen Rakamları: İşte belki de yararlı bir Roma Rakamı Dönüştürücüsü.
resim açıklamasını buraya girin

Zorluk kuralları:

  • Standart Roma Sayısal kuralları gibi pek alternatifi formları uygulanır IIIIveya VIIIIyerine IVve IX. *
  • 1.000'den fazla Romen Rakamının üzerindeki Macron çizgileri ¯(UNICODE no. 175). Yani bir satır +175iki, iki satır sayılır +350.
  • Tam sayıları temsil ettiği sürece her türlü giriş ve çıkış türünü kullanmanıza izin verilir.
  • Test senaryoları aralığında olacaktır 1 - 2,147,483,647.

* Romen Rakamıyla ilgili kurallar (Wikipedia'dan alıntı):

Sayılar, sembollerin birleştirilmesi ve değerlerin eklenmesi ile oluşturulur, böylece IIiki (iki) ve XIIIonüç (on ve üç) olur. Her sayının, konuma göre on, yüz vb. Katları temsil etmek yerine sabit bir değeri olduğu için, 207 veya 1066 gibi sayılarda olduğu gibi, sıfırların "yer tutması" na gerek yoktur; bu sayılar CCVII(iki yüz, beş ve iki) ve MLXVI(bin, elli, on, beş ve bir) olarak yazılır .

Semboller, en büyükten başlayarak değer sırasına göre soldan sağa yerleştirilir. Bununla birlikte, birkaç özel durumda, dört karakterin art arda tekrarlanmasını önlemek için ( IIIIveya gibi XXXX), çıkarma gösterimi genellikle aşağıdaki gibi kullanılır:

  • Idaha önce yerleştirilmiş Vveya Xbirini daha az gösterir, bu nedenle dördü IV(biri beşten az) ve dokuz tanesi IX(ondan az)
  • Xdaha önce yerleştirilir Lveya Condan daha az gösterir, bu nedenle kırk XL(elli'den on daha az) ve doksan XC(yüzden ondan az)
  • Cönce yerleştirilir Dveya Myüz daha az gösterir, yani dört yüzCD (yüz az beş yüz) ve dokuz yüz olan CM(yüz az bin az)
    Örneğin, MCMIV1904 1904 olan ( Mbin olduğu CMbir dokuz yüz ve IVdört).

Romen rakamlarının modern kullanımına bazı örnekler:
1954 olarak MCMLIV; 1990 olarak MCMXC; 2014 MMXIV
KAYNAK OLARAK

Genel kurallar:

  • Bu , bayt en kısa cevap kazanır.
    Kod golf dillerinin, kod yazmayan dillerle yanıt göndermenizi engellemesine izin vermeyin. 'Herhangi bir' programlama dili için mümkün olduğunca kısa bir cevap bulmaya çalışın.
  • Cevabınız için standart kurallar geçerlidir , bu nedenle STDIN / STDOUT, fonksiyon / yöntemi uygun parametrelerle, tam programları kullanmanıza izin verilir. Çağrınız.
  • Varsayılan Loopholes yasaktır.
  • Mümkünse, lütfen kodunuz için test içeren bir bağlantı ekleyin.
  • Ayrıca, gerekirse bir açıklama ekleyin.

Test senaryoları:

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-> 800ve 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. Bu yüzden ikincisini düzelttim, ama 9999doğruydu.
Kevin Cruijssen

1
Test durumu 2222222222belirtilen aralıkta değil. Ayrıca katılıyorum 5362.
Neil

1
Başlık bir Stack Overflow C sorusu gibi geliyor.
user6245072

3
Başlıkta "dördüncü" kelimesi bir kelime oyunu mu? Değilse, "ileri" olmalıdır.
Monty Harder

Yanıtlar:


4

Mathematica, 181 173 166 151 bayt

golfed

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

Ungolfed

(
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'nın RomanNumeraluygulaması 9999 için (IX) CMXCIX verir ve böylece program bu sayı için 971 değerini döndürür.

Yazıldığı gibi, ((...)) (...) ... türündeki bir Roma rakamı, uzunluk 4, ((...)) Roma rakamları için ASCII kodlarının iç içe bir listesini döndürür ... uzunluk 3'ün bir listesini döndürür, (...) ... uzunluk 2'nin bir listesini döndürür ve ... uzunluk 1'in bir listesini döndürür. Son satır, bu kuralları ekranın her bölümü için uygun makro sayısına dönüştürür. listesinde bu makroları ekler ve çıktıyı döndürmek için tüm iç içe listeyi toplar.


1
PPCG'ye Hoşgeldiniz!
16'da

@betseg Teşekkürler! Bu eğlenceli bir ilk sorundu.
HiggstonRainbird

10

Python 3, 281 278 273 269 bayt

Codegolf'daki ilk denemem, başlıyoruz. Bağlantılı soruya bakmadan yapmaya çalıştı, bu yüzden muhtemelen korkunç :)

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ábor Fekete sayesinde 8 bayt daha küçük

Ungolfed:

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)

Bazı baytları return 0 if n==0 else,return 0if n<1else
Gábor Fekete

Golfçülü sürümünüzde fişlevin adı olduğunda çağrılar bulunur g.
Gábor Fekete

Biraz daha kaydetmek n//9*10>=10*liçin n//9>=lolarak değiştirin .
Gábor Fekete

İşlev adı düzeltildi, doğru bir şekilde golf oynadığımı kontrol etmek için değiştirdim ve geri değiştirmeyi unuttum.
jDomantas


3

Mathematica, 198 bayt

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@#&

Ne yazık ki, yerleşik burada çok yardımcı olmaz, ancak eminim bu çok daha fazla golf olabilir.

Not: değerlendirir 9999 -> 971göre burada .


2

Toplu, 373 bayt

@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)

Değerleri 1, 4, 5 ve 9 kullanımlar için bir arama tablosuna göre numarasının her bir basamağını çevirerek çalışır M(V), M(X), (M(V))ve (M(X)). İsterseniz (IV), (IX), ((IV))ve ((IX))sonra kullanmak call:l 77 509 261 511ve call:l 252 859 436 861sırasıyla.


1

JavaScript (ES6), 183 bayt

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)

Not: sadece tercih (IV)etmek M(V)değil, aynı zamanda tercih (VI)etmek (V)M; aslında M'yi sadece sayının başında kullanacaktır.


1

Python, 263 bayt

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'ye hoş geldiniz, güzel ilk cevap!
Bakır

1

R, 115 bayt

Yani ... Çözümümü gönderiyorum çünkü soruyu oldukça ilginç buluyorum. Ben elimden geleni yaptım R paketleri olmadan romen sayıları ile başa çıkmak için 'ler kapasiteleri: yapabilirsiniz arasındaki tek giriş numaraları 1ve3899 gibi as.roman' ın belgelerine açıklıyor.

Ben arasındaki aralık vererek, biraz hile yüzden 1hiç de döngü: bunun uzunluğu var 'nin çıkışı ( ) . Aslında, bu web sitesine göre11 14foras.roman(3899)MMMDCCCXCIX
, en uzun roma numarası MMDCCCLXXXVIII(14 karakter) 'e karşılık gelir 2888.

Ayrıca, length bu işlevin çıktısını .

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)

Yukarıdaki sorunların üstesinden gelmek için bir çözüm görürse, lütfen yorum yapmaktan çekinmeyin.


0

Python 3, 315 bayt

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

Ungolfed sürümü:

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

Açıklama: Bu sürüm farklı bir yaklaşım kullanır, sayıdaki romen rakamlarının oluşumunu sayar.

[abs(((n-4)%5)-1)] sayısı IRomen rakamındaki s .

[((n+10**g)//(10**g*5))%2for g in r(10)] sayısı V,L,D,(V),(L),(D),((V)),((L)),((D)) s sayısıdır.

[(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)] sayısı X,C,M,(X),(C),(M),((X)),((C)),((M)) s sayısıdır.

Daha sonra oluşumları karakterin değeri ile çarpar ve toplamını döndürür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.