Elmas Döşeme ölçeklendirme


27

Herhangi bir normal altıgen, örneğin:

   ______
  /_/_/\_\
 /_/\_\/\_\
/\_\/_/\/_/\
\/_/\_\/_/\/
 \_\/_/\_\/
  \_\_\/_/

Yukarıdakileri bir ebatta döşeme olarak değerlendiriyoruz 1(elmasların kenarları bir /veya \her birinden yapıldığı için ). Aynı büyüklükte döşeme 2gibi görünür:

      ____________ 
     /   /   /\   \  
    /___/___/  \___\ 
   /   /\   \  /\   \  
  /___/  \___\/  \___\ 
 /\   \  /   /\  /   /\  
/  \___\/___/  \/___/  \ 
\  /   /\   \  /   /\  /
 \/___/  \___\/___/  \/ 
  \   \  /   /\   \  /
   \___\/___/  \___\/ 
    \   \   \  /   /
     \___\___\/___/ 

Göreviniz , istenen çıktının boyutunu belirten 1pozitif bir tamsayı N(ondalık ya da unary) ile birlikte girdi olarak böyle bir ASCII sanat eseri (boyutta ) almaktır . Daha sonra aynı döşemenin ölçeklendirilmiş bir versiyonunu çıkarmalısınız.

Not altıgen herhangi bir boyutta olabilir ve 1x1x1 kadar küçük (üç elmasları içeren) olabilir.

Ne girdi ne de çıktı, altıgen şeklini hizalamak için gerekli boşlukları veya gereğinden fazla ön boşluk içermemelidir. Hem giriş hem de çıkış isteğe bağlı olarak tek bir izleyen yeni satır içerebilir (bu seçim giriş ve çıkış için aynı olmak zorunda değildir).

STDIN (veya en yakın alternatif), komut satırı argümanı veya işlev argümanı yoluyla giriş alarak ve sonucu STDOUT (veya en yakın alternatif), fonksiyon dönüş değeri veya function (out) parametresi ile çıktı alarak bir program veya işlev yazabilirsiniz.

Bu kod golf, yani kazanılan en kısa cevap (bayt cinsinden).

Örnek Tilings

İşte gönderiminizi test etmek için kullanabileceğiniz bir avuç giriş eğimi.

 __
/_/\
\_\/

  ____
 /_/\_\
/\_\/_/\
\/_/\_\/
 \_\/_/

   ______
  /_/_/\_\
 /_/\_\/\_\
/\_\/_/\/_/\
\/_/\_\/_/\/
 \_\/_/\_\/
  \_\_\/_/

    ________
   /_/\_\_\_\
  /\_\/\_\_\_\
 /\/_/\/_/_/\_\
/\/\_\/_/_/\/\_\ 
\/\/_/\_\_\/\/_/
 \/\_\/_/\_\/_/
  \/\_\_\/_/_/
   \/_/_/_/_/

Aşağıdaki kod parçası, N = 1içinden girdiler için karşılık gelen çıktıları içerir N = 6.


20
Artık kullanıcı adınızın yanında bir tane olan elmaslarla ilgilendiğinizi görüyorum.
user12205

3
@ ace: Ne dediklerini biliyorsun: pırlantalar moderatörün en iyi arkadaşıdır.
Alex A.

