Açgözlü Romalılar!


30

Kesinlikle olumlu bir tamsayı verildiğinde, yalnızca ek kuralı kullanarak mümkün olan en kısa Romen rakamını döndürün. Çıktı, bu sıradaki karakterlerin her birinden sıfır veya daha fazlasını içermelidir MDCLXVI. Bu 14nedenle, sayı XIIIIyerine vermelidir XIV.

Karakterlerin sayısal değerleri M= 1000, D= 500, C= 100, L= 50, X= 10, V= 5, I= 1'dir.

Örnekler

3III

4 → IIII

9VIIII

42XXXXII

796DCCLXXXXVI

2017MMXVII

16807MMMMMMMMMMMMMMMMDCCCVII


1
Sen izin vermek için bir hayırsever sorgulayıcı konum 4 -> IIIIolduğu 9 -> VIIIIyanı yerine IX?
Magic Octopus Urn,


@MagicOctopusUrn VIIII9 için izin verilen tek çıktıdır.
Adám

@ Adám, 4 ve 9 kurallarının aynı olması nedeniyle, bunu örnek olarak eklemek isteyebileceğinizi de işaret ediyordu.
Magic Octopus Urn,

Yanıtlar:


12

Düz İngilizce , 1059 1025 678 641 451 399 bayt

Bir hata tuzağını kaldırarak 34 bayt kaydedildi. Sonra golf oynayarak 384 bayt kurtardı. Ardından bölme işlemini ekleme işlemi ("z") ile yeni bir işleme ("p") birleştirerek 190 bayt kurtardı. Sonra golf oynayarak 52 bayt kurtardı.

A s is a string.
To p a r remainder a s a x string a n number:
If the x is "", exit.
Divide the r by the n giving a q quotient and the r.
Fill a t s with the x's first's target given the q.
Append the t to the s.
To convert a r number to a s:
p the r the s "M" 1000.
p the r the s "D" 500.
p the r the s "C" 100.
p the r the s "L" 50.
p the r the s "X" 10.
p the r the s "V" 5.
p the r the s "I" 1.

İşte final kodunun ungolfed versiyonu, artı negatif bir sayı için bir hata tuzağı:

A roman numeral is a string.

To process a remainder given a roman numeral and a letter string is a number:
  If the letter is "", exit.
  Divide the remainder by the number giving a quotient and the remainder.
  Fill a temp string with the letter's first's target given the quotient.
  Append the temp string to the roman numeral.

To convert a number to a roman numeral:
  If the number is negative, exit.
  Put the number in a remainder.
  Process the remainder given the roman numeral and "M" is 1000.
  Process the remainder given the roman numeral and "D" is  500.
  Process the remainder given the roman numeral and "C" is  100.
  Process the remainder given the roman numeral and "L" is   50.
  Process the remainder given the roman numeral and "X" is   10.
  Process the remainder given the roman numeral and "V" is    5.
  Process the remainder given the roman numeral and "I" is    1.

10
Bekle, bu bir programlama dili mi?
Adám

3
@Adam - Evet. Düz İngilizce derler ve çalışır ve her şey. Kaynak kodu ve IDE, github.com/Folds/english
Jasper,

1
Olsa da golf yapın - sonuçta, bu kod golf, dil vitrin değil.
Sanchises,

2
Demek işini dış kaynaklı olarak almak istemiyorsan kullandığın dil bu mu?
corsiKa

@corsiKa - LOL! Ancak, yeterli kitleniz için onu kullanmaya başlayacağız (ve kütüphanelerine ekleyerek).
Jasper,

5

APL (Dyalog) , 25 22 bayt

'MDCLXVI'/⍨(0,62 5)∘⊤

Çevrimiçi deneyin!


Güzel ve temelde aklımda olan çözüm. Bununla birlikte, /reshape ( ) yerine replicate ( ) işlevini kullanabilirsiniz, böylece her birini ve katener azaltmayı ( ¨ve ,/) kesebilirsiniz .
Adám

Ayrıca, tradfn gövdesine dönüştürebilir ve input ( ) işlevini alabilir ve parens'i kaldırmak ve compose ( ) işlevini kullanmak için commute ( ) komutunu kullanabilirsiniz .
Adám

