Pirámides egipcias

15

La Gran Pirámide de Giza, la pirámide más grande de Egipto, no solo es la más antigua de las Siete Maravillas del Mundo Antiguo, sino que también es la única que permanece en gran parte intacta. Las pirámides egipcias pueden tardar hasta 20 años en construirse y son tan grandes que Al-Aziz Uthman, hijo del gran Saladino que aplastó a los cruzados, tuvo que renunciar a demoler las grandes pirámides de Giza porque se consideró una tarea demasiado grande . Las pirámides egipcias se construyeron principalmente como tumbas para los faraones del país y sus consortes durante los períodos del Imperio Antiguo y Medio (c. 2686–1690 a. C.), y hasta 2008, se descubrieron 138 pirámides egipcias.

La tarea es crear un programa que ingrese una secuencia de distancias separadas por un espacio y produzca pirámides de texto de 10 × 10 separadas por esas distancias. Una distancia de 1 es igual a dos caracteres.

Una pirámide de texto se verá así:

         /\
        /--\
       /----\
      /------\
     /--------\
    /----------\
   /------------\
  /--------------\
 /----------------\
/------------------\

Si la entrada consiste solo en un salto de línea, se producirá una pirámide, como se indicó anteriormente . Para cada pirámide, las pirámides a la izquierda se muestran como si estuvieran delante.

Ejemplo I

Entrada:

4 3 1

Salida:

         /\      /\    /\/\
        /--\    /--\  /--\-\
       /----\  /----\/----\-\
      /------\/------\-----\-\
     /--------\-------\-----\-\
    /----------\-------\-----\-\
   /------------\-------\-----\-\
  /--------------\-------\-----\-\
 /----------------\-------\-----\-\
/------------------\-------\-----\-\

Ejemplo II

Entrada:

0 9

Salida:

         /\                /\
        /--\              /--\
       /----\            /----\
      /------\          /------\
     /--------\        /--------\
    /----------\      /----------\
   /------------\    /------------\
  /--------------\  /--------------\
 /----------------\/----------------\
/------------------\-----------------\

Ejemplo III

Entrada:

11

Salida:

         /\                    /\
        /--\                  /--\
       /----\                /----\
      /------\              /------\
     /--------\            /--------\
    /----------\          /----------\
   /------------\        /------------\
  /--------------\      /--------------\
 /----------------\    /----------------\
/------------------\  /------------------\

La aplicación para cumplir estos requisitos en la menor cantidad de caracteres es la ganadora.

Referencia: Wikipedia.org

nharren
fuente
¿Supongo que se permite un espacio en blanco adicional al final de la línea?
Peter Taylor
Depende de a quién le preguntes. En la lectura más estricta de la especificación, no hay espacios en blanco después de la salida. Pero dado que esto es por diversión, no tengo ningún problema.
nharren 01 de
Entonces, ¿se permiten argumentos de línea de comando para tomar entrada?
Joey
Siempre y cuando cumpla con los requisitos. Ahora veo que la solución de Whitledge en realidad no es capaz de manejar los saltos de línea como entrada (no puedo deshacer mi voto a favor), simplemente funciona a su alrededor al producir una pirámide si no hay entrada. Pero si puede encontrar una solución que pueda manejar entradas de salto de línea (\ r o \ n está bien) como argumentos de línea de comando, entonces está bien para mí.
nharren

Respuestas:

4

Golfscript, 70 caracteres

~]0-:|;10,{:§9\-" "*"/""-"§2**+"\\"+:&|{.§>{§-(2*" "*1$}{-2*&>}if}%n}%

Puerto directo de mi solución Ruby , así que estoy seguro de que es posible acortar esto en bastantes caracteres.

Ventero
fuente
5

Windows PowerShell, 122 132 133 139

$d=@(-split$input)-gt0
0..9|%{' '*(9-($x=$_))+($a="/$('--'*$_)\")+-join($d|%{'  '*(($_-$x-1)*($x-lt$_))
$a[(-2*$_)..-1]})}

Prueba de guión .

La entrada aleatoria también hace buenas imágenes:

Pirámides aleatorias

