Esagoni connessi ASCII


21

Panoramica

Dato un numero di esagoni, disponili in una forma connessa entro i confini di un'immagine d'arte ASCII 50 per 50. La forma che scegli può essere arbitraria, qualunque cosa trovi più adatta al golf, a condizione che sia connessa. Può avere buchi a condizione che siano più grandi di un esagono (altrimenti il ​​numero di esagoni sarà ambiguo).


disposizione

Tutti gli esagoni devono essere nella seguente forma (solo questa dimensione e orientamento sono validi):

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

Due esagoni sono collegati direttamente se condividono un bordo:

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

Due esagoni non sono collegati se condividono solo un vertice:

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

Anche la condivisione di un bordo non conta come connessa:

 __
/  \
\__/
 /  \
 \__/

Una raccolta di esagoni è connessa se esiste un percorso da qualsiasi esagono a qualsiasi altro utilizzando solo esagoni direttamente collegati .

fori

Un foro delle dimensioni di un esagono in una raccolta connessa di esagoni conta come un esagono, in modo che ogni dato pezzo di arte ASCII abbia un conteggio inequivocabile di esagoni.

Questo non conta come un buco poiché il buco futuro è un singolo esagono:

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

Questo fa conteggio come foro poiché non corrisponde a un singolo esagono:

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

Ingresso e uscita

Ingresso

Un numero intero compreso tra 1 e 255.

Produzione

Una stringa di arte ASCII che rappresenta il numero di input degli esagoni collegati come descritto sopra.

  • Il numero di righe (sottostringhe separate da newline) è al massimo di 50, più un newline finale aggiuntivo opzionale.
  • Le righe non devono avere la stessa lunghezza, ma ognuna deve avere una lunghezza massima di 50.
  • Righe di lunghezza zero possono esistere sopra o sotto la forma connessa purché il numero totale di righe non superi 50.
  • Righe solo spaziali possono esistere sopra o sotto la forma connessa purché il numero totale di righe non superi 50.
  • Gli spazi possono apparire a sinistra della forma a condizione che le lunghezze delle file non superino 50 (la forma non deve essere allineata a sinistra).
  • Gli spazi possono apparire a destra della forma purché le lunghezze delle file non superino 50.
  • Tutti i caratteri che non fanno parte della forma connessa devono essere spazi o newline.

Se l'output è corretto, non è necessario che sia coerente da una corsa all'altra.

Esempi

Ingresso: 6

Uscite valide:

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

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

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

Uscite non valide:

    __
 __/  \__
/  \__/  \
\__/  \__/
/  \__/  \
\__/  \__/
   \__/      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.

vincente

Vince la risposta valida più breve in byte.


Classifica

(utilizzando lo snippet della classifica di Martin )


Temo che tutti useranno il primo esempio di output in quanto è probabilmente il più semplice da implementare.
Fatalizza il

1
@Fatalizza i miei esempi funzionano solo per un input di 6. Per un input di 255una fila orizzontale di esagoni non si adatta a un'arte ASCII 50 per 50.
trichoplax,

Potresti comunque semplicemente tornare indietro e riempire le righe sottostanti ogni volta che raggiungi il limite di 50 caratteri
Fatalizza il

1
@Fatalize La sfida è ridurre al minimo il numero di byte nel codice. Non mi importa se i modelli sono semplici, sarà interessante vedere cosa provano le persone e cosa si adatta alle diverse lingue.
trichoplax,

@Fatalize: non so se sarebbe breve o no, ma una risposta più "interessante" potrebbe fare una vera ricerca per vedere dove può posizionare gli esagoni e quindi ottenere un output più interessante.
Alex Van Liew,

Risposte:


13

CJam, 64 57 55 byte

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

Provalo qui.

Questo genererà il seguente modello, per quanto riguarda le colonne :

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

Spiegazione

Questo si basa su di Dennis eccellente punta , usando .e>per assemblare un output in arte ASCII da più pezzi. Come dice, .e>prende il massimo dal punto di vista degli elementi di due array (o stringhe) e poiché gli spazi hanno il codice di carattere più basso, possiamo usarlo per imporre qualsiasi altro carattere su una griglia di stringhe. Inoltre, se i due array non hanno la stessa lunghezza, gli elementi estranei dell'array più lungo vengono semplicemente copiati invariati. Ciò significa che i diversi modelli non devono nemmeno avere le stesse dimensioni. Per applicare questo agli array bidimensionali (poiché non vogliamo inserire le nuove righe fino alla fine), applichiamo in modo .e>accoppiato alle linee, che fornisce..e> .

L'idea di base del codice è generare Ncopie di un singolo esagono spostato nella posizione corretta. "Spostiamo" l'esagono verticalmente anteponendo linee vuote e orizzontalmente anteponendo spazi. Una volta finito, pieghiamo tutte le copie insieme, usando il bellissimo :..e>(probabilmente l'operatore più lungo che abbia mai usato in un programma CJam).

Ecco il codice:

" __
/  \
\__/"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.

Amico, dovrei davvero imparare una di queste lingue del golf.
Alex Van Liew,

@AlexVanLiew Dovresti! :) Ma non perché migliora le tue possibilità di vincere il golf del codice, ma perché CJam è un bellissimo linguaggio in cui è divertente programmare, e non conosco nessun altro linguaggio in cui la soluzione sopra (che penso sia abbastanza elegante) avrebbe avuto senso. ;)
Martin Ender il

