O arquiteto ASCII

15

Você não deseja pagar pelo caro programa de arquitetura, por isso decide criar o seu próprio. Você decide usar o ASCII para projetar seus edifícios. Seu programa terá uma única sequência de caracteres formatada de uma maneira específica e o programa produzirá o edifício.

Entrada

A entrada consiste em uma única linha de caracteres. Supõe-se que ele contenha apenas as letras a-j, os números 1-9e os símbolos -e +.

Descrição da saída

Para cada letra a-j, o programa exibirá uma linha vertical da seguinte maneira. Vamos chamar isso de coluna.

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

Por exemplo, a entrada abcdefgfedefghgfedcproduziria:

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

Uma letra pode ser prefixada com um número inteiro positivo n, que adicionará ncaracteres de espaço em branco abaixo da coluna. Nós chamaremos isso de deslocamento. Por exemplo, usando Spara notar um espaço em branco, a entrada 3b2b3bproduziria:

+ +
+++
S+S
SSS
SSS

Uma letra também pode ser prefixada com um número inteiro negativo-m , que removerá os caracteres de m espaço não em branco da coluna (não os substitua por espaços em branco, remova-os completamente). Vamos chamar isso de fatia. Por exemplo, a entrada -1j-2j-3j-4j-5j-6j-7j-8jproduziria:

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

Um deslocamento e uma fatia podem ser aplicados à mesma linha, mas o deslocamento deve ir primeiro. Em outras palavras, a letra pode ser prefixada com n-m, onde né o tamanho do deslocamento e mo tamanho da fatia. Por exemplo, usando Spara notar um espaço em branco, a entrada '2-4j' produziria:

.
.
.
*
*
*
S
S

Por fim, o +operador usado entre duas colunas indica que eles devem ser empilhados um sobre o outro na mesma coluna, em vez de em colunas separadas. Por exemplo, a entrada `2-4ja 'gera:

.
.
.
*
*
*
S
S+

Considerando que as 2-4j+asaídas de entrada :

+
.
.
.
*
*
*
S
S

Aqui está uma entrada de amostra:

abiehef+ehfhabc

E a saída resultante:

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

Parece uma velha torre de castelo destruída de algum tipo.

Aqui está outra entrada de amostra:

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

E a saída resultante:

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

(Era para ser Mario, mas não ficou muito bom ...)

Se a especificação ainda não estiver clara, eu tenho uma implementação sem golfe escrita em Python 2.7. Você pode executá-lo e experimentar para ter uma ideia de como a especificação funciona. Você também pode rir das minhas habilidades de programação.

Isso é código-golfe, e a entrada mais curta ganha. Faça perguntas nos comentários se não estiver claro.

absinto
fonte
Empilhamento de mais de duas torres é válido? Vejo "2c + b + -2c" em um de seus exemplos, mas não consigo entender se foi assim que você os empilhou.
precisa saber é o seguinte
1
As Torres @AndoDaan podem ser empilhadas infinitamente usando +. Por exemplo a+a+a+a+a, produziria cinco sinais de adição um em cima do outro.
absinto
1
Isso não é uma duplicata do codegolf.stackexchange.com/questions/18967/landscapes ?
Howard
@ Howard Huh, você está certo, estes são surpreendentemente semelhantes (as únicas adições a serem capazes de cortar a torre e empilhar torres).
Martin Ender
@Howard Huh. Não apareceu nas perguntas semelhantes que aparecem quando você digita seu título. A implementação do espaço em branco é um pouco diferente. Vou sinalizar minha postagem como duplicada e ver o que os mods pensam.
absinto

Respostas:

10

Ruby, 223 214 bytes

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

Foi divertido. :)

Embora deva ser bastante óbvio, descobri uma nova maneira de fazer esses desafios em que as cadeias são construídas a partir de colunas: apenas faça-as em linhas e transponha a matriz de caracteres antes de juntar tudo.

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
fonte
Foi experimentar diferentes estilos da linha final e saiu com: puts (0..z=g.map(&:size).max-1).map{|i|g.map{|y|(v=y[z-i])?v:?\ }*''}. Mas provavelmente não é tão divertido sem a transposição.
Vetorizado
@bitpwner Obrigado, vou dar uma olhada e testar isso mais tarde.
Martin Ender
2

Cobra - 473

Acho que o Cobra nunca ganhará um desses: /

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

Tudo agradável e comentou:

EDIT: Acabei de perceber que isso parece suspeitamente semelhante à solução Ruby. Mentes brilhantes pensam igual?

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
Furioso
fonte
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

Nada especial. Foi divertido renomear uma carga de funções por uma vez. Vou editar o código não destruído mais tarde.

Experimente aqui. Saída de amostra:

SampleOutput

AndoDaan
fonte
1

PowerShell , 214 212 209 206 200 bytes

-3 bytes obrigado @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))}

Experimente online!

Versão menos golfe:

# 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))
}
confuso
fonte
1
Regex de (-?.)deve funcionar também
Veskah
impressionante! obrigado.
Mazzy
0

Python 3, 268 bytes

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

Principalmente 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='')
Triggernometria
fonte