ASCII terhubung segi enam

21

Ikhtisar

Diberikan sejumlah segi enam, mengatur mereka menjadi bentuk yang terhubung dalam batas-batas gambar seni 50 oleh 50 ASCII. Bentuk yang Anda pilih bisa sewenang-wenang - apa pun yang menurut Anda paling cocok untuk bermain golf - asalkan tetap terhubung. Mungkin ada lubang asalkan lebih besar dari satu segi enam (jika tidak, jumlah segi enam akan ambigu).


Tata letak

Semua segi enam harus dalam bentuk berikut (hanya ukuran dan orientasi ini yang valid):

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

Dua segi enam terhubung langsung jika mereka berbagi keunggulan:

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

Dua heksagon tidak terhubung jika mereka hanya berbagi titik:

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

Berbagi setengah sisi juga tidak dihitung sebagai terhubung:

 __
/  \
\__/
 /  \
 \__/

Kumpulan hexagon terhubung jika ada jalur dari hexagon mana saja ke yang lain hanya menggunakan hexagon yang terhubung langsung .

Lubang

Sebuah lubang berukuran heksagon dalam kumpulan heksagon yang terhubung dianggap sebagai segi enam, sehingga setiap karya seni ASCII yang diberikan memiliki jumlah heksagon yang jelas.

Ini tidak dihitung sebagai lubang karena lubang prospektif adalah segi enam tunggal:

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

Ini tidak dihitung sebagai lubang karena tidak sesuai dengan segi enam tunggal:

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

Masukan dan keluaran

Memasukkan

Integer dari 1 hingga 255.

Keluaran

String seni ASCII yang mewakili jumlah input heksagon terhubung seperti dijelaskan di atas.

  • Jumlah baris (substring yang dipisahkan baris baru) paling banyak 50, ditambah tambahan baris tambahan opsional.
  • Baris tidak harus memiliki panjang yang sama, tetapi masing-masing harus memiliki panjang paling banyak 50.
  • Baris panjang nol dapat ada di atas atau di bawah bentuk yang terhubung asalkan jumlah baris tidak melebihi 50.
  • Baris spasi saja bisa ada di atas atau di bawah bentuk yang terhubung asalkan jumlah baris tidak melebihi 50.
  • Spasi dapat muncul di sebelah kiri bentuk asalkan panjang baris tidak melebihi 50 (bentuk tidak perlu disejajarkan ke kiri).
  • Spasi dapat muncul di sebelah kanan bentuk asalkan panjang baris tidak melebihi 50.
  • Setiap karakter yang tidak membentuk bagian dari bentuk yang terhubung harus berupa spasi atau baris baru.

Asalkan outputnya benar, tidak harus konsisten dari satu putaran ke putaran berikutnya.

Contohnya

Memasukkan: 6

Output yang valid:

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

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

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

Output Tidak Valid:

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

Kemenangan

Jawaban valid terpendek dalam byte menang.


Papan peringkat

(menggunakan potongan leaderboard Martin )

trichoplax
sumber
Saya khawatir semua orang akan menggunakan pola output contoh pertama karena mungkin yang paling mudah untuk diterapkan.
Fatalkan
1
@Fatalize contoh saya hanya berfungsi untuk input 6. Untuk input 255baris horizontal segi enam tidak akan cocok dengan 50 oleh 50 ASCII art.
trichoplax
Anda masih bisa mengulang dan mengisi garis-garis di bawah ini setiap kali Anda mencapai batas 50 karakter
Fatalize
1
@Fatalize Tantangannya adalah untuk meminimalkan jumlah byte dalam kode. Saya tidak keberatan jika polanya sederhana, hanya akan menarik untuk melihat apa yang orang coba dan apa yang cocok dengan bahasa yang berbeda.
trichoplax
@Fatalize: Saya tidak tahu apakah akan pendek atau tidak, tetapi jawaban yang lebih "menarik" mungkin melakukan pencarian aktual untuk melihat di mana ia dapat menempatkan segi enam dan dengan demikian mendapatkan output yang lebih menarik.
Alex Van Liew