Probabilmente imparerei Pyth o entrambi; sono entrambi praticamente la stessa cosa o è meglio degli altri?
Alex Van Liew,

@AlexVanLiew Non conosco molto Pyth, ma so che sono tutt'altro che la stessa cosa. CJam è un linguaggio basato su stack, mentre Pyth è nato come scorciatoia per Python (ma ora ha il suo set di built-in). Pyth potrebbe avere un po ' il sopravvento quando si tratta di golf, ma personalmente mi piace molto programmare in un diverso paradigma, quindi rimarrò con CJam.
Martin Ender,

Ah, capisco. Conosco Python abbastanza bene, motivo per cui mi piacerebbe imparare Pyth, ma se avrò il tempo forse proverò anche CJam!
Alex Van Liew,

7

Python 2, 219 207 caratteri

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

Accetta input su stdin.

Praticamente crea una griglia 50x50 di spazi e fa cadere gli esagoni dove appropriato. Dopo 16 esagono, non ho bisogno prima riga h(l'esagono come una matrice 2D) in modo da utilizzare i>15per avviare l'intervallo da 1 invece di 0. c=i*3%48+1;r=(i*3+1)/48*2+i%2calcola il c olumn e r ow devo iniziare a. nè un valore booleano ma viene utilizzato come numero intero per correggere i limiti (poiché h[0]sono solo 3 caratteri per evitare di sovrascrivere elementi).

Sono abbastanza contento di questo, mi sono rasato circa 50 byte dalla versione iniziale, specialmente quando mi sono ricordato della a[x:y]=bsintassi.

Uscita (n = 30):

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

Dal momento che sono consentite righe finali di spazi bianchi, ho modificato la creazione di gper creare solo 50 bytearrays invece di 3+(x>1)+x/16*2, che è il numero esatto di righe richieste, radendo da 12 byte.


6

Swift 2.0, 601 591 byte

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

Correre: swift hexagons.swift 21

Produzione:

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

Swift substringToIndexe stringByReplacingOccurencesOfStringprendi così tanti personaggi ...


Non conosco affatto Swift, ma non c'è modo di costruire quella stringa ripetitiva con meno codice?
Reto Koradi,

L'unico modo in cui conosco per ripetere una stringa è con stringByPaddingToLength, tuttavia in questo caso sarebbero 11 caratteri più lunghi rispetto alla digitazione della stringa completa.
David Skrundz,

6
Vedo che ad Apple piace davvero una concatenazione di stringhe eccessivamente dettagliata. Non male come stringByAppendingStringin Objective-C ma comunque ...
Fatalizza il

Al di fuori del code golf, questo è davvero bello perché rende la ricerca di un metodo molto più semplice.
JustSid,

4

C, 238 byte

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

Solo i spazi necessari e le nuove righe considerati per il conteggio dei personaggi.

Crea semplicemente una matrice di personaggi, li riempie in ordine inverso e quindi stampa il tutto.


2

JavaScript (ES6), 265 byte

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

Tessella esagoni di fila, da sinistra a destra, alternando su e giù, come un nido d'ape, fino a raggiungere la fine di una fila.

Ungolfed con descrizione (funziona in 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

Ruby, 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}

crea una matrice di 50 stringhe di 50 spazi, quindi sostituisce 4 caratteri in 3 righe per aggiungere gli esagoni:

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

Poiché la prima linea contiene spazi, una volta che un esagono è stato tracciato non possiamo tracciarne un altro al di sotto di esso, poiché gli spazi sovrascriverebbero gli esagoni precedenti.

Pertanto gli esagoni vengono aggiunti sotto forma di rombo 16x16 (rettangolo distorto) dal basso verso l'alto e inclinati dal basso a sinistra verso l'alto a destra.

La stringa " __ "verrà quindi sovrascritta con ulteriore \e /dove necessario.

Non registrato nel programma di 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) 

Uscita tipica (n = 250)

Dovrebbero esserci altre righe di spazi bianchi in alto qui, per un totale di 50, ma non so se c'è un modo per far impilare Stackexchange per includerli.

                                              __  
                                           __/  \ 
                                        __/  \__/ 
                                     __/  \__/  \ 
                            __    __/  \__/  \__/ 
                         __/  \__/  \__/  \__/  \ 
                      __/  \__/  \__/  \__/  \__/ 
                   __/  \__/  \__/  \__/  \__/  \ 
                __/  \__/  \__/  \__/  \__/  \__/ 
             __/  \__/  \__/  \__/  \__/  \__/  \ 
          __/  \__/  \__/  \__/  \__/  \__/  \__/ 
       __/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
    __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
 __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/    
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/       
\__/  \__/  \__/  \__/  \__/  \__/  \__/          
/  \__/  \__/  \__/  \__/  \__/  \__/             
\__/  \__/  \__/  \__/  \__/  \__/                
/  \__/  \__/  \__/  \__/  \__/                   
\__/  \__/  \__/  \__/  \__/                      
/  \__/  \__/  \__/  \__/                         
\__/  \__/  \__/  \__/                            
/  \__/  \__/  \__/                               
\__/  \__/  \__/                                  
/  \__/  \__/                                     
\__/  \__/                                        
/  \__/                                           
\__/                                              
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.