Numeri come grafica circolare


36

Innanzitutto, studia questo puzzle per avere un'idea di ciò che produrrai.

La tua sfida è quella di scrivere un programma o una funzione che genererà un grafico circolare come quelli del puzzle, dato un numero (base 10) compreso tra 1 e 100 (incluso). Questo è simile a questa sfida , tranne per il fatto che produrrete un grafico piuttosto che numeri romani. I seguenti cerchi rappresentano i numeri 1-10, da sinistra a destra:

modello del cerchio

Come afferma la risposta al puzzle, il tuo grafico dovrebbe leggere come un numero romano dall'interno verso l'esterno, dove lo spessore della linea rappresenta i simboli numerici romani e l'intero grafico rappresenta il numero. Per riferimento, ecco gli spessori delle linee di cui avrai bisogno. Ogni riga dovrebbe avere un'imbottitura 3px tra essa e la successiva.

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

Pubblica un campione o due del tuo output. Supponiamo che l'input sia corretto, scappatoie standard , ecc. Ecc. Questo è il codice golf, quindi vincono meno byte. In caso di pareggio, la maggior parte dei voti vince. In bocca al lupo!


3
È necessaria la dimensione assoluta corretta dell'immagine o è sufficiente avere le dimensioni relative giuste?
David Zhang,

@DavidZhang Sì, si prega di attenersi alla linea e alle dimensioni dell'imbottitura che ho elencato, per amor di equità.
Rip Leeb,

Risposte:


15

Mathematica - 166 181 byte

Un po 'più conciso dell'altra risposta Mathematica, grazie in parte a uno stile più privo di punti.

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

Tutto lo spazio bianco è solo per chiarezza. Ciò definisce una funzione anonima che restituisce l'immagine desiderata.

Animazione

Cerchi animati

Generare una GIF animata dei cerchi numerici è banale in Mathematica, che ha funzioni integrate per l'animazione e l'esportazione di sequenze di oggetti arbitrari. Supponendo che il codice sopra sia appena stato eseguito,

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

Esempio di output

Esempio di output


Si prega di inviare alcuni risultati. Ci scusiamo per non aver chiesto questo è il primo posto. Ho anche cambiato la domanda per accettare le funzioni.
Rip Leeb,

Grazie per i suggerimenti @ MartinBüttner. Il codice è stato corretto per produrre immagini di dimensioni corrette ed è stato aggiunto un esempio di output.
David Zhang,

3
La tua animazione si muove. Non che potrei fare di meglio.
corsiKa

Hmm, hai ragione. Non sono davvero sicuro del perché lo faccia, considerando che ho specificato esplicitamente la gamma della trama per Mathematica.
David Zhang,

Magari in relazione al
wiggling

15

Lisp comune - 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)))

Esempi

inserisci qui la descrizione dell'immagine (1) inserisci qui la descrizione dell'immagine (24)

inserisci qui la descrizione dell'immagine (104) inserisci qui la descrizione dell'immagine (1903) inserisci qui la descrizione dell'immagine(3999)

Animazione

Per numeri da 1 a 400:

Nuovo

NB: per la cronaca, questa animazione viene eseguita come segue:

Ho una versione modificata del codice, denominata ringsche restituisce la larghezza dell'immagine prodotta. Quindi, il risultato del seguente ciclo è la dimensione massima, qui 182 :

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

L'intero ciclo dura 9.573 secondi. Questo dà circa 24ms per ogni numero intero. Quindi, in una shell:

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

spiegazioni

  • La funzione accetta un numero intero Ncompreso tra 1 e 3999 e un nome file

  • Uso (format nil "~@R" N)per convertire da decimale a romano. Per esempio:

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

    La ~@R stringa di controllo del formato viene specificata per funzionare con numeri interi compresi tra 1 e 3999. Ecco perché esiste una limitazione per l'intervallo di input consentiti.

  • Ierate sulla stringa risultante per creare un elenco Pcontenente (radius width)coppie, per ogni numero C.

    • La larghezza è una semplice mappatura lineare: uso la stringa costante "IVXLCDM" per calcolare la posizione di C in essa. Moltiplicando per due e aggiungendo uno, otteniamo il valore desiderato:

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

      Questo è tuttavia fatto in modo leggermente diverso nella versione golfata:

             (position c " I V X L C D M")
      
    • Il calcolo di ciascun raggio tiene conto della larghezza di ciascun anello e degli spazi vuoti tra gli anelli. Senza alcuna ottimizzazione della velocità, i calcoli rimangono precisi perché non sono basati su float, ma numeri razionali.

      Modifica : ho modificato i parametri per conformarmi alle regole di riempimento.

  • Una volta fatto questo, conosco la dimensione richiesta della tela risultante (il doppio dell'ultimo raggio calcolato).

  • Infine, disegno un cerchio per ogni elemento di Pe salvo la tela.

1
"Questo codice supporta tutti i numeri romani (IVXLCDM)". Significa che il tuo programma accetta numeri romani come input? Non è quello che intendevo, ma piuttosto bello. Puntelli anche per l'animazione.
Rip Leeb,

1
No, no, scusami se non è chiaro: funziona per qualsiasi numero intero compreso tra 1 e 3999. Nella tua domanda, hai richiesto solo input da 1 a 100 e la tua tabella non menziona D o M ... Lo modificherò parte.
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}

Violino


Nessuno snippet di stack?
Ottimizzatore,

@Optimizer Dimenticato totalmente che ora
ce l'

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

Esempi

15

15

84

84

93

93

Formattato bene:

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

Si prega di inviare alcuni risultati. Ci scusiamo per non aver chiesto questo è il primo posto.
Rip Leeb,

3

Mathematica 9 - 301 249 byte

: D Sembra conveniente usare la conversione integrata in numeri romani, ma ehi.

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

(Quando l'ho fatto ieri sera non ho avuto molto tempo, ma mi sono reso conto che poteva essere golfato molto di più. E ho anche preso alcuni suggerimenti da David Zhang ...: D Grazie!)

Un po 'più chiaramente:

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

Questa è una funzione che puoi chiamare in questo modo:

r[144]

inserisci qui la descrizione dell'immagine

Oppure, puoi mostrare i risultati dai valori da a a b con:Table[r[i],{i,a,b}]

Nota : funziona solo per valori fino a 399.


1

Python 2, 322 296

Lo script legge il numero da convertire da stdin e genera l'immagine come markup SVG.

.. Io uso 'rosso' invece di 'nero', perché salva 2 caratteri :)

Ecco alcuni esempi: per 23: http://jsfiddle.net/39xmpq49/ per 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);
}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.