打印乐高积木


48

这一挑战是一种简单挑战。给定两个输入来描述乐高积木的高度和宽度,您已经打印了它的ASCII美术表示形式。

这是乐高积木的外观:

(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

如果您不能从测试用例中分辨出来,则顶部和底部都是width*2+3下划线和破折号,并且每一行的侧面都有管道,o's'代表小东西,并且所有内容都由空格分隔。

唯一的例外是(1, 1),它只是一个o

您将永远无法获得0任何尺寸。

这是,因此以字节为单位的最短代码胜出!


2
宽度或高度是否可能大于10?我们应该支持什么范围?
DJMcMayhem

29
特例是一个真正的可耻。
科纳·奥布莱恩

47
在接下来的几年中,我希望看到另一个“打印乐高积木”的挑战,要求编写代码告诉3D打印机生产乐高积木。
凯文-恢复莫妮卡

8
等一下,“您的语言支持的整数范围是多少?” 那不是乐高的工作原理。这些砖仅适用于少数几个非常特殊的尺寸。即使您添加盘子,您也只会得到更多。任何不丢弃(1,7)或(5,3)之类的脚本都是完全垃圾。
RegDwight '16

3
为什么单件(1,1)没有侧面?有一个真正的乐高积木,立方体上方有一个乳头。
tcrosley's

Answers:


53

Befunge,165个227字节

&::&*:1` v
v+3*2:\/\_"o",@
v       _$ v<
>"_",1-:^  2
v:,,"| ",*5<
v         _v
>" o",,1-:^$
>*v>\     #\^
5 #|:-1,"|"<
^2$<
v1, *95<
- >2*3+^
>:    #^_@

空白不如以前那样多,但是仍然存在差距。原理与以前的解决方案相同,但是布局不同。这次,要检查两个数字是否均为1,我只是拿他们的乘积,看看结果是否大于1。


旧解决方案(227字节)

v           v       <
&   >>\:2*3+>"_",1-:|
>&:1`|v ,,"| ",*52:$<   :\<
    #\v         <
     :>" o",,1-:|
     1          >"|",$\1-:|
    \`            @       $
    ^_"o",@>:!    |       2
           ^-1,*95<+3*2,*5<

可能会打更多的高尔夫球。只要看看所有空白!

这是我对MSPaint图片格式的解释的较差尝试: How to Befunge 代码沿箭头方向流动。


2
哦。我的 神。令我
震惊

25

V43,40,38 36字节

我写过的最长的V答案之一...

Àio ddÀPñóo î½o
u2Pí.«/| °|
Vr-HVr_

在线尝试!

由于其中包含unicode和不可打印的字符,因此这是一个可逆的十六进制转储:

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_

这个挑战是关于操纵文本的,对V来说是如此完美!另一方面,V在条件和数学上非常糟糕,因此(1,1)的不同输出确实把它搞砸了... :(

说明:

À                   "Arg1 times:
 io <esc>           "Insert 'o '
         dd         "Delete this line, and
           À        "Arg2 times:
            P       "Paste it

现在我们有了o的“高度”线,并且它们之间有空格。

ñ                   "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 '_'

非竞争版本(31字节):

在线尝试!

这个版本使用了一些较新的功能,因此将挑战缩短了5个字节!

第二种解释:

ddÀP

“删除行并粘贴n次”被替换ÀÄ为“重复此行n次”。(-2个字节)

óo î½o
u

这是“替换此正则表达式的第一个匹配项;撤消”被替换为

/o î½o

就是“搜索此正则表达式的匹配项”(-1字节)

最后,Ò这只是的简单同义词Vr,两者都“用'x'替换此行上的每个字符”。(-2个字节)



2
@meepl我真的不知道。它适用于50x959,但如果您增加宽度或高度,它将停止工作。我猜想这很可能是为了防止超大型程序被运行而故意在网站上施加的限制。
DJMcMayhem

1
TIO将输出限制为100 KB,主要是为了防止前端崩溃导致浏览器崩溃。
丹尼斯

22

32个 16位的低端x86机器码,57 54 51字节

@ninjalj减少了3个字节。

大量重写了代码,并成功削减了另外3个字节

十六进制

FCBA6F208D48FFE20492AAEB2389D941D1E14151B05FF3AAEB0BB87C20AB89D992F3AB92AAB00AAA4E7DEF59B02DF3AA91AAC3

输入:BX = width,SI = height,DI指向缓冲区,该缓冲区以以NULL终止的字符串接收结果,并用“ \ n”分隔行

拆卸:

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

将缩短为16位:3个66h前缀为-3个字节,“ \ r \ n”行终止为+1个字节。
ninjalj '16

为了便于阅读,您应该在字节数中划掉数字和当前数字之间的空格。
价值墨水

20

Python 2,75 73 72字节

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

返回一个字符串,带有条件来处理1,1块。

感谢Lynn和Chepner两个字节


lambda x,y:('_'*x*2+'___\n'+等保存一个字节。
林恩

1
x*'__'代替删除另一个字节2*x*'_'
chepner '16

刚加入这个社区,很抱歉询问。我怎么看它运行?我将其粘贴到终端中,然后进行打印<function <lambda> at 0x......>。我该如何测试?
Miguel

1
@Miguel将其分配给变量。它将返回该函数的值:f=lambda x:x+1; print(f(9))
Atlasologist '16

还有一个问题,如果不是很复杂的话。您如何精确地跟踪这些位?
Miguel

13

CJam,34岁

'_q~'o*"||"\*S*f*f+'-f+zN*_,H='o@?

在线尝试

说明:

'_        push a '_' character
q~        read and evaluate the input (height and width)
'o*       repeat the 'o' character <width> times
"||"\*    join the "||" string by the string of o's (putting them in between)
S*        join with spaces (inserting a space between every 2 characters)
f*        repeat each character <height> times, making it a separate string
f+        prepend '_' to each string
'-f+      append '-' to each string
z         transpose the array of strings
N*        join with newlines; lego piece is ready, special case to follow
_,        duplicate the string and get its length
H=        compare with H=17
'o        push 'o' for the true case
@         bring the lego piece to the top for the false case
?         if the length was 17, use 'o' else use the lego piece

11

Ruby,59个 56字节

匿名函数,返回多行字符串。在线尝试!

-3字节,感谢@ El'endiaStarman的把戏

->w,h{w*h<2??o:?_*(x=2*w+3)+$/+(?|+' o'*w+" |
")*h+?-*x}

11

Java,318 312 297 294 260 258字节

感谢悬崖根节省了15个字节!

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

它与命令行参数一起使用。

Ungolfed在人类可读的形式:

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

是的,即使程序已取消运行,仍然很难理解发生了什么。因此,这里有逐步的说明:

static void main(String[] A)

前两个命令行参数-我们将用来获取尺寸-可以在程序中分别作为A[0]和使用A[1]

int b = Byte.valueOf(A[0]),
    B = Byte.valueOf(A[1]),
    C = 3 + b*2;
String c = "";

b是列数,B是行数,C是专用于for循环的变量。

c是乐高积木。我们将附加行,然后在最后打印。

if (b < 2 & B < 2)
    c = "o";
else {

如果要打印的部分为1x1,则b(列数)和B(行数)都应小于2。因此,我们将其简单地设置c为单个o,然后跳到出现这种情况的语句System.out.print

for (; C-- > 0; C)
    c += "_";

在这里,我们在后面加上(integerValueOfA[0] * 2) + 3下划线c。这是所有孔上方的最上一行。

for (; B > 0; B--) {
    c += "\n|";
    for(C = b; C-- > 0;)
        c+=" o";
    c += " |";
}

这是一个循环,我们一次构造一行。没有示例,无法解释内部发生的事情。假设片段是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 += "-";

在这里,我们将(integerValueOfA[0] * 2) + 3连字符附加到该部分。这是所有孔下方最底部的行。

我用来解释for实际构建循环的4x4片段现在看起来像这样:

___________\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);

最后,我们打印件!


修订版3可能是我在Stack Exchange上发表过的最长文章。
dorukayhan

2
您可以Cfor循环中移动变量int b=Byte.valueOf(A[0]),B=Byte.valueOf(A[1]),C。在您所有的for循环中,您似乎也可以使用C-->0;检查,使其
变为

1
for循环的一些创造性用法,用于保存几个字节– pastebin.com/dhNCpi6n
悬崖根

1
如果您首先将参数转换为字节,那么您检查的是Brick的大小为1x1 if(b==1&B==1),这将使您节省20多个字节
user902383 '16

对于1x1的情况System.out.print('o');return;,也可以这样做,您可以c='o'在else块中为不同的砖块设置和放置逻辑。然后只有一个打印语句且没有返回值可以让您节省一些额外的字节
user902383 '16

9

Minkolang 0.1558个 57 56字节

是的,这是正确的。我打了一个两个的小字节 ...

nn$d*1-5&"o"O.rd2*3+$z1$([" o"]" ||"2Rlkr$Dlz["-_"0G]$O.

在这里尝试!

说明

nn                Take two numbers from input (stack is now [w h])

                  C special case C
  $d              Duplicate stack
    *1-           Multiply and subtract 1
       5&         Jump 5 spaces if truthy
         "o"O.    Top of stack was 1*1-1=0, so output "o" and stop.

                     C precalculates width of top and bottom lines for later use C
         r           Reverse stack (now [h w])
          d          Duplicate top of stack
           2*3+      Multiply top of stack by 2 and add 3
               $z    Pop this and store in register (z = 2*w+3)

                                       C generates the row C
                 1$(                   Open while loop prepopulated with top of stack
                    [" o"]             w times, push "o "
                          " ||"        Push "|| "
                               2R      Rotate twice to the right
                                 l     Push newline (10)
                                  k    Break out of while loop

                                           C duplicates the row h times C
                                   r       Reverse stack
                                    $D     Duplicate whole stack h times
                                      l    Push newline

                     C this is for the top and bottom lines C
        z[           Open for loop that repeats z times
          "-_"       Push "_-"
              0G     Relocate top of stack to bottom of stack
                ]    Close for loop

                 $O.    Output whole stack as characters and stop.

好的,这是对保存两个字节的解释的两次重要重写。我认为我不能或不会再打高尔夫球了。:P


3
第一个字节是最困难的步骤... 1000字节的开头以一位开始...
Conor O'Brien

8

Brainfuck,391个字节

我知道这可以进一步解决,但是在这一点上,我很高兴它能起作用。我将继续努力打下去。

+++++[-<+++[-<+++<++++++<+++++++<++<++++++++>>>>>]<<+<+<<+<++>>>>>>>]<<<<+<++<->>>>>>,<,>>++++++[<--------<-------->>-]<<->>+<<[>>-<<[>>>+<<<-]]>>>[<<<+>>>-]<[<->>>+<<<[>>>-<<<[>>>>+<<<<-]]>>>>[<<<<+>>>>-]<[<<<<<<<.[-].]<<<+>-]<<+>[->++>+<<]>+++[-<<<<.>>>>]>[-<<+>>]<<<<<<<<<.>>>>>>><[->[->+>+<<]<<<<<<.>>>>>>>[<<<<<<.>.>>>>>-]>[-<<+>>]<<<<<<<.<.<.>>>>>>]>[->++>+<<]>+++[-<<<.>>>]>[-<<+>>]<<

输入仅需输入两位数。照做(8, 2)您只需输入即可82

在线尝试!

分解:

首先将必要的字符放入磁带中: (newline)| o_-

+++++[-<+++[-<+++<++++++<+++++++<++<++++++++>>>>>]<<+<+<<+<++>>>>>>>]<<<<+<++<->>>>>

然后将输入收集到两个单元格中,并从每个单元格中减去48(以获取数字值而不是数字字符)

>,<,>>++++++[<--------<-------->>-]<<

接下来,检查的特殊情况(1, 1)(请注意,仅此检查就占了109个字节的代码)。似乎ifs不够难做,我们有一个嵌套的if

->>+<<[>>-<<[>>>+<<<-]]>>>[<<<+>>>-]<[<->>>+<<<[>>>-<<<[>>>>+<<<<-]]>>>>[<<<<+>>>>-]<[<<<<<<<.[-].]<<<+>-]<<+

以下是检查单元格x是零还是非零的结构:

temp0[-]+
temp1[-]
x[
 code1
 temp0-
 x[temp1+x-]
]
temp1[x+temp1-]
temp0[
 code2
temp0-]

但是,在嵌套中if,我们需要有4个临时单元格。

现在我们开始实际打印字符:

打印顶部栏和换行符:

>[->++>+<<]>+++[-<<<<.>>>>]>[-<<+>>]<<<<<<<<<.>>>>>>>

打印一个|,一行o,另一|行和一个换行符,其次数等于高度:

<[->[->+>+<<]<<<<<<.>>>>>>>[<<<<<<.>.>>>>>-]>[-<<+>>]<<<<<<<.<.<.>>>>>>] 

并打印底部栏(此处无需换行):

>[->++>+<<]>+++[-<<<.>>>]>[-<<+>>]<<

7

视网膜,52字节

字节数假定为ISO 8859-1编码。注意第六行应该包含一个空格。

\G1?
$_¶
1* 



.+
|$&|
\G.
_
r`.\G
-
s`^.{17}$|1
o

在线尝试!

输入为一进制,使用1一进制数字,空格作为分隔符,高度和宽度。

说明

该程序中的所有阶段都是裸替换,有时使用常规的regex修饰符(没有重复或循环,没有其他类型的阶段)。除了换行的常用别名外,它甚至不使用视网膜特定的替换功能。

\G1?
$_¶

这样做的目的是“相乘”两个输入。我们的目标是创建各h+2包含w 1s的行(h+2以便我们可以将top和bottom变成_and -以后)。该\G锚需要比赛开始,其中最后一个离开的。也就是说,如果我们无法匹配字符串中的字符,则其他字符也将不匹配。我们使用它只匹配1in中的h,但不匹配in ,w因为正则表达式不允许匹配分隔它们的空格。但是,我们也将其1设为可选,以便在的末尾获得另一个空匹配项h。那是h+1比赛。其中的每一个都由整个输入($_)和换行符代替。w本身保持不变,这给了我们h+2nd副本。假设输入为11 1111,那么我们现在得到:

11 1111
11 1111
11 1111
 1111

很好 我们还有一些额外的东西,但是有h+2副本w

1* 

请注意,第一行的末尾有一个空格。这将从行中删除这些前缀,因此w之后只有s。



嗯,这实际上不适用于SE的格式...第一行为空,第二行应包含一个空格。这会将空格插入每个可能的位置,即在每行的开头和结尾以及每对1s 之间:

 1 1 1 1 
 1 1 1 1 
 1 1 1 1 
 1 1 1 1 

我们将会把这些变成o后来小号

.+
|$&|

这只是将每一行都包装在一对中|

| 1 1 1 1 |
| 1 1 1 1 |
| 1 1 1 1 |
| 1 1 1 1 |

现在,我们照顾顶部和底部:

\G.
_

是时候\G再次发光了。这与第一行中的每个字符匹配,并将其转换为_

r`.\G
-

同样,但由于使用了r修饰符(从右到左模式),它与最后一行上的字符匹配并将其转换为-。现在我们有了:

___________
| 1 1 1 1 |
| 1 1 1 1 |
-----------

现在只剩下两件事了:将它们1变成os,然后如果将输入1 1变成整个东西o。我们可以在一个阶段中处理这两个问题:

s`^.{17}$|1
o

s是常规的单行模式(即,它使.匹配的换行符)。如果输入的是1 1结果,则最小长度为17个字符,因此我们可以将其与匹配,^.{17}$并替换为o。否则,如果失败,我们将匹配所有1s并替换为它们o


7

Jolf,36个字节

?w*jJρΡ,a+3ώj+2J'-"-+"d*'_lH"  ' o'o
?w*jJ                             'o   return "o" if j * J - 1
       ,a                              make a box
         +3ώj                           of width +3ώj = 3+2*j
             +2J                        of height +2J = 2+J
                '-                      specifying corners as "-"
      Ρ           "-+"                 replacing the first run of "-"s
                      d*'_lH            with a run of "_"s of equal length
     ρ                      "  '       replacing all "  "
                               ' o      with " o"

Jolf,24字节,无竞争

好吧,我内置了一个更好的盒子。

?w*jJ,AhώjJ"_-'_-'|' o'o

Jolf,38 37字节

?w*jJΆ+*'_γ+3ώjS*JΆ'|*j" o' |
"*'-γ'o

简单的东西,真的。当两个参数均为1时,请注意(数学zeta或标准偏差)仅保存0,否则为false(对于我们的情况),从而节省了一个字节。


6

05AB1E,33个字节

码:

*i'oë¹·3+©'_׶²F'|„ o¹×„ |¶}®'-×J

说明:

*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.

使用CP-1252编码。在线尝试!


6

JavaScript(ES6),89 86字节

(x,y,g=c=>c[r=`repeat`](x*2+3))=>x*y-1?g(`_`)+`
`+`| ${`o `[r](x)}|
`[r](y)+g(`-`):`o`

编辑:由于@Shaggy,节省了3个字节。


通过别名节省3个字节repeat
毛茸茸的

5

Python 2,71个字节

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

1
欢迎来到PPCG!不错的第一篇文章!
Rɪᴋᴇʀ

5

Befunge,144字节

我本来希望对这篇文章发表评论,但我还没有声誉,所以我要提出自己的答案,其工作方式类似,但结构紧凑

&::&*:1`v
v3*2:\/\_"o",@
>+:  v   >52*," |",, v
>,1-:vLEG O MAKERv::\<
^"_" _$\:|<v "o "_v
v52:+3*2$<,>,,1-:^$
>*,v <    ^"|":-1\<
v-1_@,
>:"-"^

你可以在这里测试代码


4

Reng v.4,82字节,无竞争

我推送了一个错误修复程序,该程序修复了自己覆盖的功能(请不要问;我的东西出没了)

i#wi#hhw+2e1+ø ~*x}o:{"-"ö<
"_"{:o}w2*3+#xx*2ø
"o"o~
ö"|"o"o"{Wo:o}w*"| "ooh1-?^#h

将输入作为带空格的数字输入,例如4 2在这里尝试!


8
I pushed a bug fix that fixes functions being overwritten by themselves......嗯,这是一个有趣的错误有
MKII

4

PowerShell v2 +,76个字节

param($x,$y)if($x+$y-2){"_"*($z=$x*2+3);"|$(" o"*$x) |`n"*$y+'-'*$z;exit}"o"

接受输入,然后检查一条if语句。因为非零值truthy PowerShell中,所以只要至少一个$x$y不相等1时,if将为真。

在中if,有一系列字符串乘法。首先,我们构造下划线字符串,$z以备后用。那被放置在管道上。接下来,我们构造边和弦的字符串(将弦钉乘以$x),完成$y时间,并将其与破折号$z时间连接起来。然后将该字符串放在管道上,然后我们exit。刷新管道,并隐式打印。请注意,由于.ToString()数组输出的默认分隔符为`n(并且我们正在输出字符串数组),因此我们免费获得了下划线和第一行钉之间的换行符。

如果iffalse为false,则表示处于特殊1 1情况,因此我们将"o"其自身放置在管道上并退出,并再次进行隐式打印。

例子

PS C:\Tools\Scripts\golfing> .\print-a-lego-piece.ps1 1 1
o

PS C:\Tools\Scripts\golfing> .\print-a-lego-piece.ps1 5 3
_____________
| o o o o o |
| o o o o o |
| o o o o o |
-------------

4

击,186163156148131,130个字节

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

注意:如果您确实需要乐高玩具在最后一行加上连字符,请将最后一个printf更改为

printf -- -%.0s `seq -1 $1`

并添加两个字节。


2
如果没有将其包装在函数中,这会不会短很多?另外,我不是bash方面的专家,但看起来好像有一些多余的空格。
DJMcMayhem

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

1
如果使用(),则不需要关键字function来声明函数。有一种for使用花括号的替代语法,例如:for((j=$1;j--;));{ printf o;}。如前面的示例所示,您可以通过减少和测试for的第二个表达式来保存一些字符。您可以使用反引号代替$(cmd)
ninjalj 2016年

@ninjalj谢谢,我是打高尔夫球的新手,它压缩了〜17个字节,现在是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;}

在算术上下文中,美元符号是可选的,因此您可以通过更改(($something))为$来剃除更多的字节((something))。($1仍然需要美元符号将其从字面意义上消除歧义1。)
点钟

4

Perl 5-84 77字节

84字节

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

77个字节。在Dom Hastings的帮助下

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

首先,我对为什么有人会去尝试warn在高尔夫计划中使用感到困惑,但后来我意识到您正在使用它,因为它的长度比短print。真好!
配管

是的,我认为在Perl 6中,您可以使用say代替警告来
删除

1
您也可以在Perl 5中做到这一点,只是默认情况下未启用它。我认为您可以通过在命令行中使用-E而不是-e启用所有扩展名来调用脚本来解决此问题。我是这个地方的新手,所以我不知道确切在哪里指定如何计算分数。
配管

哦,真的,我不知道。我也是新来的,所以我也不确定
Kaundur

我认为您可以将其缩短到76个字节...如果您使用的是函数,我认为返回字符串是可以接受的(请参阅JS答案,为您节省4个字节warn),则不需要在引号周围"o"(可以在另一个-2处使用一个裸字,如果您内联计算,$w则应保存另一个字节('_'x($w=3+2*$x)vs. $w=3+2*$x;... '_'x$w),最后,您可以将\n字面换行符更改为。希望有帮助!
Dom Hastings

3

C,202个 191字节

#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();}

感谢@Lince Assassino 节省了11个字节!

取消高尔夫:

#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();
}

1
您可以将第一行更改为p(char*A){printf(A);}
Lince Assassino

1
真的很感谢你!但是可以通过#define p printf
Marco Marco

3

肉桂胶,32个字节

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..."_.}.

不竞争。在线尝试。输入的格式必须完全正确,[width,height]逗号和高度之间不得有空格。

说明

字符串解压缩为此:

l[1,1]&o;?&`p___~__~
%| ~o ~|
%---~--~

第一l级映射[1,1]o(特殊情况),其他所有内容映射到字符串

`p___~__~
%| ~o ~|
%---~--~

然后,反引号表示第二阶段的开始;CG不会输出该字符串,而是截去反引号并执行该字符串。的p然后,模式将在波浪号第一个参数(宽度)内重复所有字符,然后在第二个参数(高度)内重复百分号内所有字符。因此[4,2]变成这样:

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

然后变成:

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

3

批处理,172170字节

@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=--%

编辑:由于节省了2个字节 @CᴏɴᴏʀO'Bʀɪᴇɴ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ而。

如果可以假设启用了延迟扩展,则可以节省7个字节。


%%o%%代替%o%
暴民埃里克

@EʀɪᴋᴛʜᴇGᴏʟғᴇʀ每次%o%都会替换为原始值o,因此o只会相等" o"%%o%%通过作为callof 的参数%o%,然后使用的当前值o
尼尔

你为什么不...只是do set o=%o% o
暴民埃里克

@EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o%for解析循环之前被扩展,因此循环读取for /l %i in (1,1,8) do call set o= o显然毫无意义。
尼尔

那你为什么不do set o=%%o%% o(-5)?
暴民埃里克'16

3

Vim,56击键

这似乎是一个文本编辑任务,因此Vim是显而易见的选择!我将输入作为带有两个以空格分隔的整数的文本文件,并将答案输出到同一文件中。另外,我也讨厌您使用1x1特例...无论如何:

"adt l"bDro:if@a*@b==1|wq|en<cr>Di| |<esc>@aio <esc>yy@bPVr_GpVr-ZZ

如果没有特殊情况,则需要进行35次击键

"adt x"bDi| |<esc>@aio <esc>yy@bPVr_GpVr-ZZ

对理智的人的细分:

"adt l"bD

将缓冲区中的数字删除到@a和@b中(保留空格)

         ro:if@a*@b==1|wq|en<cr>

用“ o”代替空格,如果有特殊情况,请保存并退出

                                Di| |<esc>

清除线条并书写lego块的边缘

                                          @aio <esc>

插入@a大量的“ o”以获得中间部分

                                                    yy@bP

插入行并制作@b额外副本(一个太多)

                                                         Vr_

我们在缓冲区的顶部,用下划线替换多余的行

                                                            Gp

跳到缓冲区底部,拉出我们先前拉出的线

                                                              Vr-ZZ

用破折号替换行,保存并退出



2

Haskell,76个字节

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

用法示例: 3 # 2为您提供3乘2砖的多行字符串。

取消高尔夫:

(#) :: 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

乍看之下,似乎应该用来缩短unlines,但事实并非如此。
ballesta25

2

Groovy, 1079870,64

{x,y->t=x*2+3;x<2&&y<2?"o":'_'*t+"\n"+"|${' o'*x} |\n"*y+'-'*t}

测试:

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

2

Befunge,114 113 108 101字节

我知道已经有许多Befunge解决方案,但是我相当确定可以通过采用不同的代码布局方法来加以改进。我怀疑这个答案也可以进一步推广,但是它已经比以前的任何一个都小了一点。

&::&+:2`^|,+55_"_",^
-4:,,"| "<\_|#:+1\,,"|"+55$_2#$-#$" o",#!,#:<
  ,"-"_@#:-1<
 :*2+2\-_"o",@v!:-1<

在线尝试!


您能解释为什么:<|需要字符串吗?
扎卡里

@Zacharý第一行的垂直分支实际上从未分支。此时栈顶始终为零,因此这是将栈顶放下并同时分支的捷径-本质上是此技巧
詹姆斯·霍尔德尼斯

1

APL,46个字节

{⍵≡1 1:'o'⋄'-'⍪⍨'_'⍪'|',' ','|',⍨'o '⍴⍨1 2×⌽⍵}

守卫: ⍵≡1 1:'o'特殊情况。否则'o '⍴⍨1 2×⌽⍵构建内容。剩下的只是拳击。


1

C#,198个字节

void f(int x,int y){int l=x*2+3;Console.Write(y==x&&x==1?"o":s("_",l)+"\n"+s("|"+s(" o",x)+" |\n",y)+s("-",l));}string s(string m,int u){return string.Join("",new string[u].Select(n=>m).ToArray());}

又快又脏

我必须编写一个将字符串相乘的函数

松散(建议)

public static void f(int x,int y)
{
    int l=x*2+3;
    Console.Write(y == x && x == 1 ? "o" : s("_",l)+"\n"+ s("|" + s(" o", x) + " |\n", y) + s("-",l));

}
public static string s(string m,int u)
{
    return string.Join("", new string[u].Select(n => m).ToArray());
}

我注意到您的s函数可以优化为string s(string m,int u){return string.Join("",new int[u].Select(n => m));}-.ToArray()是多余的,而string []可能也是int []。:但不是你的string.join可以使用聚合string s(string m, int u){return new int[u].Aggregate("",(t,i)=>t+m);}
奥利弗·哈勒姆

1
您可以像这样剃掉一些字节...(191)void f(int x,int y){Func<char,int,string>s=(c,i)=>new string(c,i);int l=x*2+3;Console.Write((y&x)==1?"o":s('_',l)+"\n"+s('y',y).Replace("y","| "+s('x', x)+"|\n").Replace("x","o ")+s('-',l));}
Matthew Whited

1

八度,97 95 86字节

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

我在Python中使用@atlasologist的方法进行测试(1, 1)(...,'o')[x<2>y]

感谢@Luis Mendo节省了7个字节:a=ones(1,w*2+3)*'_'a=~(1:w*2+3)+95a./a*'-'~a+45

感谢@pajonk节省了2个字节:f=


1
这不是有效的Matlab代码。您应仅将标签标记为“八度”。另外,a./a*'-'您可以使用代替~~a*'-'吗?甚至~a+45
Luis Mendo

另外,可能您可以将其保留为匿名函数(不带f=
pajonk
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.