Roma'dayken Romalılar gibi sayın?


20

Arka fon

Bu zorluk, aşağıdaki diyagramı yayınlayan bu web sitesinden esinlenmiştir :

resim açıklamasını buraya girin

Bu diyagram bize 250'nin altındaki en uzun Romen Rakamı ifadesinin 188 rakamı olduğunu ve 9 rakamı ifade etmesini gerektirir.

Meydan okuma

En Roma rakamları ifade etmek için kullanılan standart semboller aşağıdaki gibidir: { I, V, X, L, C, D, M}, karakterlerin nümerik değerlerdir M= 1000, D= 500, C= 100, L= 50, X= 10, V= 5, I1 =.

Bu meydan okumada, hedefiniz, pozitif bir tamsayı n verildiğinde , standart sembollerin n'i birleştirerek oluşturulabilecek geçerli Romen Rakamı temsillerinin sayısını hesaplamaktır .

O zaman, programınız bu hesaplamanın sonucunu çıkarmalıdır!

Girdi : Pozitif bir tamsayı n .

Çıktı : n uzunluğundaki geçerli romen rakamı ifadelerinin sayısı .

Romen Rakam İfadeleri için Kurallar

Romen Rakamları başlangıçta sadece "katkı maddesi" eşleşmesine sahipti, yani rakamlar her zaman azalan sırada yazılmıştır ve tüm sayıların değerlerinin toplamı sayının değeridir.

Daha sonra, çıkarıcı eşleştirme, daha küçük olanı daha büyük olandan çıkarmak için daha büyük bir rakamın önüne daha büyük bir rakam yerleştirme kullanımı, Roma Rakamı ifadelerini kısaltmak için yaygın hale geldi. Çıkartıcı çiftleri aşağıdaki geçersiz ifade gibi zincirli olamaz: IXL.

Aşağıdakiler, toplayıcı ve çıkarıcı eşleştirme için günümüz kurallarıdır.

  1. Çıkarma çiftinin kısmen önde gelen rakamı olarak yalnızca bir I, X ve C kullanılabilir.
  2. Çıkarma çiftinde sadece V veya X'den önce yerleştirilebilirim.
  3. X sadece bir çıkarma çiftinde L veya C'den önce yerleştirilebilir.
  4. C sadece bir çıkarma çiftinde D veya M'den önce yerleştirilebilir.
  5. Çıkarma çiftleri dışında, sayılar azalan sırada olmalıdır (yani, her çıkarıcı çiftin baştaki sayısını bırakırsanız, sayılar azalan sırada olacaktır).
  6. M, C ve X daha küçük mezheplerle eşitlenemez veya aşılamaz.
  7. D, L ve V'nin her biri yalnızca bir kez görünebilir.
  8. Sadece M 4 veya daha fazla kez tekrarlanabilir.

Diğer Notlar

  • Biz kullanarak olmayacak çubuk notasyonu; bunun yerine, herhangi bir sayıyı ifade etmek için daha fazla M ekleyeceğiz .

  • Bunlar sadece bizim romen rakamları için izleyeceğini kurallar. Bu, bizim gibi garip ifadelerin IVIde sistemimizde geçerli sayılacağı anlamına gelir .

  • Ayrıca , n uzunluğunda ifadeleri olan sayıların sayısını saymadığımızı da unutmayın , çünkü bazı sayılar birden fazla ifadeye sahiptir. Bunun yerine, yalnızca geçerli ifadelerin sayısını sayıyoruz.

Test Durumları

17

231

3105

Yukarıdakileri elle kontrol ettim, bu yüzden lütfen test senaryolarını iki kez kontrol ettiğinizden emin olun ve mümkünse daha fazlasını ekleyin!

Kazanma Kriterleri

Bu bir meydan okuma, bu yüzden eğlenin! Sadece 1'den 9'a kadar en az girdi işleyebilen çözümleri kabul edeceğim. Artık bonus!

Düzenle

