13
\$\begingroup\$

Mayan pyramids were (and are) an important part of ancient architecture, that were generally used for religious purposes.

They were usually step pyramids, but the steps on each were too steep to climb. Priests would climb to the tops of them via alternative staircases to perform ceremonies. The pyramids were also used as landmarks because of their height, and sometimes even used as burial sites for high ranking officials.


The Challenge

Write a program that can print out a pyramid schematic based on user specifications (see below).


Requirements

  • Take an input of two space-separated variables.

  • Input must be accepted through STDIN (or closest alternative).

  • Output must be through STDOUT (or closest alternative).


Input

  • Height as any positive integer. This is used as the base level's width (in blocks). Each succeeding level of the pyramid has the width n - 1 where n is the previous floor's width (in blocks).

  • Block size which will be 1 or any odd, positive integer ≤ (less than) 10.


Blocks

The given block size determines the width (and height) of each individual piece. Essentially, there are i^2 spaces inside the visible box where i is the block size.

A 1x1 block would look like this:

+++
| |
+++

While a 5x5 block would look like this:

+++++++
|     |
|     |
|     |
|     |
|     |
+++++++

Horizontally Adjacent Blocks

Horizontally side-by-side blocks must have their middle walls merged into one.

You must have this:

+++++
| | |
+++++

Instead of something like this:

++++++
| || |
++++++

Vertically Adjacent Blocks (-5% bonus)

Vertically side-by-side blocks have a special exception: the middle wall can be merged into one.

So, instead of 1x1 blocks looking like this:

 +++
 | |
 +++
+++++
| | |
+++++

They could look like this:

 +++
 | |
+++++
| | |
+++++

Examples

Input: 3 1

Output:

  +++
  | |
  +++
 +++++
 | | |
 +++++
+++++++
| | | |
+++++++

OR

  +++
  | |
 +++++
 | | |
+++++++
| | | |
+++++++

Input: 2 3

Output:

  +++++
  |   |
  |   |
  |   |
  +++++
+++++++++
|   |   |
|   |   |
|   |   |
+++++++++

OR

  +++++
  |   |
  |   |
  |   |
+++++++++
|   |   |
|   |   |
|   |   |
+++++++++

Scoreboard

To be ranked on the scoreboard, put your answer in this format:

# Language, Score

Or if you get the bonus -5%:

# Language, Score (Bytes - 5%)

Your score is just a whole number. If your score is a decimal, round up to the whole number.

