Bak ve Söyle dizisi: Romen rakamları baskısı


20

Meydan okuma açıklaması

Bak ve Söyle dizisini içeren birkaç zorluk yaşadık . Hızlı hatırlatma:

  • Dizi şununla başlar 1,
  • Bu dizinin sonraki terimleri, önceki terimde her yinelenen basamak grubunun numaralandırılmasıyla oluşturulur,

İlk birkaç terim:

1        "one"
11       "one one" (we look at the previous term)
21       "two ones"
1211     "one two, one one"
111221   "one one, one two, two ones"
312211   "three ones, two twos, one one"

Şimdi aynı şeyi yapalım, bunun yerine Romen Rakamlarını kullanalım . Biz başlamak I(Okuduğumuz bu yüzden, bunun yerine karakterlere haneli sayma kuralı uygulamak ve aynı kuralları takip IVXolarak one one, one five, one tenyerine one four, one tenveya başka bir şekilde):

I           "one"
II          "one one"
III         "two ones" = "II" + "I"
IIII        "three ones" = "III" + "I"
IVI         "four ones" = "IV" + "I"
IIIVII      "one one, one five, one one"
IIIIIVIII   "three ones, one five, two ones" = ("III" + "I") + ("I" + "V") + ("II" + "I")

Olumlu bir tamsayı verildiğinde N:

  • NBu dizinin ilk sayılarını çıktılayın (makul bir ayırıcı da iyidir["I", "II", "III", ...]
  • NBu dizinin çıktı terimi (0 indeksli olabilir).

Bu bir meydan okuma olduğundan, mümkün olduğunca kısa yapmayı unutmayın !

EDIT: Her zaman tamsayı Romen rakamları olarak ifade etmek için bir standart / tercih edilen yolu olduğuna inanıyorum ( yerine 95-> gibi ). Online Romen rakam dönüştürücüler birkaç Bence doğrulamak bulundu. Şüpheniz varsa, tüm olası uç durumları ve Romen rakamlarını yazmanın belirli kurallarını listeleyen bir çevrimiçi dönüştürücü kullanın , bu zorluğun noktası değildir.XCVVC

EDIT2: @PeterTaylor ve @GregMartin olduğuna dikkat çeken tek sayılar daha az veya hiç eşit 5Romen rakamına belirsizliği konusunda endişe etmek zorunda kalmamak için, sırayla görünür (sayılar 1- 8vardır I, II, III, IV, V, VI, VII, ve VIII)


Her tamsayı için benzersiz bir Romen rakamı ifadesi yoktur. Hangi sayıları ifade etmek gerekebilir ve bu sayıların hangi ifadeleri geçerlidir?
Peter Taylor

"Her bir tamsayı için benzersiz bir Romen rakamı ifadesi yok" ile ne demek istiyorsun? Beğen 4/ IV/ IIII? Veya 95/ XCV/ VC? Her zaman bir tamsayıyı ifade etmenin benzersiz bir yolu olmayabilir, ancak her zaman tercih edilen (standart) bir tane olduğundan eminim - yanlışsam beni düzeltin.
shooqie

1
Roma rakamları ile ne kadar ilerlememiz gerekiyor?
Maltysen

Evet, her iki durumda. İkinci durumda, bence bu tercih edilen bir görüş meselesidir.
Peter Taylor

9
@shooqie bu ayrıntılar netleştirilmemiş olsaydı, cevapları nasıl karşılaştırırdınız? Yorum yapmak için bırakılan bazı kenar durumlar varsa, gerçek puanlar anlamsızlaşır, çünkü karşılaşabileceğiniz herhangi bir golf hilesinden daha büyük bir fark yaratabilirler.
Martin Ender

Yanıtlar:


17

Perl, 49 bayt

İçin +1 içerir -p

STDIN'de 0 tabanlı dizinle çalıştırın, ör.

ecce.pl <<< 14

ecce.pl:

#!/usr/bin/perl -p
s,(.)\1*,$&/$1%182 .$1,eg for($_=/$/)x$`;y;19;IV

Sihirli formüller çok sihirlidir.

Normalde ($_=//)x$'döngü kontrolünü bir bayt daha kısa yapmak için kullanırım , ancak bu sitede puanlama 2 handikap verir, böylece 1 bayt daha uzun sürer. Daha eski perlslerde alanı daha önce bırakabilirsiniz for. Bazı perl sürümleri ;, harf çevirisini kapatmak için bir final eklemenize zorlar . Ancak yukarıda verilen, sistemimde çalışan kod.

açıklama

Çözümden koda geriye doğru çalışma:

İhtiyacımız olan dize dönüşümleri:

I     -> II
II    -> III
III   -> IIII
IIII  -> IVI
IIIII -> VI

V     -> IV
VV    -> IIV

Her değiştirme işlemi tekrarlanan karakterle biter. Ben regex kullanarak aynı karakterlerden bir dizi alacak /(.)\1*/, böylece bu ekleyerek yapılabilir $1. Önceki kısım ->içindedir $&. Bununla hala ihtiyacım var:

I     -> I
II    -> II
III   -> III
IIII  -> IV
IIIII -> V

V     -> I
VV    -> II

Yazın Iolarak 1ve V9 olarak:

1     -> 1
11    -> 11
111   -> 111
1111  -> 19
11111 -> 9

9     -> 1
99    -> 11

Önceki bölümü ->tekrarlanan sayıya bölerek bu olur:

1     -> 1
11    -> 11
111   -> 111
1111  -> 19
11111 -> 9

1     -> 1
11    -> 11

Şimdi tekrarlanan orijinal Vartık bir istisna değil. Bu yüzden bunu yapan bir ifade istiyorum:

1     -> 1
11    -> 11
111   -> 111
1111  -> 19
11111 -> 9

Ve bu basit bir modulo 182 ile yapılabilir:

1     % 182 = 1
11    % 182 = 11
111   % 182 = 111
1111  % 182 = 19
11111 % 182 = 9

(Bu bile alır IIIIIIiçin VIburada gerekli olmasa da sağa)

Sol olduğunu Tümüne çalışan değişken başlatılıyor 1indeksi 0, bir döngü içinde bu dönüşümü tekrarlayın ve sonunda yerini 1tarafından Ive 9tarafındanV

1, 9Ve 182sadece parametre kombinasyonunun bu basit bir formül çalışır.


2
Bu dahi! :)
Lynn

10

Mathematica, 113 90 83 bayt

Uzunluğu% 25'in üzerine düşüren öneriler için Martin Ender'e teşekkürler!

Mathematica'daki üst düzey komutların gösterilmesi.

Nest[Flatten[Characters@{RomanNumeral@#,#2}&@@@Reverse@@@Tally/@Split@#]&,{"I"},#]&

Saf bir işlev, bir argüman N alarak ve bu (0 dizinli) dizinin Nth elemanını karakter listesi olarak çıktılamak. Biraz yay:

Nest[
  Flatten[
    Characters @ {RomanNumeral@#,#2}& @@@
      Reverse @@@ Tally /@ Split@ #
    ]& ,
  {"I"}, #]&

Dış , N kez Nestbaşlayarak orta dört satır işlevini yineler {"I"}. Satır 4, giriş Romen rakamının karakter listesini benzer karakterlerden oluşan gruplara ayırır, her çalışmayı Tallysayar ve sayıları saydıkları karakterlerden önce koyar. Satır 3, sayıları Romen rakamları olarak işler, ardından bu Romen rakamlarını karakter listelerine böler. FlattenKomut tek boyutlu bir listeye tüm liste-of-the listelerini azaltır.

İşte ilk sürüm:

Nest[
  "" <> Flatten[{RomanNumeral@#[[1]], #[[2]]} & /@
    (Reverse@#[[1]] & /@ 
      Tally /@
        Split@Characters@#)] &,
  "I", #] &

3
Grrr Mathematica;)
Beta Çürümesi

Eğer kullanırsanız @@@yerine /@kullanabileceğiniz #ve #2yerine #[[1]]ve #[[2]]. Ayrıca, karakter listeleri kabul edilebilir dize türleridir, bu nedenle bunlarla çalışabilir ve kullanmaktan kaçınabilirsiniz Characters@.
Martin Ender

@MartinEnder Aha, benzer bir @@@kısayol olması gerektiğini biliyordum ! Kabul edilebilir dize türleri olan karakterlerin listeleri gelince (ki bu kodu kısaltacağını kabul ediyorum): Bu sitede bana topluluk standartlarını açıklayan bir yazı var mı?
Greg Martin


1
Bir kaç tasarrufu: Charactersipler otomatik böylece kullanabilirsiniz @, Reverse@#&düz olarak elbette aynı olduğu Reversebu durumda aynı zamanda bu parantez gerek yoktur. Ve öneki gösterimi (durumunda Flatten), çalışması için parantez eklemeniz gerekiyorsa hiçbir şey kaydetmez. Tüm bunları bir araya Nest[Flatten[Characters@{RomanNumeral@#,#2}&@@@Reverse@@@Tally/@Split@#]&,{"I"},#]&
Martin Ender

8

CJam ( 33 30 bayt)

"I"{e`{(4md1$^'I*\'V*@}%e_}ri*

Çevrimiçi demo

Uygulamanın doğruluğunun anahtarı aşağıdaki teoremdir:

İlk nesil ise I, hiçbir çalışma uzunluğu beşten fazla değildir

Lemma: eğer ilk nesil ise I, hiçbir dize içermez VVV. İspat çelişkilidir. Bir ilk endeks olduğunu varsayalım nhangi ninci nesil içerir VVV. Bu , önceki nesilden dönüşümün kötü olması durumunda VVVbozulursa (a)V VV: olması gerekirdi (a+5)V. Öyleyse , seçimiyle çelişen ve VV V(d)önceki nesil içerdi .VVVVVn

Şimdi, ilk endeks olduğunu varsayalım molan minci nesil içerir ...IIIIII.... Daha önce hiçbir neslin dokuz s veya dokuz s koşusu olmadığından, dize dışında Ive Vdizede basamak bulunmayabileceğini unutmayın . En az dört saniyelik bir çalışma geliyor önceki dizede s, bu nedenle önceki dizenin karşılık gelen bölümü olmalıdır vererek . Yana nesilde gelmiyor (Lemmasını bakınız), ikinci basamak bir çalışma uzunlukta olmalıdır böylece nesilde, elimizdeki . İstediğimiz beri ilk ler vermek değil yaIVII...IIIVV...... IIII IIV ...VVm-1VVVVVVIm-1...IIIVVI...IIIIIIVIVI, öncesinde dizenin başlangıcı veya bir V.

Eğer (...V)?IIIVVI...neslimiz varsa , neslimizde m-1ne var m-2? Zaten genin olduğunu gözlemledik VV. m-1olarak ayrıştırılmalıdır (a)V V(I).

Varsayalım a=2: (...V)?I IIV VI...Aslında bu ...VI IIV VI...önderlik bir Vparçası olsa da IV; yani önceki nesilde ya (...V)? IIII VV IIIII...ya (...V)? IIIII VV IIIII. Her iki şekilde de sorun yaşıyoruz VVIIIII: ikincisi Vbir çalışma uzunluğu olmalı, ancak ...VI IIII...aynı basamakla aşağıdaki (çalışma uzunluğu, basamak) çifti gerektiriyor.

Bu yüzden olmalı a=1: (...V)?II IV VI.... Nesil yana maltı bir çalışma ile ilk Is, o olmalı (...V)? II IV VI...nesil böylece, m-2olduğu (...V)? I V IIIII.... ...VIVIIIII...ancak imkansız: ancak ikincisini Vaynı haneye sahip iki ardışık (çalışma uzunluğu, basamak) çifti ile yorumlamayı seçiyoruz .

Bu nedenle nesil m-2edilmelidir ^IVIIIII...olarak çözümlenir ^IV IIII I(V)...veya ^IV III II(V).... Bunlar sırasıyla jenerasyon m-3olarak ^V III V ...ya da ^V II VV....

Ancak, ilk olarak başlayan dizelerden başlayarak Vbakarsak, bir döngü elde ederiz:

    VI IV I...
    IV III IV ...
    II IV IVI ...
    IIII IV II IV ...

ve böylece hiçbir nesil VIIIVveya ile başlamaz VIIVV. Böyle bir şey olmadığı sonucuna varmalıyız m.

teşrih

"I"          e# Initial generation
{            e# Loop...
  e`         e#   Run-length encode
  {          e#   Foreach [run-length char] pair...
    (        e#     Extract the run-length r
    4md1$^   e#     Get the number of Vs and the number of Is
             e#     The number of Vs is r/4 ; the number of Is is (r%4)^(r/4)
    'I*\'V*@ e#     Repeat strings the appropriate number of times and reorder
  }%
  e_         e#  Flatten to a simple string
}ri*         e# ... n times, where n is taken from stdin

6

Python 3, 195 bayt

Romen rakamlarında çok fazla bayt harcanır, bu yüzden orada golf oynamak mümkündür.

@ El'endiaStarman, @ Sherlock9 ve @Shooqie sayesinde

import re
def f(x,r=""):
 for v,i in(5,"V"),(4,"IV"),(1,"I"):a,x=divmod(x,v);r+=i*a
 return r
s="I"
for i in[0]*int(input()):print(s);s=re.sub(r'(.)\1*',lambda m:f(len(m.group()))+m.group()[0],s)

Boşver!


Köşeli parantezleri atlayabilirsiniz:for v,i in(5,"V"),(4,"IV"),(1,"I")
shooqie

@shooqie Bunu yapabileceğine dair hiçbir fikrim yoktu: D
Beta

for v,i in(5,"V"),(4,"IV"),(1,"I"):a,x=divmod(x,v);r+=i*abir bayt kaydeder.
Sherlock9

@ βετѧΛєҫαγ: Ayrıca, i(olduğu gibi for i in range(...)) kullanmıyorsunuz . İle dabbling denedim execama bu 1'alt' yöntem kaçtı kodu berbat gibi görünüyor, ben bir geçici çözüm bulamadı.
shooqie

@shooqie Ben kurtularak biraz kısalttımrange
Beta Çürüme

4

R, 110 107 bayt

as.romanile birleştirmek rlebunu kolaylaştırır. Kötüye kullanımı kapsamak ve yerleşik kedi davranışını <<-birkaç bayt kurtarır.

x="I"
replicate(scan(),{r=rle(strsplit(x,"")[[1]])
x<<-paste(rbind(paste(as.roman(r$l)),r$v),collapse="")})

Konsoldan N alır. İlk 2 ila N dizi terimleri çıktılar (ki bu özellik içinde olduğuna inanıyorum ...)

 [1] "II"                                                                                                                                                                                                                                     
 [2] "III"                                                                                                                                                                                                                                    
 [3] "IIII"                                                                                                                                                                                                                                   
 [4] "IVI"                                                                                                                                                                                                                                    
 [5] "IIIVII"                                                                                                                                                                                                                                 
 [6] "IIIIIVIII"                                                                                                                                                                                                                              
 [7] "VIIVIIII"                                                                                                                                                                                                                               
 [8] "IVIIIIVIVI"                                                                                                                                                                                                                             
 [9] "IIIVIVIIVIIIVII"                                                                                                                                                                                                                        
[10] "IIIIIVIIIVIIIIVIIIIIVIII"                                                                                                                                                                                                               
[11] "VIIVIIIIIVIVIIVVIIVIIII"                                                                                                                                                                                                                
[12] "IVIIIIVVIIVIIIVIIIIIVIIIIVIVI"                                                                                                                                                                                                          
[13] "IIIVIVIIIVIIIIVIIIIIVVIIVIVIIVIIIVII"                                                                                                                                                                                                   
[14] "IIIIIVIIIVIIIIIVIVIIVVIIIVIIIIVIIIVIIIIVIIIIIVIII"                                                                                                                                                                                      
[15] "VIIVIIIIIVVIIVIIIVIIIIIVIIIIIVIVIIVIIIIIVIVIIVVIIVIIII"                                                                                                                                                                                 
[16] "IVIIIIVVIIIVIIIIVIIIIIVVIIVVIIVIIIVIIIIVVIIVIIIVIIIIIVIIIIVIVI"                                                                                                                                                                         
[17] "IIIVIVIIIVIIIIIVIVIIVVIIIVIIIIIVIIIIVIIIIIVIVIIIVIIIIVIIIIIVVIIVIVIIVIIIVII"                                                                                                                                                            
[18] "IIIIIVIIIVIIIIIVVIIVIIIVIIIIIVIIIIIVVIIVIVIIVVIIVIIIVIIIIIVIVIIVVIIIVIIIIVIIIVIIIIVIIIIIVIII"                                                                                                                                           
[19] "VIIVIIIIIVVIIIVIIIIVIIIIIVVIIVVIIIVIIIIVIIIVIIIIIVIIIIVIIIIIVVIIVIIIVIIIIIVIIIIIVIVIIVIIIIIVIVIIVVIIVIIII"                                                                                                                              
[20] "IVIIIIVVIIIVIIIIIVIVIIVVIIIVIIIIIVIIIIIVIVIIVIIIIIVVIIVIVIIVVIIIVIIIIVIIIIIVVIIVVIIVIIIVIIIIVVIIVIIIVIIIIIVIIIIVIVI"                                                                                                                    
[21] "IIIVIVIIIVIIIIIVVIIVIIIVIIIIIVIIIIIVVIIVVIIVIIIVIIIIVVIIIVIIIIVIIIVIIIIIVIIIIIVIVIIVVIIIVIIIIIVIIIIVIIIIIVIVIIIVIIIIVIIIIIVVIIVIVIIVIIIVII"                                                                                             
[22] "IIIIIVIIIVIIIIIVVIIIVIIIIVIIIIIVVIIVVIIIVIIIIIVIIIIVIIIIIVIVIIIVIIIIIVIVIIVIIIIIVVIIVVIIVIIIVIIIIIVIIIIIVVIIVIVIIVVIIVIIIVIIIIIVIVIIVVIIIVIIIIVIIIVIIIIVIIIIIVIII"                                                                      
[23] "VIIVIIIIIVVIIIVIIIIIVIVIIVVIIIVIIIIIVIIIIIVVIIVIVIIVVIIVIIIVIIIIIVVIIVIIIVIIIIVVIIIVIIIIIVIIIIVIIIIIVVIIVVIIIVIIIIVIIIVIIIIIVIIIIVIIIIIVVIIVIIIVIIIIIVIIIIIVIVIIVIIIIIVIVIIVVIIVIIII"                                                   
[24] "IVIIIIVVIIIVIIIIIVVIIVIIIVIIIIIVIIIIIVVIIVVIIIVIIIIVIIIVIIIIIVIIIIVIIIIIVVIIIVIIIIVIIIIIVIVIIIVIIIIIVVIIVIVIIVVIIIVIIIIIVIIIIIVIVIIVIIIIIVVIIVIVIIVVIIIVIIIIVIIIIIVVIIVVIIVIIIVIIIIVVIIVIIIVIIIIIVIIIIVIVI"                             
[25] "IIIVIVIIIVIIIIIVVIIIVIIIIVIIIIIVVIIVVIIIVIIIIIVIIIIIVIVIIVIIIIIVVIIVIVIIVVIIIVIIIIIVIVIIVVIIVIIIVIIIIIVVIIIVIIIIVIIIVIIIIIVIIIIIVVIIVVIIVIIIVIIIIVVIIIVIIIIVIIIVIIIIIVIIIIIVIVIIVVIIIVIIIIIVIIIIVIIIIIVIVIIIVIIIIVIIIIIVVIIVIVIIVIIIVII"

1

JavaScript (ES6), 107

0 terim temelli N. Terim döndüren özyinelemeli işlev

f=(n,r='I')=>n?f(n-1,r.match(/I+|V+/g).map(x=>((n=x.length)-4?'VIII'.slice(n<5,1+n%5):'IV')+x[0]).join``):r

Ölçek

f=(n,r='I')=>n?f(n-1,r.match(/I+|V+/g).map(x=>((n=x.length)-4?'VIII'.slice(n<5,1+n%5):'IV')+x[0]).join``):r

function update() {
  O.textContent=f(I.value)
}

update()
<input id=I value=25 type=number oninput='update()'><pre id=O></pre>


1

Perl 6 , 62 bayt

{("I",{S:g/(.)$0*/{<I II III IV V>[$/.chars-1]~$0}/}...*)[$_]}

Sıfır tabanlı bir dizini kabul eden anonim işlev.

5'ten yüksek Roma rakamlarının gerekli olmadığı gerçeğini kullanır, çünkü ortaya çıkabilecek tekrarlayan rakamların tek grupları şunlardır:

I     -> II
II    -> III
III   -> IIII
IIII  -> IVI
IIIII -> VI

V     -> IV
VV    -> IIV

( çevrimiçi deneyin )

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.