Jawaban:

13

CJam, 64 57 55 byte

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

Uji di sini.

Ini akan menghasilkan pola berikut, berdasarkan kolom :

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

Penjelasan

Ini didasarkan pada tip Dennis yang luar biasa , yang digunakan .e>untuk merakit output seni ASCII dari beberapa bagian. Seperti yang dikatakannya, .e>ambil maksimum elemen-elemen dari dua array (atau string), dan karena spasi memiliki kode karakter terendah, kita dapat menggunakan ini untuk memaksakan karakter lain pada string grid. Lebih jauh, jika dua array tidak memiliki panjang yang sama, elemen-elemen asing dari array yang lebih panjang disalin tidak berubah. Ini berarti bahwa pola yang berbeda bahkan tidak perlu memiliki ukuran yang sama. Untuk menerapkan ini ke array dua dimensi (karena kami tidak ingin menyisipkan baris baru sampai akhir), kami menerapkan .e>berpasangan ke garis, yang memberi ..e>.

Ide dasar dari kode ini adalah untuk menghasilkan Nsalinan segi enam tunggal yang dipindahkan ke posisi yang tepat. Kami "memindahkan" segi enam secara vertikal dengan menambahkan baris kosong dan secara horizontal dengan menambahkan spasi. Setelah selesai, kita lipat semua salinan menjadi satu, menggunakan yang cantik :..e>(mungkin operator terpanjang yang pernah saya gunakan dalam program CJam).

Ini kodenya:

" __
/  \
\__/"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.
Martin Ender
sumber
Sobat, saya benar-benar harus mempelajari salah satu bahasa golf ini.
Alex Van Liew
@AlexVanLiew Anda harus! :) Tapi bukan karena itu meningkatkan peluang Anda memenangkan kode golf, tetapi karena CJam adalah bahasa yang indah yang menyenangkan untuk diprogram, dan saya tidak tahu bahasa lain di mana solusi di atas (yang saya pikir cukup elegan) akan masuk akal. ;)
Martin Ender
Saya mungkin akan belajar Pyth atau keduanya; Apakah keduanya sama-sama sama atau lebih baik dari yang lain?
Alex Van Liew
@AlexVanLiew Saya tidak tahu banyak Pyth, tapi saya tahu mereka jauh dari hal yang sama. CJam adalah bahasa berbasis tumpukan, sementara Pyth berasal sebagai singkatan untuk Python (tetapi sekarang memiliki set built-in sendiri). Pyth mungkin sedikit lebih unggul dalam hal bermain golf, tapi saya pribadi sangat menikmati pemrograman dalam paradigma yang berbeda, jadi saya akan tetap menggunakan CJam.
Martin Ender
Aha, begitu. Saya tahu Python cukup baik, itulah sebabnya saya ingin belajar Pyth, tetapi jika saya punya waktu mungkin saya akan mencoba CJam juga!
Alex Van Liew
7

Python 2, 219 207 karakter

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

Mengambil input pada stdin.

Cukup banyak hanya membuat kotak 50x50 ruang dan menjatuhkan segi enam di mana sesuai. Setelah segi enam-16, saya tidak perlu baris pertama h(segi enam sebagai array 2D) jadi saya menggunakan i>15untuk memulai kisaran pada 1 bukan 0. c=i*3%48+1;r=(i*3+1)/48*2+i%2menghitung dengan c olumn dan r ow saya harus mulai. nadalah boolean tetapi digunakan sebagai bilangan bulat untuk memperbaiki batas (karena h[0]hanya 3 karakter untuk menghindari menimpa barang).

Saya cukup senang dengan yang satu ini, saya mencukur sekitar 50 byte sejak versi awal, terutama ketika saya ingat a[x:y]=bsintaksnya.

