Числа як кругова графіка


36

Спочатку вивчіть цю головоломку, щоб відчути, що ви будете створювати.

Ваше завдання полягає в тому, щоб написати програму або функцію, яка виведе кругову графіку на зразок головоломки із зазначенням (базове 10) число від 1 до 100 (включно). Це схоже на це завдання , за винятком того, що ви будете створювати графічні, а не римські цифри. Наступні кола представляють числа 1-10 зліва направо:

коло візерунок

Як відповідає відповідь на головоломку, ваша графіка повинна читатись як римська цифра зсередини, де товщина рядка являє собою символи римської цифри, а вся графіка представляє число. Для ознайомлення, ось товщини ліній, які вам знадобляться. Кожен рядок повинен мати 3px прокладку між ним та наступним.

Number  Roman Numeral   Line Width
1       I               1px
5       V               3px
10      X               5px
50      L               7px
100     C               9px

Будь ласка, опублікуйте зразок чи два ваших результатів. Припустимо, що введення правильне, стандартні лазівки тощо тощо. Це кодовий гольф, тому виграє найменше байтів. У разі вирівнювання голосів виграє більшість голосів. Удачі!


3
Чи потрібний правильний абсолютний розмір зображення, чи достатньо мати правильні відносні розміри?
Девід Чжан

@DavidZhang Так, будь ласка, дотримуйтесь ліній та розмірів прокладки, які я перерахував, заради справедливості.
Ріп Ліб

Відповіді:


15

Mathematica - 166 181 байт

Трохи більш стислий, ніж інші відповіді Mathematica, частково завдяки більш стильному стилю.