Yorumcular tarafından istendiği gibi, aşağıda veya bu macun bağlantısında n = 3 için saydığım 105 kombinasyon

III IVI IXI IXV IXX VII XII XIV XIX XVI XXI XXV XXX XLI XLV XLX XCI XCV XCX XCL XCC LII LIV LIX LVI LXI LXV LXX CII CIV CIX CVI CXI CXV CXX CXL CXC CLI CLV CLX CCI CCV CCV CDL CCD CD CMI CMV CMX CML CMC CMD CMM DII DIV DIX DVI DXI DXV DXX DXL DXC DLI DLV DLX DCI DCV DCX DCL DCC MII MIV MIX MVI MXI MXV MXX MXL MXC MLI MLV MLX MCI MCV MCX MCL MCC MCD MCM MDC MDL MDV MDL MMX MML MMC MMD MMM

Düzenleme 2:

Sonuçlarınızı kontrol etmek için Jonathan Allan'ın izniyle aşağıdaki golf dışı kodu kullanın .

Düzenleme 3:

Bu meydan okumadaki tüm hatalar için özür dilerim. Bir dahaki sefere daha iyi bir iş yaptığımdan emin olacağım!


Yorumlar uzun tartışmalar için değildir; bu sohbet sohbete taşındı .
Mego

Yanıtlar:


3

Retina , 111 bayt