function getURL(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function getAnswers(){$.ajax({url:getURL(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),useData(answers)}})}function getOwnerName(e){return e.owner.display_name}function useData(e){var s=[];e.forEach(function(e){var a=e.body.replace(/<s>.*<\/s>/,"").replace(/<strike>.*<\/strike>/,"");console.log(a),VALID_HEAD.test(a)&&s.push({user:getOwnerName(e),language:a.match(VALID_HEAD)[1],score:+a.match(VALID_HEAD)[2],link:e.share_link})}),s.sort(function(e,s){var a=e.score,r=s.score;return a-r}),s.forEach(function(e,s){var a=$("#score-template").html();a=a.replace("{{RANK}}",s+1+"").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SCORE}}",e.score),a=$(a),$("#scores").append(a)})}var QUESTION_ID=57939,ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",answers=[],answer_ids,answers_hash,answer_page=1;getAnswers();var VALID_HEAD=/<h\d>([^\n,]*)[, ]*(\d+).*<\/h\d>/;
body{text-align:left!important}table thead{font-weight:700}table td{padding:10px 0 0 30px}#scores-cont{padding:10px;width:600px}#scores tr td:first-of-type{padding-left:0}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><div id="scores-cont"><h2>Scores</h2> <table class="score-table"> <thead><tr><td></td><td>User</td><td>Language</td><td>Score</td></tr></thead><tbody id="scores"></tbody> </table></div><table style="display: none"> <tbody id="score-template"><tr><td>{{RANK}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SCORE}}</td></tr></tbody></table>

\$\endgroup\$
  • \$\begingroup\$ What's the minimum input? 1 1? \$\endgroup\$ – mınxomaτ Sep 14 '15 at 20:25
  • \$\begingroup\$ Yes, which would be a single block. @minxomat It's explained under the "Input" section. \$\endgroup\$ – Zach Gates Sep 14 '15 at 20:26
  • \$\begingroup\$ What would the input 3 2 produce? \$\endgroup\$ – Hand-E-Food Sep 14 '15 at 23:08
  • \$\begingroup\$ According to the second bullet under the "Input" section, the second input integer must be odd. @Hand-E-Food If you meant to ask what would happen for an input like 2 3, it would exit when n - 1 = 0 where n is the previous floor's width in blocks. \$\endgroup\$ – Zach Gates Sep 14 '15 at 23:09
  • \$\begingroup\$ @ZachGates, thanks! Don't mind me. Clearly the coffee has failed me. \$\endgroup\$ – Hand-E-Food Sep 14 '15 at 23:27
1
\$\begingroup\$

Pyth, 45 (47 bytes - 5%)

AmvdczdVGjm.[Jh*GhHj*H?d\ \+*+2N?d\|\+\ hH;*J\+

Try it out here.

                                                   Implicit: z=input(), d=' '
    czd                                            Split input on spaces
 mvd                                               Evaluate each part of the above (convert to int)
A                                                  Store the pair in G,H
             Jh*GhH                                J = 1+(G*(H+1))
       VG                                          For N in [0 to G-1]:
          m                             hH;          Map d in [0 to H] to:
                                ?d\|\+                 Get '|' or '+' (vertical edges or corners)
                            *+2N                       Repeat the above (N+2) times
                      ?d\ \+                           Get ' ' or '+' (block centre or horizontal edge)
                    *H                                 Repeat the above H times
                   j                                   Join (|/+) by (   /+++)
           .[J                        \                Centrally pad the above to width J using spaces
         j                                           Join on newlines, implicit print
                                           *J\+    Get J '+'s, implicit print
\$\endgroup\$
  • 1
    \$\begingroup\$ +1. Better late than never. :P \$\endgroup\$ – Zach Gates Sep 21 '15 at 22:27
11
\$\begingroup\$

JavaScript (ES6), 161 (169-5%) 166 (174-5%)

Using template strings, the 2 newlines are significant and counted.

Test running the snippet below in an EcmaScript 6 browser. Firefox ok, not Chrome because it lacks support for destructuring assignment.

Code explained after the snippet.

/*Test: redefine console.log*/ console.log=x=>O.innerHTML+=x+'\n';

for([h,b]=prompt().split` `,g='+'[R='repeat'](-~b),f=' '[R](b),n=o='';h--;o+=e+(d=g[R](++n)+`+
`)+f.replace(/./g,e+('|'+f)[R](n)+`|
`))e=' '[R](h*-~b/2);console.log(o+d)
<pre id=O></pre>

Less Golfed

[h, b] = prompt().split` `; // get the space separated input values
c = -~b; // Add 1 to b. As b is of string type b+1 would be a string concatenation
g = '+'.repeat(c); // top border
f = ' '.repeat(b); // inner blank row
o = ''; // initialize output string
for(n = 0; h > 0; --h) // loop on height
{
   ++n;
   e = ' '.repeat(h*c/2); // blanks for offset from left margins
   d = g.repeat(n) + `+\n`; // top border repeated, then right end and newline
   // the block body is squared, there are as many rows as columns inside
   // so I can build the right number of rows replacing the chars in a single row
   o += e + d + f.replace(/./g, e + ('|'+f).repeat(n)+`|\n`)
}
o += d // add last top border as bottom
console.log(o)    
\$\endgroup\$
9
\$\begingroup\$

Ruby, 124 (130 - 5%)

n=(g=gets).to_i
b=g[-2].to_i+1
a=(0..n*b-1).map{|i|[?+*(i/b*b+b+1),(?|+' '*(b-1))*(i/b+1)+?|][i%b<=>0].center(n*b+1)}
puts a,a[-b]

With comments

n=(g=gets).to_i                                  #get input and interpret as a number for pyramid height (everything after the space is ignored)
b=g[-2].to_i+1                                   #the single-character block size is the second last character (just before the newline.) Add 1 to give the pitch between squares.
a=(0..n*b-1).map{|i|                             #run through all lines except the last one
[?+*(i/b*b+b+1),                                 #calculate number of + symbols
(?|+' '*(b-1))*(i/b+1)+?|]                       #or alternatively, pattern '|    |'
     [i%b<=>0]                                   #check if i%b is zero or positive to decide which to print
     .center(n*b+1)}                             #centre the text. It will be mapped to the array a.
puts a,a[-b]                                     #a contains the pyramid, minus its last line. Print it, and add the last line
\$\endgroup\$
  • \$\begingroup\$ Don't forget about your bonus -5% (bringing your score to 124). Good work! \$\endgroup\$ – Zach Gates Sep 14 '15 at 23:38
2
\$\begingroup\$

Python 2, 117 (123 bytes)

h,n=map(int,raw_input().split())
p,v='+|'
while h:p+='+'*-~n;v+=' '*n+'|';h-=1;l=~n/-2*h*' ';print l+p+('\n'+l+v)*n
print p

The idea is to build up the bricks' top p as +++++++++ and side v as | | |. The top starts as + and is augmented by n+1 +'s each layer. The side starts as | and is augmented by n spaces and a |. Each layer, we augment the tops and sides, then print one top and n sides.

To center them, we first print an indent l. It consists of a number of spaces that scales with the current height h. To update it, we decrementing the height variable h until it hits 0, after which the current layer is flush against the left edge of the screen. We print the top once more to make the bottom layer, and we're done.

\$\endgroup\$
0
\$\begingroup\$

Python 2, 200 (210 - 5%)

a,b=map(int,raw_input().split());c=0;a+=1;i=a*b+a-b;e=[i*'+']
while a-1:
 v=(('|'+' '*b)*a).rstrip();p=' '*((i-len(v))/2);a-=1;c+=1
 for u in range(b):e.insert(0,p+v)
 e.insert(0,p+'+'*len(v))
print'\n'.join(e)

I used string multiplication and stripped extra spaces.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.