Pirâmides egípcias

15

A Grande Pirâmide de Gizé, a maior pirâmide do Egito, não é apenas a mais antiga das Sete Maravilhas do Mundo Antigo, mas é também a única a permanecer praticamente intacta. As pirâmides egípcias podem levar até 20 anos para serem construídas e são tão grandes que Al-Aziz Uthman, filho do grande Saladino que esmagou os cruzados, teve que desistir de demolir as grandes pirâmides de Gizé porque foi considerada uma tarefa muito grande . As pirâmides egípcias foram construídas principalmente como túmulos para os faraós do país e seus consortes durante os períodos do Reino Antigo e Médio (c. 2686-1690 aC) e, a partir de 2008, 138 pirâmides egípcias foram descobertas.

A tarefa é criar um programa que insira uma sequência de distâncias separadas por um espaço e produza pirâmides de texto 10 × 10 separadas por essas distâncias. Uma distância de 1 é igual a dois caracteres.

Uma pirâmide de texto ficará assim:

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

Se a entrada consistir apenas em uma quebra de linha, uma pirâmide será produzida, como acima . Para cada pirâmide, as pirâmides à esquerda são exibidas como se estivessem na frente.

Exemplo I

Entrada:

4 3 1

Resultado:

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

Exemplo II

Entrada:

0 9

Resultado:

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

Exemplo III

Entrada:

11

Resultado:

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

O aplicativo para atender a esses requisitos com a menor quantidade de caracteres é o vencedor.

Referência: Wikipedia.org

nharren
fonte
Presumo que espaço em branco adicional no final da linha seja permitido?
Peter Taylor
Depende de quem você pergunta. Na leitura mais estrita da especificação, não há espaços em branco após a saída. Mas, como isso é divertido, não tenho problema com isso.
nharren
Então argumentos de linha de comando para receber entrada são permitidos?
Joey
Desde que atenda aos requisitos. Agora vejo que a solução de Whitledge não é capaz de lidar com quebras de linha como entrada (não posso desfazer meu voto positivo), ela simplesmente funciona em torno dela produzindo uma pirâmide se não houver entrada. Mas se você puder encontrar uma solução que possa lidar com entradas de quebra de linha (\ r ou \ n está correta) como argumentos da linha de comando, tudo bem comigo.
precisa saber é o seguinte

Respostas:

4

Golfscript, 70 caracteres

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

Porta direta da minha solução Ruby , por isso tenho certeza de que é possível reduzi-la em alguns caracteres.

Ventero
fonte
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]})}

Script de teste .

A entrada aleatória também cria boas imagens:

Pirâmides aleatórias

Joey
fonte
Funciona se eu adicionar $input=Read-Hostna parte superior, caso contrário, não solicitará entrada. Como isso deve ser executado?
N / a
@harren: echo 0 3 4 1|powershell -noprofile -file pyramids.ps1Ou do PowerShell '0 1 4 3' | .\pyramids.ps1. Este é um problema frequente com golfe em PowerShell, infelizmente, como você só pode aceitar qualquer canalizada-in de entrada ou de entrada interativo. O PowerShell realmente não tem a noção de stdin que outros idiomas e ambientes possuem, e isso às vezes mostra. Eu geralmente busco entrada direcionada, a menos que a tarefa exija explicitamente interatividade, como Adivinhe o número .
Joey
Ah sim, agora funciona. Meu pressionamento de botão não estava produzindo nenhum resultado, e eu não conseguia entender o porquê.
N / a
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

Estou bastante insatisfeito com isso! Parece muito longo. Ideias?

MtnViewMark
fonte
Dentro do lambda, você pode alterar a grande pilha de ++'s para uma única lista e usar concat aka >>=id. Não sei se isso vai ajudar. Outro ponto seria usar em foldr1vez de foldr.
FUZxxl
Obrigado pelas idéias. Também não ajuda neste caso: a conversão de ++sequências economiza apenas um caractere por item, e a sobrecarga da final concaté muito alta aqui. Não é foldrpossível usar o foldr1formulário, pois o tempo de resultado é Stringo tipo de lista [Int](as 1variantes foldexigem que sejam iguais.)
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
fonte
Por curiosidade, esse python é 2.5? Para que isso funcione no python 3.2, envolvi a função map em uma função list, alterei raw_input () para input () e alterei print para print ().
N / a
@harren: funciona em ambos 2.4.4 e 2.5.2 para mim.
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
fonte
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}

Versão ligeiramente mais curta, que recebe a entrada como argumentos da linha de comando e não do 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}

Não posso acreditar que ninguém fez uma solução regex ainda. Perl está longe de ser minha melhor linguagem, então isso provavelmente pode perder muito mais. Eu estaria interessado em ver uma implementação sed, se alguém estiver pronto para o desafio.

(Obrigado, @mbx, por 4 caracteres).

Peter Taylor
fonte
foreach == para -> save 4 caracteres
mbx
você testou sua versão com os casos de teste fornecidos ?!
MBX
@mbx, sim, funciona para mim. Perl 5.10.1, Ubuntu. Que bug você está vendo?
Peter Taylor
@ Peter Taylor - no meu ubuntu e win32 também funciona bem. Eu tentei pela primeira vez em ideone que está executando o perl 5.12.1.
mbx
2
»Se a entrada consistir apenas em uma quebra de linha«, na entrada padrão, na verdade.
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}

Não vou ganhar com JavaScript, mas agora há uma entrada de JavaScript :)

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

pimvdb
fonte
1

Rubi (112)

Um pouco menor que a solução Ruby da Ventero, com uma abordagem diferente. Comecei a aprender Ruby, então isso provavelmente pode ser bastante reduzido.

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

PowerShell, 105 98 bytes, a leitura mais estrita da especificação

-7 bytes da resposta do migimaru .

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

Script de teste:

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

Resultado:

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

Powershell, 101 94, divertido com um espaço em branco líder

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

Não consegui obter a versão C # 3 mais curta que essa. Não sei exatamente o número de caracteres, mas suspeito que perdi. :-(

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
fonte
3
Você confundiu Code Bowling e Code Golf por acaso?
Joey
1
Pelo menos finja tentar. As pessoas não manterão uma linguagem detalhada contra você se você jogar .
dmckee --- gatinho ex-moderador
Eu acho que essa é a sua versão detalhada para explicar seus truques bacanas. Parece que você esqueceu de publicar a versão do golfe.
MBX
@ Joey, @ dmckee - Pensei em fazer uma versão de golfe, mas não cheguei a isso. Eu sou terrível neste jogo de qualquer maneira. Código obscuro é completamente contrário à minha natureza. Eu provavelmente deveria ficar longe dos quebra-cabeças de golfe! - @mbx - Infelizmente, não há truques bacanas.
perfil completo de Jeffrey L Whitledge