Angka sebagai Grafis Edaran

36

Pertama, pelajari puzzle ini untuk merasakan apa yang akan Anda hasilkan.

Tantangan Anda adalah menulis program atau fungsi yang akan menghasilkan grafik lingkaran seperti yang ada di teka-teki, diberi nomor (basis 10) antara 1 dan 100 (inklusif). Ini mirip dengan tantangan ini , kecuali bahwa Anda akan menghasilkan grafik daripada angka romawi. Lingkaran berikut mewakili angka 1-10, dari kiri ke kanan:

pola lingkaran

Sebagai jawaban untuk teka-teki menyatakan, grafik Anda harus membaca seperti angka romawi dari dalam-ke luar, di mana ketebalan garis mewakili simbol angka romawi dan seluruh grafik mewakili angka. Untuk referensi Anda, berikut adalah ketebalan garis yang Anda perlukan. Setiap baris harus memiliki bantalan 3px di antara itu dan yang berikutnya.

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

Silakan kirim sampel atau dua dari output Anda. Asumsikan input benar, celah standar , dll, dan sebagainya. Ini adalah kode golf, byte paling sedikit menang. Dalam hal seri, sebagian besar suara menang. Semoga berhasil!

Rip Leeb
sumber
3
Apakah ukuran absolut yang benar dari gambar diperlukan, atau apakah cukup untuk memiliki ukuran relatif yang tepat?
David Zhang
@ DavidZhang Ya, tolong tetap pada garis dan ukuran bantalan yang saya daftarkan, demi keadilan.
Rip Leeb

Jawaban:

15

Mathematica - 166 181 byte

Sedikit lebih ringkas daripada jawaban Mathematica lainnya, sebagian berkat gaya yang lebih bebas poin.

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

Semua spasi putih hanya untuk kejelasan saja. Ini mendefinisikan fungsi anonim yang mengembalikan grafik yang diinginkan.

Animasi

Lingkaran animasi

Membuat GIF animasi dari lingkaran angka adalah sepele dalam Mathematica, yang memiliki fungsi bawaan untuk menghidupkan dan mengekspor sekuens objek sewenang-wenang. Dengan asumsi kode di atas baru saja dieksekusi,

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

Contoh Output

Contoh output

David Zhang
sumber
Silakan kirim beberapa hasil. Maaf karena tidak menanyakan ini tempat pertama. Saya juga mengubah pertanyaan untuk menerima fungsi.
Rip Leeb
Terima kasih atas sarannya @ MartinBüttner. Kode telah diperbaiki untuk menghasilkan gambar berukuran benar, dan contoh keluaran telah ditambahkan.
David Zhang
3
Animasi Anda bergoyang. Bukannya aku bisa melakukan yang lebih baik.
corsiKa
Hmm, kamu benar. Saya benar-benar tidak yakin mengapa ia melakukan itu, mengingat saya menentukan rentang plot secara eksplisit untuk Mathematica.
David Zhang
Mungkin terkait dengan gerak-gerik itu: mathematica.stackexchange.com/q/134272
coredump
15

Gangguan Umum - 376 331 304 byte

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

Contohnya

masukkan deskripsi gambar di sini(1) masukkan deskripsi gambar di sini(24)

masukkan deskripsi gambar di sini(104) masukkan deskripsi gambar di sini(1903) masukkan deskripsi gambar di sini(3999)

Animasi

Untuk angka dari 1 hingga 400:

Baru

NB: Sebagai catatan, animasi ini dilakukan sebagai berikut:

Saya memiliki versi kode yang dimodifikasi, dinamai ringsyang mengembalikan lebar gambar yang dihasilkan. Oleh karena itu, hasil dari loop berikut adalah ukuran maksimum, di sini 182 :

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

Seluruh loop membutuhkan 9,573 detik. Itu memberi sekitar 24 ms untuk setiap bilangan bulat. Kemudian, dalam sebuah shell:

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

