Hexagones connectés ASCII


21

Aperçu

Étant donné un certain nombre d'hexagones, organisez-les en une forme connectée dans les limites d'une image d'art ASCII 50 x 50. La forme que vous choisissez peut être arbitraire - tout ce que vous trouvez le plus propice au golf - tant qu'elle est connectée. Il peut avoir des trous à condition qu'ils soient plus grands qu'un hexagone (sinon le nombre d'hexagones sera ambigu).


Disposition

Tous les hexagones doivent être sous la forme suivante (seules cette taille et cette orientation sont valides):

 __
/  \
\__/    Note there are 2 underscores per horizontal edge.

Deux hexagones sont directement connectés s'ils partagent un bord:

 __               __
/  \__           /  \
\__/  \          \__/
   \__/    or    /  \
                 \__/

Deux hexagones ne sont pas connectés s'ils ne partagent qu'un sommet:

 __  __
/  \/  \
\__/\__/

Partager un demi-bord ne compte pas non plus comme connecté:

 __
/  \
\__/
 /  \
 \__/

Une collection d'hexagones est connectée s'il existe un chemin d'un hexagone à un autre utilisant uniquement des hexagones directement connectés .

des trous

Un trou de taille hexagonale dans une collection connectée d'hexagones compte comme un hexagone, de sorte que toute œuvre d'art ASCII donnée ait un nombre d'hexagones sans ambiguïté.

Cela ne compte pas comme un trou car le trou potentiel est un seul hexagone:

    __
 __/  \__
/  \__/  \
\__/  \__/
/  \__/  \
\__/  \__/
   \__/      7 hexagons (not 6 with a hole)

Cela ne compte comme un trou , car elle ne correspond pas à un seul hexagone:

    __
 __/  \__
/  \__/  \__
\__/  \__/  \
/  \__   \__/
\__/  \__/  \
   \__/  \__/
      \__/      8 hexagons with a hole

Entrée et sortie

Contribution

Un entier de 1 à 255.

Production

Une chaîne artistique ASCII représentant le nombre d'entrée d'hexagones connectés comme décrit ci-dessus.

  • Le nombre de lignes (sous-chaînes séparées par des sauts de ligne) est au maximum de 50, plus une nouvelle ligne de fin facultative supplémentaire.
  • Les rangées n'ont pas besoin d'être de la même longueur, mais chacune doit avoir une longueur d'au plus 50.
  • Des lignes de longueur nulle peuvent exister au-dessus ou en dessous de la forme connectée à condition que le nombre total de lignes ne dépasse pas 50.
  • Des lignes d'espace uniquement peuvent exister au-dessus ou en dessous de la forme connectée à condition que le nombre total de lignes ne dépasse pas 50.
  • Des espaces peuvent apparaître à gauche de la forme à condition que la longueur des rangées ne dépasse pas 50 (la forme n'a pas besoin d'être alignée à gauche).
  • Des espaces peuvent apparaître à droite de la forme à condition que la longueur des rangées ne dépasse pas 50.
  • Tous les caractères qui ne font pas partie de la forme connectée doivent être des espaces ou des retours à la ligne.

À condition que la sortie soit correcte, il n'est pas nécessaire qu'elle soit cohérente d'une exécution à l'autre.

Exemples

Contribution: 6

Sorties valides:

 __    __    __
/  \__/  \__/  \__
\__/  \__/  \__/  \
   \__/  \__/  \__/

 __    __
/  \__/  \
\__/  \__/
/  \__/  \
\__/  \__/
   \__/

          __
 __      /  \
/  \__   \__/
\__/  \__/  \
   \__/  \__/
      \__/
      /  \
      \__/

Sorties non valides:

    __
 __/  \__
/  \__/  \
\__/  \__/
/  \__/  \
\__/  \__/
   \__/      Invalid for 6 as the centre hole counts as a 7th hexagon.

 __    __    __      __
/  \__/  \__/  \    /  \
\__/  \__/  \__/    \__/
   \__/  \__/                Invalid as the 6 hexagons are not connected.

 __    __    __  __
/  \__/  \__/  \/  \
\__/  \__/  \__/\__/
   \__/  \__/           Invalid as vertex touching does not count as connected.

 __    __       __
/  \__/  \     /  \
\__/  \__/     \__/
/  \__/  \
\__/  \__/
   \__/       Invalid as the 6 connected hexagons are not the only visible characters.

Gagnant

La réponse valide la plus courte en octets l'emporte.


Classement

(en utilisant l'extrait de classement de Martin )


Je crains que tout le monde utilise le premier exemple de modèle de sortie car il est probablement le plus facile à mettre en œuvre.
Fatalize

1
@Fatalize mes exemples ne fonctionnent que pour une entrée de 6. Pour une entrée d' 255une rangée horizontale d'hexagones ne rentrera pas dans un art ASCII 50 x 50.
trichoplax

Vous pouvez toujours simplement boucler et remplir les lignes ci-dessous chaque fois que vous atteignez la limite de 50 caractères
Fatalize

1
@Fatalize Le défi est de minimiser le nombre d'octets dans le code. Cela ne me dérange pas si les modèles sont simples, il sera juste intéressant de voir ce que les gens essaient et ce qui convient à différentes langues.
trichoplax

@Fatalize: Je ne sais pas si ce serait court ou non, mais une réponse plus "intéressante" pourrait faire une recherche réelle pour voir où il peut placer des hexagones et ainsi obtenir une sortie plus intéressante.
Alex Van Liew

Réponses:


13

CJam, 64 57 55 octets

" __
/  \
\__/"N/{_SS/\+_47>S3*f{\+}_2>\@?}q~(*]:..e>N*

Testez-le ici.

Cela générera le modèle suivant, par colonne :

 __    __    __    __    __    __
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/  \
\__/  \__/  \__/  \__/  \__/  \__/
/  \__/  \__/  \__/  \__/  \__/
\__/  \__/  \__/  \__/  \__/  \
/  \__/  \__/  \__/  \__/  \__/
\__/  \__/  \__/  \__/  \__/  \
/  \__/  \__/  \__/  \__/  \__/
\__/  \__/  \__/  \__/  \__/  \
/  \__/  \__/  \__/  \__/  \__/
\__/  \__/  \__/  \__/  \__/

Explication

Ceci est basé sur l' excellente astuce de Dennis , qui permet .e>d'assembler une sortie d'art ASCII à partir de plusieurs pièces. Comme il le dit, .e>prend le maximum élément par élément de deux tableaux (ou chaînes), et puisque les espaces ont le code de caractère le plus bas, nous pouvons l'utiliser pour imposer tout autre caractère sur une grille de chaînes. De plus, si les deux tableaux n'ont pas la même longueur, les éléments étrangers du tableau plus long sont simplement copiés tels quels. Cela signifie que les différents motifs n'ont même pas besoin d'avoir la même taille. Pour appliquer cela à des tableaux à deux dimensions (parce que nous ne voulons pas insérer les sauts de ligne jusqu'à la fin), nous appliquons .e>par paire aux lignes, ce qui donne ..e>.

L'idée de base du code est de générer des Ncopies d'un seul hexagone déplacé vers la bonne position. On "déplace" l'hexagone verticalement en ajoutant des lignes vides et horizontalement en ajoutant des espaces. Une fois que nous avons terminé, nous plions toutes les copies ensemble, en utilisant le magnifique :..e>(probablement le plus long opérateur que j'ai jamais utilisé dans un programme CJam).

