Images binaires des nombres triangulaires

18

Mes défis ont tendance à être un peu difficiles et peu attrayants. Voici donc quelque chose de simple et amusant.

La séquence d'Alcuin

La séquence d'Alcuin A(n) est définie par le comptage des triangles. A(n)est le nombre de triangles dont les côtés et le périmètre sont entiers n. Cette séquence est appelée d'après Alcuin of York.

Les premiers éléments de cette séquence, à commencer par n = 0:

0, 0, 0, 1, 0, 1, 1, 2, 1, 3, 2, 4, 3, 5, 4, 7, 5, 8, 7, 10, 8, ...

Par exemple A(9) = 3, parce que les seuls triangles avec des côtés et un périmètre entiers 9sont 1 - 4 - 4, 3 - 3 - 3et 2 - 3 - 4. Vous pouvez voir les 3 triangles valides ci-dessous.

Triangles à côtés entiers et périmètre 9

Il y a un schéma assez intéressant dans cette séquence. Par exemple A(2*k) = A(2*k - 3).

Pour plus d'informations, voir A005044 sur OEIS.

Défi

Mais votre défi concerne la représentation binaire de ces nombres. Si nous convertissons chaque numéro de séquence en sa représentation binaire, les mettons dans des vecteurs de colonne et les alignons, cela crée une image binaire assez intéressante.

Dans l'image suivante, vous pouvez voir la représentation binaire des numéros de séquence A(0), A(1), ..., A(149). Dans la première colonne, vous pouvez voir la représentation binaire de A(1), dans la deuxième colonne la représentation de A(1), etc.

Représentation binaire de la séquence d'Alcuin de n = 0 à 149

Vous pouvez voir une sorte de motif répétitif sur cette image. Cela ressemble même un peu à des fractales, si vous regardez par exemple l'image avec les numéros de séquence A(600), A(601), ..., A(899).

Représentation binaire de la séquence d'Alcuin de n = 600 à 899

Votre travail consiste à générer une telle image. Votre fonction, votre script recevra deux entiers 0 <= m < n, et il doit générer l'image binaire de la séquence d'Alcuin A(m), A(m+1), A(m+2), ..., A(n-2), A(n-1). Donc, l'entrée 0, 150génère la première image, l'entrée 600, 900la deuxième image.

Vous pouvez utiliser n'importe quel format graphique populaire que vous souhaitez. Disons tous les formats qui peuvent être convertis en png en utilisant image.online-convert.com . Alternativement, vous pouvez afficher l'image à l'écran. Aucune première ligne blanche n'est autorisée!

C'est du code-golf. Ainsi, le code le plus court (en octets) gagne.

Jakube
la source
3
Eh, j'étais intéressé à relever ce défi jusqu'à ce que j'arrive à la partie sur la création d'une image binaire. Cela semble être une étape étrangère. Je n'ai pas envie d'apprendre une bibliothèque pour la création d'images en Python, et je m'attends à ce que si je le faisais, il n'y aurait pas grand-chose au golf.
xnor
1
@xnor: Utilisez ensuite un format d'image simple comme PBM .
Jakube
Est-ce que c'est white=1 and black=0l'inverse?
Maltysen
@Maltysen white=0 and black=1. Donc dans l'autre sens. A(0)produit une colonne blanche, A(9)=3produit une colonne blanche avec 2 pixels noirs en bas.
Jakube
1
Êtes-vous sûr que la première image est correcte? Il en a 0,0,0,1,0,2pendant la liste au début de la question 0,0,0,1,0,1.
Maltysen

Réponses:

2

J ( 52 45 (page de code 437))

Ce serait permis (je pense)

