Kim tự tháp Ai Cập


15

Kim tự tháp Giza vĩ đại, kim tự tháp lớn nhất ở Ai Cập, không chỉ là lâu đời nhất trong Bảy kỳ quan thế giới cổ đại, mà còn là nơi duy nhất còn nguyên vẹn. Kim tự tháp Ai Cập có thể mất tới 20 năm để xây dựng và lớn đến mức Al-Aziz Uthman, con trai của Saladin vĩ đại, người đã nghiền nát Thập tự quân, phải từ bỏ việc phá hủy Kim tự tháp Giza vĩ đại vì nó được coi là một nhiệm vụ quá lớn . Các kim tự tháp Ai Cập hầu hết được xây dựng làm lăng mộ cho các Pharaoh của đất nước và các phối ngẫu của họ trong thời kỳ Vương quốc Trung cổ và Trung cổ (khoảng 2686 mật1690 BCE), và đến năm 2008, 138 kim tự tháp Ai Cập đã được phát hiện.

Nhiệm vụ là tạo ra một chương trình nhập một chuỗi các khoảng cách được phân tách bằng một khoảng trắng và tạo ra các kim tự tháp văn bản 10 × 10 cách nhau bởi các khoảng cách đó. Khoảng cách 1 bằng hai ký tự.

Một kim tự tháp văn bản sẽ trông như thế này:

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

Nếu đầu vào chỉ bao gồm một ngắt dòng, thì một kim tự tháp sẽ được tạo ra, như trên . Đối với mỗi kim tự tháp, các kim tự tháp ở bên trái được hiển thị như thể chúng ở phía trước.

Ví dụ tôi

Đầu vào:

4 3 1

Đầu ra:

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

Ví dụ II

Đầu vào:

0 9

Đầu ra:

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

Ví dụ III

Đầu vào:

11

Đầu ra:

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

Ứng dụng để thực hiện các yêu cầu này với số lượng nhân vật ít nhất là người chiến thắng.

Tham khảo: Wikipedia.org


Tôi đoán rằng khoảng trắng bổ sung ở cuối dòng được phép?
Peter Taylor

Phụ thuộc vào người bạn hỏi. Trong bài đọc nghiêm ngặt nhất của thông số kỹ thuật, không có khoảng trắng theo sau đầu ra. Nhưng cho rằng đây là cho vui, tôi không có vấn đề với nó.
nharren

Vì vậy, đối số dòng lệnh để lấy đầu vào được phép?
Joey

Miễn là nó đáp ứng yêu cầu. Bây giờ tôi thấy rằng giải pháp của Whitledge thực sự không thể xử lý các ngắt dòng như đầu vào (tôi không thể hoàn tác upvote của mình), nó chỉ đơn giản hoạt động xung quanh nó bằng cách tạo ra một kim tự tháp nếu không có đầu vào. Nhưng nếu bạn có thể tìm thấy một giải pháp có thể xử lý các đầu vào ngắt dòng (\ r hoặc \ n là tốt) như dòng lệnh lập luận, thì với tôi cũng không sao.
nharren

Câu trả lời:


4

Golf, 70 ký tự

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

Cổng trực tiếp của giải pháp Ruby của tôi , vì vậy tôi chắc chắn có thể rút ngắn điều này bằng một vài ký tự.


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

Kiểm tra kịch bản .

Đầu vào ngẫu nhiên cũng làm cho hình ảnh đẹp:

Kim tự tháp ngẫu nhiên


Nó hoạt động nếu tôi thêm $input=Read-Hostở trên cùng, nếu không nó không yêu cầu đầu vào. Làm thế nào điều này nên được chạy?
nharren

@nharren: echo 0 3 4 1|powershell -noprofile -file pyramids.ps1Hoặc từ PowerShell '0 1 4 3' | .\pyramids.ps1. Đây là vấn đề thường xuyên với chơi golf trong PowerShell, thật đáng buồn, vì bạn chỉ có thể chấp nhận hoặc cấp nước tập trung trong đầu vào hoặc đầu vào tương tác. PowerShell không thực sự có khái niệm về stdin các ngôn ngữ và môi trường khác và điều này đôi khi cho thấy. Tôi thường đi đầu vào đường ống, trừ khi nhiệm vụ gọi tương tác rõ ràng, như Đoán số .
Joey

À vâng, bây giờ nó hoạt động. Nút nghiền của tôi không mang lại kết quả nào, và tôi không thể hiểu tại sao.
nharren