Voici le code:

" __
/  \
\__/"N/    e# Get a 2D character grid of the hexagon.
{          e# Read input N, repeat this block N-1 times.
  _        e#   Make a copy, so we leave the last hexagon on the stack.
  SS/\+    e#   Prepend two empty lines.
  _47>     e#   Make a copy and discard the first 47 lines.
  S3*f{\+} e#   Prepend 3 spaces to each line. This copy has been moved back to
           e#   the top and one column to the right.
  _2>      e#   Make a copy and discard another two lines.
  \@?      e#   If any lines were left after that, pick the copy in the next column,
           e#   otherwise, stay in the same column.
}q~(*      
]:..e>     e# Wrap all the hexagons in an array and fold them into a single grid.
N*         e# Join them with newline characters.

Mec, je dois vraiment apprendre une de ces langues de golf.
Alex Van Liew

@AlexVanLiew Vous devriez! :) Mais pas parce que cela améliore vos chances de gagner au golf à code, mais parce que CJam est une belle langue qui est amusante à programmer, et je ne connais aucune autre langue dans laquelle la solution ci-dessus (qui je pense est assez élégante) aurait fait sens. ;)
Martin Ender

J'apprendrais probablement Pyth ou les deux; sont-ils tous les deux à peu près la même chose ou sont-ils meilleurs que les autres?
Alex Van Liew

