La gran pirámide de ASCII


25

Introducción

Es 2600 aC y la gente está construyendo pirámides ahora. Ya formaron la base de la pirámide, pero no saben cómo continuar. Entonces, te pidieron ayuda.

Las reglas para hacer una pirámide son bastante simples. Para la capa sobre la capa anterior, todo lo que necesita hacer es seguir esta guía manual paso a paso:

  1. Corta los bordes de la capa anterior.

  2. Por encima del /personaje, debe haber un \personaje y viceversa. Esto se aplica a todos los caracteres excepto los bordes.

  3. El carácter más a la izquierda es siempre un /y el carácter más a la derecha es siempre \.

Tomemos un ejemplo de una base para una pirámide:

//\/\/\\

Cortamos los bordes, dejando:

 /\/\/\

Cambiamos las barras diagonales por barras diagonales hacia atrás y viceversa:

 \/\/\/

El carácter más a la izquierda es siempre un /y el carácter más a la derecha es siempre un \, así que cambiamos eso:

 //\/\\

Colocamos esta capa en la capa anterior:

 //\/\\
//\/\/\\

Continuamos hasta llegar a la cima (que parece /\). Entonces, eventualmente obtenemos:

   /\
  //\\
 //\/\\
//\/\/\\

Esto es lo que necesita para generar.

La tarea

Dada la base de una pirámide (con una longitud mayor que 3), genera la pirámide completa. Puede asumir con seguridad que el carácter más a la izquierda es /y el carácter más a la derecha es a \. También puede suponer que la longitud de la base es siempre uniforme . Se permite el uso de espacios finales . El uso de espacios iniciales también está permitido, siempre que la pirámide permanezca en su lugar. Se permite el uso de 1 nueva línea final y 1 nueva línea principal .

Casos de prueba

Input: /\\\
Output:
 /\
/\\\

Input: //\\///\/\
Output:
    /\
   /\\\
  /\///\
 ///\\\/\
//\\///\/\

Input: /////////////\
Output:
      /\
     /\\\
    /////\
   /\\\\\\\
  /////////\
 /\\\\\\\\\\\ 
/////////////\

Este es el , por lo que gana el envío con la menor cantidad de bytes.


Me recuerda a un autómata celular elemental . Tal vez eso sería un desafío futuro interesante?
DoctorHeckle

Respuestas:


9

jalea ,28 26 2524 bytes

QṚ,QyḊḊṖṖj@QµÐĿµJ’⁶ẋ⁸żYṚ

-4 bytes gracias a Dennis

Receta:

