# 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

# 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!

# 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!

# Befunge, 114113108 101 bytes

I know there are already a number of Befunge solutions, but I was fairly certain they could be improved upon by taking a different approach to the layout of the code. I suspect this answer can be golfed further as well, but it is already a fair bit smaller than either of the previous entries.

&::&+:2^|,+55_"_",^
-4:,,"| "<\_|#:+1\,,"|"+55$_2#$-#$" o",#!,#:< ,"-"_@#:-1< :*2+2\-_"o",@v!:-1<  Try it online! • Can you explain why the string :<| is needed? May 29 '18 at 18:20 • @Zacharý That vertical branch on the first line never actually branches up. The top of the stack is always zero at that point, so it's a shortcut for dropping the stack top and branching down at the same time - essentially this tip. Nov 28 '18 at 18:59 # Vim, 56 keystrokes This seems like a text editing task, so Vim is the obvious choice! I take input as a text file with two space separated integers and output the answer into the same file. Also, I hate you for having the 1x1 special case... Anyway: "adt l"bDro:if@a*@b==1|wq|en<cr>Di| |<esc>@aio <esc>yy@bPVr_GpVr-ZZ  and if there hadn't been for the special case, 35 keystrokes "adt x"bDi| |<esc>@aio <esc>yy@bPVr_GpVr-ZZ  ## A breakdown for sane people: "adt l"bD  Delete numbers from buffer into @a and @b (space char kept)  ro:if@a*@b==1|wq|en<cr>  Replace space with "o" and if special case, save and quit  Di| |<esc>  Clear the line and write the edges of the lego block  @aio <esc>  Insert @a lots of "o " to get a finished middle part  yy@bP  Yank line and make @b extra copies (one too many)  Vr_  We are at top of buffer, replace extra line with underscores  Gp  Jump to bottom of buffer, pull line that we yanked earlier  Vr-ZZ  Replace line with dashes, save and quit ## JavaScript (ES6), 89 86 bytes (x,y,g=c=>c[r=repeat](x*2+3))=>x*y-1?g(_)+ +|${o [r](x)}|
[r](y)+g(-):o


Edit: Saved 3 bytes thanks to @Shaggy.

• Save 3 bytes by aliasing repeat. May 2 '17 at 22:25

# 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

## 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 |
-------------