@AlexVanLiew Je ne connais pas beaucoup Pyth, mais je sais qu'ils sont loin de la même chose. CJam est un langage basé sur la pile, tandis que Pyth est à l'origine un raccourci pour Python (mais a maintenant son propre ensemble de fonctions intégrées). Pyth a peut-être légèrement le dessus en ce qui concerne le golf, mais personnellement, j'aime vraiment la programmation dans un paradigme différent, donc je m'en tiendrai à CJam.
Martin Ender

Aha je vois. Je connais assez bien Python, c'est pourquoi j'aimerais apprendre Python, mais si j'ai le temps, je vais peut-être essayer CJam aussi!
Alex Van Liew

7

Python 2, 219 207 caractères

b=bytearray(' ');h=['__ ','/  \\','\\__/'];k=range;x=input();g=[b*50for _ in k(50)]
for i in k(x):
 c=i*3%48+1;r=(i*3+1)/48*2+i%2
 for m in k(i>15,3):n=m==0;g[r+m][c+n:c+4-n]=h[m]
print"\n".join(map(str,g))

Prend une entrée sur stdin.

À peu près crée simplement une grille d'espaces 50x50 et plops les hexagones là où c'est approprié. Après le 16e hexagone, je ne suis pas besoin de la première rangée de h(l'hexagone comme un tableau 2D) , donc je l' utilise i>15pour démarrer la plage à 1 au lieu de 0. c=i*3%48+1;r=(i*3+1)/48*2+i%2calcule le c OLONNE et r OW que je dois commencer à. nest un booléen mais est utilisé comme un entier pour fixer les limites (puisqu'il h[0]n'y a que 3 caractères pour éviter d'écraser les trucs).

Je suis assez content de celui-ci, j'ai rasé environ 50 octets depuis la version initiale, surtout quand je me suis souvenu de la a[x:y]=bsyntaxe.

Sortie (n = 30):

  __    __    __    __    __    __    __    __
 /  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__
 \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \
 /  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/
 \__/  \__/  \__/  \__/  \__/  \__/  \__/  \
    \__/  \__/  \__/  \__/  \__/  \__/  \__/
(plus 44 lines of spaces each 50 wide)

Étant donné que les lignes de fin d'espaces sont autorisées, j'ai modifié la création de gpour ne créer que 50 bytearrays au lieu de 3+(x>1)+x/16*2, ce qui correspond au nombre exact de lignes requises, ce qui réduit de 12 octets.


6

Swift 2.0, 601 591 octets

import Cocoa
var a=Int(Process.arguments[1])!,b="/  \\__".join([String](count:9,repeatedValue:""))+"/",c="\\__/  ".join([String](count:9,repeatedValue:""))+"\\",d=c.startIndex,e=c.endIndex,j=[c.stringByReplacingOccurencesOfString("\\",withString:" ").stringByReplacingOccurencesOfString("/",withString:" ").substringToIndex(advance(d,3*a,e)),b.substringToIndex(advance(d,3*a+a%2,advance(e,-1)))]
while a>0{j+=[c.substringToIndex(advance(d,3*a+1,e)),b.substringToIndex(advance(d,3*a+(a+1)%2,e)]
a<=16 ?j+=[" "+j.removeLast().substringFromIndex(advance(d,1))]:()
a-=16}
for l in j{print(l)}

Courir: swift hexagons.swift 21

Production:

 __    __    __    __    __    __    __    __    
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/
\__/  \__/  \__/
   \__/  \__/  

Swift substringToIndexet stringByReplacingOccurencesOfStringprendre tant de personnages ...


Je ne connais pas du tout Swift, mais n'y a-t-il pas un moyen de construire cette chaîne répétitive avec moins de code?
Reto Koradi

La seule façon que je sache de répéter une chaîne est avec stringByPaddingToLength, mais dans ce cas, ce serait 11 caractères de plus que de taper la chaîne complète.
David Skrundz

6
Je vois qu'Apple aime vraiment la concaténation de chaînes trop verbeuse. Pas aussi mauvais que stringByAppendingStringdans Objective-C mais quand même ...
Fatalize

En dehors du golf de code, c'est vraiment sympa car cela rend la recherche d'une méthode beaucoup plus facile.
JustSid

4

C, 238 octets

#define h(A) c[m+A/4][n+A%4]
i,m,n;
f(a)
{
    char c[50][51];
    for(i=0;i<50;i++)for(m=0;m<51;m++)c[i][m]=m-50?32:0;
    for(;a;)
        m=a/12*2,n=a%12*3,a--%2?m=a/12*2+1,n=a%12*3+3:0,
        h(1)=h(2)=h(9)=h(10)=95,h(4)=h(11)=47,h(7)=h(8)=92;
    for(;i;)puts(c-i--+50);
}

Seuls les espaces nécessaires et les nouvelles lignes sont pris en compte pour le nombre de caractères.

Il crée simplement une matrice de caractères, les remplit dans l'ordre inverse, puis imprime le tout.


2

JavaScript (ES6), 265 octets

A=Array;f='forEach';U=x=1;y=0;a=A.from(A(51),_=>A.from(A(51),_=>' '));d=h=>(` __
/  \\
\\__/`.split`
`[f]((l,i)=>[...l][f]((c,j)=>{if('_/\\'.indexOf(a[x+i][y+j])<0)a[x+i][y+j]=c})),(x+=U*-2+1),(U=!U),(C-y<=3?((U=x+=2),y=0):y+=3),--h?d(h):a.map(d=>d.join``).join`
`)

Tesselle les hexagones d'affilée, de gauche à droite, alternant de haut en bas - comme un nid d'abeilles - jusqu'à la fin d'une rangée.

Non golfé avec description (fonctionne dans Firefox):

'use strict';
const CAP = 51;
var a = Array.from(Array(51), () => Array.from(Array(51),() => ' '))

function draw (hexagons, x, y, a, up) {
  // x, y (row, col) represents the current position of the cursor
  /*
  
    Here's a map of the first three iterations:
    
            01234567
     0        __
     1     __/  \__
     2    /  \__/  \
     3    \__/  \__/

    For the first 17 iterations, the cursor will be at:
    
      # | x | y
      ----------
      1 | 1 | 0
      2 | 0 | 3
      3 | 1 | 6
      4 | 0 | 9
      5 | 1 | 12
      6 | 0 | 15
      7 | 1 | 18
      8 | 0 | 21
      9 | 1 | 24
     10 | 0 | 27
     11 | 1 | 30
     12 | 0 | 33
     13 | 1 | 36
     14 | 0 | 39
     15 | 1 | 42
     16 | 0 | 45
     17 | 3 | 0      <- moves back to the first row

  */
` __
/  \\
\\__/`
  // split the hexagon into three lines
  .split('\n').forEach((line, index) => {
    // and for each line
    ;[...line].forEach((char, j) => {
      // if the cursor position (x, y) translated
      // by (index, j) is not already part of a hexagon
      // then replace it with the current (index, j) piece
      // of the hexagon
      /*
         0123
       0  __
       1 /  \
       2 \__/
       
      */
      if ('_/\\'.indexOf(a[x + index][y + j]) < 0)
        a[x + index][y + j] = char
    })
  })
  
  // `up` represents the next hexagon
  // if true, the next hexagon will be drawn attached to
  // the top right edge of the current hexagon
  if (up) {
    x -= 1
  // otherwise, it'll be drawn attached to the bottom right edge
  } else {
    x += 1
  }

  // move three columns to the right
  y += 3
  // change directions
  up = !up

  // if within the right boundary of the 51x51 matrix,
  // move back to the left edge and down 2 rows
  // and draw the next hexagon as an `up` hexagon
  if (51 - y <= 3) {
    y = 0
    x += 2
    up = true
  }

  // if hexagons > 0, then recurse and draw the next hexagon
  // otherwise, return the array (join the columns in each row, then join each row
  // by a new line)
  return --hexagons ?
    draw(hexagons, x, y, a, up)
    : a.map(d => d.join('')).join('\n')
}

var n = parseInt(prompt('Number to draw:'))
var r = draw(n, 1, 0, a, true)
document.write('<pre>' + r.replace(/\n/g, '<br>') + '</pre>')


2

Rubis, 120

->n{a=(1..50).map{' '*50}
n.times{|i|x=i%16*3
3.times{|j|a[47-i/16*2-x/3+j][x..x+3]=[' __ ','/  \\','\__/'][j]}}
puts a}

crée un tableau de 50 chaînes de 50 espaces, puis substitue 4 caractères sur 3 lignes pour ajouter les hexagones:

" __ "
"/  \"
"\__/"

Comme la première ligne contient des espaces, une fois qu'un hexagone a été tracé, nous ne pouvons pas en tracer un autre en dessous, car les espaces écraseraient les hexagones précédents.

Par conséquent, les hexagones sont ajoutés sous la forme d'un losange 16x16 (rectangle déformé) de bas en haut, et incliné de bas à gauche en haut à droite.

La chaîne " __ "sera alors remplacée par des informations supplémentaires \et /si nécessaire.

Non testé dans le programme de test

g=->n{
  a=(1..50).map{' '*50}              #make an array of 50 strings of 50 spaces
  n.times{|i|                        #loop through all hexagons
    x=i%16*3                         #x coordinate of top left corner of hexagon, 16 per row
    3.times{|j|                      #loop through 3 lines to print hexagon.
      a[47-i/16*2-x/3+j][x..x+3]=    #47-i/16*2 : start at the bottom and work up. each row is 2 lines high and contains 16 hexagons. x/3 : slant upwards as the row moves right. 
       [' __ ','/  \\','\__/'][j]    #These are the symbols for each of the 3 lines required for a hexagon. [x..x+3] defines which characters have to be replaced in each string.
    }      
  }
  puts a                             #print to stdout
}

N=gets.to_i
g.call(N) 

Sortie typique (n = 250)

Il devrait y avoir quelques rangées d'espaces supplémentaires en haut ici, pour faire un total de 50, mais je ne sais pas s'il existe un moyen d'obtenir Stackexchange au format pour les inclure.

                                              __  
                                           __/  \ 
                                        __/  \__/ 
                                     __/  \__/  \ 
                            __    __/  \__/  \__/ 
                         __/  \__/  \__/  \__/  \ 
                      __/  \__/  \__/  \__/  \__/ 
                   __/  \__/  \__/  \__/  \__/  \ 
                __/  \__/  \__/  \__/  \__/  \__/ 
             __/  \__/  \__/  \__/  \__/  \__/  \ 
          __/  \__/  \__/  \__/  \__/  \__/  \__/ 
       __/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
    __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
 __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/    
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/       
\__/  \__/  \__/  \__/  \__/  \__/  \__/          
/  \__/  \__/  \__/  \__/  \__/  \__/             
\__/  \__/  \__/  \__/  \__/  \__/                
/  \__/  \__/  \__/  \__/  \__/                   
\__/  \__/  \__/  \__/  \__/                      
/  \__/  \__/  \__/  \__/                         
\__/  \__/  \__/  \__/                            
/  \__/  \__/  \__/                               
\__/  \__/  \__/                                  
/  \__/  \__/                                     
\__/  \__/                                        
/  \__/                                           
\__/                                              
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.