Dairesel Grafik Olarak Sayılar


36

İlk önce, üreteceğiniz şeye dair bir fikir edinmek için bu bulmacayı inceleyin .

Buradaki zorluk, bulmacanınkiler gibi dairesel bir grafik çıkaran bir program veya fonksiyon yazmaktır (1 ile 100 arasında (10'lu bir sayı). Bu, bu meydan okumaya benzer , ancak roma rakamlarından ziyade bir grafik üreteceksiniz. Aşağıdaki daireler 1-10 arasındaki sayıları soldan sağa gösterir:

daire modeli

Bulmacanın cevabını belirttiği gibi, grafiğinizin içten dışa bir romen rakamı gibi okunması gerekir, burada çizgi kalınlığı romen rakamı sembollerini ve tüm grafik rakamı temsil eder. Referans için, burada ihtiyacınız olacak çizgi kalınlıkları. Her satır, bir sonraki ve bir 3px dolgusu olmalıdır.

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

Lütfen çıktınızın bir veya iki örneğini gönderin. Girdilerin doğru olduğunu, standart boşlukların , vb. Olduğunu varsayalım . Bu kod golf, yani en az bayt kazanıyor. Beraberlik durumunda çoğu oy kazanır. İyi şanslar!


3
Görüntünün doğru mutlak boyutu gerekli mi, yoksa doğru göreceli boyutlara sahip olmak yeterli mi?
David Zhang

@DavidZhang Evet, lütfen adalet adına listelediğim çizgiye ve dolgu ölçülerine yapıştırın.
Rip Leeb

Yanıtlar:


15

Mathematica - 166 181 bayt

Diğer Mathematica cevaplarından biraz daha kısa, kısmen daha puansız bir stil sayesinde.

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] &

Tüm boşluklar sadece netlik içindir. Bu, istenen grafiği döndüren isimsiz bir işlevi tanımlar.

Animasyon

Animasyonlu çevreler

Sayı çevrelerinin bir animasyonlu GIF oluşturmak, keyfi nesnelerin dizilerini canlandırmak ve dışa aktarmak için yerleşik işlevlere sahip olan Mathematica'da önemsizdir. Yukarıdaki kodun yeni yürütüldüğünü varsayarsak,

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

Örnek çıktı

Örnek çıktı


Lütfen birkaç sonuç gönderin. Bunu sormadığım için özür dilerim. Ayrıca, işlevleri kabul etmesi için soruyu değiştirdim.
Rip Leeb

Önerileriniz için teşekkürler @ MartinBüttner. Kod, doğru boyutta görüntüler elde etmek için düzeltildi ve örnek çıktı eklendi.
David Zhang

3
Animasyon kıpırdanıyor. Daha iyisini yapabileceğimden değil.
corsiKa

Hmm, haklısın. Mathematica için arsa aralığını açıkça belirttiğimi düşündüğümde, bunun neden böyle olduğundan emin değilim.
David Zhang,

Belki de
kıpırdatmakla

15

Ortak Lisp - 376 331 304 bayt

(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)))

Örnekler

görüntü tanımını buraya girin(1) görüntü tanımını buraya girin(24)

görüntü tanımını buraya girin(104) görüntü tanımını buraya girin(1903) görüntü tanımını buraya girin(3999)

Animasyon

1 - 400 arası numaralar için:

Yeni

Not: Kayıt için bu animasyon aşağıdaki gibi yapılır:

ringsÜretilen görüntünün genişliğini döndüren adlı kodun değiştirilmiş bir sürümüne sahibim . Bu nedenle, aşağıdaki döngünün sonucu, burada 182 olan maksimum boyuttur :

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

Bütün döngü 9.573 saniye sürer. Bu her tamsayı için yaklaşık 24ms verir. Sonra bir kabukta:

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

Ungolfed

(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))))

açıklamalar

  • İşlev, N1 ile 3999 arasında bir tam sayı ve bir dosya adı alır.

  • (format nil "~@R" N)Ondalıktan romaya dönüştürmek için kullanıyorum . Örneğin:

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

    ~@R Biçim kontrol dizesi 1 ve izin verilen girdilerin aralığı için bir sınırlama yoktur yüzden 3999 arasındaki tamsayılar için işe belirtilir.

  • Her sayı için çiftleri Piçeren bir liste oluşturmak için sonuçtaki dizgiyi (radius width)yineliyorum.

    • Genişlik basit bir doğrusal haritalamadır: İçindeki C'nin konumunu hesaplamak için "IVXLCDM" sabit dizesini kullanıyorum. İki ile çarparak ve bir tane ekleyerek, istenen değeri elde ederiz:

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

      Ancak bu, golf versiyonunda biraz farklı yapılır:

             (position c " I V X L C D M")
      
    • Her yarıçapın hesaplanması, her bir halkanın genişliğini ve halkalar arasındaki boş alanları dikkate alır. Herhangi bir hız optimizasyonu olmadan, hesaplamalar kesindir çünkü yüzerlere değil rasyonel sayılara dayanırlar.

      Düzenleme : Parametreleri dolgu kurallarına uyacak şekilde değiştirdim.

  • Bu yapıldığında, elde edilen kanvasın istenen boyutunu biliyorum (en son hesaplanan yarıçapın iki katı).

  • Sonunda, her element için bir daire çizerim Pve tuvali saklarım.

1
"Bu kod tüm romen rakamları (IVXLCDM) destekler". Bu, programınızın giriş olarak romen rakamları aldığı anlamına mı geliyor? İstediğim bu değildi, ama oldukça havalı. Animasyon için sahne de.
Rip Leeb

1
Hayır, hayır, pardon bu net değilse: 1 ile 3999 arasındaki herhangi bir tamsayı için işe yarar. Sorunuzda, yalnızca 1 ile 100 arasında bir giriş yapmanız gerekir ve tablonuz D veya M'den bahsetmez ... Bunu düzenleyeceğim Bölü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}

Keman


Yığın pasajı yok mu?
Doktor

@Optimizer Tamamen unutmuş olduk şimdi
TwiNight

5

Java, 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);}}

Örnekler

15

15

84

84

93

93

Güzel biçimlendirilmiş:

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);
    }
}

Lütfen birkaç sonuç gönderin. Bunu sormadığım için özür dilerim.
Rip Leeb

3

Mathematica 9 - 301 249 bayt

: D Yerleşik olarak Romen rakamlarına geçmeyi kullanmak hile yapar, ancak hey.

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ün gece bunu yaptığımda fazla zamanım olmadı, ama daha çok golf oynayabileceğini fark ettim. Ayrıca David Zhang'dan bazı ipuçları aldım ...: D Teşekkürler!)

Biraz daha net:

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}]
    )

Bu, şöyle çağırabileceğiniz bir fonksiyondur:

r[144]

görüntü tanımını buraya girin

Veya, değerlerinden sonuçlar gösterebilir bir etmek b ile:Table[r[i],{i,a,b}]

Not : Bu sadece 399'a kadar olan değerler için çalışır.


1

Python 2, 322 296

Komut stdin'den dönüştürülecek sayıyı okur ve görüntüyü SVG işaretlemesi olarak çıkarır.

.. 'Siyah' yerine 'kırmızı' kullanıyorum çünkü 2 karakter kazandırıyor :)

İşte bazı örnekler: 23 için: http://jsfiddle.net/39xmpq49/ için 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);
}

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.