ASCII Mimar


15

Pahalı mimari program için para ödemek istemezsiniz, bu yüzden kendi programınızı yapmaya karar verirsiniz. Binalarınızı tasarlamak için ASCII kullanmaya karar verdiniz. Programınız belirli bir şekilde biçimlendirilmiş tek bir dize alacak ve program binanın çıktısını alacaktır.

Giriş

Giriş tek bir karakter satırından oluşur. Sadece harfleri içerdiği varsayılabilir a-j, sayılar 1-9ve semboller -ve +.

Çıktı Açıklaması

Her harf için a-j, program aşağıdaki gibi dikey bir çizgi çıkarır. Buna sütun diyeceğiz.

         .
        ..
       ...
      ****
     *****
    ******
   -------
  --------
 +++++++++
++++++++++
abcdefghij

Örneğin, girdinin abcdefgfedefghgfedcçıktısı:

             .
      *     ***
     ***   *****
    ***** *******
   ---------------
  -----------------
 ++++++++++++++++++
+++++++++++++++++++

Bir sütuna, sütunun altına boşluk karakteri nekleyecek pozitif bir tamsayı eklenebilir n. Buna ofset diyeceğiz. Örneğin, Sbir boşluğu not etmek için kullanarak 3b2b3bçıktı:

+ +
+++
S+S
SSS
SSS

Bir mektup da öneki edilebilir negatif tamsayı -molur, kaldırma alt m boşluk olmayan sütunun karakterler (boşluk ile bunların yerine, tamamen kaldırın). Buna bir dilim diyeceğiz. Örneğin, girdinin -1j-2j-3j-4j-5j-6j-7j-8jçıktısı:

.
..
...
*...
**...
***...
-***...
--***...
+--***..

Aynı satıra bir ofset ve bir dilim uygulanabilir, ancak ofset önce gitmelidir. Başka bir deyişle, harf öneki olabilir n-mnerede, nofset boyutudur ve mdilimin boyutudur. Örneğin, Sbir boşluğu not etmek için '2-4j' girdisi çıktı alır:

.
.
.
*
*
*
S
S

Son olarak, +iki sütun arasında kullanılan operatör, ayrı sütunlar yerine aynı sütunda üst üste istiflenmeleri gerektiğini belirtir. Örneğin, giriş 2-4ja çıktısı:

.
.
.
*
*
*
S
S+

Oysa giriş 2-4j+açıkışları:

+
.
.
.
*
*
*
S
S

İşte bir örnek giriş:

abiehef+ehfhabc

Ve sonuçta ortaya çıkan çıktı:

      *
      -
  .   -
  . . +. .
  * * +* *
  * * ****
  ********
  --------
  --------  -
 +++++++++ ++
+++++++++++++

Bir tür eski yıkılmış kale kule gibi görünüyor.

İşte başka bir örnek girdi:

6b5b+a6b1-2d+3-4f1-2d+-2c+2-4f+1-2d+-2c2-2d+1-4g+1-2c+b+-2c+-4e2-7j+-4g+d+-2c+-4f2-7j+-5h+b+-2c+a+-3f2-7j+-7i+-4e+b+b+a+-4f2-7i+a+-7h+-4f+b+b+a+-4f2-7j+-7h+-4f+a+-7h+a+-7i+-4f2-7j+-7i+-6h+a+-7i+b+-4e3-7i+a+-7h+-4e+a+-7h+b+1-7h3-7j+1-4f+-7h+b+-4f+a3-7j+2-4f+a+-4f+b3-2d+-2d+3-4g+b3-2d+-2d+-2c

Ve sonuçta ortaya çıkan çıktı:

      ****** +++
     ******+.*++
     ---++.+ ***
    -+-+++..++**
    -+--+++.+++*
    --++++.+..*
      +++++.+**
+++****.******  -
+++*****.**..  --
 +   ***....+..--
      ...+.....--
    --.........--
   ---......
   --

(Mario olması gerekiyordu ama çok iyi olmadı ...)

Spesifikasyon hala net değilse, Python 2.7'de yazılmış golf olmayan bir uygulamam var . Spesifikasyonu nasıl çalıştığına dair bir fikir edinmek için çalıştırabilir ve deney yapabilirsiniz. Programlama becerilerime de gülmeyi seçebilirsiniz.

Bu kod golf, bu yüzden en kısa giriş kazanır. Net değilse, yorumlarda soru sorun.


İkiden fazla kulenin istiflenmesi geçerlidir? Örneklerinizden birinde "2c + b + -2c" ifadesini görüyorum, ancak bunları bu şekilde istiflediyseniz, çözemiyorum.
AndoDaan

1
@AndoDaan Towers + ile sonsuz şekilde istiflenebilir. Örneğin a+a+a+a+a, beş artı işareti üst üste çıktı.
Absinthe


