Египетские пирамиды


15

Великая пирамида в Гизе, самая большая пирамида в Египте, является не только самой старой из семи чудес древнего мира, но и единственной, которая остается в значительной степени неповрежденной. На строительство египетских пирамид может уйти до 20 лет, и они настолько велики, что Аль-Азиз Усман, сын великого Саладина, сокрушившего крестоносцев, должен был отказаться от разрушения Великих пирамид Гизы, потому что это считалось слишком большой задачей . Египетские пирамиды были построены в основном в качестве гробниц для фараонов страны и их супругов во времена Старого и Среднего царства (ок. 2686–1690 гг. До н.э.), а по состоянию на 2008 г. было обнаружено 138 египетских пирамид.

Задача состоит в том, чтобы создать программу, которая вводит последовательность расстояний, разделенных пробелом, и создает текстовые пирамиды 10 × 10, разделенные этими расстояниями. Расстояние 1 равно двум символам.

Текстовая пирамида будет выглядеть так:

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

Если вход состоит только из разрыва строки, то будет создана одна пирамида, как указано выше . Для каждой пирамиды пирамиды слева отображаются так, как если бы они были спереди.

Пример I

Входные данные:

4 3 1

Выход:

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

Пример II

Входные данные:

0 9

Выход:

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

Пример III

Входные данные:

11

Выход:

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

Приложение для выполнения этих требований в наименьшем количестве символов является победителем.

Ссылка: Wikipedia.org


Я предполагаю, что дополнительные пробелы в конце строки разрешены?
Питер Тейлор

Зависит от того, кого вы спрашиваете. В самом строгом прочтении спецификации нет пробела после вывода. Но, учитывая, что это ради удовольствия, у меня нет проблем с этим.
nharren

Значит, аргументы командной строки для ввода данных разрешены?
Джои

Пока это соответствует требованиям. Теперь я вижу, что решение Уитледжа на самом деле не способно обрабатывать разрывы строк в качестве входных данных (я не могу отменить свое возражение), оно просто работает вокруг этого, создавая пирамиду, если нет входных данных. Но если вы можете найти решение, которое может обрабатывать вводы переноса строки (\ r или \ n нормально) в качестве аргументов командной строки, то это нормально для меня.
nharren

Ответы:


4

Гольфскрипт, 70 знаков

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

Прямой порт моего решения на Ruby , так что я уверен, что это можно сократить на несколько символов.


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

Тестовый скрипт .

Случайный ввод также делает для хороших изображений:

Случайные пирамиды


Это работает, если я добавляю $input=Read-Hostсверху, иначе это не просит ввода. Как это должно быть запущено?
nharren

@nharren: echo 0 3 4 1|powershell -noprofile -file pyramids.ps1или из PowerShell '0 1 4 3' | .\pyramids.ps1. Это частая проблема с игрой в гольф в PowerShell, к сожалению, как вы можете принимать только либо по трубопроводу, на входе или интерактивного ввода. PowerShell на самом деле не имеет понятия о стандартах, которые есть в других языках и средах, и это иногда показывается. Я обычно обращаюсь к каналу ввода, если только задача явно не требует интерактивности, как « Угадай число» .
Джоу

Ах да, теперь это работает. Мои пуговицы не дали никаких результатов, и я не мог понять, почему.
nharren

4

Haskell, 148 символов

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

Я совершенно недоволен этим! Просто слишком долго. Идеи?


Внутри лямбды вы можете поменять большую кучу ++на один список и использовать concat aka >>=id. Я не знаю, поможет ли это. Другой пункт будет использовать foldr1вместо foldr.
FUZxxl

Спасибо за идеи. В этом случае это не помогает: преобразование ++последовательностей экономит только один символ на элемент, а накладные расходы на финал concatздесь слишком высоки. foldrНе может использовать foldr1форму как раз результата , Stringтогда как тип списка [Int](The 1варианты foldтребуют , чтобы они были одинаковыми.)
MtnViewMark

4

Python, 123 символа

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:]

Из любопытства этот питон 2.5? Чтобы заставить это работать в Python 3.2, я обернул функцию карты в функцию списка, изменил raw_input () на input () и изменил print на print ().
nharren

@nharren: у меня работает как в 2.4.4, так и в 2.5.2.
Кит Рэндалл

4

Ruby 1.9, 116 символов

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]}]*""}

2

Perl, 130 126 132 символов

$_=<>;$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}

Немного более короткая версия, которая принимает входные данные в качестве аргументов командной строки, а не из стандартного ввода:

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

Не могу поверить, что никто еще не нашел решение для регулярных выражений. Perl очень далек от того, чтобы быть моим лучшим языком, так что он может потерять намного больше. Мне было бы интересно увидеть реализацию sed, если кто-то готов принять вызов.

(Спасибо, @mbx, за 4 символа).


foreach == для -> сохранить 4
символа

Вы тестировали свою версию с данными тестами?
mbx

@mbx, да, у меня работает. Perl 5.10.1, Ubuntu. Какую ошибку вы видите?
Питер Тейлор

@Peter Taylor - на моем Ubuntu и Win32 он также работает нормально. Я сначала попробовал это на ideone, который работает на Perl 5.12.1.
mbx

2
»Если вход состоит только из разрыва строки« на самом деле намекает на стандартный ввод.
Джои

1

JavaScript, 396 байт

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}

Я не собираюсь выигрывать с помощью JavaScript, но сейчас есть запись JavaScript :)

Использование: _("1 2 3")и т. Д.


1

Рубин (112)

Немного короче, чем решение Ventero Ruby, с другим подходом. Я только начал изучать Ruby, так что это, вероятно, можно немного уменьшить.

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

1

Powershell, 105 98 байт, самое строгое чтение спецификации

-7 байт из ответа Мигимару .

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

Тестовый скрипт:

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

Выход:

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

Powershell, 101 94, веселье с одним ведущим пробелом

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

0

Я не мог получить версию C # 3 короче, чем эта. Я точно не знаю количество персонажей, но подозреваю, что проиграл. :-(

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();
            }
        }
    }

}

3
Вы случайно не перепутали Code Bowling и Code Golf?
Джои

1
По крайней мере, притворяться, чтобы попробовать. Люди не будут произносить многословный язык против вас, если вы играете в гольф .
dmckee --- котенок экс-модератора

Я думаю, что это ваша многословная версия, чтобы объяснить ваши изящные трюки. Кажется, вы забыли опубликовать версию для гольфа.
mbx

@Joey, @dmckee - я думал о том, чтобы сделать версию для гольфа, но не дошел до этого. В любом случае, я ужасен в этой игре. Неясный код полностью противоречит моей природе. Наверное, мне стоит держаться подальше от головоломок для гольфа! - @mbx - К сожалению, нет хитрых хитростей.
Джеффри Л Уитледж
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.