Tidak disatukan

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

Penjelasan

  • Fungsi ini mengambil bilangan bulat Nantara 1 dan 3999 dan nama file

  • Saya menggunakan (format nil "~@R" N)untuk mengkonversi dari desimal ke roman. Sebagai contoh:

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

    The ~@R kontrol format string ditentukan untuk bekerja untuk bilangan bulat antara 1 dan 3999. Itu sebabnya ada batasan untuk berbagai masukan diperbolehkan.

  • Saya beralih pada string yang dihasilkan untuk membangun daftar yang Pberisi (radius width)pasangan, untuk setiap angka C.

    • Lebar adalah pemetaan linear sederhana: Saya menggunakan string konstan "IVXLCDM" untuk menghitung posisi C di dalamnya. Mengalikan dengan dua dan menambahkan satu, kami memperoleh nilai yang diinginkan:

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

      Namun ini dilakukan sedikit berbeda dalam versi golf:

             (position c " I V X L C D M")
      
    • Perhitungan setiap jari-jari memperhitungkan lebar masing-masing cincin serta ruang kosong di antara cincin. Tanpa optimasi kecepatan, perhitungan tetap tepat karena tidak didasarkan pada float, tetapi bilangan rasional.

      Sunting : Saya mengubah parameter untuk mematuhi aturan padding.

  • Setelah ini selesai, saya tahu ukuran kanvas yang diperlukan (dua kali radius komputasi terbaru).

  • Akhirnya, saya menggambar lingkaran untuk setiap elemen Pdan menyimpan kanvas.
coredump
sumber
1
"Kode ini mendukung semua angka romawi (IVXLCDM)". Apakah itu berarti program Anda mengambil angka romawi sebagai input? Bukan itu yang saya maksudkan, tapi cukup keren. Alat peraga untuk animasi juga.
Rip Leeb
1
Tidak, tidak, maaf jika tidak jelas: ini berfungsi untuk bilangan bulat apa pun antara 1 dan 3999. Dalam pertanyaan Anda, Anda hanya memerlukan input dari 1 hingga 100, dan tabel Anda tidak menyebutkan D atau M ... Saya akan mengeditnya bagian.
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}

Biola

TwiNight
sumber
Tidak ada cuplikan tumpukan?
Pengoptimal
@ Opptizer Benar-benar lupa kami memilikinya sekarang
TwiNight
5

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

Contohnya

15

15

84

84

93

93

Diformat dengan baik:

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);
    }
}
Ypnypn
sumber
Silakan kirim beberapa hasil. Maaf karena tidak menanyakan ini tempat pertama.
Rip Leeb
3

Mathematica 9 - 301 249 byte

: D Rasanya menggelikan untuk menggunakan konversi bawaan ke angka Romawi, tapi hei.

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

(Ketika saya melakukan ini tadi malam, saya tidak punya banyak waktu, tetapi saya menyadari bahwa itu bisa menjadi golf lebih jauh. Dan saya juga mengambil beberapa petunjuk dari David Zhang ...: D Terima kasih!)

Sedikit lebih jelas:

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

Ini adalah fungsi yang dapat Anda panggil seperti ini:

r[144]

masukkan deskripsi gambar di sini

Atau, Anda dapat menampilkan hasil dari nilai a ke b dengan:Table[r[i],{i,a,b}]

Catatan : Ini hanya berfungsi untuk nilai hingga 399.

kukac67
sumber
1

Python 2, 322 296

Script membaca nomor yang akan dikonversi dari stdin, dan menampilkan gambar sebagai markup SVG.

.. Saya menggunakan 'merah' bukan 'hitam', karena menghemat 2 karakter :)

Berikut adalah beberapa contoh: untuk 23: http://jsfiddle.net/39xmpq49/ untuk 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>'
pelaku diet
sumber
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);
}

wolfhammer
sumber