[:|:' █'{~[:#:[:([:<.48%~*:+24+6*]*2|])(}.i.)

Vidage hexadécimal

(Rien de vraiment spécial, le carré noir est DB 16 ou 219 10 en page de code 437.)

0000: 5b 3a 7c 3a 27 20 db 27 7b 7e 5b 3a 23 3a 5b 3a   [:|:' .'{~[:#:[:
0010: 28 5b 3a 3c 2e 34 38 25 7e 2a 3a 2b 32 34 2b 36   ([:<.48%~*:+24+6
0020: 2a 5d 2a 32 7c 5d 29 28 7d 2e 69 2e 29            *]*2|])(}.i.)

Usage

Cela sort comme suit (les balises de code gâchent le tout en ajoutant de l'espace entre les lignes):

   A=:[:|:' █'{~[:#:[:([:<.48%~*:+24+6*]*2|])(}.i.)
   0 A 100
                                                                             █ █████████████████████                                          
                                                     █ ██████████████████████ █              █ █████                          
                                     █ ██████████████ █          █ ██████████ █      █ ██████ █                   
                         █ ██████████ █      █ ██████ █    █ ████ █    █ ████ █  █ ██ █  █ ██ █  █ █  
                 █ ██████ █    █ ████ █  █ ██ █  █ ██ █  █  █  █  █  █  ██ ██ ██  ██  ██  ██  ██  ██
           █ ████ █  █ ██ █  █  █  █  ██  ██  ██  ██  ██  █  █  █  █ ██ █  █ ████ █                               
       █ ██ █  █  ██  ██  ██  █  █ ██ █                █ ██ █  █  ██  ██  ██  █  █ ██ █                                   
   █ ██ ██  ██ ██ █        █ ██ ██  ██ ██ █        █ ██ ██  ██ ██ █        █ ██ ██  ██ ██ █        █    
   2000 A 2100
████████████████████████████████████████████████████████████████████████████████████████████████████

████████████████████████████████████████████████████████████████████████████████████████████████████
                                                                             █ █████████████████████
                             █ ██████████████████████████████████████████████ █
     █ ██████████████████████ █                      █ ██████████████████████ █
█████ █          █ ██████████ █          █ ██████████ █          █ ██████████ █          █ █████████
 ████ █    █ ████ █    █ ████ █    █ ████ █    █ ████ █    █ ████ █    █ ████ █    █ ████ █    █ ███
█  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █
██  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █ ██ ██ █
 █ ██ ██ ██ ██ ██ █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  ██ ██ ██ ██ ██  █  █
  ██ ██ ██  █  █  ██ ██ ██  █  █  █  █  █  █  █  █  █  █  █  █  █  █ ██ ██ ██ █  █  █  █ ██ █  █ ██
 █ ██ █  █ ██ █  █ ██ █  █ ██ █  █  █  █  █  █  █  █  █  █  ██ ██ ██  █  █  ██  ██ ██ ██  ██  ██  ██
  ██  ██  ██  ██  ██  ██  ██  ██ ██ ██  █  █  █  █  █  █ ██ █  █ ██ █  █ ████ █    █ ██████ █
█ █                        █ ████ █  █ ██ █  █  █  █  ██  ██  ██  ██  ██  █  █  █  █ ██ █  █ ████ █
 █ ██ █                █ ██ █  █  ██  ██  ██  █  █ ██ █                █ ██ █  █  ██  ██  ██  █  █ █
██  ██ ██ █        █ ██ ██  ██ ██ █        █ ██ ██  ██ ██ █        █ ██ ██  ██ ██ █        █ ██ ██

Dans la console J standard, il n'y a pas d'espacement entre les lignes, donc j'appelle la règle «Alternativement, vous pouvez afficher l'image à l'écran». (Nulle part n'a-t-il été dit que cette image devait être représentée en tant que format d'image sensible en interne)

EDIT: Jconsole (par opposition à JQT) utilise la page de code 437 par défaut, et rend correctement les rectangles lors de leur utilisation à partir d'une chaîne.

ɐɔıʇǝɥʇuʎs
la source
9

Mathematica, 126 122 121 121 89 octets

Image[1-Thread@IntegerDigits[l=Round[(#+3#~Mod~2)^2/48]&/@Range@##,2,⌈2~Log~Max@l⌉]]&

Ceci définit une fonction sans nom prenant les deux entiers comme paramètres et affichant l'image à l'écran. Il trace chaque carré comme un seul pixel, mais si vous le souhaitez, vous pouvez réellement zoomer.

J'utilise maintenant une formule explicite donnée dans l'article OEIS (la première dans la section Mathematica, merci à David Carraher de l'avoir signalé). C'est aussi incroyablement rapide maintenant.

Voici le code en retrait avec quelques commentaires:

Image[1-Thread@IntegerDigits[   (* 3. Convert each number to padded binary, transpose
                                      invert colours, and render as Image. *)
    l = Round[
      (#+3#~Mod~2)^2/48
    ] & /@ Range@##,            (* 1. Turn input into a range and get the Alcuin
                                      number for each element. *)
    2,
    ⌈2~Log~Max@l⌉               (* 2. Determine the maximum number of binary digits. *)
]] &

Voici la sortie pour 0, 600:

entrez la description de l'image ici

Martin Ender
la source
À peu près la même taille (car les plafonds gauche et droit doivent être précisés):Image[1 - Thread@IntegerDigits[ l = Round[If[EvenQ[#], #^2, (# + 3)^2]/48] & /@ Range@##, 2, \[LeftCeiling]2~Log~Max@l\[RightCeiling]]] &
DavidC
@DavidCarraher Merci, je l'ai joué un peu plus loin. :) (Aurait dû vérifier l'article OEIS.)
Martin Ender
8

CJam ( 56 55 53 caractères) / GolfScript (64 caractères)

CJam:

"P1"q~,>{_1&3*+_*24+48/}%_:e>2b,\2_$#f+2fbz(,@@:~~]N*

GolfScript:

"P1"\~,>{.1&3*+.*24+48/}%.$-1=2base,\{2.$?+2base}%zip(,@@{~}/]n*

Les deux produisent une sortie au format NetPBM et sont essentiellement des ports l'un de l'autre.

Dissection

CJam                 GolfScript           Explanation

"P1"                 "P1"\                NetPBM header
q~,>                 ~,>                  Create array [m .. n-1]
{_1&3*+_*24+48/}%    {.1&3*+.*24+48/}%    Map the sequence calculation
_:e>2b,\             .$-1=2base,\         Compute image height H as highest bit
                                          in largest number in sequence
2_$#f+2fb            {2.$?+2base}%        Map sequence to bits, ensuring that
                                          each gives H bits by adding 2^H
z(,@@                zip(,@@              Transpose and pull off dummy row to use
                                          its length as the "width" in the header
:~~                  {~}/                 Flatten double array and dump on stack
]N*                  ]n*                  Separate everything with whitespace

Merci à Optimizer pour CJam 56 -> 53.

Peter Taylor
la source
1
Pour une raison quelconque, vous n'avez pas "P1" au début et économisez donc 1 octet en évitant le ``?
Optimizer
@Optimizer, trop habitué à penser en GS.
Peter Taylor
Pas tout à fait: la hauteur doit apparaître dans la sortie. Mais il y a encore une économie à faire avec le raccourcissement de la carte.
Peter Taylor
51:'PoXq~{_1&3*+_*24+48/}%>_:e>2b,\2_$#f+2fbz(,@@]e_N*
Optimizer
5

Pyth - 101 60 59

Sorties a .pbm. Peut probablement être joué au golf plus.

Km.B/++24*dd**6%d2d48rvzQJCm+*\0-eSmlkKlddK"P1"lhJlJjbmjbdJ

Très peu golfé car je vais traduire en Pyth.

Explication à venir. Regardez maintenant le code Python équivalent.

Il utilise l'algorithme OEIS pour calculer la séquence, puis il se convertit en binaire, remplit les nombres, effectue une rotation de matrice et la formate en une pbmimage. Comme je n'utilise pas la force brute, c'est incroyablement rapide.

         K=
 m          rvzQ      Map from eval input to eval input
  .B                  Binary rep
   /      48          Divided by 48
    ++                Triple sum      
     24               Of 24,
     *dd              Square of d
     **               Triple product
      6               6
      %d2             Modulo d%2
      d               Var d
J                     Set J=
 C                    Matrix rotation from columns of row to rows of columns
  m           K       Map K (This does padding)
   +                  String concat
    *                 String repeat
     \0               "0"
     -     ld         Subtract the length of the column from
      eS              The max
       mlkK           Of all the column lengths
    d                 The column
"P1"                  Print header "P1"
l                     Length of
 hJ                   First row
lJ                    Number of columns
jb                    Join by linebreaks
 m  J                 Map on to J
  jb                  Joined columns by linb
   d

Voici l' 600,900exemple:

600 - 900

Essayez-le ici en ligne .

Maltysen
la source
4

R - 127 125

Je ne sais pas si cela est totalement conforme aux règles. Il ne génère pas d'image dans un fichier, mais il crée un raster et le trace sur un périphérique de sortie.

J'ai trouvé la même formule que Martin, mais ici .

Il utilise une fonction sans nom.

require(raster);function(m,n)plot(raster(mapply(function(n)rev(as.integer(intToBits(round((n+n%%2*3)^2/48)))),m:n),0,n,0,32))

Exécutez comme suit

require(raster);(function(m,n)plot(raster(mapply(function(n)rev(as.integer(intToBits(round((n+n%%2*3)^2/48)))),m:n),0,n,0,32)))(0,600)

Produit l'intrigue suivante

entrez la description de l'image ici

MickyT
la source
Vous pouvez supprimer 7 octets en ne vous attachant pas rasterà l'espace de noms, car raster()c'est la seule chose spécifique à ce package. Au lieu de cela, faites-le raster::raster(...).
Alex A.
@AlexA. Merci, fera cette modification
MickyT
@AlexA. Malheureusement, je viens de l'essayer et cela me dérange. Je soupçonne que c'est parce que raster nécessite également sp. Je vais voir si je peux le retrouver.
MickyT
Bummer. Désolé de vous avoir égaré.
Alex A.
3

Python 2 + PIL , 255 184

Ma première version utilisait PIL pour afficher une image:

i,R,B=input,range,lambda x:bin((x*x+6*x*(x%2)+24)/48)[2:]
def F(k,v):i.load()[k]=v
a,b=i(),i();h=len(B(b));from PIL import Image;i=Image.new('P',(b-a,h))
[F((x-a,y),int(B(x).zfill(h)[y])) for x in R(a,b) for y in R(h)]
i.putpalette([255]*3+[0]*3)
i.show()

La nouvelle version produit juste une image PPM n & b sur stdout:

i,R,B=input,range,lambda x:bin((x*x+6*x*(x%2)+24)/48)[2:]
def p(s):print s
a,b=i(),i();h=len(B(b));p('P1 %i %i'%(b-a,h))
[p(' '.join([B(x).zfill(h)[y] for x in R(a,b)])) for y in R(h)]
diète
la source
Certains caractères sont enregistrés pour la version PPM: vous n'avez pas besoin d'espace avant for. Vous pouvez éviter les parens x%2en changeant l'ordre en x%2*.... Il est plus court de ne pas définir l'impression en tant que fonction et d'utiliser simplement deux forboucles imbriquées , en utilisant print ...,pour éviter les sauts de ligne et un blanc printpour commencer une nouvelle ligne. Une astuce pour forcer les extensions binaires à avoir une longueur hsans zfillest d'ajouter 2**h, puis d'extraire les derniers hchiffres.
xnor
2

JAVASCRIPT - 291

Code:

(function(a,b,c){c.width=b;t=c.getContext('2d');t.strokeStyle='black';for(i=a;i<=b;i++){g=(Math.floor(((i*i)+6*i*(i%2)+24)/48)>>>0).toString(2);l=g.length;for(j=0;j<l;j++){if(g[l-1-j]=='1'){t.rect(i-a,j,1,1);t.fill();}}}document.body.appendChild(c);})(0,300,document.createElement('canvas'))

Explication:

(function (a, b, c) {
    //setting canvas width
    c.width = b;
    //get context 2d of canvas
    t = c.getContext('2d');
    //setting storke style.
    t.strokeStyle = 'black';
    //looping from a to b
    for (i = a; i <= b; i++) {
        //calculating A(i) and converting it to a binary string
        g = (Math.floor(((i * i) + 6 * i * (i % 2) + 24) / 48) >>> 0).toString(2);
        //looping through that string
        for (j = 0; j < g.length; j++) {
            //since canvas is upside down and the first digit is actually the last digit:
            if (g[g.length - 1 - j] == '1') {
                //we create the 1 by 1 rect
                t.rect(i - a, j, 1, 1);
                //we draw the rect
                t.fill();
            }
        }
    }
    //we append everything to the body
    document.body.appendChild(c);
    //parameters are put here
})(0, 300, document.createElement('canvas'))

Résultat:

Oui le résultat est à l' envers, mais c'est parce que 0,0sur un js canvasest en haut à gauche. : 3 La séquence d'Alquin

Démo:

Démo sur jsfiddle

kemicofa soutient Monica
la source