4

Haskell, 148 ký tự

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

Tôi khá không hài lòng với điều này! Nó chỉ cảm thấy quá dài. Ý tưởng?


Bên trong lambda, bạn có thể thay đổi một đống lớn ++thành một danh sách và sử dụng concat aka >>=id. Tôi không biết liệu nó sẽ giúp. Một điểm khác sẽ được sử dụng foldr1thay vì foldr.
FUZxxl

Cảm ơn các ý tưởng. Không giúp được gì trong trường hợp này: Chuyển đổi ++trình tự chỉ giúp bạn tiết kiệm một ký tự cho mỗi mục và chi phí chung của trận chung kết concatlà quá cao ở đây. Không foldrthể sử dụng foldr1biểu mẫu làm thời gian kết quả Stringtrong khi loại danh sách là [Int](Các 1biến thể foldyêu cầu chúng phải giống nhau.)
MtnViewMark

4

Con trăn, 123 ký tự

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

Vì tò mò, con trăn này có phải là 2.5 không? Để làm việc này trong python 3.2, tôi đã bọc hàm ánh xạ trong hàm danh sách, thay đổi raw_input () thành input () và thay đổi print thành print ().
nharren

@nharren: hoạt động trong cả 2.4.4 và 2.5.2 đối với tôi.
Keith Randall

4

Ruby 1.9, 116 ký tự

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 ký tự

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

Phiên bản ngắn hơn một chút, lấy đầu vào làm đối số dòng lệnh thay vì từ 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}

Không thể tin rằng không ai đã làm một giải pháp regex nào. Perl là một chặng đường dài từ ngôn ngữ tốt nhất của tôi, vì vậy điều này có thể mất nhiều hơn nữa. Tôi rất muốn thấy một triển khai sed, nếu có ai đó thách thức.

(Cảm ơn, @mbx, vì 4 ký tự).


foreach == for -> lưu 4 ký tự
mbx

Bạn đã thử phiên bản của mình với các bản thử nghiệm đã cho chưa?!
mbx

@mbx, vâng, làm việc cho tôi. Perl 5.10.1, Ubuntu. Bạn đang nhìn thấy lỗi gì?
Peter Taylor

@Peter Taylor - trên Ubuntu của tôi và win32 nó cũng hoạt động tốt. Lần đầu tiên tôi đã thử nó trên ideone đang chạy perl 5.12.1.
mbx

2
»Nếu ​​đầu vào chỉ bao gồm ngắt dòng« gợi ý ở đầu vào tiêu chuẩn, thực tế.
Joey

1

JavaScript, 396 byte

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}

Tôi sẽ không giành chiến thắng với JavaScript, nhưng bây giờ có một mục JavaScript :)

Cách sử dụng: _("1 2 3")v.v.


1

Hồng ngọc (112)

Hơi ngắn hơn so với giải pháp Ruby của Venter, với một cách tiếp cận khác. Tôi mới bắt đầu học Ruby, vì vậy điều này có thể giảm đi một chút.

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

1

Quyền hạn, 105 98 byte, cách đọc thông số kỹ thuật nghiêm ngặt nhất

-7 byte từ câu trả lời của Migimaru .

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

Kịch bản thử nghiệm:

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

Đầu ra:

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

Powershell, 101 94, vui vẻ với một khoảng trắng hàng đầu

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

0

Tôi không thể có phiên bản C # 3 ngắn hơn phiên bản này. Tôi không biết chính xác số lượng nhân vật, nhưng tôi nghi ngờ rằng mình đã mất. :-(

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
Bạn có nhầm lẫn Code Bowling và Code Golf không?
Joey

1
Ít nhất là giả vờ thử. Mọi người sẽ không giữ ngôn ngữ dài dòng chống lại bạn nếu bạn đánh gôn .
dmckee

Tôi đoán đó là phiên bản dài dòng của bạn để giải thích các thủ thuật tiện lợi của bạn. Có vẻ như bạn đã quên đăng phiên bản golf của nó.
mbx

@Joey, @dmckee - Tôi đã nghĩ về việc làm một phiên bản golf, nhưng vẫn chưa có nó. Dù sao thì tôi cũng rất tệ trong trò chơi này. Mã tối nghĩa đi ngược lại hoàn toàn với bản chất của tôi. Tôi có lẽ nên tránh xa các câu đố golf! - @mbx - Đáng buồn thay, không có thủ thuật tiện lợi.
Jeffrey L Whitledge
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.