Teşekkürler, ama ikinci yorumunuzla ne demek istiyorsunuz? Bunu, bayt sayısını artırmadan yapmanın bir yolunu düşünemiyorum
TwiNight


1
Bu bir olurdu pasajı saymak sürece {}veya ∇f∇fonksiyonunu çevreleyen
TwiNight

5

Retina , 57 42 bayt

Unary'e dönüştürür, daha sonra açgözlülükle Is demetlerini daha yüksek olanlarla sırayla değiştirir.

.*
$*I
I{5}
V
VV
X
X{5}
L
LL
C
C{5}
D
DD
M

Çevrimiçi deneyin

Martin sayesinde 15 bayt kurtardı


Bu çok zekice.
Adám

7
Diğer yoldan gitmek çok daha kısa: tio.run/##K0otycxL/…
Martin Ender

IÜnite olarak unary kullanarak girdi alamaz mısın?
Adám

2
@ Adám Retina'nın şimdi tamsayı girişini kolayca idare edebileceğini göz önünde bulundurarak, bunu yapmanın ucuz olduğunu düşünüyorum.
mbomb007

5

Python 2,64 bayt

f=lambda n,d=5,r='IVXLCD':r and f(n/d,7-d,r[1:])+n%d*r[0]or'M'*n

Çevrimiçi deneyin!

Çıkış dizesini başlangıçta açgözlülükle en büyük kısmını alarak oluşturma yerine, bu onu sondan oluşturur. Örneğin, I's sayısı n%5, sonra V' s sayısı n/5%2, vb. Bu, 5 ve 2 dönüşümlü art arda oranlarla karışık baz dönüşümüdür.

İşte yinelemeli bir eşdeğer:

Python 2,68 bayt

n=input();s='';d=5
for c in'IVXLCD':s=n%d*c+s;n/=d;d^=7
print'M'*n+s

Çevrimiçi deneyin!

MHiçbir büyük basamaklı olarak orada bunlardan herhangi sayıda mevcut olabilir çünkü 'ın ihtiyacı ayrı ayrı ele alınması. Böylece, diğer yer değerleri atandıktan sonra, kalan değer M'e dönüştürülür .

Karşılaştırma için açgözlü bir strateji (69 bayt):

Python 2,69 bayt

f=lambda n,d=1000,r='MDCLXVI':r and n/d*r[0]+f(n%d,d/(d%3*3-1),r[1:])

Çevrimiçi deneyin!

Geçerli hane değeri d, bir sonraki hatayı üretmek için 2 veya 5'e bölünür. d%3Bize hangisinin olduğunu d%3==1söyleyişin değeri : eğer bölücü 2; ve eğer d%3==2, 5 ile bölün.


4

Mathematica, 81 bayt