Cevabı bildiğimi düşünüyorum, ama umarım yanılıyorum: Boş satırlara liderlik etmek, yasadışı ilan ettiğiniz ön alan olarak sayılır mı? İlk çözümümün N-1önde gelen boş satırları var. :(
Reto Koradi

@RetoKoradi Gerçekten, önde gelen yeni hatlar yok. Üzgünüm.
Martin Ender

1
Ben düşündüm. Bana yaklaşık 10 bayta maloldu. Sorunu ilk tanıdığımda göründüğü kadar kötü değil.
Reto Koradi

Yanıtlar:


8

CJam, 85 79 76 72 bayt

li:Tlf*NqN/T,f{ff{"_/"2$#_1<@+*~ST*@t}:+z{S+e`);e~{"_ "/"__"*W%}T2**N}/}

Boyut ilk satırda olmalıdır. Ve elmas izler.

Çok iyi golf oynamam ... Karakterlerin yarısı detaylardan geldi.

Açıklamalar (önceki sürüm)

li:T            e# Read the size and save to T.
qN/             e# Read and split to lines.
\,fm*           e# Convert each character X to [X 0] [X 1]... [X T(]
{~              e# For each [X I] in each line:
    ST*         e# T spaces.
    \           e# I.
    "_\\"3$#    e# If X is '_, '\ or '/, return Y = 0, 1, -1 respectively.
    _W>@+       e# If it was '_ or '\, increase I by one.
    *(          e# I * Y - 1.
    @t          e# Set the character at that position to X.
}f%
:z:+            e# Make the returned lists from each iteration across T lines.
{S+e`);e~N+}%   e# Boring details to remove trailing spaces and append a newline.
T(>(\s          e# Boring details to extract the first line and only work on others.
{_{"_ "/"__"*W%}2*_@=!}g
                e# Boring details to make underlines expand left and right.

10

Python 2, 164

def g(s,n,j=1):
 for W in s.split("\n"):exec"O=p='';d=0\nfor c in W:q=' _'[j*'_'in p+c];e=[n-j,j-1][c=='/'];O+=q*(e+d)+[c,q][c>'^'];p=c;d=n+~e\nprint O;j-=1;"*j;j=n

Test durumlarında çıktı.

Peki, burada neler oluyor?

Ana fikir, orijinaldeki her karakterin bir n*nbloğa dağılmasıdır. Örneğin, n = 4 için /olabilir

   /
  /
 /
/___

Orijinal karakter her satırda bir kez görünür ve her iki tarafa da dolgu yapılır. İşte, bu kadar solda ve ve _sağda. Sadece alt satır '_'; Gerisi her zaman ' '.

Asıl zorluk, sağdaki dolgunun yaklaşmakta olan sembole bağlı olmasıdır. Özellikle, '/ 'farklı bir dolgu maddesi var '/_', bu yüzden biraz ileriye bakmamız gerekiyor. Dahası, sondaki boşluklardan kaçınmak için, son sembolde olduğumuzu not etmek ve sağdaki dolgudan kaçınmamız gerekir.

Her iki sorunu da yalnızca geçerli karakterin soluna basarak doldururuz. Bunu yaptığımızda, mevcut dolgu sembolünü kullanarak önceki karakterden sağdaki dolguyu da yaparız. Bu nedenle, önceki karakterden sağdaki dolguyu, mevcut karakterden soldaki dolguyu, ardından geçerli karaktere yazdırırız. Ayrıca bir sonraki karakterin ödemesi gereken doldurma "borcunu" tutar.

Şimdi kodun üzerinden gidelim.

def g(s,n,j=1):
    for W in s.split("\n"):
        while j:
            O=p='';d=0
            for c in W:
                q=' _'[j*'_'in p+c]
                e=[n-j,j-1][c=='/']
                O+=q*(e+d)+[c,q][c>'^']
                p=c
                d=n+~e
            print O;j-=1;
        j=n

Giriş dizesi sve ölçek faktörüdür n. Biz baskı, çizgi-by-line gitmek nher giriş hattı için çizgiler Wendeksli kopyalarla, j=n,n-1,...,2,1. İlk satır sadece bir kez kopyalanır, jbunu 1'e başlatarak elde ederiz, ancak nher bir döngüye değiştiririz .

Girdi satırında yinelenerek yazdırılacak satırı biriktiririz O. Öncelikle, qen alt satırda olmamızın altını çizen ve mevcut ya da önceki karakterin alt çizgi olması durumunda uygun bir dolgu karakteri bulduk, aksi halde boşluk.

Sonra sola koymak için dolgu miktarına karar veririz ( e). Çünkü /, j-1(azalan satır-kopya sayısı ile azalır) ve tamamlayıcı n-jiçin \. Diğer karakterlere de aynı şekilde davranıyoruz. Örneğin, _bir satır nalt çizgi veriyor gibi görünmesine rağmen , aslında sol ve sağ alt çizgi ile doldurulmuş tek bir alt çizgi verir. Bu verimsiz görünüyor, ama bize ile çalışır sağlar _ve aynı çerçevede /ve \biz bunu ve toptan o, önemli değil "Merkez" çizgi pozisyonuna ile \; Bu seçenek aynı zamanda üst sıranın özel kasa olmadan çalışmasını sağlar.

Sonra, çıktı dizisine ekleriz. Dolgu sembolünü qve şu andaki doldurma miktarını ebulduk, ancak dolma borcunu dönceki sembolden de hatırlamamız gerekiyor . Yani ekleriz q*(e+d). Ardından, calt satırı olmayan bir satırda alt çizgi kullanmaktan kaçınmamız gerektiği dışında, alt çizgi dolgu sembolüne dönüştürerek sabitlediğimiz sembolü ekleriz.

Son olarak, n+~dmevcut sol doldurma miktarının tamamlayıcısı olan doldurma borç tutarını kaydederiz . Mevcut sembolü de kaydederiz p, böylece önceki sembolün olup olmadığını öğreniriz _.


3

JavaScript ( ES6 ) 274 281 289 338

// GOLFED
F=(b,n)=>{
b=b[R='replace'](/ |_/g,c=>c[T='repeat'](n))[R](/_(?=[\\\/])/g,'_'[T](n))[R](/\/\\/g,`/${'  '[T](n-1)}\\`)
.split('\n');
for(i=l=b.length*n-n+1;--i;)
b[i]=i%n?b[i+1][R](/_/g,' ')[R](/\/ ?/g,' /')[R](/ \\(.)?/g,'\\$1$1')
:' '[T](i>l/2?n-1:0)+b[i/n];
return b.join('\n')}


// UNGOLFED
U=(b,n)=>{
  b=b
  .replace(/ |_/g,c=>c.repeat(n))
  .replace(/_(?=[\/\\])/g,'_'.repeat(n))
  .replace(/\/\\/g,`/${'  '.repeat(n-1)}\\`)
  .split('\n');
  for(i=l=b.length*n-n+1;--i;)
  {
    if(i%n)
     b[i]=b[i+1]
     .replace(/_/g,' ')
     .replace(/\/ ?/g,' /')
     .replace(/ \\/g,'\\ ').replace(/ +$/,'')
     .replace(/ \\(.)?/g,'\\$1$1')
    else {
      b[i]=b[i/n]
      if(i>l/2)b[i]=' '.repeat(n-1)+b[i];
    }
  }
  return b.join('\n')
}

//TEST

test=[
' __\n/_/\\\n\\_\\/',
'  ____\n /_/\\_\\\n/\\_\\/_/\\\n\\/_/\\_\\/\n \\_\\/_/',
'   ______\n  /_/_/\\_\\\n /_/\\_\\/\\_\\\n/\\_\\/_/\\/_/\\\n\\/_/\\_\\/_/\\/\n \\_\\/_/\\_\\/\n  \\_\\_\\/_/',
'    ________\n   /_/\\_\\_\\_\\\n  /\\_\\/\\_\\_\\_\\\n /\\/_/\\/_/_/\\_\\\n/\\/\\_\\/_/_/\\/\\_\\\n\\/\\/_/\\_\\_\\/\\/_/\n \\/\\_\\/_/\\_\\/_/\n  \\/\\_\\_\\/_/_/\n   \\/_/_/_/_/'
]

test.forEach(t=>{
  var row = '<td>'+t+'<td>'
  for(rr=2;rr<5;rr++)
    row += '<td>'+F(t,rr)+'</td>'
  OUT.innerHTML += '<tr>'+row+'</tr>'
})
td {
  font-family: monospace;
  white-space: pre;
}
(better full page)
<table id=OUT></table>


3

Python 2, 217 211 195 194 190

b,f,s='\/ '
R=str.replace
def m(g,n,z=1):
 for d in g.split('\n'):
    for i in range(z):a=z+~i;print[i,a][d[-1]>f]*s+R(R(R(R(d,s,s*n),'_','_ '[i<z-1]*(z+n-1)),f+b,f+s*2*i+b),b+f,b+s*2*a+f);z=n

Sp3000 sayesinde 6 bayt.

Çağrı mİlk argüman bir dize, ve ikinci argüman tekrar sayısı olarak elmas olmak.

Bu, 3 adımlı bir dize değiştirme sırasını temel alır:

  • İlk önce, çizgiye bağlı olarak alt çizgi sayısını 2n-1 boşluk veya alt çizgi ile değiştirin.
  • İkinci olarak, yerine /\sahip / \hatları üzerinden 2 * (n-1) 2 giden ara alanlar sayısı ile.
  • Üçüncü olarak, yerine \/sahip \ /hatları üzerinden 2 ila 2 * (n-1) giden ara alanlar sayısı ile.

Ardından, öndeki boşlukları doğru yapmak ve ilk çizgiyi doğru yapmak için çok çeşitli şeyler vardır.

Programın son satırının 4 boşluk değil, bir sekme olması gerektiğini unutmayın. Markdown sekmeleri desteklemiyor.


İki golf: (i+(n-i+~i)*(d[-1]>f)) --> [i,n+~i][d[-1]>f]ve sadece bir '_'kez kullanıyorsunuz, bu yüzden onu tanımlayan bir baytı harcıyorsunuz.
Sp3000

3

Python, 272 238 228 243 bayt

Güncellenmiş sürüm, şimdi bir dizge dizisi yerine girdi olarak tek bir dizge alır. Ayrıca, önceki sürümde bulunan sondaki boşlukları da kaldırır. Ne yazık ki bu değişikliklerin boyutu artar.

s,u,f,b=' _/\\'
r=str.replace
def d(t,n,j=1):
 for p in t.split('\n'):
  for k in range(n-j,n):m,v=n+~k,'_ '[k<n-1];print r(r(r(r(r(r(r(r(p,f+u,'(_'),u+b,'_)'),s,s*n),u,v*n),f,s*m+f+s*k),'(',v*m+f+v*k),b,s*k+b+s*m),')',v*k+b+v*m).rstrip();j=n

Boşluklu sürüm ve okunabilirlik için daha küçük birimlere bölünmüş ifadeler:

s, u, f, b = ' ', '_', '/', '\\'
def d(t, n):
    j = n - 1
    for p in t:
        for k in range(j, n):
            m, v = n - 1 - k, '_ '[k < n - 1]
            q = p[:-1]
            q = q.replace(f + u, '(_')
            q = q.replace(u + b, '_)')
            q = q.replace(s, s * n)
            q = q.replace(u, v * n)
            q = q.replace(f, s * m + f + s * k)
            q = q.replace('(', v * m + f + v * k)
            q = q.replace(b, s * k + b + s * m)
            q = q.replace(')', v * k + b + v * m)
            print q
            j = 0

Buradaki temel yaklaşım:

  1. Girişteki tüm çizgiler üzerinde döngü yapın.
  2. Her satır için, Nher bir döngü yinelemesinde bir çıktı satırı üreten , çıktı boyutu üzerinde döngü. Çıktı başlangıcında boş satırlar oluşmasını önlemek için yalnızca son çıkış satırının üretildiği ilk satır için özel bir durum vardır.
  3. Satırdaki her karakteri karakterlerle değiştirin N, burada:
    • Her boşluk, Nboşluklarla değiştirilir .
    • Her alt çizgi, Nilk N -1döngü yinelemeleri için boşluklarla Nve son döngü yinelemesi için alt çizgilerle değiştirilir.
    • Eğik çizgiler ve ters eğik çizgiler N - 1boşluk veya alt çizgi ile doldurulur .

Buradaki en zor kısım, eğik çizgi / ters eğik çizgi için dolgunun bir sonraki (eğik çizgi için) veya önceki (ters eğik çizgi için) giriş karakterine bağlı olarak boşluk veya alt çizgi kullanmasıdır. Bu dize değiştirme stratejisi ile iyi uymuyor gibiydi.

Bunu çözmek için yaptığım şey, ilk önce belirli iki karakter kombinasyonunu farklı karakterlerle değiştirmem, böylece gerçek değiştirme sırasında onlara farklı davranabiliyorum. Örneğin, /_ile değiştirilir (_. Bundan sonra (, etkin bir şekilde "sonradan alt çizgi çizer" ve ardından buna göre ikame edilebilir.

Fonksiyonu test etmek için kullanılan ana program:

import sys
import Golf

n = int(sys.argv[1])
t = ''.join(sys.stdin).rstrip()

Golf.d(t, n)

1
n-1-kisn+~k
özyinelemeli

Tam açıklama ile ilgili olarak: Çözümümün bazı sonda boşluklar ürettiğini öğrendim. Çıktı tanımında buna izin verilmediğinden, gereksinimleri karşılamıyor. En kötü durumda, .rstrip()9 karakter daha eklemek zorunda kalacağım . Umarım daha iyisini yapabilirim ve ayrıca 5 karakteri kesmenin bir yolunu buldum.
Reto Koradi

Giriş biçiminize izin verilmiyor gibi görünüyor. sys.stdinizin verilen bir giriş parametresi değildir - dizenin kendisini değiştirmeniz gerekir.
isaacg

Kullanabilirsiniz sys.stdinve int(sys.argv[1])değişken olarak geçmelerini bekleyerek onları ücretsiz olarak alamayacaksınız (eğer adil bir rangeoyunduysa , o zaman takma adları değiştirip yerine koymayı da bekleyebilirsiniz ). .
Martin Ender

@ MartinBüttner Girdiyi işlev argümanı olarak alabileceğimi söylüyor. Burada yaptığım şey bu değil mi? Fonksiyon argümanını yine de bir dizi listeyle değiştirecektim. Bu iyi olur mu? Çok farklı değil, çünkü hem stdindizelerin listesi hem de dizge dizisidir.
Reto Koradi

1

Perl, 132

#!perl -p
INIT{$f=pop}s!.!$&x$f!ge;s! $!! while s!\\+\K\\|/(/)! $1!;
for$x(2..m!/!*$f){print y!_! !r;s!\\.?! \\!g;s!./(.)?!/$1$1!g;s!_ !__!g}

Kombine STDIN ve ARGV girişi. Örnek:

$ perl ~/hex.pl <~/hex.txt 3
         __________________
        /     /     /\     \
       /     /     /  \     \
      /_____/_____/    \_____\
     /     /\     \    /\     \
    /     /  \     \  /  \     \
   /_____/    \_____\/    \_____\
  /\     \    /     /\    /     /\
 /  \     \  /     /  \  /     /  \
/    \_____\/_____/    \/_____/    \
\    /     /\     \    /     /\    /
 \  /     /  \     \  /     /  \  /
  \/_____/    \_____\/_____/    \/
   \     \    /     /\     \    /
    \     \  /     /  \     \  /
     \_____\/_____/    \_____\/
      \     \     \    /     /
       \     \     \  /     /
        \_____\_____\/_____/

1

Ruby 236 237

->i,z{i.split(?\n).map{|l|z.times.map{|y|l.size.times.map{|i|z.times.map{|x|c=l[i]
z<y+2&&(l[i-1..i]=='_\\'||l[i..i+1]=='/_')&&o=?_
(c<?!||(x==y&&c==?\\)||(z==y+1&&c>?^)||(x+y+1==z&&c==?/))&&o=c
o||' '}.join}.join.rstrip}-['']}.join ?\n}

Çevrimiçi test: http://ideone.com/e6XakQ

Golf oynamadan önceki kod budur:

-> diamond, zoom {
  diamond.split(?\n).map do |l|
    zoom.times.map do |y|
      l.size.times.map do |i|
        zoom.times.map do |x|
          out_char = crt_char = l[i]

          out_char = ' '

          # _ has to be continued under / or \
          if zoom == y+1 && l[i-1..i]=='_\\'
            out_char = ?_
          end
          if zoom == y+1 && l[i..i+1]=='/_'
            out_char = ?_
          end

          # logic to "zoom" \, / and _ characters 
          out_char = crt_char if crt_char == ' '
          out_char = crt_char if x==y && crt_char == ?\\  
          out_char = crt_char if zoom==y+1 && crt_char == ?_
          out_char = crt_char if x+y+1==zoom && crt_char == ?/

          out_char
        end.join
      end.join.rstrip
    end - ['']
  end.join ?\n
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.