Arsitek ASCII

15

Anda tidak ingin membayar uang untuk program arsitektur mahal, jadi Anda memutuskan untuk membuat sendiri. Anda memutuskan untuk menggunakan ASCII untuk mendesain bangunan Anda. Program Anda akan mengambil string tunggal yang diformat dengan cara tertentu, dan program akan menampilkan bangunan.

Memasukkan

Input terdiri dari satu baris karakter. Dapat diasumsikan hanya berisi huruf a-j, angka 1-9, dan simbol -dan +.

Deskripsi Output

Untuk setiap huruf a-j, program akan menampilkan garis vertikal sebagai berikut. Kami akan menyebutnya kolom.

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

Misalnya, input abcdefgfedefghgfedcakan menghasilkan:

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

Surat dapat diawali dengan bilangan bulat positif n, yang akan menambahkan nkarakter spasi putih di bawah kolom. Kami akan menyebutnya offset. Misalnya, menggunakanS untuk memberi notasi spasi putih, input 3b2b3bakan menampilkan:

+ +
+++
S+S
SSS
SSS

Surat juga dapat diawali dengan bilangan bulat negatif-m , yang akan menghapus karakter m non-spasi bawah kolom (tidak menggantikannya dengan spasi putih, menghapusnya seluruhnya). Kami akan menyebutnya sepotong. Misalnya input-1j-2j-3j-4j-5j-6j-7j-8j akan menghasilkan:

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

Offset dan sepotong dapat diterapkan ke baris yang sama, tetapi offset harus pergi dulu. Dengan kata lain, huruf dapat diawali dengan n-m, di mana nukuran offset, dan mukuran irisan. Misalnya, gunakan Suntuk memberi notasi spasi putih, input '2-4j' akan menampilkan:

.
.
.
*
*
*
S
S

Terakhir, +operator yang digunakan antara dua kolom menunjukkan bahwa mereka harus ditumpuk satu sama lain dalam kolom yang sama, bukan dalam kolom terpisah. Misalnya, input `2-4ja 'menghasilkan:

.
.
.
*
*
*
S
S+

Sedangkan 2-4j+aoutput input :

+
.
.
.
*
*
*
S
S

Berikut adalah contoh input:

abiehef+ehfhabc

Dan output yang dihasilkan:

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

Tampak seperti menara kastil yang sudah hancur.

Berikut ini input sampel lain:

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

Dan output yang dihasilkan:

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

(Seharusnya Mario tapi ternyata tidak terlalu baik ...)

Jika spesifikasinya masih tidak jelas, saya memiliki implementasi non-golf ditulis dengan Python 2.7. Anda dapat menjalankannya dan bereksperimen untuk merasakan bagaimana spesifikasi bekerja. Anda juga dapat memilih untuk menertawakan keterampilan pemrograman saya.

Ini adalah kode-golf, sehingga entri terpendek menang. Ajukan pertanyaan dalam komentar jika tidak jelas.

Absinth
sumber
Penumpukan lebih dari dua menara valid? Saya melihat "2c + b + -2c" di salah satu contoh Anda, tapi saya tidak bisa melihat apakah itu cara Anda menumpuknya.
AndoDaan
1
@AndoDaan Towers dapat ditumpuk tanpa batas menggunakan +. Misalnya a+a+a+a+aakan menampilkan lima tanda plus di atas satu sama lain.
absinthe
@Howard Huh, Anda benar, ini sangat mirip (satu-satunya tambahan adalah untuk dapat memotong menara dan menumpuk menara).
Martin Ender
@Howard Huh. Itu tidak muncul pada pertanyaan serupa yang muncul ketika Anda mengetikkan judul Anda. Implementasi spasi putih sedikit berbeda. Saya akan menandai posting saya sebagai duplikat dan melihat apa yang dipikirkan oleh mod.
absinthe

Jawaban:

10

Ruby, 223 214 byte

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$/

Itu tadi menyenangkan. :)

Meskipun seharusnya cukup jelas, saya menemukan cara baru untuk melakukan tantangan ini di mana string telah dibangun dari kolom: lakukan saja dalam baris, dan transpos susunan karakter sebelum bergabung dengan semuanya.

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.
Martin Ender
sumber
Adalah mencoba gaya yang berbeda dari garis akhir dan keluar dengan: puts (0..z=g.map(&:size).max-1).map{|i|g.map{|y|(v=y[z-i])?v:?\ }*''}. Tapi mungkin tidak begitu menyenangkan tanpa transpos.
Vektorized
@ bitpwner Terima kasih, saya akan melihat dan mengujinya nanti.
Martin Ender
2

Cobra - 473

Saya tidak berpikir Cobra akan memenangkan salah satu dari ini: /

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

Semua bagus dan berkomentar:

EDIT: Baru sadar ini terlihat mirip dengan solusi Ruby. Pemikir hebat berfikir yang sama?

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
Suram
sumber
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

Tidak ada yang spesial. Itu menyenangkan untuk mengubah nama fungsi butt-load untuk sekali sekalipun. Saya akan mengedit kode yang ungolfed nanti.

Cobalah di sini. Output sampel:

SampleOutput

AndoDaan
sumber
1

PowerShell , 214 212 209 206 200 byte

-3 byte terima kasih @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))}

Cobalah online!

Versi yang kurang golf:

# 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))
}
mazzy
sumber
1
Regex of (-?.)seharusnya bekerja juga
Veskah
luar biasa! Terima kasih.
mazzy
0

Python 3, 268 byte

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

Sebagian besar ungolfed:

# 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='')
Triggernometri
sumber