Joey
fuente
Funciona si agrego $input=Read-Hosten la parte superior, de lo contrario no pide entrada. ¿Cómo se debe ejecutar esto?
nharren 01 de
@nharren: echo 0 3 4 1|powershell -noprofile -file pyramids.ps1O de PowerShell '0 1 4 3' | .\pyramids.ps1. Este es un problema frecuente con jugar al golf en PowerShell, por desgracia, ya que sólo puede aceptar ya sea entubada de entrada o entrada interactiva. PowerShell realmente no tiene la noción de stdin que otros lenguajes y entornos tienen y esto se muestra a veces. Por lo general, voy por la entrada canalizada, a menos que la tarea explícitamente requiera interactividad, como Adivina el número .
Joey
Ah sí, ahora funciona. Mi combinación de botones no estaba dando ningún resultado, y no podía entender por qué.
nharren 01 de
4

Haskell, 148 caracteres

r=replicate
p d=map(\k->foldr(\n i->r(9-k)' '++'/':r(2*k)'-'++"\\"++drop(11+k)(r(2*n)' '++i))""$d++[0])[0..9]
main=interact$unlines.p.map read.words

¡Estoy bastante insatisfecho con esto! Simplemente se siente demasiado tiempo. Ideas?

MtnViewMark
fuente
Dentro de la lambda, puede cambiar la gran pila de ++'s en una sola lista y usar concat aka >>=id. No sé si ayudará. Otro punto sería usar en foldr1lugar de foldr.
FUZxxl
Gracias por las ideas Tampoco ayuda en este caso: la conversión de ++secuencias solo le ahorra un personaje por elemento, y la sobrecarga de la final concates demasiado alta aquí. No se foldrpuede usar el foldr1formulario porque el tiempo de resultado es Stringmientras que el tipo de lista es [Int](Las 1variantes foldrequieren que sean iguales.)
MtnViewMark
4

Python, 123 caracteres

N=[10]+map(int,raw_input().split())
for y in range(10):print''.join((2*n*' '+'/'+2*y*'-'+'\ ')[-2*n-1:-1]for n in N)[9-y:]
Keith Randall
fuente
Por curiosidad, ¿es este Python 2.5? Para que esto funcione en python 3.2, envolví la función de mapa en una función de lista, cambié raw_input () a input () y cambié print a print ().
nharren
@nharren: funciona tanto en 2.4.4 como en 2.5.2 para mí.
Keith Randall
4

Ruby 1.9, 116 caracteres

d=gets.split-[?0]
10.times{|i|puts [?\s*(9-i),l=?/+?-*2*i+?\\,d.map{|r|i<(r=r.to_i)??\s*2*(r+~i)+l :l[-2*r,99]}]*""}
Ventero
fuente
2

Perl, 130 126 132 caracteres

$_=<>;$s=" "x9;map{$k.="/\\"."  "x($_-1)if$_}split;$_="$s$k/\\$s\n";for$i(0..9){print;s%\\-%-\\%g;s%\\/%-\\%g;s%\\ %-\\%g;s% /%/-%g}

Versión ligeramente más corta que toma la entrada como argumentos de línea de comandos en lugar de desde stdin:

$s=" "x9;map{$k.="/\\"."  "x($_-1)if$_}@ARGV;$_="$s$k/\\$s\n";for$i(0..9){print;s%\\-%-\\%g;s%\\/%-\\%g;s%\\ %-\\%g;s% /%/-%g}

No puedo creer que nadie haya hecho una solución regex todavía. Perl está muy lejos de ser mi mejor idioma, por lo que esto probablemente puede perder mucho más. Me interesaría ver una implementación sed, si alguien está preparado para el desafío.

(Gracias, @mbx, por 4 caracteres).

Peter Taylor
fuente
foreach == para -> guardar 4 caracteres
mbx
¿Has probado tu versión con los casos de prueba?
mbx
@mbx, sí, funciona para mí. Perl 5.10.1, Ubuntu. ¿Qué error estás viendo?
Peter Taylor
@ Peter Taylor: en mi ubuntu y win32 también funciona bien. Primero lo probé en ideone que ejecuta perl 5.12.1.
mbx
2
»Si la entrada consiste solo en un salto de línea«, sugiere una entrada estándar, en realidad.
Joey
1

JavaScript, 396 bytes

