Ägyptische Pyramiden


15

Die Große Pyramide von Gizeh, die größte Pyramide Ägyptens, ist nicht nur das älteste der sieben Weltwunder der Antike, sondern auch das einzige , das größtenteils erhalten geblieben ist. Der Bau der ägyptischen Pyramiden kann bis zu 20 Jahre dauern und ist so groß, dass Al-Aziz Uthman, der Sohn des großen Saladins, der die Kreuzfahrer niedergeschlagen hatte, auf die Zerstörung der großen Pyramiden von Gizeh verzichten musste, da dies als zu große Aufgabe angesehen wurde . Die ägyptischen Pyramiden wurden in der Zeit des Alten und Mittleren Reiches (ca. 2686–1690 v. Chr.) Hauptsächlich als Gräber für die Pharaonen und ihre Gefährten gebaut. Ab 2008 wurden 138 ägyptische Pyramiden entdeckt.

Die Aufgabe besteht darin, ein Programm zu erstellen, das eine Abfolge von durch ein Leerzeichen getrennten Abständen eingibt und 10 × 10 Textpyramiden erzeugt, die durch diese Abstände getrennt sind. Ein Abstand von 1 entspricht zwei Zeichen.

Eine Textpyramide sieht folgendermaßen aus:

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

Wenn die Eingabe nur aus einem Zeilenumbruch besteht, wird wie oben eine Pyramide erzeugt . Für jede Pyramide werden die Pyramiden links so angezeigt, als wären sie vorne.

Beispiel I

Eingang:

4 3 1

Ausgabe:

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

Beispiel II

Eingang:

0 9

Ausgabe:

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

Beispiel III

Eingang:

11

Ausgabe:

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

Der Antrag, diese Anforderungen in der geringsten Anzahl von Zeichen zu erfüllen, ist der Gewinner.

Referenz: Wikipedia.org


Ich gehe davon aus, dass zusätzliche Leerzeichen am Ende der Zeile zulässig sind?
Peter Taylor

Kommt drauf an wen du fragst. Beim strengsten Lesen der Spezifikation folgt der Ausgabe kein Leerzeichen. Aber da dies nur zum Spaß ist, habe ich kein Problem damit.
nharren

Kommandozeilenargumente zur Eingabe sind also erlaubt?
Joey

Solange es den Anforderungen entspricht. Ich sehe jetzt, dass die Whitledge-Lösung keine Zeilenumbrüche als Eingabe verarbeiten kann (ich kann meine Aufwärtsbewertung nicht rückgängig machen), sondern sie einfach umgeht, indem eine Pyramide erstellt wird, wenn keine Eingabe vorhanden ist. Aber wenn Sie eine Lösung finden, die Zeilenumbruch-Eingaben (\ r oder \ n ist in Ordnung) als Befehlszeilenargumente verarbeiten kann, ist dies für mich in Ordnung.
nharren

Antworten:


4

Golfscript, 70 Zeichen

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

Direkte Portierung meiner Ruby-Lösung , daher bin ich sicher, dass es möglich ist, diese um einige Zeichen zu kürzen.


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

Skript testen .

Zufällige Eingabe sorgt auch für schöne Bilder:

Zufällige Pyramiden


Es funktioniert, wenn ich oben hinzufüge $input=Read-Host, sonst fragt es nicht nach Eingabe. Wie soll das laufen?
nharren

@nharren: echo 0 3 4 1|powershell -noprofile -file pyramids.ps1Oder von PowerShell '0 1 4 3' | .\pyramids.ps1. Dies ist ein häufiges Problem bei in Powershell golf spielen, leider, da man nur akzeptieren kann entweder verrohrt-in - Eingang oder interaktive Eingabe. PowerShell hat nicht wirklich die Vorstellung von Standard, die andere Sprachen und Umgebungen haben, und das zeigt sich manchmal. Normalerweise greife ich zu Pipe-Eingaben, es sei denn, die Aufgabe fordert explizit Interaktivität, z. B. Errate die Nummer .
Joey

Ah ja, jetzt funktioniert es. Mein Knopfdruck brachte keine Ergebnisse und ich konnte nicht herausfinden warum.
nharren