# 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. # PHP 7, 98 bytes <?=($P=str_pad)("",$w=3+2*$argv[1],_).$P("",$argv[2]*++$w,$P("
| ",$w-1,"o ")."|").$P("
",$w,"-");  str_pad saves a little from str_repeat. Juggling with preincrement on $w saves two bytes.
But version 7 is needed for assigning $r while using it at the same time. # Java, 318312297294260 258 bytes Saved 15 bytes thanks to cliffroot! interface a{static void main(String[]A){int b=Byte.valueOf(A[0]),B=Byte.valueOf(A[1]),C=3+b*2;String c="";if(b<2&B<2)c="o";else{for(;C-->0;)c+="_";for(;B-->0;){c+="\n|";for(C=b;C-->0;)c+=" o";c+=" |";}c+="\n";for(C=3+b*2;C-->0;)c+="-";}System.out.print(c);}}  It works with command line arguments. Ungolfed In a human-readable form: interface a { static void main(String[] A) { int b = Byte.valueOf(A[0]), B = Byte.valueOf(A[1]), C = 3 + b*2; String c = ""; if (b < 2 & B < 2) c = "o"; else { for (; C-- > 0;) c += "_"; for (; B-- > 0;) { c += "\n|"; for (C = b; C-- >0;) c += " o"; c += " |"; } c += "\n"; for(C = 3 + b*2; C-- >0;) c += "-"; } System.out.print(c); } }  Yes, it's still difficult to understand what's going on even when the program is ungolfed. So here goes a step-by-step explanation: static void main(String[] A)  The first two command line arguments -which we'll use to get dimensions- can be used in the program as A[0] and A[1] (respectively). int b = Byte.valueOf(A[0]), B = Byte.valueOf(A[1]), C = 3 + b*2; String c = "";  b is the number of columns, B is the number of rows and C is a variable dedicated for use in for loops. c is the Lego piece. We'll append rows to it and then print it at the end. if (b < 2 & B < 2) c = "o"; else {  If the piece to be printed is 1x1, then both b (number of columns) and B (number of rows) should be smaller than 2. So we simply set c to a single o and then skip to the statement that System.out.prints the piece if that's the case. for (; C-- > 0; C) c += "_";  Here, we append (integerValueOfA[0] * 2) + 3 underscores to c. This is the topmost row above all holes. for (; B > 0; B--) { c += "\n|"; for(C = b; C-- > 0;) c+=" o"; c += " |"; }  This is the loop where we construct the piece one row at a time. What's going on inside is impossible to explain without examples. Let's say that the piece is 4x4: Before entering the loop, c looks like this: ___________ After the first iteration (\n denotes a line feed): ___________\n | o o o o | After the second iteration: ___________\n | o o o o |\n | o o o o | After the third iteration: ___________\n | o o o o |\n | o o o o |\n | o o o o |  . c += "\n"; for (C = 3 + b*2; C-- > 0;) c += "-";  Here, we append (integerValueOfA[0] * 2) + 3 hyphens to the piece. This is the row at the very bottom, below all holes. The 4x4 piece I used for explaining the for loop where the piece is actually constructed now looks like this: ___________\n | o o o o |\n | o o o o |\n | o o o o |\n | o o o o |\n -----------  System.out.print(c);  And finally, we print the piece! • Probably Revision 3 made this the longest post I've ever made on Stack Exchange. Jun 30 '16 at 3:57 • You can move C variable from for loops int b=Byte.valueOf(A[0]),B=Byte.valueOf(A[1]),C. In all your for loops it also seems like you can use C-->0; checks, makes it 298, pastebin.com/uj42JueL Jun 30 '16 at 7:51 • some creative usage of for loops for few bytes saved – pastebin.com/dhNCpi6n Jun 30 '16 at 8:23 • if you convert your arguments to bytes first, then your check is size of brick is 1x1 will be if(b==1&B==1) which allows you to save over 20 bytes Jul 1 '16 at 10:34 • also for the case 1x1 instead doing this System.out.print('o');return;, you could set c='o' and placed logic for different bricks in else block. then having single print statement and no return allow you to save some additional bytes Jul 1 '16 at 10:44 ## Batch, 172 170 bytes @echo off if "%*"=="1 1" echo o&exit/b set o= for /l %%i in (1,1,%1)do call set o=%%o%% o echo ---%o: o=--% for /l %%i in (1,1,%2)do echo ^|%o% ^| echo ---%o: o=--%  Edit: Saved 2 bytes thanks to @CᴏɴᴏʀO'Bʀɪᴇɴ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ. I can save 7 bytes if I can assume delayed expansion is enabled. • %%o%% instead of %o%? Jun 30 '16 at 18:47 • @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o% would be replaced with original value of o each time, so that o would only ever equal " o". %%o%% goes through as an argument to call of %o%, which then uses the current value of o. – Neil Jun 30 '16 at 19:36 • Why don't you... just do set o=%o% o? Jul 1 '16 at 7:53 • @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o% gets expanded before the for loop is parsed, so the loop reads for /l %i in (1,1,8) do call set o= o which is obviously pointless. – Neil Jul 1 '16 at 8:19 • Why don't you do set o=%%o%% o then (-5)? Jul 1 '16 at 8:25 # 32 16-bit little-endian x86 machine code, 5754 51 bytes 3 bytes less thanks to @ninjalj. Heavily rewrote the code and have managed to shave off another 3 bytes In hex FCBA6F208D48FFE20492AAEB2389D941D1E14151B05FF3AAEB0BB87C20AB89D992F3AB92AAB00AAA4E7DEF59B02DF3AA91AAC3  Input: BX=width, SI=height, DI points to the buffer that receives result as a NULL-terminated string with lines separated by "\n" ## Disassembly: fc cld ba 6f 20 mov dx,0x206f ;Storing ' o' in DX for later use 8d 48 ff lea cx,[bx+si-0x1] ;CX=width+height-1 e2 04 loop _main0 ;--CX & brahch if not zero 92 xchg dx,ax ;(1,1) case, swap DX & AX aa stosb ;AL == 'o', CX == 0 eb 23 jmp _end _main0: 89 d9 mov cx,bx 41 inc cx d1 e1 shl cx,1 41 inc cx ;Calculate (width+1)*2+1 51 push cx ;and save it for future use b0 5f mov al,0x5f ;'_' f3 aa rep stosb ;Output the whole line of them eb 0b jmp _loopstart ;Jump into the loop _loop: b8 7c 20 mov ax,0x207c ;' |' ab stosw ;Output it once (left bar + space) 89 d9 mov cx,bx ;Copy width 92 xchg dx,ax ;AX == ' o' f3 ab rep stosw ;Output it CX times 92 xchg dx,ax ;Swap values back, AL == '|' aa stosb ;Output only the right bar _loopstart: b0 0a mov al,0x0a ;Newline. Can be replaced with mov ax,0x0a0d for windows newline aa stosb ;convention (at the cost of 1 byte), with stosb replaced with stosw 4e dec si ;Height-- 7d ef jge _loop ;Continue if si >= 0 (this accounts for the dummy first pass) 59 pop cx b0 2d mov al,0x2d ;'-' f3 aa rep stosb ;Output bottom line _end: 91 xchg cx,ax ;CX == 0, so swap to get zero in AL aa stosb ;NULL-terminate output c3 retn  • Would be shorter as 16-bit: -3 bytes for 3 66h prefixes, +1 byte for "\r\n" line termination. Jul 4 '16 at 17:54 • You should put spaces between the crossed-out numbers and the current numbers in your byte count, for readability. Jul 8 '16 at 20:34 # V, 43, 40, 38 36 bytes One of the longest V answers I've ever written... Àio ddÀPñóo î½o u2Pí.«/| °| Vr-HVr_  Try it online! Since this contains unicode and unprintable characters, here is a reversible hexdump: 0000000: c069 6f20 1b64 64c0 50f1 f36f 20ee bd6f .io .dd.P..o ..o 0000010: 0d0a 7532 50ed 2eab 2f7c 20b0 7c0d 0a56 ..u2P.../| .|..V 0000020: 722d 4856 725f r-HVr_  This challenge is about manipulating text, so perfect for V! On the other hand, V is terrible at conditionals and math, so the differing output for (1, 1) really screwed it up... :( Explanation: À "Arg1 times: io <esc> "Insert 'o ' dd "Delete this line, and À "Arg2 times: P "Paste it  Now we have 'Height' lines of o's with spaces between them. ñ "Wrap all of the next lines in a macro. This makes it so that if any "Search fails, execution will stop (to handle for the [1, 1] case) ó "Search and replace o î½o "'o'+space+0 or 1 newlines+another 'o' u "Undo this last search/replace 2P "Paste twice í "Search and replace on every line .«/| °| "A compressed regex. This surrounds every non-empty line with bars. Vr- "Replace the current (last) line with '-' H "Move to line one Vr_ "Replace this line with '_'  Non-competing version (31 bytes): Try it online! This version uses several features that are newer then this challenge to be 5 bytes shorter! Second explanation: ddÀP  which is "Delete line, and paste it n times" is replaced with ÀÄ which is "Repeat this line n times". (-2 bytes) óo î½o u  which was "Replace the first match of this regex; Undo" was replaced with /o î½o  Which is just "Search for a match of this regex" (-1 byte) And lastly, Ò is just a simple synonym for Vr, which both "Replace every character on this line with 'x'". (-2 bytes) • how come it seems broken at the bottom with this v.tryitonline.net/… Jul 1 '16 at 17:44 • @meepl I really have no idea. It works on 50x959 but if you increase the width or height it stops working. I'm guessing it's most likely a restriction intentionally placed on the website to prevent extremely large programs from being ran. Jul 1 '16 at 17:50 • TIO limits the output to 100 KB, mainly to prevent the frontend from crashing your browser. Jul 27 '16 at 1:26 # Cinnamon Gum, 32 bytes 0000000: 6c07 d5f5 7a5d 9cdf 5ae6 52ae 4050 0c35 l...z]..Z.R.@P.5 0000010: 18d9 052f 0082 9b42 e7c8 e422 5fe4 7d9f .../...B..."_.}.  Non-competing. Try it online. Input must be exactly in the form [width,height] with no space in between the comma and the height. # Explanation The string decompresses to this: l[1,1]&o;?&p___~__~ %| ~o ~| %---~--~  The first l stage maps [1,1] to o (the special case) and everything else to the string p___~__~ %| ~o ~| %---~--~  The backtick then signals the start of a second stage; instead of outputting that string, CG chops off the backtick and executes the string. The p mode then repeats all the characters inside the tildes first parameter (width) times and then afterwards repeats the characters inside the percent signs second parameter (height) times. So for [4,2] it turns into this: ___________ %| o o o o | %-----------  and then into: ___________ | o o o o | | o o o o | -----------  # 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

