Єгипетські піраміди


15

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

Завдання полягає в створенні програми, яка вводить послідовність відстаней, розділених пробілом, і створює 10 × 10 текстових пірамід, розділених цими відстанями. Відстань 1 дорівнює двом символам.

Текстова піраміда буде виглядати приблизно так:

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

Якщо вхід складається лише з розриву рядка, тоді буде створена одна піраміда, як зазначено вище . Для кожної піраміди ліворуч піраміди відображаються так, ніби вони передують.

Приклад I

Вхід:

4 3 1

Вихід:

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

Приклад II

Вхід:

0 9

Вихід:

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

Приклад III

Вхід:

11

Вихід:

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

Додаток для виконання цих вимог у найменшій кількості символів є переможцем.

Довідка: Wikipedia.org


Я припускаю, що додаткові пробіли в кінці рядка дозволені?
Пітер Тейлор

Залежить, кого ви запитаєте. У найсуворішому зчитуванні специфікації немає пробілів після виводу. Але враховуючи, що це для задоволення, у мене немає проблем з цим.
nharren

Тож дозволені аргументи командного рядка для введення?
Joey

Поки вона відповідає вимогам. Зараз я бачу, що рішення Whitledge насправді не в змозі обробляти рядкові розриви як вхідні дані (я не можу скасувати своє оновлення), він просто працює навколо нього, створюючи піраміду, якщо немає вводу. Але якщо ви можете знайти рішення, яке може обробляти введення рядкових рядків (\ 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 насправді не має поняття stdin, якими володіють інші мови та середовища, і це іноді виявляється. Зазвичай я задіююсь за допомогою введення, якщо завдання явно не вимагає інтерактивності, як-от Відгадайте число .
Joey

Ага так, зараз це працює. Моє натискання кнопок не дало жодних результатів, і я не міг зрозуміти, чому.
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

Я цілком незадоволений цим! Це просто занадто довго відчувається. Ідеї?


Всередині лямбда ви можете змінити велику купу ++"s" в один список і використовувати concat aka >>=id. Не знаю, чи допоможе це. Іншим моментом було б використання foldr1замістьfoldr .
FUZxxl

Дякую за ідеї. Ні в цьому випадку не допомагає: Перетворення++ послідовностей економить лише один символ на елемент, а накладні витрати на фінал concatтут занадто високі. foldrНе може використовувати foldr1форму якраз результату , Stringтоді як тип списку [Int](The 1варіанти foldвимагають , щоб вони були однаковими.)
MtnViewMark

4

Пітон, 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, я загорнув функцію map у функцію списку, змінив raw_input () на input () та змінив print на print ().
nharren

@nharren: для мене працює і в 2.4.4, і в 2.5.2.
Кіт Рендалл

4

Рубін 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}

Трохи коротша версія, яка приймає дані як аргументи командного рядка, а не з 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}

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

(Спасибі, @mbx, за 4 години).


foreach == for -> зберегти 4 символи
mbx

ви протестували свою версію за допомогою заданих тестів ?!
mbx

@mbx, так, працює для мене. Perl 5.10.1, Ubuntu. Яку помилку ви бачите?
Пітер Тейлор

@Peter Taylor - на моєму ubuntu та win32 це також чудово працює. Я вперше спробував це на ideone, який працює на Perl 5.12.1.
mbx

2
Якщо фактичний вхід складається лише з розриву рядка, натякає на стандартне введення.
Joey

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)

Трохи коротший, ніж рішення 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?
Joey

1
Принаймні зробіть вигляд, що спробуєте. Люди не матимуть багатослівної мови проти вас, якщо ви пограєте на ній.
dmckee --- колишнє кошеня модератора

Я думаю, що це ваша багатослівна версія, щоб пояснити ваші витончені хитрощі. Здається, ви забули опублікувати його версію для гольфу.
mbx

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