function p(a){for(u=0;u<10;u++){t[u+a][9-u]="/";for(k=9-u+1+a;k<10+u+a;k++)t[k][u]="-";
t[10+u+a][u]="\\"}}function _(a){t=[];for(i=0;i<50;i++){t[i]=[];for(j=0;j<10;j++)t[i][j]=" "
}var a=a.split(" "),b=a.reduce(function(a,b){return a-0+(b-0)})*2;for(i=a.length-1;i>=0;
i--)p(b),b-=a[i]*2-0;p(0);a="";for(j=0;j<10;j++){b="";for(i=0;i<50;i++)b+=t[i][j];
a+=b.replace(/\s+$/,"")+(j<9?"\n":"")}return a}

No voy a ganar con JavaScript, pero ahora hay una entrada de JavaScript :)

Uso: _("1 2 3")etc.

pimvdb
fuente
1

Rubí (112)

Ligeramente más corto que la solución Rubí de Ventero, con un enfoque diferente. Acabo de empezar a aprender Ruby, por lo que probablemente esto se pueda reducir bastante.

s=' '*9+r='/\\';gets.split.map{|i|s+=' '*2*(i.to_i-1)+r}
10.times{puts s;s.gsub!' /','/-';s.gsub!(/\\.?/,'-\\')}
migimaru
fuente
1

Powershell, 105 98 bytes, la lectura más estricta de la especificación

-7 bytes de la respuesta de migimaru .

