Piramida Mesir


15

Piramida Agung Giza, piramida terbesar di Mesir, tidak hanya yang tertua dari Tujuh Keajaiban Dunia Kuno, tetapi juga satu - satunya yang tetap utuh. Piramida Mesir dapat memakan waktu hingga 20 tahun untuk dibangun dan sangat besar sehingga Al-Aziz Uthman, putra Saladin besar yang menghancurkan Tentara Salib, harus menyerah menghancurkan piramida Agung Giza karena itu dianggap tugas yang terlalu besar . Piramida Mesir sebagian besar dibangun sebagai makam untuk Firaun negara itu dan pendamping mereka selama periode Kerajaan Lama dan Tengah (sekitar 2686-1690 SM), dan pada 2008, 138 piramida Mesir telah ditemukan.

Tugasnya adalah membuat program yang memasukkan urutan jarak yang dipisahkan oleh spasi, dan menghasilkan 10 × 10 teks piramida yang dipisahkan oleh jarak tersebut. Jarak 1 sama dengan dua karakter.

Piramida teks akan terlihat seperti ini:

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

Jika input hanya terdiri dari satu baris, maka satu piramida akan diproduksi, seperti di atas . Untuk setiap piramida, piramida di sebelah kiri ditampilkan seolah-olah berada di depan.

Contoh I

Memasukkan:

4 3 1

Keluaran:

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

Contoh II

Memasukkan:

0 9

Keluaran:

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

Contoh III

Memasukkan:

11

Keluaran:

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

Aplikasi untuk memenuhi persyaratan ini dalam jumlah karakter paling sedikit adalah pemenangnya.

Referensi: Wikipedia.org


Saya kira spasi putih tambahan di akhir baris diizinkan?
Peter Taylor

Tergantung siapa yang kamu tanya. Dalam pembacaan spesifikasi yang ketat, tidak ada spasi putih mengikuti output. Tetapi mengingat ini untuk bersenang-senang, saya tidak punya masalah dengan itu.
nharren

Jadi argumen baris perintah untuk mengambil input diperbolehkan?
Joey

Asalkan memenuhi persyaratan. Saya melihat sekarang bahwa solusi Whitledge sebenarnya tidak mampu menangani linebreaks sebagai input (saya tidak dapat membatalkan upvote saya), itu hanya bekerja di sekitarnya dengan menghasilkan piramida jika tidak ada input. Tetapi jika Anda dapat menemukan solusi yang dapat menangani input linebreak (\ r atau \ n baik-baik saja) sebagai argumen baris perintah, maka tidak masalah dengan saya.
nharren

Jawaban:


4

Golfscript, 70 karakter

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

Port langsung dari solusi Ruby saya , jadi saya yakin mungkin untuk mempersingkat ini dengan beberapa karakter.


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

Skrip uji .

Input acak juga menghasilkan gambar yang bagus:

Piramida acak


Ini berfungsi jika saya menambahkan $input=Read-Hostdi bagian atas, jika tidak ia tidak meminta input. Bagaimana ini harus dijalankan?
nharren

@nharren: echo 0 3 4 1|powershell -noprofile -file pyramids.ps1Atau dari PowerShell '0 1 4 3' | .\pyramids.ps1. Ini adalah masalah yang sering dengan bermain golf di PowerShell, sedih, karena Anda hanya dapat menerima baik pipa-masukan atau masukan interaktif. PowerShell tidak benar-benar memiliki gagasan tentang stdin yang dimiliki oleh bahasa dan lingkungan lain dan ini terkadang muncul. Saya biasanya mencari input yang disalurkan, kecuali tugas secara eksplisit meminta interaktivitas, seperti Tebak nomornya .
Joey

Ah ya, sekarang berhasil. Tumbuk tombol saya tidak membuahkan hasil apa pun, dan saya tidak tahu mengapa.
nharren

4

Haskell, 148 karakter

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

