Напишите программу, которая считает римскими цифрами от 1 до 100, и напечатайте эти числа стандартным выводом. Каждое из чисел должно быть разделено пробелами.
Вы не можете использовать любую встроенную функцию для преобразования в римские цифры или внешнее приложение или библиотеку для этого.
Желаемый результат
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
Так как это сложная игра в гольф, выигрывает самый короткий код .
Ответы:
Perl 69 байт
Работает по волшебной формуле. Выражение
"32e$&"%72726
преобразует каждую цифру следующим образом:0⇒32, 1⇒ 320, 2⇒ 3200, 3⇒ 32000, 4⇒29096, 5⇒56, 6⇒560, 7⇒5600, 8⇒56000, 9⇒50918
После применения перевода
y/016/IXV/
мы получаем это: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
Остальные цифры (
2-57-9
) удаляются. Обратите внимание, что это можно улучшить на один байт, используя формулу, которая переводит012
вместо016
упрощения/XVI60-9/
в/XVI0-9/
. Я не смог найти его, но, возможно, вам повезет больше.Как только одна цифра была преобразована таким образом, процесс повторяется для следующей цифры, добавляя результат и переводя предыдущие
XVI
sCLX
в то же самое время, когда происходит перевод новой цифры.Обновление
Исчерпывающий поиск не выявил ничего более короткого. Однако я нашел альтернативное 69-байтовое решение:
Этот использует
0-2
заменуIXV
, но имеет модуль, который на одну цифру длиннее.Обновление:
6665 байтЭта версия заметно отличается, поэтому я должен сказать несколько слов об этом. Формула, которую он использует, на самом деле на один байт длиннее!
Не в силах сократить формулу больше, чем она есть, я решил проиграть то, что у меня было. Прошло совсем немного времени, пока я не вспомнил своего старого друга
$\
. Когдаprint
выдается отчет,$\
он автоматически добавляется в конец вывода. Мне удалось избавиться от неудобной$a[$_]
конструкции для двухбайтового улучшения:Намного лучше, но это
$\=!print$"
все еще выглядело немного многословно. Затем я вспомнил альтернативную формулу равной длины, которую я нашел, которая не содержала число3
ни в одном из своих преобразований цифр. Таким образом, можно использовать$\=2+print
вместо этого и заменить полученное3
место пробелом:Также 67 байтов, из-за необходимого пробела между
print
иfor
.Но, если бы формула , которая не использовать в
1
любом месте,$\=2+print
становится$\=print
еще два байта на сумму экономии. Даже если бы он был на один байт длиннее, это все равно было бы улучшением.Как оказалось, такая формула существует, но она на один байт длиннее оригинальной, в результате чего итоговая оценка составляет 65 байт :
методология
Был задан вопрос, как можно найти такую формулу. В общем, поиск волшебной формулы для обобщения любого набора данных является вопросом вероятности. То есть вы хотите выбрать форму, которая с наибольшей вероятностью даст что-то похожее на желаемый результат.
Изучая первые несколько римских цифр:
есть некоторая закономерность, которую можно увидеть. В частности, с 0-3, а затем снова с 5-8 каждый последующий член увеличивается в длине на одну цифру. Если бы мы хотели создать отображение из цифр в цифры, мы бы хотели иметь выражение, которое также увеличивается в длине на одну цифру для каждого последующего члена. Логическим выбором является k • 10 d, где d - соответствующая цифра, а k - любая целочисленная константа.
Это работает для 0-3 , но 4 должен сломать образец. То, что мы можем сделать здесь, это прибавить по модулю:
k • 10 d % m , где m находится где-то между k • 10 3 и k • 10 4 . Это оставит диапазон 0-3 нетронутым и изменит 4 так , чтобы он не содержал четыре
I
с. Если мы дополнительно ограничим наш алгоритм поиска таким образом, чтобы модульный остаток 5 , назовем его j , был меньше m / 1000 , это также обеспечит регулярность 5-8 . Результат примерно такой:Как вы можете видеть, если мы заменим
0
сI
, 0-3 и 5-8 все гарантированно будет отображаться правильно! Значения 4 и 9 должны быть грубыми. В частности, 4 должен содержать один0
и одинj
(в этом порядке), а 9 должен содержать один0
, за которым следует еще одна цифра, которая больше нигде не появляется. Конечно, есть ряд других формул, которые по стечению обстоятельств могут привести к желаемому результату. Некоторые из них могут быть даже короче. Но я не думаю, что есть такие, кто может добиться успеха так же, как этот.Я также экспериментировал с множественными заменами
I
и / илиV
с некоторым успехом. Но увы, ничего короче того, что у меня уже было. Вот список самых коротких решений, которые я нашел (количество решений на 1-2 байта больше, слишком много, чтобы перечислять):источник
HTML + JavaScript + CSS (137)
HTML (9)
JavaScript (101)
CSS (27)
Выход
...
Демо на JSBin
источник
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
лучший гольф-код ответа Scleaver:
источник
Питон, 139
источник
С
177160147 символовЕсть более короткие решения, но их нет в C, так что вот моя попытка.
Новое решение, полностью отличающееся от моего предыдущего:
Предыдущее решение (160 символов):
Логика:
1.
f
печатает число от 1 до 10.c
Используются цифры, которые могут бытьIVX
илиXLC
. Вызывается один раз для десятков, один раз для тех.2. Если
n%5==0
- ничего не печатать илиc[n/5]
что естьI
илиV
(илиL
илиC
).3. Если
n%4==4
-4
или9
- распечататьI
(илиX
), с помощьюn+1
.4. Если
n>4
- печатать5
(то естьV
илиL
) тоn-5
.5. Если
n<4
- печататьI
тоn-1
(т.е.n
разI
).источник
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
Вдохновленный более длинной версией, я наткнулся на польскую группу новостей (по крайней мере, Chrome думал, что это польский язык).
источник
Q (
8180)2-й срез:
1-й срез:
источник
Питон, 168
объяснение
Используя эти значения, возьмите наибольшее значение не больше n и вычтите его из n. Повторяйте, пока n не станет 0.
источник
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""
сохраняет два символа. В остальном очень мило.Рубин 1.9,
140132Это буквально считается от 1 до 100 римскими цифрами. Начинается с пустой строки, затем циклически добавляется «I», а затем повторно применяется ряд правил подстановки, эффективно добавляя 1.
Редактировать: Добавлен номер версии, так как
?I
работает только в 1.9, и использовал изменения @ Howard для обрезки некоторых символов.источник
r while
->0while
,r.sub!(*q)
->r.sub! *q
. Вы также можете перетащить печать внутри цикла и использовать100.times{...}
вместо оператора map.(%w[IIII VIV XXXX LXL]<</(.)((?!\1)[^I])\1/).zip(%w(IV IX XL XC)<<'\2')
экономит 7 символов.Руби 112 символов
В основном используется
to_roman
метод, описанный здесь , но для краткости используется zip-массив.источник
Mathematica
159 150142Встроенное решение :
IntegerString
38 символовисточник
Perl 205
Golfed:
источник
MUMPS 184
Тот же алгоритм, что и у @cardboard_box, у которого я дословно взял объяснение -
объяснение
Используя эти значения, возьмите наибольшее значение не больше n и вычтите его из n. Повторяйте, пока n не станет 0.
источник
R , 85 байт
Попробуйте онлайн!
Использует случайную
utils
переменную пакета,.romans
чтобы получить значения римских цифр, но выполняет преобразование само по себе; встроенный подход будет 20 байтов:cat(as.roman(1:100))
источник
cat(paste(as.roman(1:100)))
или простоas.roman(1:100)
. Weird.cat
указывают на то, что он выполняет меньше преобразований, чемprint
и работает только наatomic
векторах - так что это объясняет!APL 128
Я попробовал решение для индексирования в APL:
Он может быть на 4 байта короче в начале индекса 0 вместо 1, но реальный пробел в пространстве - это создание матрицы индекса посредством:
До сих пор я не смог генерировать индексы на лету!
источник
Латекс (138)
источник
Питон, 125
источник
PHP,
3837 байт<ol type=I><?=str_repeat("<li>",100);
-1 байт благодаря @manatwork
Та же идея, что и в ответе Патрика , но на более компактном языке. Бьет Mathematica !
Попробуйте онлайн!
источник
;
, тогда нет необходимости?>
.VBA (Excel), 245 байт
созданная функция для повторения и замены - 91 байт
Function s(a,b):s=String(a,b):End Function Function b(x,y,z):b=Replace(x,y,z):End Function
используя непосредственное окно ( 154 байта )
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
источник
Java (OpenJDK 8) , 152 байта
Попробуйте онлайн!
Объяснение:
источник
TeX, 354 байта
Некоторое объяснение: TeX предоставляет встроенную команду
\romannumeral
для преобразования чисел в римские цифры. Поскольку вопрос не позволяет использовать встроенные функции, приведенный выше код представляет собой версию для гольфа того же самого алгоритма, который использует оригинальный компилятор TeX Кнута\romannumeral
(см. TeX: Программа , § 69print_roman_int
), повторно реализованный в TeX.Поскольку он хочет оставить читателю радость от размышлений о том, как этот код работает, Кнут отказывается дать объяснение этой части кода. Поэтому я последую их примеру и просто приведу неоправданную и слегка измененную версию, которая ближе к оригиналу, чем приведенный выше код:
источник