@Howard Huh, haklısın, bunlar şaşırtıcı derecede benzer (tek eklemeler kuleyi kesip kuleleri istiflemek).
Martin Ender

@Howard Huh. Başlığınızı yazdığınızda ortaya çıkan benzer sorularda ortaya çıkmadı. Beyaz alanın uygulanması biraz farklıdır. Yazımı kopya olarak işaretleyeceğim ve modların ne düşündüğünü göreceğim.
Absinthe

Yanıtlar:


10

Yakut, 223 214 bayt

g=$*[0].split(/(?<=[a-j])(?!\+)/).map{|r|r.scan(/(\d*)(-\d+)?([a-j])/).map{|a,b,c|' '*a.to_i+'++--***...'[-b.to_i..c.ord-97]}*''}
puts g.map{|s|s.ljust(g.map(&:size).max).chars.reverse}.transpose.map(&:join).join$/

Bu eğlenceliydi. :)

Her ne kadar oldukça açık olsa da, dizelerin sütunlardan oluşturulduğu bu zorlukları yapmanın yeni bir yolunu keşfettim: bunları satırlar halinde yapın ve her şeye katılmadan önce karakter dizisini değiştirin.

g=$*[0].split(/(?<=[a-j])(?!\+)/)               # Split into columns.
       .map{|r|                                 # For each column
            r.scan(/(\d*)(-\d+)?([a-j])/)       # Split into components.
             .map{|a,b,c|                       # For each component
                ' '*a.to_i+                     # Prepend spaces if any.
                '++--***...'[-b.to_i..c.ord-97] # Select the appropriate slice of the tower.
            }*''                                # Join all components together.
        }
puts g.map{|s|                                  # For each column
            s.ljust(g.map(&:size).max)          # Pad with spaces on the right such that. 
                                                # all columns are the same height.
            .chars.reverse                      # Turn into character array and reverse.
      }
      .transpose                                # Mirror in the main diagonal.
      .map(&:join)                              # Join lines.
      .join$/                                   # Join columns.

Nihai hattının farklı stilleri denemek oldu ve çıktı: puts (0..z=g.map(&:size).max-1).map{|i|g.map{|y|(v=y[z-i])?v:?\ }*''}. Ama muhtemelen devrik olmadan o kadar eğlenceli değil.
Vectörize

@bitpwner Teşekkürler, daha sonra bir göz atacağım ve test edeceğim.
Martin Ender

2

Kobra - 473

Cobra'nın bunlardan birini kazanacağını sanmıyorum: /

use System.Text.RegularExpressions
class P
    def main
        r=Regex.matches(Console.readLine,r'(?<=^|[a-j])(([^a-j]*[a-j])+?)(?=[^+]|$)')
        z,l=0String[](r.count)
        for m in r.count,for n in'[r[m]]'.split('+'),l[m]+=' '.repeat(int.parse('0[Regex.match(n,r'(?<!-)\d+')]'))+'++--***...'[int.parse('0[Regex.match(n,r'(?<=-)\d+')]'):' abcdefghij'.indexOf(n[-1:])]
        for y in l,if y.length>z,z=y.length
        for x in-z+1:1
            for y in l,Console.write(if(-x<y.length,y[-x],' '))
            print

Hepsi güzel ve yorumladı:

EDIT: Bunun Ruby çözümüne kuşkuyla benzediğini fark ettim. Büyük akıllar benzer mi?

use System.Text.RegularExpressions
class P
    def main
        r=Regex.matches(Console.readLine,r'(?<=^|[a-j])(([^a-j]*[a-j])+?)(?=[^+]|$)')
        # Split into columns
        z,l=0,String[](r.count)
        # Assign the column-array
        for m in r.count
        # Loop through columns
            for n in'[r[m]]'.split('+')
            # Loop through individual letter instructions
            # - within columns
                l[m]+=
                # Add characters to the last column
                    ' '.repeat(int.parse('0[Regex.match(n,r'(?<!-)\d+')]'))+
                    # Any spaces, plus
                    '++--***...'[:' abcdefghij'.indexOf(n[-1:])]
                    # The default column string
                        [int.parse('0[Regex.match(n,r'(?<=-)\d+')]'):]
                        # Sliced to the right length
        for y in l,if y.length>z,z=y.length
        # Determine the maximum length of any column
        for x in-z+1:1
            for y in l
            # Loop through columns so that they rotate to the left
                Console.write(if(-x<y.length,y[-x],' '))
                # Write the character in the current position
            print
            # Insert newlines

2

Lua - 451

