El arquitecto ASCII

15

No desea pagar dinero por el costoso programa arquitectónico, por lo que decide rodar el suyo. Decide usar ASCII para diseñar sus edificios. Su programa tomará una sola cadena formateada de una manera específica, y el programa generará el edificio.

Entrada

La entrada consiste en una sola línea de caracteres. Se puede suponer que solo contiene las letras a-j, los números 1-9y los símbolos -y +.

Descripción de salida

Para cada letra a-j, el programa generará una línea vertical de la siguiente manera. Llamaremos a esto una columna.

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

Por ejemplo, la entrada abcdefgfedefghgfedcgeneraría:

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

Una letra puede tener como prefijo un número entero positivo n, que agregará ncaracteres de espacio en blanco debajo de la columna. Llamaremos a esto un desplazamiento. Por ejemplo, usando Spara anotar un espacio en blanco, la entrada 3b2b3bgeneraría:

+ +
+++
S+S
SSS
SSS

Una letra también puede tener como prefijo un número entero negativo-m , que eliminará los caracteres de la columna que m no sean espacios en blanco (no los reemplace con espacios en blanco, elimínelos por completo). Llamaremos a esto una rebanada. Por ejemplo, la entrada -1j-2j-3j-4j-5j-6j-7j-8jgeneraría:

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

Se puede aplicar un desplazamiento y un corte a la misma línea, pero el desplazamiento debe ir primero. En otras palabras, la letra puede tener el prefijo n-m, donde nes el tamaño del desplazamiento y mel tamaño de la porción. Por ejemplo, usando Spara anotar un espacio en blanco, la entrada '2-4j' generaría:

.
.
.
*
*
*
S
S

Por último, el +operador utilizado entre dos columnas indica que deben apilarse una encima de la otra en la misma columna en lugar de en columnas separadas. Por ejemplo, la entrada '2-4ja' sale:

.
.
.
*
*
*
S
S+

Mientras que las 2-4j+asalidas de entrada :

+
.
.
.
*
*
*
S
S

Aquí hay una entrada de muestra:

abiehef+ehfhabc

Y la salida resultante:

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

Parece una antigua torre de castillo destruida de algún tipo.

Aquí hay otra entrada de muestra:

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

Y la salida resultante:

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

(Se suponía que era Mario, pero no resultó muy bueno ...)

Si la especificación aún no está clara, tengo una implementación sin golf escrita en Python 2.7. Puede ejecutarlo y experimentar para tener una idea de cómo funciona la especificación. También puede optar por reírse de mis habilidades de programación.

Este es el código de golf, por lo que gana la entrada más corta. Haga preguntas en los comentarios si no está claro.

Ajenjo
fuente
¿Es válido el apilamiento de más de dos torres? Veo "2c + b + -2c" en uno de sus ejemplos, pero no puedo entender si así es como los apiló.
AndoDaan
1
@AndoDaan Towers se puede apilar infinitamente usando +. Por ejemplo, a+a+a+a+ageneraría cinco signos más uno encima del otro.
ajenjo
1
¿No es este un duplicado de codegolf.stackexchange.com/questions/18967/landscapes ?
Howard
@Howard Huh, tienes razón, estos son sorprendentemente similares (las únicas adiciones son poder cortar la torre y apilar torres).
Martin Ender
@Howard Huh. No apareció en las preguntas similares que aparecen cuando escribe su título. Sin embargo, la implementación del espacio en blanco es un poco diferente. Marcaré mi publicación como un duplicado y veré qué piensan las modificaciones.
Absenta

Respuestas:

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

Eso fue divertido. :)

Aunque debería ser bastante obvio, descubrí una nueva forma de hacer estos desafíos donde las cadenas se han construido a partir de columnas: simplemente hágalas en filas y transponga la matriz de caracteres antes de unir todo.

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
fuente
Era probar diferentes estilos de la línea final y salió con: puts (0..z=g.map(&:size).max-1).map{|i|g.map{|y|(v=y[z-i])?v:?\ }*''}. Pero probablemente no sea tan divertido sin la transposición.
Vectorizado el
@bitpwner Gracias, echaré un vistazo y probaré esto más tarde.
Martin Ender
2

Cobra - 473

No creo que Cobra vaya a ganar uno de estos: /

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

Todo agradable y comentado:

EDITAR: Acabo de darme cuenta de que esto parece sospechosamente similar a la solución Ruby. ¿Grandes mentes piensan 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
Οurous
fuente
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. Sin embargo, fue divertido cambiar el nombre de una carga de funciones a tope por una vez. Editaré el código sin golf más adelante.

Pruébalo aquí. Salida de muestra:

Salida de muestra

AndoDaan
fuente
1

PowerShell , 214 212 209 206 200 bytes

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

Pruébalo en línea!

Versión menos golfizada:

# 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
fuente
1
Regex de (-?.)debería funcionar también
Veskah
¡increíble! Gracias.
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='')

En su mayoría sin golf:

# 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='')
Triggernometry
fuente