Table@@@Thread@{r=Characters@"MDCLXVI",#~NumberDecompose~FromRomanNumeral@r}<>""&

Açıkça değerleri kullanarak ve karşılık gelen sayıları türetmek bir bayt daha uzun gibi görünüyor:

Table@@@Thread@{RomanNumeral[n={1000,500,100,50,10,5,1}],#~NumberDecompose~n}<>""&

1
Güzel !:FromRomanNumeral@r
DavidC

4

Excel, 236 193 161 bayt

@ BradC sayesinde 43 bayt kaydedildi

Bu noktada, cevap gerçekten tamamen @ BradC'e aittir . Başka bir 32 bayt kaydedildi.

=REPT("M",A1/1E3)&REPT("D",MOD(A1,1E3)/500)&REPT("C",MOD(A1,500)/100)&REPT("L",MOD(A1,100)/50)&REPT("X",MOD(A1,50)/10)&REPT("V",MOD(A1,10)/5)&REPT("I",MOD(A1,5))

biçimlendirilmiş:

=REPT("M",A1/1E3)
    &REPT("D",MOD(A1,1E3)/500)
    &REPT("C",MOD(A1,500)/100)
    &REPT("L",MOD(A1,100)/50)
    &REPT("X",MOD(A1,50)/10)
    &REPT("V",MOD(A1,10)/5)
    &REPT("I",MOD(A1,5))

Sen değiştirerek bazı tasarruf edeceğiz CONCATENATEolan &her bir öğe arasındaki ve QUOTIENTbirlikte INT(A/B).
BradC

2 daha fazla tasarruf: bir tam sayı değilseREPT zaten sayıyı kısaltır , böylece her birini kaldırarak 30 bayttan tasarruf edebilirsiniz INT(). İkisini de değiştirerek 2 tane daha tasarruf 1000edin 1E3(Excel, girdikten sonra bu şekilde tutmak istemiyor olsa da).
BradC

Evet, 1E3davranışı gördüm . Cevap güncellendi.
Wernisch

3

Perl 5 , 66 bayt

65 bayt kodu + -pbayrak.

$s=1e3;for$@(MDCLXVI=~/./g){$\.=$@x($_/$s);$_%=$s;$s/=--$|?2:5}}{

Çevrimiçi deneyin!

Bayt sayısını değiştirmeden, MDCLXVI=~/./gyerine M,D,C,L,X,V,I; ve --$|?2:5tarafından $|--*3+2.

Çok daha uzun ( 99 bayt ), var:

$_=M x($_/1e3).D x($_%1e3/500).C x($_%500/100).L x($_%100/50).X x($_%50/10).V x($_%10/5).I x($_%5)

3

CJam , 35 28 bayt

Martin Ender sayesinde -7 bayt

q~{5md\2md\}3*]W%"MDCLXVI".*

Çevrimiçi deneyin!

açıklama

q~         e# Read and eval input (push the input as an integer).
{          e# Open a block:
 5md\      e#  Divmod the top value by 5, and bring the quotient to the top.
 2md\      e#  Divmod that by 2, and bring the quotient to the top.
}3*        e# Run this block 3 times.
]W%        e# Wrap the stack in an array and reverse it. Now we've performed the mixed-base
           e# conversion.
"MDCLXVI"  e# Push this string.
.*         e# Element-wise repetition of each character by the numbers in the other array.
           e# Implicitly join and print.

3

C #, 127 bayt

f=n=>n>999?"M"+f(n-1000):n>499?"D"+f(n-500):n>99?"C"+f(n-100):n>49?"L"+f(n-50):n>9?"X"+f(n-10):n>4?"V"+f(n-5):n>0?"I"+f(n-1):""

Özyineleme kullanarak tamamen zor kodlanmış bir üçlü deyim.

Tam / Biçimli sürüm:

using System;

class P
{
    static void Main()
    {
        Func<int, string> f = null;
        f = n => n > 999 ? "M" + f(n - 1000)
                         : n > 499 ? "D" + f(n - 500)
                                   : n > 99 ? "C" + f(n - 100)
                                            : n > 49 ? "L" + f(n - 50)
                                                     : n > 9 ? "X" + f(n - 10)
                                                             : n > 4 ? "V" + f(n - 5)
                                                                     : n > 0 ? "I" + f(n - 1)
                                                                             : "";

        Console.WriteLine(f(3));
        Console.WriteLine(f(4));
        Console.WriteLine(f(42));
        Console.WriteLine(f(796));
        Console.WriteLine(f(2017));
        Console.WriteLine(f(16807));

        Console.ReadLine();
    }
}

n>0sadece n.
Hesap MakinesiFeline

@CalculatorFeline C # ' intda değil, dolaylı olarak a bool.
TheLethalCoder

Bu talihsizlik.
Hesap MakinesiFeline

@CalculatorFeline Evet, C # bazen kendi iyiliği için çok güçlü bir şekilde yazılmıştır.
TheLethalCoder

3

05AB1E , 29 26 25 bayt

¸5n3×Rvćy‰ì}"MDCLXVI"Ss×J

Çevrimiçi deneyin!

açıklama

¸                           # wrap input in a list
 5n                         # push 5**2
   3×                       # repeat it 3 times
     Rv                     # for each digit y in its reverse
       ć                    # extract the head of the list 
                            # (div result of the previous iteration, initially input)
        y‰                  # divmod with y
          ì                 # prepend to the list
           }                # end loop
            "MDCLXVI"S      # push a list of roman numerals
                      s×    # repeat each a number of times corresponding to the result
                            # of the modulus operations
                        J   # join to string

3

JavaScript (ES6), 81 75 69 Bayt

@Neil, @ Jörg Hülsermann'ın cevabını taşıdığı için teşekkürler.

@Shaggy sayesinde 6 bayt kaydedildi

