Kiến trúc sư ASCII


15

Bạn không muốn trả tiền cho chương trình kiến ​​trúc đắt tiền, vì vậy bạn quyết định tự mình thực hiện. Bạn quyết định sử dụng ASCII để thiết kế các tòa nhà của bạn. Chương trình của bạn sẽ lấy một chuỗi duy nhất được định dạng theo một cách cụ thể và chương trình sẽ xuất tòa nhà.

Đầu vào

Đầu vào bao gồm một dòng ký tự. Nó có thể được coi là chỉ chứa các chữ cái a-j, số 1-9và ký hiệu -+.

Mô tả đầu ra

Đối với mỗi chữ cái a-j, chương trình sẽ xuất ra một hàng dọc như sau. Chúng tôi sẽ gọi đây là một cột.

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

Chẳng hạn, đầu vào abcdefgfedefghgfedcsẽ xuất ra:

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

Một chữ cái có thể được thêm tiền tố với một số nguyên dương n, sẽ thêm các nký tự khoảng trắng bên dưới cột. Chúng tôi sẽ gọi đây là một sự bù đắp. Chẳng hạn, bằng cách sử dụng Sđể ghi chú một khoảng trắng, đầu vào 3b2b3bsẽ xuất ra:

+ +
+++
S+S
SSS
SSS

Một chữ cái cũng có thể được thêm tiền tố với một số nguyên âm-m , sẽ loại bỏ các ký tự m không phải khoảng trắng dưới cùng của cột (không thay thế chúng bằng khoảng trắng, loại bỏ chúng hoàn toàn). Chúng tôi sẽ gọi đây là một lát. Chẳng hạn, đầu vào -1j-2j-3j-4j-5j-6j-7j-8jsẽ xuất ra:

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

Một phần bù và một lát có thể được áp dụng cho cùng một dòng, nhưng phần bù phải đi trước. Nói cách khác, chữ cái có thể được thêm tiền tố vào n-m, nkích thước của phần bù và mlà kích thước của lát cắt. Chẳng hạn, bằng cách sử dụng Sđể ghi chú một khoảng trắng, đầu vào '2-4j' sẽ xuất ra:

.
.
.
*
*
*
S
S

Cuối cùng, +toán tử được sử dụng giữa hai cột biểu thị rằng chúng nên được xếp chồng lên nhau trong cùng một cột thay vì trong các cột riêng biệt. Chẳng hạn, đầu ra `2-4ja 'đầu vào:

.
.
.
*
*
*
S
S+

Trong khi các đầu 2-4j+ara đầu vào :

+
.
.
.
*
*
*
S
S

Đây là một đầu vào mẫu:

abiehef+ehfhabc

Và kết quả đầu ra:

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

Trông giống như một tòa tháp lâu đài bị phá hủy cũ.

Đây là một đầu vào mẫu khác:

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

Và kết quả đầu ra:

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

(Đáng lẽ là Mario nhưng không thành công lắm ...)

Nếu thông số kỹ thuật vẫn chưa rõ ràng, tôi có một triển khai không chơi gôn được viết bằng Python 2.7. Bạn có thể chạy nó và thử nghiệm để cảm nhận về cách thức hoạt động của đặc tả. Bạn cũng có thể chọn cười vào kỹ năng lập trình của tôi.

Đây là mã golf, vì vậy, chiến thắng ngắn nhất. Đặt câu hỏi trong ý kiến ​​nếu không rõ ràng.


Xếp chồng hơn hai tòa tháp có hợp lệ? Tôi thấy "2c + b + -2c" trong một trong những ví dụ của bạn, nhưng tôi không thể biết đó là cách bạn xếp chúng.
AndoDaan

1
@AndoDaan Towers có thể được xếp chồng lên nhau bằng cách sử dụng +. Ví dụ, a+a+a+a+asẽ xuất ra năm dấu cộng với nhau.
absinthe

1
Đây không phải là bản sao của codegolf.stackexchange.com/questions/18967/landscapes ?
Howard

@Howard Huh, bạn nói đúng, đây là những điều tương tự đáng ngạc nhiên (sự bổ sung duy nhất là có thể cắt tháp và xếp chồng tháp).
Martin Ender

@Howard Huh. Nó không xuất hiện trên các câu hỏi tương tự xuất hiện khi bạn nhập tiêu đề của bạn. Việc thực hiện các khoảng trắng là một chút khác nhau mặc dù. Tôi sẽ gắn cờ bài viết của mình dưới dạng trùng lặp và xem các mod nghĩ gì.
absinthe

Câu trả lời:


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

Đó là niềm vui. :)

Mặc dù nó khá rõ ràng, tôi đã khám phá ra một cách mới để thực hiện những thách thức này, nơi các chuỗi được xây dựng từ các cột: chỉ cần thực hiện chúng trong các hàng và hoán chuyển mảng các ký tự trước khi nối mọi thứ.

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.

Đã thử các phong cách khác nhau của dòng cuối cùng và đưa ra : puts (0..z=g.map(&:size).max-1).map{|i|g.map{|y|(v=y[z-i])?v:?\ }*''}. Nhưng có lẽ không vui như vậy nếu không có sự chuyển vị.
Vectorized

@bitpwner Cảm ơn, tôi sẽ xem xét và kiểm tra điều này sau.
Martin Ender

2

Rắn hổ mang - 473

Tôi không nghĩ Cobra sẽ giành được một trong những điều sau: /

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

Tất cả tốt đẹp và bình luận:

EDIT: Mới nhận ra điều này có vẻ đáng ngờ tương tự như giải pháp Ruby. Tư tưởng lớn gặp nhau?

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

Không có gì đặc biệt. Thật là vui khi đổi tên một chức năng mông một lần. Tôi sẽ chỉnh sửa mã không mã hóa sau.

Hãy thử nó ở đây. Đầu ra mẫu:

Mẫu thử


1

PowerShell , 214 212 209 206 200 byte

-3 byte cảm ơn @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))}

Hãy thử trực tuyến!

Phiên bản ít chơi gôn hơn:

# 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 of (-?.)nên hoạt động quá
Veskah

tuyệt vời! cảm ơn.
mê mẩn

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

Chủ yếu là vô lương tâm:

# 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='')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.