4

Haskell, 148 Zeichen

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

Ich bin damit ziemlich unzufrieden! Es fühlt sich einfach viel zu lang an. Ideen?


Im Lambda können Sie den großen Stapel von ++'s in eine einzige Liste ändern und concat aka verwenden >>=id. Ich weiß nicht, ob es helfen wird. Ein weiterer Punkt wäre die Verwendung von foldr1anstelle von foldr.
FUZxxl

Danke für die Ideen. Beides hilft in diesem Fall nicht: Durch das Konvertieren von ++Sequenzen wird nur ein Zeichen pro Element gespeichert, und der Overhead des Finales concatist hier zu hoch. Das Formular foldrkann nicht verwendet werden foldr1, da die Ergebniszeit ist, Stringwährend der [Int]1fold
Listentyp

4

Python, 123 Zeichen

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

Ist das aus Neugier Python 2.5? Damit dies in Python 3.2 funktioniert, habe ich die Map-Funktion in eine Listenfunktion eingebunden, raw_input () in input () und print in print () geändert.
nharren

@nharren: funktioniert in 2.4.4 und 2.5.2 für mich.
Keith Randall

4

Ruby 1.9, 116 Zeichen

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 Zeichen

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

Etwas kürzere Version, die Eingaben eher als Befehlszeilenargumente als von stdin akzeptiert:

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

Ich kann nicht glauben, dass noch niemand eine Regex-Lösung gemacht hat. Perl ist weit davon entfernt, meine beste Sprache zu sein, daher kann dies wahrscheinlich viel mehr verlieren. Ich würde mich über eine sed-Implementierung freuen, wenn sich jemand der Herausforderung stellt.

(Danke, @mbx, für 4 Zeichen).


foreach == for -> speichere 4 Zeichen
mbx

hast du deine version mit den angegebenen testfällen getestet ?!
mbx

@mbx, ja, funktioniert bei mir. Perl 5.10.1, Ubuntu. Welchen Bug siehst du?
Peter Taylor

@ Peter Taylor - auf meinem Ubuntu und Win32 funktioniert es auch gut. Ich habe es zuerst auf ideone ausprobiert dem Perl 5.12.1 läuft.
mbx

2
»Wenn die Eingabe nur aus einem Zeilenumbruch besteht« verweist eigentlich auf die Standardeingabe.
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}

Ich werde mit JavaScript nicht gewinnen, aber es gibt jetzt einen JavaScript-Eintrag :)

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


1

Rubin (112)

Etwas kürzer als die Ruby-Lösung von Ventero mit einem anderen Ansatz. Ich habe gerade angefangen, Ruby zu lernen, daher kann dies wahrscheinlich einiges reduziert werden.

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

1

Power Shell, 105 98 Bytes, das strengste Lesen der Spezifikation

-7 Bytes von Migimarus Antwort .

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

Testskript:

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

Ausgabe:

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

Powershell, 101 94, Spaß mit einem führenden Leerzeichen

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

0

Ich konnte die C # 3-Version nicht kürzer bekommen. Ich kenne die Anzahl der Charaktere nicht genau, aber ich vermute, dass ich verloren habe. :-(

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
Haben Sie Code Bowling und Code Golf zufällig verwechselt?
Joey

1
Tu wenigstens so, als ob du es versuchst. Die Leute werden keine wörtliche Sprache gegen Sie haben, wenn Sie Golf spielen .
dmckee

Ich denke, das ist deine ausführliche Version, um deine raffinierten Tricks zu erklären. Sie haben anscheinend vergessen, die Golfversion zu veröffentlichen.
mbx

@Joey, @dmckee - Ich habe darüber nachgedacht, eine Golfversion zu machen, bin aber nicht dazu gekommen. Ich bin sowieso schrecklich in diesem Spiel. Undurchsichtiger Code widerspricht vollkommen meiner Natur. Ich sollte mich wohl von den Golfrätseln fernhalten! - @mbx - Leider gibt es keine raffinierten Tricks.
Jeffrey L Whitledge
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.