Output (n = 30):

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

Karena garis trailing spasi putih diizinkan, saya mengubah pembuatan guntuk hanya membuat 50 bytearraydetik 3+(x>1)+x/16*2, yang merupakan jumlah tepat baris yang diperlukan, mengurangi 12 byte.

Alex Van Liew
sumber
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)}

Untuk berlari: swift hexagons.swift 21

Keluaran:

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

Swift substringToIndexdan stringByReplacingOccurencesOfStringmengambil begitu banyak karakter ...

David Skrundz
sumber
Saya tidak tahu Swift sama sekali, tetapi tidak adakah cara untuk membangun string berulang dengan kode yang lebih sedikit?
Reto Koradi
Satu-satunya cara saya tahu untuk mengulang string adalah dengan stringByPaddingToLength, namun dalam hal ini akan menjadi 11 karakter lebih lama daripada mengetikkan string penuh.
David Skrundz
6
Saya melihat Apple benar-benar menyukai penggabungan string yang terlalu bertele-tele. Tidak seburuk stringByAppendingStringdi Objective-C tapi masih ...
Fatalize
Di luar kode golf ini sangat bagus karena membuat mencari metode jadi lebih mudah.
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);
}

Hanya spasi dan baris baru yang perlu dipertimbangkan untuk penghitungan karakter.

Ini hanya membuat matriks karakter, mengisinya dengan urutan terbalik, dan kemudian mencetak semuanya.

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

Tessellates hexagon berturut-turut, dari kiri ke kanan, bergantian naik-turun — seperti sarang madu — hingga akhir baris tercapai.

Tidak digabungkan dengan deskripsi (berfungsi di 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>')

royhowie
sumber
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}

membuat array 50 string 50 spasi, kemudian mengganti 4 karakter dalam 3 baris untuk menambahkan segi enam:

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

Karena baris pertama berisi spasi, begitu sebuah segi enam telah diplot, kita tidak dapat memplot yang lain di bawahnya, karena spasi akan menimpa hexagon sebelumnya.

Oleh karena itu hexagon ditambahkan dalam bentuk belah ketupat 16x16 (persegi panjang terdistorsi) dari bawah ke atas, dan miring dari kiri bawah ke kanan atas.

String " __ " kemudian akan ditimpa dengan tambahan \dan di /mana diperlukan.

Tidak digabungkan dalam program uji

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) 

Output khas (n = 250)

Seharusnya ada beberapa baris spasi putih di bagian atas di sini, untuk membuat total 50, tapi saya tidak tahu apakah ada cara untuk mendapatkan format Stackexchange untuk memasukkan mereka.

                                              __  
                                           __/  \ 
                                        __/  \__/ 
                                     __/  \__/  \ 
                            __    __/  \__/  \__/ 
                         __/  \__/  \__/  \__/  \ 
                      __/  \__/  \__/  \__/  \__/ 
                   __/  \__/  \__/  \__/  \__/  \ 
                __/  \__/  \__/  \__/  \__/  \__/ 
             __/  \__/  \__/  \__/  \__/  \__/  \ 
          __/  \__/  \__/  \__/  \__/  \__/  \__/ 
       __/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
    __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
 __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/    
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/       
\__/  \__/  \__/  \__/  \__/  \__/  \__/          
/  \__/  \__/  \__/  \__/  \__/  \__/             
\__/  \__/  \__/  \__/  \__/  \__/                
/  \__/  \__/  \__/  \__/  \__/                   
\__/  \__/  \__/  \__/  \__/                      
/  \__/  \__/  \__/  \__/                         
\__/  \__/  \__/  \__/                            
/  \__/  \__/  \__/                               
\__/  \__/  \__/                                  
/  \__/  \__/                                     
\__/  \__/                                        
/  \__/                                           
\__/                                              
Level River St
sumber