# Befunge, 144 Bytes

I would have prefered to comment to this post, but I don't have the reputation yet, so I'm putting an answer of my own, which works a similar way, but is slightly more compact

&::&*:1v
v3*2:\/\_"o",@
>+:  v   >52*," |",, v
>,1-:vLEG O MAKERv::\<
^"_" _$\:|<v "o "_v v52:+3*2$<,>,,1-:^$>*,v < ^"|":-1\< v-1_@, >:"-"^  you can test the code here # Perl 5 - 84 77 bytes 84 Bytes sub l{($x,$y)=@_;$w=3+2*$x;warn$x*$y<2?"o":'_'x$w.$/.('| '.'o 'x$x."|\n")x$y.'-'x$w}


77 Bytes. With some help from Dom Hastings

sub l{($x,$y)=@_;$x*$y<2?o:'_'x($w=3+2*$x).('
| '.'o 'x$x."|")x$y.$/.'-'x$w}

• First I was confused as to why someone would go to the effort of using warn in a golf program, but then I realized you're using it because it's shorter than print. Nice!
– pipe
Jul 3 '16 at 13:11
• Yeah, I think in Perl 6 you can take another byte off by using say instead of warn Jul 3 '16 at 18:34
• You can do that in Perl 5 too, just that it's not enabled by default. I think that you can get around that in code-golf by calling your script from the command line with -E instead of -e, enabling all the extensions. I'm new to this place so I don't know exactly where it's specified how to count the scores though.
– pipe
Jul 3 '16 at 18:46
• Oh really, I didn't know that. I'm new here as well so I'm also not sure Jul 4 '16 at 6:59
• I think you can shorten this to 76 bytes... If you're using a function I believe returning the string is acceptable (see the JS answer, saving you 4 bytes for warn), you don't need quotes around the "o" (you can use a bareword for another -2), if you inline the calculation of $w you should save another byte ('_'x($w=3+2*$x) vs. $w=3+2*$x; ... '_'x$w) and lastly, you can change the \n for a literal newline. Hope that helps! Jul 5 '16 at 9:23

# Python 2, 71 bytes

lambda x,y:('o',x*'__'+'___\n'+'| %s|\n'%('o '*x)*y+'-'*(x*2+3))[x+y>2]

• Welcome to PPCG! Nice first post! Jul 5 '16 at 14:35

# Groovy, 107, 98, 70, 64

{x,y->t=x*2+3;x<2&&y<2?"o":'_'*t+"\n"+"|${' o'*x} |\n"*y+'-'*t}  Testing: (2,2) (1,1) (8,2) (1,4) _______ | o o | | o o | ------- o ___________________ | o o o o o o o o | | o o o o o o o o | ------------------- _____ | o | | o | | o | | o | -----  # 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 ## 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 # 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 # 05AB1E, 33 bytes Code: *i'oë¹·3+©'_×¶²F'|„ o¹×„ |¶}®'-×J  Explanation: *i'o # If both input equal 1, push "o" ë # Else, do... ¹·3+ # Push input_1 × 2 + 3 © # Copy this number to the register '_× # Multiply by "_" ¶ # Push a newline character ²F } # Do the following input_2 times: '| # Push "|" „ o # Push " o" ¹× # Multiply this by input_1 „ | # Push " |" ¶ # Push a newline character ® # Retrieve the value from the register '-× # Multiply by "-" J # Join everything and implicitly print.  Uses the CP-1252 encoding. Try it online!. ## Python 2, 7573 72 bytes lambda x,y:(x*'__'+'___\n'+('| '+'o '*x+'|\n')*y+'-'*(x*2+3),'o')[x<2>y]  Returns a string, with a conditional to handle the 1,1 block. Thanks to Lynn and Chepner for two bytes • lambda x,y:('_'*x*2+'___\n'+ etc. saves a byte. – Lynn Jun 30 '16 at 1:31 • Knock off another byte with x*'__' instead of 2*x*'_'. Jul 1 '16 at 14:24 • Just join this Comunity, sorry for asking. How can i see it run? i paste it in the terminal and just prints <function <lambda> at 0x......>. How can i test this? Jul 2 '16 at 10:29 • @Miguel assign it to a variable. It'll return the value of the function: f=lambda x:x+1; print(f(9)) Jul 2 '16 at 11:23 • One more question if not to complicated to answer. How can you trace the bits so precisely? Jul 2 '16 at 11:30 # 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! J, 59 bytes. ' o|_='&({~)@:((4,~3,2(,~"1)2 0,"1(1 0&($~)@,+:))^:(0===]))


## C, 202 191 bytes

#define p printf
i,w,h;t(char*c){for(i=0;p(c),++i<w*2+3;);p("\n");}f(){t("_");for(i=0;i<w*h;)i%w<1?p("| o "):p("o "),i++%w>w-2&&p("|\n");t("-");}main(){scanf("%d %d",&w,&h);w*h<2?p("o"):f();}


Thanks to @Lince Assassino for saving 11 bytes!

Ungolfed:

#include <stdio.h>
#define p printf

int i, w, h;

void t(char *c)
{
for(i=0; p(c), ++i<w*2+3;);
p("\n");
}

void f()
{
t("_");
for(i=0; i<w*h;)
{
i%w<1 ? p("| o ") : p("o ");
i++%w>w-2 && p("|\n");
}
t("-");
}

int main()
{
scanf("%d %d", &w, &h);
w*h<2 ? p("o") : f();
}

• You can change your first line for p(char*A){printf(A);} Jul 1 '16 at 17:34
• Really, thank you! But it's possible to make shorter with #define p printf Jul 1 '16 at 18:16

# 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. ## Bash, 186,163,156, 148,131, 130 Bytes  ## Arg1 - Lego width ## Arg2 - Lego height function print_lego() { (($1+$2>2))&&{ printf _%.0s seq -1$1
echo
for((i=$2;i--;)){ printf \| for((j=$1;j--;)){
printf o
}
echo \|
}
printf =%.0s seq -1 $1 echo }||echo o }  Note: If you really need the lego to have hyphens for the last line, then change the last printf to printf -- -%.0s seq -1$1


