# Print a Lego piece

This challenge is a simple one. Given two inputs, describing the height and width of a Lego piece, you have print an ASCII art representation of it.

Here is how the Lego pieces are supposed to look:

(4, 2)

___________
| o o o o |
| o o o o |
-----------

(8, 2)

___________________
| o o o o o o o o |
| o o o o o o o o |
-------------------

(4, 4)

___________
| o o o o |
| o o o o |
| o o o o |
| o o o o |
-----------

(3, 2)

_________
| o o o |
| o o o |
---------

(1, 1)

o


If you can't tell from the test-cases, the top and bottom are width*2+3 underscores and dashes, and each row has pipes for the sides, o's for the little things, and everything is separated by spaces.

The only exception for this is (1, 1), which is just a single o.

You will never get 0 for any of the dimensions.

This is , so shortest code in bytes wins!

var QUESTION_ID=84050,OVERRIDE_USER=31343;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(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){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<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="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

• Is it possible that the width or the height will be greater than 10? What range should we support? Jun 30 '16 at 2:37
• The special case is a real bummer. Jun 30 '16 at 3:03
• In the next few years, I want to see another "Print a Lego piece" challenge that requires writing the code to tell a 3D printer to produce a Lego. Jun 30 '16 at 8:47
• Wait, "whatever integer range your language supports"? That ain't how LEGO works. The bricks are only available in a handful of very specific dimensions. Even if you add in plates, you only get a couple more. Any script that does not discard input such as (1,7) or (5,3) is complete garbage. Jul 1 '16 at 14:43
• Why doesn't the single piece (1,1) have sides? There is a real Lego piece with a single nipple on top of a cube. Jul 2 '16 at 0:00

## Octave, 9795 86 bytes

@(w,h){[a=~(1:w*2+3)+95;repmat(['| ' repmat('o ',1,w) '|'],h,1);~a+45],'o'}{(w*h<2)+1}


I used the @atlasologist's method in Python to test (1, 1): (...,'o')[x<2>y]

Thanks to @Luis Mendo for saving 7 bytes: a=ones(1,w*2+3)*'_' to a=~(1:w*2+3)+95 and a./a*'-' to ~a+45

Thanks to @pajonk for saving 2 bytes: f=

• This is not valid Matlab code. You should label as "Octave" only. Also, instead of a./a*'-' can you use ~~a*'-'? Or even ~a+45? Jun 30 '16 at 16:51
• Also, probably you can leave it as an anonymous function (without f=) Jun 30 '16 at 17:30

J, 59 bytes.

' o|_='&({~)@:((4,~3,2(,~"1)2 0,"1(1 0&($~)@,+:))^:(0===]))  # Retina, 112 111 bytes Makes the piece the correct width, then adds rows. Performs a substitution at the end if the result was a 1x1. Takes input like 4,2. Byte count assumes ISO 8859-1 encoding. \d+$*
1$¶___¶| |¶--- +s1(,.*)(¶.* )(.*)$1__$2o$3--
+sm1(.*)(^.*$¶)(.*)$1$2$2$3 ,¶ _____¶\| o \|¶----- o  Try it online ### Fun fact: You can give multiple inputs on separate lines and it will add them together into a single LEGO! ## Common Lisp, 286 bytes (let((columns(read))(rows(read)))(when(and(= columns 1)(= rows 1))(progn(write-char #\o)(exit)))(dotimes(i(+(* columns 2)3))(write-char #\_))(terpri)(dotimes(i rows)(format t "| ")(dotimes(i columns)(format t "o "))(format t "| ")(terpri))(dotimes(i(+(* columns 2)3))(write-char #\-)))  • this shows you have 285, not 286 bytes. (let((c(read))(r(read)))(when(and(= c 1)(= r 1))(progn(#1=write-char #\o)(exit)))(#2=dotimes #4=(i(+(* c 2)3))(#1# #\_))(terpri)(#2#(i r)#3=(format t "| ")(#2#(i c)(format t "o "))#3#(terpri))(#2# #4# (#1# #\-))) saves 73 bytes. I used c instead of columns, r instead of rows, also #n# and #n= reader macro where you reuse things. – user65167 Feb 25 '17 at 10:04 • This saves 103 bytes: (lambda(c r)(if(=(* c r)1)(format t"o"(exit)))(#1=dotimes #2=(i(+(* c 2)3))(format t"_"))(terpri)(#1#(i r)#3=(format t"| ")(#1#(i c)(format t"o "))#3#(terpri))(#1# #2#(format t"-"))), I think anonymous function is allowed. What I don't like is fact that for (f 1 1) output is not shown (or it's shown but program exits too quickly to see it) but it was in your solution from the beggining. – user65167 Feb 25 '17 at 19:04 # PHP 4.1, 103 bytes This is based on my answer on https://codegolf.stackexchange.com/a/57883/14732, which was where all the heavy lifting was done. <?$R=str_repeat;printf($W+$H<3?o:"_%'_".($Z=1+$W*2)."s_
%s-%1$'-{$Z}s-",'',$R('|'.$R(' o',$W).' | ',$H));


This answer requires that short_open_tags and register_globals are enabled (which it is enabled by default).

You can pass the values using the keys W and H, over POST, GET, SESSION and COOKIE.

This outputs warnings to STDERR, which aren't errors. According to https://codegolf.meta.stackexchange.com/a/1655/14732, this is acceptable as long as it isn't disallowed in the question.
Removing the warnings costs me 2 bytes.

## Racket 174 bytes

(λ(w h)(let((dl(λ(s)(displayln s)))(d(λ(s)(display s))))(for((x(+ 3(* w 2))))(d"_"))
(dl"")(for((x h))(d"| ")(for((y w))(d"o "))(d"|")(dl""))(for((x(+ 3(* w 2))))(d"-"))))


Ungolfed:

(define (f1 w h)
(let ((dl (λ (s) (displayln s)))
(d (λ (s) (display s))))
(for ((x (+ 3 (* w 2))))
(d "_"))
(dl "")
(for ((x h))
(d "| ")
(for ((y w))
(d "o "))
(d "|")
(dl ""))
(for ((x (+ 3 (* w 2))))
(d "-"))))


Testing:

(f 5 2)


Output:

_____________
| o o o o o |
| o o o o o |
-------------


# Charcoal, 41 bytes

¿⁼η⁼θ¹o≔⁺³×θ²κＵＲκ⁺²ηＰ×κ_Ｍ⁺η¹↓Ｐκ↗Ｆη«Ｐ×θ o↑


Draws a box to get the vertical sides, then manually draws the top and bottom.

Then, prints the o's line by line.

Link is to verbose version of code.

Try it online!

# SpecBAS - 87 bytes

1 INPUT w,h: x=w*2+3: ?IIF$(w=1 AND h=1,"o","_"*x+#13+(("| "+("o "*w)+"|"#13)*h)+"-"*x)  Uses an inline-IF to either print single "o" when width and height are 1, otherwise builds up a string. #13 is the line feed character. # Scala, 90 bytes (w:Int,h:Int)=>{val A=2*w+3;if(w*h==1)"o"else s"${"_"*A}\n${s"|${"o "*w}|\n"*h}${"-"*A}"}  paste the above function into your Scala REPL, and then invoke the function with the width and height arguments. • Hello, and welcome to PPCG! This is a great first post! There is only one small issue: we commonly use Scala, 170 bytes not Scala - 170 bytes. They both work, but out byte snippet counters look for the first, according to my research. Jul 1 '16 at 23:21 • @NoOneIsHere thanks. fixed. and also shortened the submission from 170 to 94 bytes. Enjoying this... :-) Jul 2 '16 at 9:50 • @PeterPerháč You need to use Level 1 headers, so not fixed. Instead of **Scala, 94 bytes**, use #Scala, 94 bytes. Jul 2 '16 at 13:18 • You can use anonymous functions, i.e. {val A=2*w+3;if(w*h==1)"o"else s"${"_"*A}\n${s"|${"o "*w}|\n"*h}${"-"*A}"} (not snippets, though). Jul 2 '16 at 17:30 # JavaScript ES6, 134 124 Bytes function p(e,n){r='repeat';e*n-1?x="_"[r](2*e+3)+"\n"+("|"+" o"[r](e)+" |\n")[r](n)+"-"[r](2*e+3)+"\n":x="o",console.log(x)}  • I can shave off 4 bytes by using [r] instead of .repeat: function p(e,n){r='repeat';1==e&&1==n?x="0":x="_"[r](2*e+3)+"\n"+("|"+" o"[r](e)+" |\n")[r](n)+"-"[r](2*e+3)+"\n",console.log(x)} Jun 30 '16 at 9:20 • The output for 1,1 should be o, not 0. Also, I don't see any use of ES6 here, so you can change the version. – Neil Jun 30 '16 at 12:22 • You can replace function p(e,n) with p=(e,n)=> for 6 bytes. Jun 30 '16 at 14:14 • You're assigning x= twice. The second assignation can be removed for an extra 2 bytes, and x can be replaced altogether with a console.log( ? : ), bringing it down to 113 bytes: p=(e,n)=>{r='repeat';console.log(e*n-1?"_"[r](2*e+3)+"\n"+("|"+" o"[r](e)+" |\n")[r](n)+"-"[r](2*e+3)+"\n":"o")}  Jun 30 '16 at 15:10 • Guess what, welcome to PPCG! Jul 1 '16 at 8:04 # JavaScript ECMAScript6 (929491 87 Bytes) 92 Characters a=(w,h,r='repeat')=>w-h?"__"[r](w)+"__\n"+("|"+" o"[r](w)+" |\n")[r](h)+"--"[r](w)+"---":"o" ## Everything below here is Correct 94 Characters a=(w,h,r='repeat')=>w*h-1?"__"[r](w)+"__\n"+("|"+" o"[r](w)+" |\n")[r](h)+"--"[r](w)+"---":"o" 91 Characters a=(w,h)=>w*h-1?${"__"[r='repeat'](w)}__\n+('|'+" o"[r](w)+' |\n')[r](h)+"-"[r](w*2+3):"o"

87 Characters (Smallest so Far)

a=(w,h)=>w*h-1?'__'[r='repeat'](w)+__
+('|'+' o'[r](w)+ |
)[r](h)+'-'[r](w*2+3):'o'


I took what I learned from the other JavaScript Submissions and made it a lot smaller by writing mine from scratch and then working my way down, turns out you don't need any console.log or alert as by default it will push it to the console when there is an output

I am still working on it to see if I can make it smaller yet

• I think your first line of output is one character short. Jan 11 '18 at 23:32

# Swift, 182 Bytes

func p(w:Int,h:Int){let i=w*2+3;var s="";if w+h<3{s="o"}else{for _ in 0..<i{s+="_"};for _ in 0..<h{s+="\n|";for _ in 0..<w{s+=" o"};s+=" |"};s+="\n";for _ in 0..<i{s+="-"}};print(s)}


If this was a closure implementation the func p(w:Int,h:Int) could be deleted and w replaced with $0 and h replaced with $1 but then it would be only the implementation not the interface so I felt that was cheating...

## 2nd attempt 180 Bytes

func q(w:Int,h:Int){let l=w*2+3;var s="",a="";if w+h<3{s="o"}else{for _ in 0..<l{s+="_";a+="-"};for x in 0..<h*w{s+=x%h==0 ? "\n| o":x%h==w-1 ? " o |":" o"};s+="\n";s+=a};print(s)}


Improved using ternaries. Only 2 bytes though...

## 3rd attempt 263 bytes

func r(w:Int,h:Int){let l=w*2+3;var s="";if w+h<3{s="o"}else{for a in 0..<(h+2)*l{if a<l{s+="_";continue};if a>=(h+2)*l-l{s+=a%l==0 ? "\n-":"-";continue};let v=a%l>0&&a%l<l-2;s+=a%l==0 ? "\n|":v&&(a%l)%2==0 ? "o":v&&(a%l)%2==1 ? " ":a%l==l-1 ? "|":" "}};print(s)}


The reason I include this is because my original thought was to decrease the amount of for loops. Whilst this is more verbose it only has the one iteration (also it took me quite a long time so here it is again in a more friendly format):

func r(w: Int, h: Int) {
let l = w * 2 + 3
var str = ""
if w + h < 3 {
str = "o"
} else {
for a in 0..<(h + 2) * l {
if a < l {
str += "_"
continue
}
if a >= (h + 2) * l - l {
str += a % l == 0 ? "\n-" : "-"
continue
}
let v = a % l > 0 && a % l < l - 2
str += a % l == 0 ? "\n|" : v && (a % l) % 2==0 ? "0" : v && (a % l) % 2 == 1 ? " " : a % l == l - 1 ? "|" : " "
}
}
print(str)
}


There are a lot of ternary conditions here so I'm sure it can be optimised further.

• Welcome to the site! Nice first post.
– user58826
May 2 '17 at 21:04

# MAWP, 131 bytes

@1A{1M\}>1M!//~[1A~!~]%~!2W3M[1A95W2W5M;]%~
[1A25W;65W1M4W;~[1A84W;77W2W43W1MM;]%~84W;65W1M4W;]~25W;2W3M[1A95W;]


The special case was a pain, but I managed to 'golf' a solution under 150 bytes here.

### Output

4 3
___________
| o o o o |
| o o o o |
| o o o o |
-----------
`

Try it!