Saya sangat tidak puas dengan ini! Rasanya terlalu lama. Ide ide?


Di dalam lambda, Anda dapat mengubah tumpukan besar ++menjadi satu daftar dan menggunakan alias concat >>=id. Saya tidak tahu apakah itu akan membantu. Poin lain akan menggunakan foldr1alih-alih foldr.
FUZxxl

Terima kasih atas idenya. Tidak ada yang membantu dalam hal ini: Mengubah ++urutan hanya menghemat satu karakter per item, dan overhead final concatterlalu tinggi di sini. Tidak foldrdapat menggunakan foldr1formulir karena waktu hasilnya adalah Stringsedangkan jenis daftar adalah [Int]( 1Varian foldmemerlukannya sama.)
MtnViewMark

4

Python, 123 karakter

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

Karena penasaran, apakah ini python 2.5? Agar ini berfungsi dalam python 3.2, saya membungkus fungsi peta dalam fungsi daftar, mengubah raw_input () menjadi input (), dan mengubah cetak untuk mencetak ().
nharren

@nharren: bekerja di 2.4.4 dan 2.5.2 untuk saya.
Keith Randall

4

Ruby 1.9, 116 karakter

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 karakter

$_=<>;$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 yang sedikit lebih pendek yang mengambil input sebagai argumen command-line daripada dari 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}

Tidak percaya tidak ada yang melakukan solusi regex. Perl jauh dari menjadi bahasa terbaik saya, jadi ini mungkin bisa kehilangan lebih banyak. Saya akan tertarik untuk melihat implementasi sed, jika seseorang siap untuk tantangan.

(Terima kasih, @mbx, untuk 4 karakter).


foreach == untuk -> save 4 chars
mbx

Sudahkah Anda menguji versi Anda dengan testcas yang diberikan ?!
mbx

@ MBX, ya, bekerja untuk saya. Perl 5.10.1, Ubuntu. Bug apa yang kamu lihat?
Peter Taylor

@ Peter Taylor - di ubuntu saya dan win32 berfungsi dengan baik. Saya pertama kali mencobanya pada ideone yang menjalankan perl 5.12.1.
mbx

2
»Jika input hanya terdiri dari satu baris« petunjuk pada input standar, sebenarnya.
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}

Saya tidak akan menang dengan JavaScript, tetapi ada entri JavaScript sekarang :)

Penggunaan: _("1 2 3")dll


1

Ruby (112)

Sedikit lebih pendek dari solusi Ruby Ventero, dengan pendekatan yang berbeda. Saya baru mulai belajar Ruby, jadi ini mungkin dapat dikurangi sedikit.

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 byte, pembacaan yang paling ketat dari spec

-7 byte dari jawaban migimaru .

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

Skrip uji:

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

Keluaran:

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

Powershell, 101 94, bersenang-senang dengan satu spasi putih terkemuka

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

0

Saya tidak bisa mendapatkan versi C # 3 lebih pendek dari ini. Saya tidak tahu persis jumlah karakternya, tetapi saya curiga bahwa saya telah kalah. :-(

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
Apakah Anda mengacaukan Code Bowling dan Code Golf secara kebetulan?
Joey

1
Setidaknya pura-pura mencoba. Orang tidak akan mengadakan bahasa verbose terhadap Anda jika Anda golf itu.
dmckee --- ex-moderator kitten

Saya kira itu adalah versi verbose Anda untuk menjelaskan trik bagus Anda. Sepertinya Anda lupa memposting versi golfnya.
mbx

@ Joey, @dmckee - Saya berpikir untuk membuat versi golf, tetapi belum sempat melakukannya. Lagipula, aku mengerikan dalam game ini. Kode tidak jelas sepenuhnya bertentangan dengan sifat saya. Saya mungkin harus menjauh dari teka-teki golf! - @mbx - Sayangnya, tidak ada trik bagus.
Jeffrey L Whitledge
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.