Tulis program yang menghitung dari 1 hingga 100 dalam Angka Romawi dan cetak angka-angka ini dengan output standar. Masing-masing angka harus dipisahkan dengan spasi.
Anda tidak dapat menggunakan fungsi bawaan untuk mengubah ke angka romawi atau aplikasi eksternal atau pustaka untuk melakukannya.
Hasil yang diinginkan adalah
I II III IV V VI VII VIII IX X XI XII XIII XIV XV XVI XVII XVIII XIX XX XXI XXII XXIII XXIV XXV XXVI XXVII XXVIII XXIX XXX XXXI XXXII XXXIII XXXIV XXXV XXXVI XXXVII XXXVIII XXXIX XL XLI XLII XLIII XLIV XLV XLVI XLVII XLVIII XLIX L LI LII LIII LIV LV LVI LVII LVIII LIX LX LXI LXII LXIII LXIV LXV LXVI LXVII LXVIII LXIX LXX LXXI LXXII LXXIII LXXIV LXXV LXXVI LXXVII LXXVIII LXXIX LXXX LXXXI LXXXII LXXXIII LXXXIV LXXXV LXXXVI LXXXVII LXXXVIII LXXXIX XC XCI XCII XCIII XCIV XCV XCVI XCVII XCVIII XCIX C
Karena ini adalah tantangan kode golf, kode terpendek menang .
Jawaban:
Perl 69 byte
Bekerja dengan formula ajaib. Ekspresi
"32e$&"%72726
mengubah setiap digit dengan cara berikut:0⇒32, 1⇒320, 2⇒3200, 3⇒32000, 4⇒29096, 5⇒56, 6⇒560, 7⇒5600, 8⇒56000, 9⇒50918
Setelah menerapkan terjemahan
y/016/IXV/
, kami memiliki ini sebagai gantinya:0⇒32, 1⇒32 I , 2⇒32 II , 3⇒32 III , 4⇒29 I 9 V , 5⇒5 V , 6⇒5 VI , 7⇒5 VII , 8⇒5 VIII , 9⇒5 I 9 X 8
Sisa digit (
2-57-9
) dihapus. Perhatikan bahwa ini dapat ditingkatkan dengan satu byte dengan menggunakan formula yang diterjemahkan012
bukan016
, menyederhanakan/XVI60-9/
untuk/XVI0-9/
. Saya tidak dapat menemukan satu, tapi mungkin Anda akan lebih beruntung.Setelah satu digit ditransformasi dengan cara ini, proses berulang untuk digit berikutnya, menambahkan hasilnya, dan menerjemahkan sebelumnya
XVI
keCLX
pada saat yang sama terjemahan untuk digit baru terjadi.Perbarui
Pencarian lengkap tidak mengungkapkan apa pun yang lebih pendek. Namun, saya menemukan solusi 69 byte alternatif:
Yang ini menggunakan
0-2
substitusi untukIXV
, tetapi memiliki modulo yang satu digit lebih panjang.Pembaruan:
6665 byteVersi ini sangat berbeda, jadi saya mungkin harus mengatakan beberapa kata tentang itu. Rumus yang digunakannya sebenarnya satu byte lebih panjang!
Karena tidak dapat mempersingkat formula, saya memutuskan untuk mengurangi apa yang saya miliki. Tidak lama sampai saya ingat teman lama saya
$\
. Ketikaprint
statment dikeluarkan,$\
secara otomatis ditambahkan ke akhir output. Saya dapat menyingkirkan$a[$_]
konstruksi canggung untuk peningkatan dua byte:Jauh lebih baik, tapi itu
$\=!print$"
masih tampak agak bertele-tele. Saya kemudian ingat formula panjang alternatif yang sama yang saya temukan yang tidak mengandung angka3
dalam transformasi digitnya. Jadi, seharusnya bisa digunakan$\=2+print
sebagai gantinya, dan gantikan hasilnya3
dengan spasi:Juga 67 byte, karena spasi yang diperlukan antara
print
danfor
.Tetapi, jika ada formula yang tidak menggunakan di
1
mana pun,$\=2+print
menjadi$\=print
penghematan dua byte lagi. Bahkan jika itu satu byte lebih lama, itu masih akan menjadi perbaikan.Ternyata, formula seperti itu memang ada, tetapi satu byte lebih panjang dari aslinya, menghasilkan skor akhir 65 byte :
Metodologi
Pertanyaannya adalah bagaimana orang bisa menemukan formula seperti itu. Secara umum, menemukan formula ajaib untuk menggeneralisasi set data apa pun adalah masalah probabilitas. Artinya, Anda ingin memilih bentuk yang mungkin menghasilkan sesuatu yang mirip dengan hasil yang diinginkan.
Mengeluarkan beberapa angka romawi pertama:
ada beberapa keteraturan untuk dilihat. Khususnya, dari 0-3 dan sekali lagi dari 5-8 , setiap istilah berturut-turut bertambah panjangnya dengan satu angka. Jika kami ingin membuat pemetaan dari angka ke angka, kami ingin memiliki ekspresi yang juga bertambah panjang satu digit untuk setiap istilah berturut-turut. Pilihan logis adalah k • 10 d di mana d adalah digit yang sesuai, dan k adalah konstanta bilangan bulat apa pun.
Ini berfungsi untuk 0-3 , tetapi 4 perlu memutus pola. Apa yang bisa kita lakukan di sini adalah menempel pada modulo:
k • 10 d % m , di mana m berada di antara k • 10 3 dan k • 10 4 . Ini akan membuat rentang 0-3 tidak tersentuh, dan memodifikasi 4 sehingga tidak akan mengandung empat
I
s. Jika kami juga membatasi algoritma pencarian kami sehingga residu modular 5 , sebut saja j , kurang dari m / 1000 , ini akan memastikan bahwa kami juga memiliki keteraturan dari 5-8 juga. Hasilnya kira-kira seperti ini:Seperti yang Anda lihat, jika kita ganti
0
denganI
, 0-3 dan 5-8 semuanya dijamin akan dipetakan dengan benar! Nilai untuk 4 dan 9 perlu dipaksakan dengan kasar. Secara khusus, 4 harus mengandung satu0
dan satuj
(dalam urutan itu), dan 9 perlu mengandung satu0
, diikuti oleh satu digit lain yang tidak muncul di tempat lain. Tentu saja, ada sejumlah formula lain, yang oleh beberapa kebetulan kebetulan dapat menghasilkan hasil yang diinginkan. Beberapa dari mereka bahkan mungkin lebih pendek. Tapi saya tidak berpikir ada yang mungkin berhasil seperti ini.Saya juga bereksperimen dengan beberapa penggantian untuk
I
dan / atauV
dengan beberapa keberhasilan. Namun sayang, tidak ada yang lebih pendek dari apa yang sudah saya miliki. Berikut adalah daftar solusi terpendek yang saya temukan (jumlah solusi 1-2 byte lebih berat terlalu banyak untuk dicantumkan):sumber
HTML + JavaScript + CSS (137)
HTML (9)
JavaScript (101)
CSS (27)
Keluaran
...
Demo di JSBin
sumber
document.write('<ol>'+"<li style='list-style:upper-roman'/>".repeat(100)+'</ol>')
(ES6)document.write("<li style='list-style:upper-roman'/>".repeat(100))
Python 116
kode golf yang lebih baik dari jawaban scleaver:
sumber
Python, 139
sumber
C,
177160147 karakterAda solusi yang lebih pendek, tetapi tidak ada dalam C, jadi inilah upaya saya.
Solusi baru, sangat berbeda dari yang sebelumnya:
Solusi sebelumnya (160 karakter):
Logika:
1.
f
mencetak angka dari 1 hingga 10.c
adalah angka yang digunakan, yang dapat berupaIVX
atauXLC
. Dipanggil satu kali untuk puluhan satu kali untuk yang satu.2. Jika
n%5==0
- tidak mencetak apa pun atauc[n/5]
yangI
atauV
(atauL
atauC
).3. Jika
n%4==4
-4
atau9
- cetakI
(atauX
), olehn+1
.4. Jika
n>4
- cetak5
(yaituV
atauL
) lalun-5
.5. Jika
n<4
- cetakI
lalun-1
(yaitun
waktuI
).sumber
f(c,n){printf("%.*s",n%5>3?2:n%5+n/5,"XLXXXCIVIIIX "+c+(n%5>3?n%4*4:2-n/5));}main(i){for(;i<100;f(12,4))f(0,i/10),f(6,i++%10);puts("C");}
JavaScript, 123
Terinspirasi oleh versi yang lebih panjang, saya menemukan di newsgroup Polandia (setidaknya, Chrome pikir itu Polandia).
sumber
Q (
8180)2nd cut:
1st cut:
sumber
Python, 168
Penjelasan
Dengan menggunakan nilai-nilai ini, ambil nilai terbesar yang tidak lebih besar dari n dan kurangi dari n. Ulangi sampai n adalah 0.
sumber
r=lambda n,l,v:n and(n<v[0]and r(n,l[1:],v[1:])or l[0]+r(n-v[0],l,v))or""
menyimpan dua karakter. Kalau tidak, sangat bagus.Ruby 1.9,
140132Ini secara harfiah dihitung dari 1 hingga 100 dalam angka Romawi. Mulai dengan string kosong, kemudian loop melalui menambahkan "I" dan kemudian berulang kali menerapkan serangkaian aturan substitusi, secara efektif menambahkan 1.
Sunting: Menambahkan nomor versi, karena
?I
hanya berfungsi di 1.9, dan menggunakan perubahan @ Howard untuk memangkas beberapa karakter.sumber
r while
->0while
,r.sub!(*q)
->r.sub! *q
. Anda juga dapat menarik cetakan di dalam lingkaran dan menggunakan100.times{...}
alih-alih pernyataan peta.(%w[IIII VIV XXXX LXL]<</(.)((?!\1)[^I])\1/).zip(%w(IV IX XL XC)<<'\2')
menghemat 7 karakter.Ruby 112 chars
Pada dasarnya menggunakan
to_roman
metode yang dijelaskan di sini , tetapi menggunakan array zip untuk singkatnya.sumber
Mathematica
159 150142Built-in solusi :
IntegerString
, 38 charssumber
perl 205
Golf:
sumber
MUMPS 184
Algoritma yang sama dengan @cardboard_box, dari siapa saya telah mengambil penjelasan kata demi kata -
Penjelasan
Dengan menggunakan nilai-nilai ini, ambil nilai terbesar yang tidak lebih besar dari n dan kurangi dari n. Ulangi sampai n adalah 0.
sumber
R , 85 byte
Cobalah online!
Menggunakan
utils
variabel paket acak.romans
untuk mendapatkan nilai - nilai angka romawi, tetapi melakukan konversi dengan sendirinya; pendekatan bawaan adalah 20 byte:cat(as.roman(1:100))
sumber
cat(paste(as.roman(1:100)))
atau hanyaas.roman(1:100)
. Aneh.cat
menunjukkan bahwa ia melakukan lebih sedikit konversi daripadaprint
dan hanya berfungsi padaatomic
vektor - jadi itu menjelaskan hal ini!APL 128
Saya mencoba solusi pengindeksan di APL:
Ini bisa menjadi 4 byte lebih pendek dalam asal indeks 0 bukannya 1 tetapi ruang nyata babi adalah generasi dari matriks indeks melalui:
Sejauh ini saya belum bisa menghasilkan indeks dengan cepat!
sumber
LaTeX (138)
sumber
Python, 125
sumber
PHP,
3837 byte<ol type=I><?=str_repeat("<li>",100);
-1 byte terima kasih kepada @manatwork
Gagasan yang sama dengan jawaban Patrick , tetapi dalam bahasa yang lebih ringkas. Beats Mathematica !
Cobalah secara Online!
sumber
;
, maka tidak perlu?>
.VBA (Excel), 245 byte
Fungsi dibuat untuk Pengulangan dan Ganti - 91 byte
Function s(a,b):s=String(a,b):End Function Function b(x,y,z):b=Replace(x,y,z):End Function
menggunakan jendela langsung ( 154 byte )
p="I":for x=1to 100:?b(b(b(b(b(b(b(b(s(x,p),s(100,p),"C"),s(90,p),"XC"),s(50,p),"L"),s(40,p),"XL"),s(10,p),"X"),s(9,p),"IX"),s(5,p),"V"),s(4,p),"IV"):next
sumber
Java (OpenJDK 8) , 152 byte
Cobalah online!
Penjelasan:
sumber
TeX, 354 byte
Beberapa penjelasan: TeX menyediakan perintah
\romannumeral
bawaan untuk mengonversi angka menjadi angka Romawi. Karena pertanyaan tidak memungkinkan untuk menggunakan fungsi-fungsi bawaan, kode di atas adalah versi golf dari algoritma yang sama yang digunakan oleh compiler TeX asli Knuth untuk\romannumeral
(lihat TeX: Program , § 69,print_roman_int
) diimplementasikan kembali di TeX.Karena ia ingin meninggalkan kegembiraan karena bingung bagaimana kode ini bekerja untuk pembaca, Knuth menolak untuk memberikan penjelasan tentang bagian kode ini. Jadi saya akan mengikuti dan memberikan versi yang tidak diubah dan sedikit dimodifikasi, yang lebih dekat ke aslinya daripada kode di atas:
sumber