~(`.+
*$(CM)CDXCXCXCXLIXIXIXIVII
.(.)
.+¶$$&$¶$$&$1$¶$$&$&¶L`.{0,$+}\b¶D`¶
¶$
¶.+¶$$&$¶$$&I¶L`[A-Z]{$+}\b¶D`¶.+

Çevrimiçi deneyin! Ben yalnızca bir tane çıkarmalıya her kullanabileceği anlamına etmek 1. kural yanlış anlaşılmış gibi bu yeniden yazılmış halidir I, Xve C. Açıklama: Komut dosyasının ilk kısmı, girdiyi bir CMçift dizeye, ardından diğer olası çıkarıcı çiftlere genişletir . Her çift isteğe bağlıdır ve her çiftin ilk karakteri de çift içinde isteğe bağlıdır. Üçüncü aşama daha sonra, çift listesini girişi alan ve çiftteki ikinci veya her iki karakterin seçeneği ile üç kopya oluşturan Retina komutları listesine genişletir, ardından sonuçları keser ve tekilleştirir. Son aşama daha sonra son görevleri gerçekleştirmek için kod ekler: önce girdiyi, muhtemelen bir final eklemek için genişletmekI, ardından yanlış uzunluktaki sonuçları filtrelemek, ardından sonuçları tekilleştirmek ve son olarak sonuçları saymak için kullanılır. Sonuçta elde edilen Retina betiği değerlendirilir.

Not: Teoride, 4. satırın sonundan 15 bayt kaydedilebilir, ancak bu komut dosyasının TIO'da gösterilmesi için çok yavaş olmasını sağlar n=1.


@JonathanAllan Ah, o zaman aynı öncü sayıya sahip birden fazla çıkarıcı çift eklersiniz, bu yanlıştır.
Neil

2
@JonathanAllan Aynı bayt sayısı için tesadüfen yeni yeniden yazma!
Neil

5

Python 2 , 177 168 162 bayt

import re,itertools as q
f=lambda n:sum(None!=re.match("^M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$",(''.join(m)))for m in q.product('MDCLXVI',repeat=n))

Çevrimiçi deneyin!

Oldukça yeniyim, bunu golf etmeme yardım et! Bu, gerçek romen rakamlarını kontrol eder, normal ifadenin,IVI

@Bead Possum sayesinde -9 bayt !

@Ovs sayesinde -6 bayt


Evet, örnekte n = 3 durumunun yanlış olabileceğini düşünüyorum. Başlangıçta 93 ^M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$
alıyordum


1
@JonathanAllan Yaklaşık iki gün boyunca bu kuralların mantıklı olduğundan emin olmak için Math stackexchange'i soruyorum. Sanırım yeterince yapmadım :(
Don Bin

1
@RushabhMehta Bu çok iyi biçimlendirilmiş bir meydan okuma ve programlamak eğlencelidir, romen rakamı tanımının nitrit-cesaretindeki talihsiz bir nüans hakkında kötü hissetmeyin. Bu sizin meydan okuma, uygun gördüğünüz gibi belirtin. diğer anlamda uygulanabilir, sadece daha zor
Easton Bornemeier

1
Bu 3 93yerine doğru cevabı vermiyor gibi görünüyor105
Jo King

3

JavaScript (ES7), 133 bayt

Düzenleme : OP tarafından bir referans uygulaması olarak verilen Jonathan Allan kod tarafından döndürülen sonuçları eşleştirmek için düzeltildi .


n=>[...Array(m=k=7**n)].reduce(s=>s+/^1*5?4{0,3}3?2{0,3}6?0{0,3}$/.test((--k+m).toString(7).replace(/0[62]|2[34]|4[51]/g,s=>s[1])),0)

Çevrimiçi deneyin!

Nasıl?

N1

[...Array(m = k = 7 ** n)].reduce(s => … (--k + m).toString(7) …, 0)

Bundan sonra, her rakam bir Roma rakamı sembolü olarak yorumlanacaktır:

0I,1M,2X,3L,4C,5D,6V

2) formun geçerli tüm Subtractive çiftleri yerine ABsahip B:

.replace(/0[62]|2[34]|4[51]/g, s => s[1]))  // in the code
.replace(/I[VX]|X[LC]|C[DM]/g, s => s[1]))  // with Roman symbols

Örnekler:

  • XLIXIV olur LXV
  • XIIVolur XIVbir bırakarak Isonraki test başarısız yapacak
  • ICdeğişmeden kalır, bu da Iyerinde geçersiz kalır

3) Kalan sembollerin doğru sırada olduğunu ve izin verilenden daha fazla görünmediğini kontrol ediyoruz:

/^1*5?4{0,3}3?2{0,3}6?0{0,3}$/.test(…)  // in the code
/^M*D?C{0,3}L?X{0,3}V?I{0,3}$/.test(…)  // with Roman symbols

Kutsal inek, bunun ezoterik olmayan dillerde 200 bayttan daha kısa sürede yapılmasını beklemiyordum! Bunun nasıl çalıştığını açıklamak ister misiniz?
Don Bin

Ancak, bunun biraz talihsiz olan TIO'da * n *> 4 için işe yaramadığını fark ettim.
Don Bin

@RushabhMehta Daha yüksek değerleri test etmek için özyinelemeli olmayan bir sürüm ekledim. Bunu golf oynadığım zaman bir açıklama ekleyeceğim.
Arnauld

0

Cı, 150 123 bayt

Açıklamayı yeterince yakından okumadım, bu yüzden bu, standart Romen rakamlarının sayısını (benzeri ifadelerin IVIsayılmadığı) üretir . Biraz çaba gösterdiğim için, yine de paylaşacağımı düşündüm.

#define F(X) for(X=10;X--;)
x[]={0,1,2,3,2,1,2,3,4,2};f(i,o,a,b,c){for(i++;i--;)F(a)F(b)F(c)o+=i==x[a]+x[b]+x[c];return o;}

Orijinal (150 bayt):

#define F(X) for(X=10;X--;)
i,o,a,b,c,x[]={0,1,2,3,2,1,2,3,4,2};main(){scanf("%i",&i);for(i++;i--;)F(a)F(b)F(c)o+=i==x[a]+x[b]+x[c];printf("%i\n",o);}

1
Yalnızca geçerli gönderiler gönderebilirsiniz.
Okx

@CurtisBechtel Sanırım çözümü burada tutabilirsiniz, ancak meydan okuma kurallarını karşılamak için değiştirmeye çalışırım.
Don Bin

1
Sanırım F(X)ve arasındaki boşluğu kaldırabilirsinizfor(X=10;X--;)
Zacharý
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.