QṚ,QyḊḊṖṖj@QµÐĿµJ’⁶ẋ⁸żYṚ - one argument: input()
Q  Q       Q             - set of Left=input(): "/\"
 Ṛ                       - reverse Left: "\/"
  ,                      - Left-pair-Right: ["\/","/\"]
     ḊḊṖṖ                - dequeue Left twice, then pop twice: input()[2:-2]
    y                    - translate Right with mapping in Left: swaps internal slashes
         j@              - join Right with separator Left (@ swaps operands)
            µ  µ         - chain separators to form a 1,1,1 chain of chains
             ÐĿ          - loop while results are unique and collect them
                J        - yield [1,...,len(Left=input())]
                 ’       - decrement: [0,....len(input())-1]
                  ⁶      - " "
                   ẋ     - repeat Left Right times: ["", " ", ...]
                    ⁸ż   - zip Right and Left (⁸ is the link's Left argument):
                                ...pads the loop results
                      Y  - joins Left with line-feeds
                       Ṛ - reverse Left

(servir con limonada, esas pirámides son para trabajadores sedientos)

Prepare su propia pirámide de corte en TryItOnline , o pruebe todos los degustadores sugeridos por el OP



11

Pyth - 27 26 bytes

Reduce por la operación dada en el OP hasta que se repite, que es el caso de la línea en blanco.

j_.e+*kdb.ujXtPtPNK"\/")_K

Test Suite .


8

Python 2, 78 bytes

f=lambda s,p='\n':(s[2:]and f('/%s\\'%s.translate('/\\'*128)[2:-2],p+' '))+p+s

Una función recursiva que genera una cadena. Cada capa de la pirámide se agrega a la llamada recursiva con la capa sobre ella. El prefijop , que comienza como un personaje de nueva línea, gana un espacio más para formar el triángulo. La siguiente capa se produce intercambiando barras, cortando el primero y los dos últimos símbolos, y emparejándola dentro de una barra izquierda y derecha.

Python 3 puede guardar un byte haciendo *99entranslate , ya que se eliminó el requisito de longitud 256.


Inteligente usando traducir, pero ¿no tenemos que imprimir?
Jonathan Allan

@JonathanAllan No por defecto , solo tienes que dar salida como dice el desafío.
xnor

6

Haskell, 98 94 90 85 bytes

q=init.tail
s '/'='\\'
s _='/'
t#""=t++"\\\n"
t#l=(' ':t)#(s<$>q l)++t++l#""
("/"#).q

Ejemplo de uso (nota: en Haskell las barras invertidas dentro de cadenas literales tienen que escaparse \\ ):

*Main> putStr $ (("/"#).q) "//\\\\///\\/\\"
    /\
   /\\\
  /\///\
 ///\\\/\
//\\///\/\

Enfoque recurrente simple: #hace el trabajo mediante mapeo s, que voltea el/ y \, en los elementos internos. El parámetro adicional trealiza un seguimiento del nivel de sangría y se expande con un espacio en cada llamada recursiva.

Nota: la segunda llamada recursiva de #(-> l#"") salta directamente al caso base y es solo una forma corta de agregar l, \y una nueva línea, es decir, reemplaza++l++"\\\n" .

Editar: @xnor ahorró 5 bytes. ¡Gracias!


l++"\\\n"Aspecto del producto l#"".
xnor

1
Una forma interesante de intercambiar dos caracteres en una cadena ses [c|x<-s,c<-"ab",c/=x].
xnor

@xnor: He intentado muchas cosas para deshacerme del segundo ++"\\\n", pero me perdí esta. ¡Gracias!
nimi

6

Python 3, 108104101 94 91 89 88 bytes

b,f='\/';p=lambda t,n='\n':(t[2:]and p(f+''.join(map({f:b,b:f}.get,t[2:-2]))+b,n+' '))+n+t

-7 bytes gracias a xnor (¡avisándome que no tenemos que imprimir!)
-3 bytes gracias a xnor (tomando la declaración fuera de la declaración de función [d'oh])
-1 byte gracias a Dennis (reemplazar f,b='/\\'con b,f='\/')

Pruébalo en ideone . Nota: entrada ajustada para doble barra invertida (incluso las cadenas sin procesar no funcionarán si terminan en un número impar de barras invertidas).


Puede declarar conjuntamente f,b='/\\'fuera de la función.
xnor

@xnor Gracias, no puedo contar ^^
Jonathan Allan

5

JavaScript (ES6), 91 86 bytes

f=
(s,t=`
`)=>s[2]?f(`/${s.slice(2,-2).replace(/./g,c=>c>`/`?`/`:`\\`)}\\`,t+` `)+t+s:t+s
;
<input placeholder=Basis oninput=o.textContent=f(this.value)><pre id=o>

La salida incluye un carácter de nueva línea líder.


3

Rubí, 80 bytes.

f=->s{s[-3]>?!&&f[" "+s.gsub(/^( *\/).|.(.$)?/){$1||$2||($&>?/??/:?\\)}]
puts s}

Sin golf

f = ->s{
  s[-3] > ?! &&
    f[" " + s.gsub(/^( *\/).|.(.$)?/) {
      $1 || $2 || ($& > ?/ ? ?/ : ?\\)
    }]
  puts s
}

Véalo en ideone: http://ideone.com/HN0l0Y


mi mal, no vi eso fen el cuerpo
Cyoce

3

Lote, 137 bytes

@echo off
if %1==/\ goto g
set s=%1
set s=\%s:~2,-2%/
set s=%s:/=-%
set s=%s:\=/%
set s=%s:-=\%
call %0 %s% "%~2 "
:g
echo %~2%1

Convenientemente, mi uso de %~2y %1significa que evito tener que gastar bytes setlocal. Explicación: Dado que Batch no realizará reemplazos en la cadena vacía, tenemos que configurar la siguiente capa con los bordes "incorrectos", que luego se corregirán como parte de los reemplazos de cadena.


2

BASH (sed + sort) 71 66 Bytes

sed -rne':l;p;y|\\|1|;y|/|\\|;y|1|/|;th;:h;s|\\.(.*)./| /\1\\|;tl'|sort   
sed -rne':l;p;y|\\/|1\\|;y|1|/|;th;:h;s|\\.(.*)./| /\1\\|;tl'|sort

la entrada proviene de stdin.
Ejemplo:

echo '//\\' |sed -rne':l;p;y|\\|1|;y|/|\\|;y|1|/|;th;:h;s|\\.(.*)./| /\1\\|;tl'|sort

 /\
/\\\

Explicación:
-n- suprima la impresión automática
:l- y tlvuelva al principio si esta línea era otra cosa que /\
p - imprima esta línea
y|\\/|1\\|;y|1|/|- reemplace \con 1, /con \, y luego 1con /
th;:h- pruebe y salte al mismo lugar, de modo que solo se pruebe la siguiente sustitución más tarde
s|\\.(.*)./| /\1\\|, reemplace los dos cortes externos en cada lado con {space}/y \
sort, spaceviene antes, /así que esto pone todo en el orden correcto


2

05AB1E, 42 38 36 bytes

Dg;<FÐgÍ©£R®ÍN-£„/\‡'/ðN>׫«R'\«}r»

Pruébalo en línea!

Explicación:

# Read the input to the stack, loop for 0 .. len(input) / 2 - 1
Dg;<F
# Save the layer by pushing a copy on the stack, then push
# len(layer) - 2 to both the top of the stack and register_c
     ÐgÍ©
# a = pop(); b = pop(); push(b[0:a].reverse())
# This removes the last 2 characters and reverses
         £R
# push(register_c - 2 - N)
           ®ÍN-
# a = pop(); b = pop(); push(b[0:a])
# This removes the leading spaces and the first two slashes
               £
# Push "/\" and "\/" to the stack.
                 „/\Â
# Transliterate the slashes
                     ‡
# Add N+1 spaces and a / to the end of the (reversed) current layer
                      '/ðN>׫«
# Reverse the layer and add a \ to the end.
                              R'\«
# End the loop
                                  }
# Reverse the stack and join it with newlines. It is implicitly printed.
                                   r»

(Gracias a Emigna por señalar eso DD -> Ðy DR -> Â).


Dg;GDðK¦¦¨¨„/\‡'\«R'/«ðN׫R}r»ahorra 7 bytes.
Emigna

Eso me parece lo suficientemente diferente que creo que deberías agregar tu propia respuesta :).
timones

1

Go, 300 276 bytes

package main
import(."regexp";."os")
func p(b string)string{
s:=MustCompile(`((\s*.)(\S*)(\S))`).FindStringSubmatch(b)
if s[3]!=""{r:=""
for _,c:=range s[3][1:len(s[3])-1]{r+=`\/`[c/64:c/46]}
return p(" "+s[2]+r+`\`)+s[1]+"\n"}
return s[1]+"\n"}
func main(){print(p(Args[1]))}

Versión larga:

package main

import (
    "regexp"
    "os"
)

func pyramid(base string) string {
    m := regexp.MustCompile(`^((\s*\S)(\S*)(\S))\s*`).FindStringSubmatch(base)
    if len(m[3]) > 0 {
        reversed := ""
        for _, c := range m[3][1:len(m[3]) - 1] {
            if c == '/' {
                reversed += `\`
            } else {
                reversed += `/`
            }
        }
        return pyramid(" " + m[2] + reversed + m[4]) + m[1] + "\n"
    }
    return m[1] + "\n"
}

func main() {
    print(pyramid(os.Args[1]))
}

import(."regexp";."os")ahorra 2 bytes
Sefa

@Sefa Gracias, exprimí otros 22 bytes.
Roland Illig

1

Perl, 53 52 bytes

Incluye +1 para -p

Ejecutar con la entrada en STDIN, p. Ej.

./pyramid.pl <<< '//\\///\/\'

pyramid.pl:

#!/usr/bin/perl -p
s%^( *)/.(.*)..%"$1 \\$2/
"=~y|\\/|/\\|r.$&%e&&redo

1

05AB1E , 31 bytes

Dg;GDðK¦¦¨¨„/\‡'\«R'/«ðN׫R}r»

Explicación

Dg;G                        }    # for N in [1..len(input)/2-1]
    D                            # make a copy of previous layer
     ðK                          # remove all spaces
       ¦¦¨¨                      # remove first 2 and last 2 chars
           „/\‡                 # replace '/' with '\' and vice versa
                '\«              # add a backslash at the end
                   R             # reverse
                    '/«          # ad a slash at the end
                       ðN׫      # add N spaces
                           R     # reverse back
                             r»  # reverse stack and join on newline
                                 # implicitly print

Pruébalo en línea


1

> <> , 186 179 175 171 bytes

0&v &+1&<
  >i:0)?^~&2,:&v
v'/'~v?:-1<  }0<
o    >84*o^-$;?=@:&:&}:~<
\&::&{:@+$}1+[{l1-$-2*:&1+{
>}1-:?!v$:l2%?!vo
^o'/'v?~e  (*5a<
^o'\'< &   >~]a'\'oo{1+:^
  {$1- >:?!^

oooh hombre, esta es definitivamente mi mayor> <> respuesta hasta ahora.

Probablemente todavía queda algo de golf por hacer (el área inferior es bastante derrochadora)

Pruébalo en línea


0

Powershell, 142 bytes

function s($s){if($s.Trim()-eq'/\'){return $s}
$n=$s-replace'\\','#'-replace'/','\'-replace'#','/'-replace'\\.(.*)./',' /$1\'
(s($n))+"`n$s"
}

0

C #, 250 bytes

s=>{int j=s.Length/2,i=0;var l=new string[j];l[j-1]=s;while(++i<j){var n=l[j-i].Trim().Substring(1,l[j-i].Trim().Length-2);l[j-i-1]=new string(' ',i)+"/"+n.Replace("/","#").Replace(@"\","/").Replace("#",@"\").Substring(1,n.Length-2)+@"\";}return l;};

Definitivamente se puede jugar más, pero mi cerebro se apagó, así que decidí dejarlo como está por el momento.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.