c = Characters; r = Riffle;
Graphics[r[{0, 0}~Disk~# & /@ Reverse@Accumulate[
    l = {3} ~Join~ r[2 Position[c@"IVXLC", #][[1, 1]] - 1 & /@ 
        c@IntegerString[#, "Roman"], 3]], {White, Black}],
    ImageSize -> 2 Total@l] &

Весь пробіл призначений лише для ясності. Це визначає анонімну функцію, яка повертає потрібну графіку.

Анімація

Анімовані кола

Створення анімованого GIF з числових кіл є тривіальним у Mathematica, який має вбудовані функції для анімації та експорту послідовностей довільних об'єктів. Припускаючи, що вищезазначений код щойно виконаний,

Table[Show[%@n, PlotRange -> {{-100, 100}, {-100, 100}}, 
    ImageSize -> 200], {n, 1, 399, 1}];
Export["animcircles.gif", %]

Приклад Вихід

Приклад виведення


Будь ласка, опублікуйте кілька результатів. Вибачте за те, що не питаєте, що це перше місце. Я також змінив питання, щоб прийняти функції.
Ріп Ліб

Дякую за пропозиції @ MartinBüttner. Код був зафіксований для виведення зображень правильного розміру, і додано приклад виводу.
Девід Чжан

3
Ваша анімація хитається. Не те, щоб я міг зробити краще.
corsiKa

Хм, ти маєш рацію. Я дійсно не впевнений, чому це робиться, враховуючи, що я чітко вказав діапазон сюжету для Mathematica.
Девід Чжан

Може бути пов'язано з ворушити: mathematica.stackexchange.com/q/134272
CoreDump

15

Лист звичайний - 376 331 304 байти

(use-package(car(ql:quickload'vecto)))(lambda(n o &aux(r 3)l p)(map()(lambda(c)(setf l(position c" I V X L C D M")p(append`((set-line-width,l)(centered-circle-path 0 0,(+(/ l 2)r))(stroke))p)r(+ r l 3)))(format()"~@R"n))(with-canvas(:width(* 2 r):height(* 2 r))(translate r r)(map()'eval p)(save-png o)))

Приклади

введіть тут опис зображення(1) введіть тут опис зображення(24)

введіть тут опис зображення(104) введіть тут опис зображення(1903) введіть тут опис зображення(3999)

Анімація

Для номерів від 1 до 400:

Нові

NB: Для запису ця анімація робиться наступним чином:

У мене є модифікована версія коду, названа ringsякою повертає ширину створеного зображення. Отже, результат наступного циклу - максимальний розмір, тут 182 :

 (loop for x from 1 to 400
       maximize (rings x (format nil "/tmp/rings/ring~3,'0d.png" x)))

Весь цикл займає 9.573 секунди. Це дає приблизно 24 мс для кожного цілого числа. Потім в оболонці:

 convert -delay 5 -loop 0 -gravity center -extent 182x182 ring*png anim.gif

Безумовно

(ql:quickload :vecto)
(use-package :vecto)

(lambda (n o)
  (loop with r = 3
        for c across (format nil "~@R" n)
        for l = (1+ (* 2(position c"IVXLCDM")))
        for h = (/ l 2)
        collect `(,(incf r h),l) into p
        do (incf r (+ h 3))
        finally (with-canvas(:width (* 2 r) :height (* 2 r))
                  (loop for (x y) in p
                        do (set-line-width y)
                           (centered-circle-path r r x)
                           (stroke))
                  (save-png o))))

Пояснення

  • Функція приймає ціле число Nміж 1 і 3999 і ім'ям файлу

  • Я використовую (format nil "~@R" N)для перетворення з десяткової в римську. Наприклад:

     (format nil "~@R" 34) => "XXXIV"
    

    Рядок ~@R управління форматом визначений для роботи на цілі числа від 1 до 3999. Ось чому існує обмеження для діапазону дозволених входів.

  • Я повторюю над отриманим рядком, щоб створити список, Pщо містить (radius width)пари, для кожної цифри С.

    • Ширина - це просте лінійне відображення: я використовую постійний рядок "IVXLCDM" для обчислення положення С у ньому. Помноживши на два і додавши одне, отримуємо потрібне значення:

             (1+ (* 2 (position c "IVXLCDM")))
      

      Однак це робиться дещо інакше в гольф-версії:

             (position c " I V X L C D M")
      
    • При обчисленні кожного радіуса враховується ширина кожного кільця, а також порожні проміжки між кільцями. Без будь-якої оптимізації швидкості обчислення залишаються точними, оскільки вони базуються не на поплавках, а на раціональних числах.

      Редагувати : я змінив параметри, щоб відповідати правилам прокладки.

  • Після цього я знаю необхідний розмір отриманого полотна (вдвічі більший за останній обчислений радіус).

  • Нарешті, я малюю коло для кожного елемента Pта зберігаю полотно.

1
"Цей код підтримує всі римські цифри (IVXLCDM)". Чи означає це, що ваша програма приймає римські цифри як вхідні дані? Це не те, що я задумав, але досить круто. Реквізити для анімації теж.
Ріп Ліб

1
Ні, ні, вибачте, якщо це незрозуміло: воно працює для будь-якого цілого числа від 1 до 3999. У вашому запитанні вам потрібні були лише дані від 1 до 100, а у вашій таблиці не вказано D або M ... Я редагую це частина.
coredump

8

HTML + JQuery, 288

HTML

<canvas>

JS

    r=3;w=9;c=$('canvas').get(0).getContext('2d')
    for(i=prompt(),e=100;e-.1;e/=10){
    if((x=Math.floor(i/e)%10)==4)d(w)+d(w+2)
    else if(x==9)d(w)+d(w+4)
    else{if(x>4)d(w+2)
    for(j=x%5;j;j--)d(w)}
    w-=4}
    function d(R){c.lineWidth=R
    c.beginPath()
    c.arc(150,75,r+=R/2,0,7)
    c.stroke()
    r+=R/2+3}

Скрипка


Немає фрагмента стека?
Оптимізатор

@Optimizer Повністю забув, що ми маємо це зараз
TwiNight

5

Ява, 565

import java.awt.*;class Z{public static void main(String[]s){int i=new Byte(s[0]),j=i/10,k=i%10;String t="",u;if(j>8)t="59";if(j>9)t="9";if(j==4)t="57";else if(j<9){t=j>4?"7":"";j-=j>4?5:0;if(j>0)t+="5";if(j>1)t+="5";if(j>2)t+="5";}if(k>8)t+="15";if(k==4)t+="13";else if(k<9){t+=k>4?"3":"";k-=k>4?5:0;if(k>0)t+="1";if(k>1)t+="1";if(k>2)t+="1";}u=t;Frame f=new Frame(){public void paint(Graphics g){g.setColor(Color.BLACK);int x=0;for(char c:u.toCharArray()){int z=c-48,q=x;for(;x<q+z;)g.drawOval(99-x,99-x,x*2,x++*2);x+=3;}}};f.setSize(200,200);f.setVisible(1>0);}}

Приклади

15

15

84

84

93

93

Відформатовано:

import java.awt.*;    
class Z {    
    public static void main(String[] s) {
        int i = new Byte(s[0]), j = i / 10, k = i % 10;
        String t = "", u;
        if (j > 8)
            t = "59";
        if (j > 9)
            t = "9";
        if (j == 4) {
            t = "57";
        } else if (j < 9) {
            t = j > 4 ? "7" : "";
            j -= j > 4 ? 5 : 0;
            if (j > 0)
                t += "5";
            if (j > 1)
                t += "5";
            if (j > 2)
                t += "5";
        }
        if (k > 8)
            t += "15";
        if (k == 4) {
            t += "13";
        } else if (k < 9) {
            t += k > 4 ? "3" : "";
            k -= k > 4 ? 5 : 0;
            if (k > 0)
                t += "1";
            if (k > 1)
                t += "1";
            if (k > 2)
                t += "1";
        }
        u = t;
        Frame f = new Frame() {
            public void paint(Graphics g) {
                g.setColor(Color.BLACK);
                int x = 0;
                for (char c : u.toCharArray()) {
                    int z = c - 48, q = x;
                    for (; x < q + z;) {
                        g.drawOval(99 - x, 99 - x, x * 2, x++ * 2);
                    }
                    x += 3;
                }
            }
        };
        f.setSize(200, 200);
        f.setVisible(1 > 0);
    }
}

Будь ласка, опублікуйте кілька результатів. Вибачте за те, що не питаєте, що це перше місце.
Ріп Ліб

3

Mathematica 9 - 301 249 байт

: D Зрозуміло використовувати вбудований перехід на римські цифри, але ей.

l=Length;k=Characters;r@n_:=(w=Flatten[Position[k@"IVXLC",#]*2-1&/@k@IntegerString[n,"Roman"]];Show[Table[Graphics@{AbsoluteThickness@w[[i]],Circle[{0,0},(Join[{0},Accumulate[3+w]]+3)[[i]]+w[[i]]/2]},{i,Range@l@w}],ImageSize->{(Total@w+(l@w)*3)*2}])

(Коли я робив це вчора ввечері, у мене не було багато часу, але я зрозумів, що це може бути полегшене в гольф. І я також взяв деякі підказки від Девіда Чжана ...: D Спасибі!)

Трохи чіткіше:

l=Length;
k=Characters;
r@n_:=
    (
    w=Flatten[Position[k@"IVXLC",#]*2-1&/@k@IntegerString[n,"Roman"]];
    Show[Table[Graphics@{AbsoluteThickness@w[[i]],Circle[{0,0},(Join[{0},Accumulate[3+w]]+3)[[i]]+w[[i]]/2]},{i,Range@l@w}],ImageSize->{(Total@w+(l@w)*3)*2}]
    )

Це функція, яку можна викликати так:

r[144]

введіть тут опис зображення

Або ви можете показати результати від значень a до b за допомогою:Table[r[i],{i,a,b}]

Примітка . Це працює лише для значень до 399.


1

Пітон 2, 322 296

Сценарій читає число, яке потрібно перетворити з stdin, і виводить зображення у вигляді розмітки SVG.

.. Я використовую "червоний" замість "чорний", тому що це економить 2 символи :)

Ось кілька зразків: для 23: http://jsfiddle.net/39xmpq49/ для 42: http://jsfiddle.net/7Ls24q9e/1/

i=input();r=9
def R(n,p):
 global r,i;i-=n;print '<circle r="{0}" stroke-width="{1}"/>'.format(r,p);r+=p+3
print '<svg viewBox="-50 -50 99 99" fill="none" stroke="red">',[[R(n,int(p)) for p in s*int(i/n)] for n,s in zip([100,90,50,40,10,9,5,4,1],'9/59/7/57/5/15/3/13/1'.split('/'))]and'','</svg>'

1

JavaScript 342 334 308

function R(n){var v=document,o=[],x=1,c=v.body.appendChild(v.createElement('canvas')).getContext('2d')
while(n)v=n%10,y=x+2,o=[[],[x],[x,x],[x,x,x],[x,y],[y],[y,x],[y,x,x],[y,x,x,x],[x,x+=4]][v].concat(o),n=(n-v)/10
v=3
while(x=o.shift())c.lineWidth=x,c.beginPath(),c.arc(150,75,v+x/2,0,7),c.stroke(),v+=x+3}

for (var i = 1; i <= 100; i++) {
  R(i);
}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.