n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:‌​2),a=1e3)

Test durumları:


1
Birkaç bayt kaydetmek n%=xiçin repeatyöntem içinde hareket edebilmelisiniz .
Shaggy

1
FYI PHP cevabının bir limanı sadece 69 byte:n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:2),a=1e3)
Neil

Thanks @Neil, Ben yazı güncellendi. Tekrar ziyaret etmek istediğim kodlanmış diziyi kaldırıyor
Craig Ayre

2

/// , 50 bayt

/1/I//IIIII/V//VV/X//XXXXX/L//LL/C//CCCCC/D//DD/M/

Çevrimiçi deneyin!

Girişleri unary olarak alır ve giriş için TIO'daki altbilgi alanını kullanıyorum, böylece çıktı önce bir yeni satırla geliyor.


2

Python 3 , 100 97 96 94 93 91 90 bayt

  • 4 + 2 bayt kaydedildi: kullanımı def; Varsayılan parametre olarak dizi girintili alanı azalttı; istenmeyen değişken bildirimi kaldırıldı
  • @shooqie 1 byte a%=kısayol kaydetti
  • 2 bayt kurtarıldı: yeniden düzenlendi ve içerideki parantezler (a//i)kaldırıldı
  • @Wondercricket 1 bayt kaydetti: diziyi varsayılan parametreden []bir girinti alanı pahasına kaldırılan işleve taşıyın , böylece 1 bayt tasarruf edin.
def f(a):
 b=1000,500,100,50,10,5,1
 for i in b:print(end=a//i*'MDCLXVI'[b.index(i)]);a%=i

Çevrimiçi deneyin!


1
a%=ibir bayt kısa :)
shooqie

1
bİşlev içinde bir değişken olarak saklayarak da bir bayt kaydedebilirsiniz . Bu parantez gerekliliğini ortadan kaldırır -b=1000,500,100,50,10,5,1
Wondercricket

2

Cubix , 69 74 80 bayt

/.UI,..N&..0\0&/52"IVXLCDM"U,r%ws;rr3tu;pw..u;qrUosv!s.u\psq,!@Us(0;U

Çevrimiçi deneyin!

        / . U I
        , . . N
        & . . 0
        \ 0 & /
5 2 " I V X L C D M " U , r % w
s ; r r 3 t u ; p w . . u ; q r
U o s v ! s . u \ p s q , ! @ U
s ( 0 ; U . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

Çalışıyor İzle

Biraz daha sıkıştırmayı başardım, ancak özellikle üstte bazı sinir bozucu no-op'lar var.

  • 52"IVXLCDM"Ugerekli bölenleri ve karakterleri yığına koyun. 5 ve 2, div / mod değerini azaltmak için kullanılacak ve karakterler kullanıldıktan sonra atılacaktır.
  • UIN0/&0\&,/UÜst yüze u dönüşür ve girişi elde etmek için uzun bir tura başlar ve 1000'i istifin üzerine iter. İlk bölme yapılır ve bir rsonraki snippet'in üzerine bir u dönüşü yapılır . Bu, biraz tasarruf yapmak istediğim bir alandı.
  • ,r%ws;rrdivmod döngüsünün başlangıcı. tamsayı bölme, sonucu uzağa döndürme modunu döndürün, ardından giriş, geçerli bölen ve bölme sonucu düşürülecek yığının tepesini yeniden düzenleyin.
  • 3tus mevcut karakteri üste getir ve bölme sonucu ile değiştir.
  • !vsoUs(0;Ubu yazdırma döngüsüdür. div sonucu 0'dan fazla iken, karakter çıkışı ile değiştirin, geri değiştirin, azaltın, 0'a basın ve bırakın. 0'da, pop yığını üzerinde (bölme sonucunu kaldır) ve küpün etrafına yönlendirilir.
  • \u;pwpsq,!@Urq;ubit yeniden yönlendirme ile, bu karakteri yığından kaldırır, 5 ve 2'yi en üste çıkarır, değiştirir ve geriye doğru iter. Kalan bölücü azaltmak için kullanılır. 0'a düşerse durur, aksi takdirde 5 veya 2'yi aşağıya doğru itin ve döngüye tekrar girin.

1

Mathematica, 130 bayt

(f=#~NumberDecompose~{1000,500,100,50,10,5,1};""<>{Flatten@Table[Table[{"M","D","C","L","X","V","I"}[[i]],f[[i]]],{i,Length@f}]})&

1

Python 2 , 109 90 bayt

lambda n,r=[1000,500,100,50,10,5,1]:''.join(n%a/b*c for a,b,c in zip([n+1]+r,r,'MDCLXVI'))

Çevrimiçi deneyin!


1000olabilir 1e3(sorun olmamalıdır bir şamandıra olmasının sakıncası yoksa)
CalculatorFeline

@CalculatorFeline sonucu a'ya çevirir floatve bir katarı float ile çarpamazsınız : c
Rod


1

T-SQL, 164 bayt

SELECT REPLICATE('M',n/1000)+IIF(n%1000>499,'D','')
      +REPLICATE('C',n%500/100)+IIF(n%100>49,'L','')
      +REPLICATE('X',n%50/10)+IIF(n%10>4,'V','')
      +REPLICATE('I',n%5)
FROM t

Satır sonları yalnızca okunabilirlik için eklendi.

Bu sürüm çok daha uzun (230 karakter), ancak çok daha fazla "SQL benzeri" hissediyor:

DECLARE @ INT,@r varchar(99)=''SELECT @=n FROM t
SELECT'I's,1v INTO m
INSERT m VALUES('V',5),('X',10),('L',50),('C',100),('D',500),('M',1000)
L:
    SELECT @-=v,@r+=s 
    FROM m WHERE v=(SELECT MAX(v)FROM m WHERE v<=@)
IF @>0GOTO L
SELECT @r

Tüm char-değer eşlemelerini içeren bir tablo m yapar ve ardından en büyük değeri <= sayı bulup, eşleşen karakteri birleştirerek döngüler.


1

Japt , 34 bayt

"IVXLCD"£%(U/=Y=v *3+2Y)îXÃw i'MpU

Çevrimiçi test edin!

"IVXLCD"£    %(U/=Y=v  *3+2Y )îXÃ w i'MpU
"IVXLCD"mXY{U%(U/=Y=Yv *3+2,Y)îX} w i'MpU : Ungolfed
                                          : Implicit: U = input number
"IVXLCD"mXY{                    }         : Map each char X and its index Y in this string to:
                  Y=Yv *3+2               :   Set Y to 5 for even indexes, 2 for odd.
               U/=                        :   Divide U by this amount.
            U%(            ,Y)            :   Modulate the old value of U by 5.
                              îX          :   Repeat the character that many times.
                                          : This returns e.g. "IIVCCCD" for 16807.
                                  w       : Reverse the entire string.
                                    i'MpU : Prepend U copies of 'M' (remember U is now the input / 1000).
                                          : Implicit: output result of last expression

1

JavaScript (ES6), 65 bayt

Özyinelemeli bir işlev.

f=(n,a=(i=0,1e3))=>n?a>n?f(n,a/=i++&1?5:2):'MDCLXVI'[i]+f(n-a):''

Nasıl?

İkinci özyinelemeli çağrı f(n-a)gerçekten olmalı f(n-a,a). 2. parametre ihmal, tarafından ave iher zaman (sırasıyla 1000 ve 0) yeniden başlatılır yeni bir Roma basamaklı nihai sonuca eklenir. Bu ihtiyaçtan daha fazla özyinelemeye neden olur, ancak fonksiyonun sonucunu değiştirmez ve 2 bayt kazandırır.

Test durumları


1

J , 26 23 bayt

Adám sayesinde 3 bayt kaydedildi.

'MDCLXVI'#~(_,6$2 5)&#:

Çevrimiçi deneyin!

APL'ye benzer şekilde cevap aynıdır.

'MDCLXVI'#~(_,6$2 5)&#:
           (       )&#:   mixed base conversion from decimal
              6$2 5       2 5 2 5 2 5
            _,            infinity 2 5 2 5 2 5
                          this gives us e.g. `0 0 0 0 1 0 4` for input `14`
'MDCLXVI'#~               shape each according to the number of times on the right
                          this is greedy roman numeral base conversion

J'yi tanıdığımdan değil, neden #.invyerine #:?
Adám

@ Adám Ah, iyi nokta. Ben alışıldığı kullanmak #.invyerine #:böyle bir şey beri, 2 #: 4IS 0iken, 2 #.inv 4olduğu1 0 0
Conor O'Brien

Evet, aynı şeyi APL'de yapıyorum. Şimdi çözümünüz gerçekten APL çözümüyle eşdeğerdir.
Adám

#olduğu /; ~olduğu ; $olduğu ; &olduğu ; #:olduğunu . Tek fark, APL cevapları gibi kullanabilmeniz için sonsuzluğu _kullanmanızdır 0.
Adám

@ Adám Huh, havalı.
Conor O'Brien,

1

Toplu iş, 164 bayt

@set/pn=
@set s=
@for %%a in (1000.M 500.D 100.C 50.L 10.X 5.V 1.I)do @call:c %%~na %%~xa
@echo %s:.=%
@exit/b
:c
@if %n% geq %1 set s=%s%%2&set/an-=%1&goto c

STDIN'de girişi ele alır.


1

Oracle SQL, 456 bayt

select listagg((select listagg(l)within group(order by 1)from dual start with trunc((n-nvl(n-mod(n,p),0))/v)>0 connect by level<=trunc((n-nvl(n-mod(n,p),0))/v)))within group(order by v desc)from (select 2849n from dual)cross join(select 1000v,null p,'m'l from dual union select 500,1000,'d'from dual union select 100,500,'c'from dual union select 50,100,'l'from dual union select 10,50,'x'from dual union select 5,10,'v'from dual union select 1,5,'i'from dual)

Çıktılar:

mmdcccxxxxviiii

Lütfen satırın gerçek boyutunun 460 bayt olduğunu unutmayın, çünkü giriş numarasını içerir (2849).

Ungolfed:

select listagg(
            (select listagg(l, '') within group(order by 1) 
             from dual 
             start with trunc((n-nvl(p*trunc(n/p),0))/v) > 0 
             connect by level <= trunc((n-nvl(p*trunc(n/p),0))/v) )
        ) within group(order by v desc)
from (select 2348 n
    from dual
) cross join (
    select 1000v, null p, 'm' l from dual union 
    select 500, 1000, 'd' from dual union
    select 100, 500, 'c' from dual union
    select 50, 100, 'l' from dual union
    select 10, 50, 'x' from dual union
    select 5, 10, 'v' from dual union
    select 1, 5, 'i' from dual     
)

Nasıl çalışır: Her bir harften kaç tanesine ihtiyacım olduğunu hesaplarım, en yüksek değeri bir (M için sonsuz) değerine ulaşabileceğimi hesaplayarak ve sonra o mektubun değeri ile bunun sonucu arasında bir tamsayı bölüştürürüm.

2348, kaç taneye Cihtiyacım var? trunc((2348-mod(2348,500))/100)= 3.

Ardından, listaggo mektubu 3 kez birlikte ( CONNECT BYihtiyacım olan 3 satırı oluşturmak için kullanmak ). Sonunda ben listaggher şeyi birlikte yaparım .

Biraz hantal, ama çoğu select from dualdönüşüm tablosundaki s ve bu konuda çok fazla şey yapamam ...


0

Java (OpenJDK 8) , 119 118 bayt

n->{String s="";for(int v[]={1,5,10,50,100,500,1000},i=7;i-->0;)for(;n>=v[i];n-=v[i])s+="IVXLCDM".charAt(i);return s;}

Çevrimiçi deneyin!

@TheLethalCoder sayesinde bir bayt kaydedildi


1
Döngü için bir bayt kaydetmek için ilk vve ilan edebilir misiniz i?
TheLethalCoder

@TheLethalCoder Evet, kesinlikle. İlk başta bunun benim iç incelememi geçemediği konusunda başka bir fikrim vardı: p
Olivier Grégoire

0

Kömür , 61 50 46 bayt

NνA⁰χWφ«W¬‹νφ«§MDCLXVIχA⁻νφν»A⁺¹χχA÷φ⎇﹪χ²¦²¦⁵φ

Çevrimiçi deneyin!

Açıklama:

Nν                   Take input as number and assign it to ν
A⁰χ                  Let χ=0
Wφ«                  While φ>0 (φ has a predefined value of 1000)
    W¬‹νφ«               While v>=φ 
        §MDCLXVIχ             Take the char from string "MDCLXVI" at position χ
        A⁻νφν»               Let ν=ν-φ
    A⁺¹χχ                Increment χ
    A÷φ⎇﹪χ²¦²¦⁵φ        If χ is odd, divide φ by 5, else divide φ by 2
  • Neil sayesinde 4 byte kurtarıldı, yorumunun ikinci bölümüne nasıl devam edeceğimi çözmeye çalışıyorum.

1
NνBirden bayt kısadır ANν, ¬‹1 çıkarılarak birden bayt kısadır ve kullanmak durumunda ÷yerine (IntDivide) (Divide) daha sonra kullanabilir φdış döngü koşulu olarak. Ancak, MDCLXVIdoğrudan bunun üzerinden döngü yaparak 40 bayta indirebileceğinizi düşünüyorum .
Neil

@Neil, aptal, neden "daha az değil" kullanabildiğimde "daha büyük veya eşit" bir operatör olmadığını anlamaya çalışıyorum. Tamsayılı bölümün kullanımını çok zekice. Şimdi yorumunuzun son bölümünü düşünmek için biraz zaman tanıyın ...
Charlie

String döngü fikrimi geliştirdim ve aynı uzunluktaki @ xnor'ın Python cevabı portuyla birlikte ayrı bir cevap olarak yayınladım.
Neil

0

C ++, 272 Bayt

#include <cstdio>
#include <map>
std::map<int,char> m = {{1000,'M'},{500,'D'},{100,'C'},{50,'L'},{10,'X'},{5,'V'},{1,'I'}};
int main(){unsigned long x;scanf("%d",&x);for(auto i=m.rbegin();i!=m.rend();++i)while(x>=i->first){printf("%c", i->second);x=x-i->first;}return 0;}

0

C, 183 Bayt

#include <stdio.h>
int v[]={1000,500,100,50,10,5,1};
char*c="MDCLXVI";
int main(){int x;scanf("%d",&x);for(int i=0;i<sizeof v/sizeof(int);i++)for(;x>=v[i];x-=v[i])putc(c[i],stdout);}

Daha önce olduğu gibi aynı algoritma, sadece bir std :: map yerine düz c dizileri kullanarak, kısmen @ xnor'ın cevabından ilham almak ve harfleri saklamak için bir dize kullanmak.



0

Ortak Lisp, 113 bayt

Bu isimsiz bir fonksiyondur ve sonucu bir dizge olarak döndürür.

(lambda(value)(setf(values a b)(floor v 1000))(concatenate 'string(format()"~v,,,v<~>"a #\M)(format nil"~@:r"b)))

Tanımlayıcı değişken isimleri ve yorumlarıyla Ungolfed:

(defun format-roman (value)
  ;; Get "value integer-divided by 1000" and "value mod 1000"
  (setf (values n_thousands remainder) (floor value 1000))
  (concatenate 'string
               ;; Pad the empty string n_thousands times, using "M" as the 
               ;; padding character
               (format () "~v,,,v<~>" n_thousands #\M)
               ;; Format the remainder using "old-style" Roman numerals, i.e. 
               ;; numerals with "IIII" instead of "IV"
               (format nil "~@:r" remainder)))

CL yerleşik Romen rakam biçimlendiricisine sahiptir. Ne yazık ki, 3999'dan büyük numaralar için çalışmıyor.


0

Kömür , 34 bayt

NςA²ξFMDCLXVI«×ι÷ςφA﹪ςφςA÷φξφA÷χξξ

Aslen @ CarlosAlego'nun cevabına dayanıyor. @ Xnor'ın Python çözümünün bir bağlantı noktası da 34 bayttır:

NθA⁵ξFIVXLCD«←×ι﹪θξA÷θξθA÷χξξ»←×Mθ

Düzenleme: @ xnor'ın diğer Python çözümünün bir bağlantı noktası 33 bayttır!

NθFMDCLXVI«×ι÷θφA﹪θφθA÷φ⁺׳﹪φ³±¹φ

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Kullanmış olduğunuz Not ⁺׳﹪φ³±¹yerine ⁻׳﹪φ³¦¹deverbosifier halen ayırıcı eklemek için başarısız çünkü.


1
Huh, bu Romalılardan daha çok Yunanca görünüyor.
Adám
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.