• Wouldn't this be quite a bit shorter if it wasn't wrapped in a function? Also, I'm not an expert in bash but it looks like it's got some extra whitespace. Jun 30 '16 at 4:26
• It would be ~170 as a one-liner: (($x+$y==2))&&echo o||{ printf _%.0s $(seq -1$x);echo;for((i=0;i<$y;i++));do printf \|;for((j=0;j<$x;j++));do printf o;done;echo \|;done;printf =%.0s $(seq -1$x);echo;}
– user53101
Jun 30 '16 at 13:00
• If you use (), you don't need the keyword function to declare a function. There is an alternate for syntax using braces, e.g: for((j=$1;j--;));{ printf o;}. As shown in the previous example, you can save some characters by decrementing and testing in for's second expression. You can use backticks instead of $(cmd). Jun 30 '16 at 19:48
• @ninjalj Thanks, I'm new to code golf -- that squeezes another ~17 bytes off, the one-liner is now 152: (($x+$y==2))&&echo o||{ printf _%.0s seq -1 $x;echo;for((i=$y;i--;)){ printf \|;for((j=$x;j--;)){ printf o;};echo \|;};printf =%.0s seq -1$x;echo;}
– user53101
Jul 1 '16 at 0:28
• Dollar signs are optional in arithmetic context, so you can shave a few more bytes by changing (($something)) to ((something)) throughout. ($1 still needs the dollar sign to disambiguate it from the literal 1.) May 2 '18 at 9:53

1#1="o"
w#h|f<-w*2+3=f!"_"++'\n':h!('|':w!" o"++" |\n")++f!"-"
n!s=[1..n]>>s


Usage example: 3 # 2 gives you a multiline string for a 3-by-2 brick.

Ungolfed:

(#) :: Int -> Int -> String
1     #   1    = "o"
width # height = let longWidth = 2 * width + 3 in -- golfed as 'f'
(        longWidth times "_"  ++   "\n" )
++ height   times ( "|" ++     width times " o" ++ " |\n" )
++                  (        longWidth times "-"            )

-- | golfed as (!)
times :: Int -> [a] -> [a]
times n s = concat \$ replicate n s

• At first glance that looked like it should be shorter with unlines`, but it's not. Jul 3 '16 at 21:40