($a=' '+-join(,5+$args-gt0|%{'  '*--$_+'/\'}))
1..9|%{($a=$a-replace' /','/-'-replace'\\.?','-\')}

Script de prueba:

$f = {

($a=' '+-join(,5+$args-gt0|%{'  '*--$_+'/\'}))
1..9|%{($a=$a-replace' /','/-'-replace'\\.?','-\')}

}

@(
,(@"
         /\
        /--\
       /----\
      /------\
     /--------\
    /----------\
   /------------\
  /--------------\
 /----------------\
/------------------\
"@)

,(@"
         /\      /\    /\/\
        /--\    /--\  /--\-\
       /----\  /----\/----\-\
      /------\/------\-----\-\
     /--------\-------\-----\-\
    /----------\-------\-----\-\
   /------------\-------\-----\-\
  /--------------\-------\-----\-\
 /----------------\-------\-----\-\
/------------------\-------\-----\-\
"@, 4,3,1)

,(@"
         /\                /\
        /--\              /--\
       /----\            /----\
      /------\          /------\
     /--------\        /--------\
    /----------\      /----------\
   /------------\    /------------\
  /--------------\  /--------------\
 /----------------\/----------------\
/------------------\-----------------\
"@, 0,9)

,(@"
         /\                    /\
        /--\                  /--\
       /----\                /----\
      /------\              /------\
     /--------\            /--------\
    /----------\          /----------\
   /------------\        /------------\
  /--------------\      /--------------\
 /----------------\    /----------------\
/------------------\  /------------------\
"@, 11)
) | % {
    $expected, $a = $_
    $result = &$f @a
    ($result-join"`n")-eq$expected
    $result 
}

Salida:

True
         /\
        /--\
       /----\
      /------\
     /--------\
    /----------\
   /------------\
  /--------------\
 /----------------\
/------------------\
True
         /\      /\    /\/\
        /--\    /--\  /--\-\
       /----\  /----\/----\-\
      /------\/------\-----\-\
     /--------\-------\-----\-\
    /----------\-------\-----\-\
   /------------\-------\-----\-\
  /--------------\-------\-----\-\
 /----------------\-------\-----\-\
/------------------\-------\-----\-\
True
         /\                /\
        /--\              /--\
       /----\            /----\
      /------\          /------\
     /--------\        /--------\
    /----------\      /----------\
   /------------\    /------------\
  /--------------\  /--------------\
 /----------------\/----------------\
/------------------\-----------------\
True
         /\                    /\
        /--\                  /--\
       /----\                /----\
      /------\              /------\
     /--------\            /--------\
    /----------\          /----------\
   /------------\        /------------\
  /--------------\      /--------------\
 /----------------\    /----------------\
/------------------\  /------------------\

Powershell, 101 94, diversión con un espacio en blanco líder

($a=-join(,6+$args-gt0|%{'  '*--$_+'/\'}))
1..9|%{($a=$a-replace' /','/-'-replace'\\.?','-\')}
mazzy
fuente
0

No pude obtener la versión C # 3 más corta que esta. No sé si el personaje cuenta exactamente, pero sospecho que he perdido. :-(

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace PyramidRenderer
{
    /// <summary>
    /// Generates ASCII-art pyramids at user-specified horizontal locations to
    /// the standard output stream.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Generates one or more ASCII-art pyramids at the locations specified and 
        /// sends them to the standard output stream.
        /// </summary>
        /// <param name="args">The command-line arguments. These should be non-negative 
        /// integers that specify the horizontal distance of each additional pyramid from the 
        /// preceeding pyramid. Whether or not any distances are suppplied, a pyramid
        /// is rendered at the starting location.</param>
        public static void Main(string[] args)
        {
            try
            {
                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

                int[] pyramidDistances = ParsePyramidLocationsFromCommandLine(args).ToArray();
                PyramidCollection pyramids = new PyramidCollection(pyramidDistances);
                pyramids.RenderToText(Console.Out);
            }
            catch (ArgumentException ex)
            {
                Console.Error.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// Handler for the unhandled exception. This just displays the error message to 
        /// the standard error stream.
        /// </summary>
        /// <param name="sender">Required but unnecessary sender object for the event handler.</param>
        /// <param name="e">The object that represents the exception.</param>
        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Debug.Assert(e.ExceptionObject != null);

            string exceptionText;
            Exception ex = e.ExceptionObject as Exception;
            if (ex == null)
                exceptionText = e.ExceptionObject.ToString();
            else
                exceptionText = ex.Message;
            Console.Error.WriteLine(exceptionText);
        }

        /// <summary>
        /// Takes the command-line arguments and converts them to a sequence of 
        /// non-negative integers.
        /// </summary>
        /// <param name="args">The command-line arguments as supplied to Main.</param>
        /// <returns>A sequence of integers that represent the user’s distance selections.</returns>
        /// <exception cref="ArgumentException">An invalid argument was supplied.</exception>
        private static IEnumerable<int> ParsePyramidLocationsFromCommandLine(string[] args)
        {
            Debug.Assert(args != null);

            foreach (string arg in args)
            {
                int result;
                if (int.TryParse(arg, out result))
                {
                    if (result < 0)
                        throw new ArgumentException(string.Format("Invalid distance specified: {0}", arg));

                    yield return result;
                }
                else
                {
                    throw new ArgumentException(string.Format("Invalid option: {0}", arg));
                }
            }
        }
    }

    /// <summary>
    /// Represents a single pyramid to be rendered.
    /// </summary>
    internal class Pyramid
    {
        /// <summary>
        /// The height of the pyramids in text rows. The width of each pyramid will be
        /// twice the height.
        /// </summary>
        internal const int Height = 10;

        /// <summary>
        /// The length in characters of the horizontal unit distance in which the user 
        /// specifies the pyramid distances.
        /// </summary>
        internal const int PyramidUnits = 2;

        /// <summary>
        /// The character to output as the background of the pyramids.
        /// </summary>
        private const char backgroundChar = ' ';

        /// <summary>
        /// The character to output as the left edge of the pyramids.
        /// </summary>
        private const char leftEdgeChar = '/';

        /// <summary>
        /// The character to output within each pyramid, between the edges.
        /// </summary>
        private const char brickChar = '-';

        /// <summary>
        /// The character to output as the right edge of the pyramids.
        /// </summary>
        private const char rightEdgeChar = '\\';

        /// <summary>
        /// The absolute horizonal location of the pyramid’s bottom left corner as 
        /// specified in PyramidUnits.
        /// </summary>
        private int position;

        /// <summary>
        /// Constructs a new pyramid object at the specified location.
        /// </summary>
        /// <param name="position">The absolute horizonal location of the pyramid’s bottom
        /// left corner in PyramidUnits.</param>
        internal Pyramid(int position)
        {
            Debug.Assert(position >= 0);

            this.position = position;
        }

        /// <summary>
        /// Renders a single row the pyramid to the supplied text stream starting at
        /// the indicated location.
        /// </summary>
        /// <param name="textWriter">The output stream to which the pyramid is to
        /// be rendered.</param>
        /// <param name="row">The row of the pyramid to render. Zero is the top row,
        /// and Height - 1 is the bottom row.</param>
        /// <param name="startingPosition">The text character position—indexed at zero—at 
        /// which the rendering is to begin. If non-zero, this identifies the column one 
        /// past the ending location of the previous pyramid.</param>
        /// <returns>The horizontal location (in characters) at which the next item 
        /// may be rendered.</returns>
        internal int RenderRow(TextWriter textWriter, int row, int startingPosition)
        {
            Debug.Assert(textWriter != null);
            Debug.Assert(row >= 0);
            Debug.Assert(startingPosition >= 0);

            int leftBoundary = Height - 1 - row + position * PyramidUnits;
            int rightBoundary = Height + row + position * PyramidUnits;

            startingPosition = RenderField(textWriter, backgroundChar, startingPosition, leftBoundary);
            startingPosition = RenderField(textWriter, leftEdgeChar, startingPosition, leftBoundary + 1);
            startingPosition = RenderField(textWriter, brickChar, startingPosition, rightBoundary);
            startingPosition = RenderField(textWriter, rightEdgeChar, startingPosition, rightBoundary + 1);
            return startingPosition;
        }

        /// <summary>
        /// Outputs a sequence of repeated characters from the indicated starting position to
        /// just before the ending position, unless the starting position is already equal to
        /// or greater than the ending position.
        /// </summary>
        /// <param name="textWriter">The output stream to which the field is to be rendered.</param>
        /// <param name="character">The character to be repeated in the output.</param>
        /// <param name="startingPosition">The location at which rendering may begin in 
        /// characters indexed at zero.</param>
        /// <param name="endingPosition">The location one past the location at which rendering
        /// is to end.</param>
        /// <returns>The position at which the next field may begin.</returns>
        private static int RenderField(TextWriter textWriter, char character, int startingPosition, int endingPosition)
        {
            Debug.Assert(textWriter != null);
            Debug.Assert(startingPosition >= 0);
            Debug.Assert(endingPosition >= 0);

            int charCount = endingPosition - startingPosition;
            if (charCount <= 0)
                return startingPosition;
            textWriter.Write(new string(character, charCount));
            return endingPosition;
        }
    }

    /// <summary>
    /// A collection of pyramids to be displayed.
    /// </summary>
    internal class PyramidCollection
    {
        /// <summary>
        /// A left-to-right ordered list of the pyramids that the user has 
        /// requested to be rendered.
        /// </summary>
        List<Pyramid> allPyramids = new List<Pyramid>();

        /// <summary>
        /// Constructs a new pyramid collection.
        /// </summary>
        /// <param name="distances">The distances of each non-leftmost pyramid (in PyramidUnits) after
        /// the previous pyramid. The total number of pyramids will be one greater than the length of
        /// the distances array.</param>
        internal PyramidCollection(int[] distances)
        {
            Debug.Assert(distances != null);

            int nextPosition = 0;
            allPyramids.Add(new Pyramid(nextPosition));
            foreach (int nextDistance in distances)
            {
                Debug.Assert(nextDistance >= 0);

                try
                {
                    checked
                    {
                        nextPosition += nextDistance;
                        int endLocation = nextPosition * Pyramid.PyramidUnits + Pyramid.Height * 2;
                    }
                }
                catch (OverflowException)
                {
                    // Ignore any pyramids specified beyond the integer maximum distance.
                    break;
                }
                allPyramids.Add(new Pyramid(nextPosition));
            }
        }

        /// <summary>
        /// Outputs ASCII-art images of the pyramids in this collection to the 
        /// provided output stream.
        /// </summary>
        /// <param name="textWriter">The output stream to which the pyramids
        /// are to be rendered.</param>
        internal void RenderToText(TextWriter textWriter)
        {
            Debug.Assert(textWriter != null);

            for (int row = 0; row < Pyramid.Height; row++)
            {
                int startingPosition = 0;
                foreach (Pyramid pyramid in allPyramids)
                {
                    startingPosition = pyramid.RenderRow(textWriter, row, startingPosition);
                }
                textWriter.WriteLine();
            }
        }
    }

}
Jeffrey L Whitledge
fuente
3
¿Confundiste Code Bowling y Code Golf por casualidad?
Joey
1
Al menos finge intentarlo. La gente no tendrá un lenguaje detallado contra usted si lo juega golf .
dmckee --- ex-gatito moderador
Supongo que esa es tu versión detallada para explicar tus ingeniosos trucos. Parece que olvidó publicar la versión de golf de la misma.
mbx
@Joey, @dmckee: pensé en hacer una versión de golf, pero no he podido hacerlo. Soy terrible en este juego de todos modos. El código oscuro va completamente en contra de mi naturaleza. ¡Probablemente debería alejarme de los rompecabezas de golf! - @mbx - Lamentablemente, no hay trucos ingeniosos.
Jeffrey L Whitledge