a=arg[1]j='++--***...'I=io.write M=string.match U=string.sub T=table.insert n=''y=0 t={}m=0 for i in a:gmatch('[%-%d]*[a-j]%+?')do b=M(i,'-(%d)')b=b or 0 s=M(U(i,1,1),'%d')s=s or 0 n=n..(' '):rep(s)..U(U(j,1,M(U(i,-2),'[a-j]'):byte()-96),1+b,-1)if U(i,-1,-1)~="+"then T(t,n)m=m<#n and #n or m n=""y=y+1 end end T(t,n)n=''for k,v in pairs(t)do n=#v<m and n..v..(' '):rep(m-#v)or n..v end for i=m,1,-1 do for k=0,m*y-1,m do I(U(n,i+k,i+k))end I'\n'end

Özel birşey yok. Gerçi bir sürü işlevi yeniden adlandırmak eğlenceliydi. Çözülmemiş kodu daha sonra düzenleyeceğim.

Burada deneyin. Örnek Çıktı:

SampleOutput


1

PowerShell , 214 212 209 206 200 bayt

-3 bytes teşekkürler @Veskah

switch -r($args-split'(-?.)'){\+{$c=1}\d{sv('ps'[0-gt$_])$_}[a-j]{if(!$c){$t+=,''}$t[-1]+=' '*$p+-join'++--***...'[-$s..($_[0]-97)];$c=$p=$s=0}}($t|% Le*|sort)[-1]..1|%{-join($t|% *ht $_|% ch*($_-1))}

Çevrimiçi deneyin!

Daha az golf versiyonu:

# make table with lines instead columns
switch -r($args-split'(-?.)'){
    \+ {$c=1}
    \d {set-variable ('ps'[0-gt$_]) $_}
    [a-j] {
        if(!$c){$t+=,''}
        $t[-1]+=' '*$p+-join'++--***...'[-$s..($_[0]-97)]
        $c=$p=$s=0
    }
}
# transpose
($t|% Length|sort)[-1]..1|%{
    -join($t|% padRight $_|% chars($_-1))
}

1
Regex de (-?.)çalışması gerekir
Veskah

müthiş! Teşekkürler.
mazzy

0

Python 3, 268 bayt

import re
q,t=[(p,' '*int(o or 0)+'++--***...'[-int(s or 0):ord(l)-96])for p,o,s,l in re.findall('(\+?)(\d?)(-\d)?(.)',input())],[]
while q:p,s=q.pop(0);t+=[t.pop()+s if p else s]
t=[*zip(*[[*c.ljust(max(map(len,t)))]for c in t])][::-1]
for l in t:print(*l,sep='')

Çoğunlukla dinlenmemiş:

# import the regex module
import re

# array to store initial input
q = []
# array to store translated output
t = []

# split string from stdin into column groups, like: ('plus or blank', 'offset or blank', 'slice or blank', 'letter')
# ex: 6b1-2d+a would become:
# [('','6','','b'), ('', '1', '-2', 'd'), ('+', '', '', 'a')]
i = re.findall('(\+?)(\d?)(-\d)?(.)',input())

# iterate through the groups returned by the regex
for p,o,s,l in i:
    # create offset string
    # int() cannot parse '', but empty strings are falsey,
    # so (o or 0) is equivalent to 'parse the string as an int, or return 0 if it is empty'
    offset = ' ' * int(o or 0)

    # get the starting point of the slice
    # since the regex returns the minus, it must be negated after converting the string to an int
    # as before, (s or 0) ensures that the slice is converted to an int properly
    start = -int(s or 0)
    # since 'a' is ordinal 97, this ensures that the end position will be 1-9
    end = ord(l) - 96
    # slice the largest possible column string with the calculated start and end positions
    a = '++--***...'[start:end]
    # add the space offset
    a = offset + a
    # add the plus sting and the column string to the array
    q.append( (p, a) )

# while q is not empty
while q:
    # remove the first item from the list and separate it into a plus variable and a column string
    p, s = q.pop(0)

    # if p is not blank, it is a '+'
    # if p is truthy, remove the last item added and add s to it
    # otherwise just return s
    # append the resulting item to the ongoing list
    t += [t.pop()+s if p else s]

temp = []
for c in t:
    # call len() on all items in t, then return the maximum length
    m = max(map(len, t))
    # left justify c by adding spaces to the right, up to m total characters
    c = c.ljust(m)
    # unpack c into a list
    # this is equivalent to list(c), but shorter
    c = [*c]
    # add the list of characters to the array
    temp.append(c)

t = temp

# t is currently a list of rows, and needs to be rotated so that it displays correctly
# input: 'abcdefghij'
# before:
#
# +
# ++
# ++-
# ++--
# ++--*
# ++--**
# ++--***
# ++--***.
# ++--***..
# ++--***...
#
# after:
#
#  ++++++++++
#   +++++++++
#    --------
#     -------
#      ******
#       *****
#        ****
#         ...
#          ..
#           .
# 
t = [*zip(*t)]
# t is currently upside down, reverse the list
t = t[::-1]

# for each line (currently a list of characters)
for l in t:
    # unpack the list into print as arguments, do not add a space between arguments
    print(*l,sep='')
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.