Imprimir uma peça de Lego

48

Este desafio é um simples um. Dadas duas entradas, descrevendo a altura e a largura de uma peça de Lego, você imprime uma representação de arte ASCII.

Aqui está como as peças de Lego devem ficar:

(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

Se você não pode distinguir dos casos de teste, as width*2+3partes superior e inferior são sublinhados e traços, e cada linha tem tubos para os lados, osão para as pequenas coisas e tudo é separado por espaços.

A única exceção para isso é (1, 1), que é apenas uma única o.

Você nunca obterá 0nenhuma das dimensões.

Isso é , então o código mais curto em bytes vence!

Maltysen
fonte
2
É possível que a largura ou a altura sejam maiores que 10? Que faixa devemos apoiar?
DJMcMayhem
29
O caso especial é realmente uma chatice.
Conor O'Brien
47
Nos próximos anos, quero ver outro desafio "Imprimir uma peça de Lego" que exija a escrita do código para dizer a uma impressora 3D que produza um Lego.
Kevin - Restabelece Monica
8
Espere, "qualquer intervalo de números inteiros que seu idioma suportar"? Não é assim que a LEGO funciona. Os tijolos estão disponíveis apenas em várias dimensões muito específicas. Mesmo se você adicionar pratos, você terá apenas mais alguns. Qualquer script que não descarte entradas como (1,7) ou (5,3) é lixo completo.
RegDwight
3
Por que a peça única (1,1) não tem lados? Há uma verdadeira peça de Lego com um único mamilo em cima de um cubo.
tcrosley

Respostas:

53

Anterior , 165 227 bytes

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

Não há tanto espaço em branco como antes, mas ainda existem lacunas. O princípio é o mesmo da solução anterior, mas o layout é diferente. Desta vez, para verificar se os dois números são 1, estou apenas pegando o produto e vendo se o resultado é maior que 1.


Solução antiga (227 bytes)

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

Pode ser possível jogar mais. Basta olhar para todo esse espaço em branco!

Aqui está minha pobre tentativa de explicação no formulário de imagem do MSPaint: O Como Befunge código flui na direção da seta.


fonte
2
ah meu. Deus. Blows my mind
lukas.pukenis
25

V , 43, 40, 38 36 bytes

Uma das respostas V mais longas que eu já escrevi ...

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

Experimente online!

Como ele contém caracteres unicode e não imprimíveis, eis um hexdump reversível:

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_

Esse desafio é manipular o texto, perfeito para o V! Por outro lado, V é terrível em condicionais e matemática, então a saída diferente para (1, 1) realmente estragou tudo ... :(

Explicação:

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

Agora temos linhas 'O' de altura com espaços entre elas.

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

Versão não concorrente (31 bytes):

Experimente online!

Esta versão usa vários recursos que são mais novos, então esse desafio é 5 bytes mais curto!

Segunda explicação:

ddÀP

que é "Excluir linha e cole-a n vezes" é substituído por ÀÄ"Repita esta linha n vezes". (-2 bytes)

óo î½o
u

que foi "Substitua a primeira correspondência deste regex; Desfazer" foi substituído por

/o î½o

Que é apenas "Procurar uma correspondência com esta expressão regular" (-1 byte)

E, por último, Òé apenas um sinônimo simples para Vr, que ambos "Substitua todos os caracteres nesta linha por 'x'". (-2 bytes)

DJMcMayhem
fonte
como é que parece quebrado na parte inferior com este v.tryitonline.net/...
metersk
2
@meepl Eu realmente não tenho ideia. Funciona em 50x959, mas se você aumentar a largura ou a altura, ele parará de funcionar. Acho que é mais provável que uma restrição seja intencional no site para impedir a execução de programas extremamente grandes.
DJMcMayhem
11
O TIO limita a saída a 100 KB , principalmente para impedir que o front-end trate seu navegador.
Dennis
22

32 código de máquina x86 little-endian de 16 bits, 57 54 51 bytes

3 bytes a menos graças ao @ninjalj.

Reescreveu fortemente o código e conseguiu remover outros 3 bytes

Em hexadecimal

FCBA6F208D48FFE20492AAEB2389D941D1E14151B05FF3AAEB0BB87C20AB89D992F3AB92AAB00AAA4E7DEF59B02DF3AA91AAC3

Entrada: BX = largura, SI = altura, DI aponta para o buffer que recebe o resultado como uma sequência terminada em NULL com linhas separadas por "\ n"

Desmontagem:

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
meden
fonte
Seria menor como 16 bits: -3 bytes para 3 prefixos de 66 h, +1 byte para finalização de linha "\ r \ n".
Ninjalj 4/16
Você deve colocar espaços entre os números cruzados e os números atuais na sua contagem de bytes, para facilitar a leitura.
Value Ink
20

Python 2, 75 73 72 bytes

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

Retorna uma string, com uma condição para manipular o bloco 1,1.

Obrigado a Lynn e Chepner por dois bytes

atlasologist
fonte
lambda x,y:('_'*x*2+'___\n'+etc. salva um byte.
Lynn
11
Bata outro byte com em x*'__'vez de 2*x*'_'.
Chepner
Apenas entre nesta comunidade, desculpe por perguntar. Como posso vê-lo funcionar? colo no terminal e apenas imprimo <function <lambda> at 0x......>. Como posso testar isso?
Miguel
11
@ Miguel atribui-o a uma variável. Ele retornará o valor da função:f=lambda x:x+1; print(f(9))
atlasologist
Mais uma pergunta, se não for complicado de responder. Como você pode rastrear os bits com tanta precisão?
Miguel
13

CJam, 34

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

Experimente online

Explicaçã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
aditsu
fonte
11

Ruby, 59 56 bytes

Função anônima, retorna uma sequência de linhas múltiplas. Experimente online!

-3 bytes graças a um truque emprestado de @ El'endiaStarman

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

Java, 318 312 297 294 260 258 bytes

Economizou 15 bytes graças ao 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);}}

Funciona com argumentos de linha de comando.

Ungolfed De uma forma legível por humanos:

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

Sim, ainda é difícil entender o que está acontecendo, mesmo quando o programa está sendo destruído. Então, aqui vai uma explicação passo a passo:

static void main(String[] A)

Os dois primeiros argumentos da linha de comando - que usaremos para obter dimensões - podem ser usados ​​no programa como A[0]e A[1](respectivamente).

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

bé o número de colunas, Bé o número de linhas e Cé uma variável dedicada para uso em forloops.

cé a peça de Lego. Vamos anexar linhas a ele e depois imprimi-lo no final.

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

Se a peça a ser impressa for 1x1, ambas b(número de colunas) e B(número de linhas) devem ser menores que 2. Portanto, definimos ccomo uma única oe, em seguida, pularemos para a declaração que System.out.printé a peça, se for o caso.

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

Aqui, anexamos (integerValueOfA[0] * 2) + 3sublinhados a c. Esta é a linha superior, acima de todos os orifícios.

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

Este é o loop em que construímos a peça uma linha por vez. O que está acontecendo lá dentro é impossível de explicar sem exemplos. Digamos que a peça seja 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 += "-";

Aqui, anexamos (integerValueOfA[0] * 2) + 3hífens à peça. Esta é a linha na parte inferior, abaixo de todos os buracos.

A peça 4x4 que eu usei para explicar o forloop em que a peça é realmente construída agora fica assim:

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

E, finalmente, imprimimos a peça!

dorukayhan quer Monica de volta
fonte
Provavelmente, a revisão 3 tornou esse o post mais longo que já fiz no Stack Exchange.
dorukayhan quer Monica de volta
2
Você pode mover a Cvariável dos forloops int b=Byte.valueOf(A[0]),B=Byte.valueOf(A[1]),C. Em todos os seus loops também parece que você pode usar C-->0;cheques, torna 298, pastebin.com/uj42JueL
cliffroot
11
algum uso criativo de forlaços para alguns bytes salvos - pastebin.com/dhNCpi6n
cliffroot
11
se você converter seus argumentos para bytes primeiro, depois o cheque é o tamanho de tijolo é 1x1 será if(b==1&B==1)que lhe permite poupar mais de 20 bytes
user902383
também para o caso 1x1, ao invés disso System.out.print('o');return;, você pode definir c='o'e colocar a lógica para diferentes tijolos no outro bloco. em seguida, ter declaração de impressão única e sem retorno permitem salvar alguns bytes adicionais
user902383
9

Minkolang 0.15 , 58 57 56 bytes

Sim está certo. I golfed off um dois stinkin pequenos bytes ...

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

Experimente aqui!

Explicaçã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.

Ok, são duas reescritas significativas da explicação para dois bytes salvos. Eu não acho que posso ou vou jogar algo mais fora deste. : P

El'endia Starman
fonte
3
O primeiro byte é o passo mais difícil ... o início de 1000 bytes começa com um único bit ...
Conor O'Brien
8

brainfuck, 391 bytes

Eu sei que isso pode ser mais desvalorizado, mas neste momento estou feliz que funcione. Continuarei a trabalhar para melhorar.

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

A entrada precisa ser fornecida com apenas dois dígitos. Como fazer (8, 2), basta entrar 82.

Experimente online!

Demolir:

Primeiro, coloque os caracteres necessários na fita: (newline)| o_-

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

Em seguida, colete a entrada em duas células e subtraia 48 de cada uma (para obter o valor numérico e não o caractere numérico)

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

Em seguida, verifique o caso especial de (1, 1)(Observe que apenas essa verificação representa 109 bytes do código). Como se ifs não fossem difíceis o suficiente para fazer no cérebro, temos um aninhado if:

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

A seguir está a estrutura para verificar se uma célula x é zero ou diferente de zero:

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

No entanto, em um aninhado if, precisamos ter 4 células temporárias.

Agora chegamos à impressão real de caracteres:

Imprima a barra superior e uma nova linha:

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

Imprima a |, uma linha de o, outra |e uma nova linha várias vezes igual à altura:

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

E imprima a barra inferior (nenhuma nova linha é necessária aqui):

>[->++>+<<]>+++[-<<<.>>>]>[-<<+>>]<<
Gato de negócios
fonte
7

Retina , 52 bytes

A contagem de bytes assume a codificação ISO 8859-1. Observe que a sexta linha deve conter um único espaço.

\G1?
$_¶
1* 



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

Experimente online!

A entrada é unária, usando 1como dígito unário, o espaço como separador e a altura seguidos pela largura.

Explicação

Todos os estágios deste programa são substituições simples, ocasionalmente com um modificador regular de regex (sem repetição ou loops, sem outros tipos de estágios). Ele nem usa recursos de substituição específicos da Retina, além do alias usual para feeds de linha.

\G1?
$_¶

O objetivo disso é "multiplicar" as duas entradas. Nosso objetivo é criar h+2linhas com w 1s cada ( h+2para que possamos transformar a parte superior e inferior em _e -mais tarde). A \Gâncora requer que a partida comece de onde a última parou. Ou seja, se alguma vez falharmos em corresponder a um caractere na string, outros caracteres também não corresponderão. Usamos isso para corresponder apenas aos 1s h, mas não wporque o regex não permite que o espaço que os separa seja correspondido. No entanto, também fazemos o 1opcional, para que possamos obter uma correspondência vazia adicional no final de h. Isso é h+1correspondências. Cada um desses é substituído por toda a entrada ( $_) seguida por um avanço de linha.wpermanece intocado, o que nos dá a h+2nd cópia. Digamos que a entrada foi 11 1111, então agora temos:

11 1111
11 1111
11 1111
 1111

Isso é muito bom. Temos algumas coisas extras, mas as h+2cópias westão lá.

1* 

Observe que há um espaço no final da primeira linha. Isso remove esses prefixos das linhas para que só tenhamos os ws depois.



Ah, bem, isso realmente não funciona com a formatação do SE ... a primeira linha está vazia e a segunda linha deve conter um único espaço. Isso insere espaços em todas as posições possíveis, ou seja, no início e no final de cada linha e entre cada par de 1s:

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

Vamos transformá-los em os mais tarde

.+
|$&|

Isso simplesmente envolve todas as linhas em um par de |:

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

Agora cuidamos da parte superior e inferior:

\G.
_

Hora de \Gbrilhar novamente. Isso corresponde a cada caractere na primeira linha e o transforma em um _.

r`.\G
-

A mesma coisa, mas devido ao rmodificador (modo da direita para a esquerda), isso corresponde aos caracteres na última linha e os transforma em -. Então agora temos:

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

Há apenas duas coisas a fazer agora: transformá-las 1em os e, se a entrada foi, 1 1então, transformar a coisa toda em ovez disso. Podemos lidar com ambos com um único estágio:

s`^.{17}$|1
o

sé o modo de linha única regular (ou seja, faz .corresponder os feeds de linha). Se a entrada foi 1 1o resultado, terá o tamanho mínimo de 17 caracteres para que possamos correspondê-la ^.{17}$e substituí-la por o. Caso contrário, se isso falhar, apenas corresponderemos a todos os se 1substituiremos por eles o.

Martin Ender
fonte
7

Jolf, 36 bytes

?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 bytes, não-competitivo

Bem, eu fiz uma caixa melhor embutida.

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

Jolf, 38 37 bytes

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

Coisas simples, realmente. Salvou um byte ao observar que (zeta matemática ou desvio de posição) é apenas 0 quando ambos os argumentos são 1 e, caso contrário, é falsey (no nosso caso).

Conor O'Brien
fonte
6

05AB1E , 33 bytes

Código:

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

Explicação:

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

Usa a codificação CP-1252 . Experimente online! .

Adnan
fonte
6

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`

Editar: salvou 3 bytes graças a @Shaggy.

Neil
fonte
Salve 3 bytes usando o alias repeat.
Shaggy
5

Python 2, 71 bytes

lambda x,y:('o',x*'__'+'___\n'+'| %s|\n'%('o '*x)*y+'-'*(x*2+3))[x+y>2]
Lulhum
fonte
11
Bem-vindo ao PPCG! Bom primeiro post!
Rɪᴋᴇʀ
5

Befunge, 144 bytes

Eu preferiria comentar este post, mas ainda não tenho reputação, por isso estou colocando uma resposta própria, que funciona de maneira semelhante, mas é um pouco mais compacta

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

você pode testar o código aqui

Maliafo
fonte
4

Reng v.4, 82 bytes, não-competitivo

Apertei uma correção de bug que corrige funções sendo substituídas por elas mesmas (por favor, não pergunte; minhas coisas estão assombradas)

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

Recebe entrada como números unidos por espaço, como 4 2. Experimente aqui!

Conor O'Brien
fonte
8
I pushed a bug fix that fixes functions being overwritten by themselves... Bem, isso é um bug interessante ter
MKII
4

PowerShell v2 +, 76 bytes

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

Recebe entrada e depois verifica uma ifdeclaração. Como valores diferentes de zero são verdadeiros no PowerShell, desde que pelo menos um deles $xe $ynão seja igual a 1, ifisso será verdadeiro.

Dentro do if, há uma série de multiplicações de strings. Primeiro, construímos nossa série de sublinhados, economizando $zpara mais tarde. Isso é colocado no pipeline. Em seguida, construímos nossa série de lados e pinos (com os pinos multiplicados por $x), $ytempos concluídos e concatenamos isso com nossos $ztempos de traços . Essa string é então colocada no pipeline e nós exit. O pipeline está nivelado e a impressão está implícita. Observe que obtemos a nova linha entre os sublinhados e a primeira linha de pegs gratuitamente, uma vez que o .ToString()separador padrão para a saída da matriz é `n(e estamos produzindo uma matriz de strings).

Se iffor falso, estamos no 1 1caso especial , apenas colocamos "o"no pipeline e saímos , com a impressão novamente implícita.

Exemplos

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 |
-------------
AdmBorkBork
fonte
4

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
}

Nota: Se você realmente precisa que o lego tenha hífens para a última linha, altere a última impressãof para

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

e adicione dois bytes.


fonte
2
Isso não seria um pouco menor se não estivesse envolvido em uma função? Além disso, eu não sou especialista em bash, mas parece que ele tem algum espaço em branco extra.
DJMcMayhem
Seria ~ 170 como um 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;}
11
Se você usar (), não precisará da palavra function- chave para declarar uma função. Há uma alternativa forsintaxe utilizando cintas, por exemplo: for((j=$1;j--;));{ printf o;}. Como mostrado no exemplo anterior, você pode salvar alguns caracteres decrementando e testando na forsegunda expressão. Você pode usar backticks em vez de $(cmd).
Ninjalj
@ninjalj Obrigado, eu sou novo para golf código - que aperta outro ~ 17 bytes off, o one-liner é agora 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;}
Os cifrões são opcionais no contexto aritmético, para que você possa raspar mais alguns bytes mudando (($something))para ((something))todo. ( $1Ainda precisa do sinal de dólar para disambiguate-lo do literal 1.)
tripleee
4

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. Com alguma ajuda de Dom Hastings

sub l{($x,$y)=@_;$x*$y<2?o:'_'x($w=3+2*$x).('
| '.'o 'x$x."|")x$y.$/.'-'x$w}
Kaundur
fonte
Primeiro, fiquei confuso sobre o motivo de alguém se esforçar para usar warnem um programa de golfe, mas depois percebi que você o está usando porque é mais curto que print. Agradável!
pipe
Sim, eu acho que em Perl 6, você pode tomar um outro byte off usando digamos, em vez de avisar
Kaundur
11
Você também pode fazer isso no Perl 5, só que não está ativado por padrão. Eu acho que você pode contornar isso no código-golfe chamando seu script na linha de comando com, em -Evez de -e, habilitando todas as extensões. Eu sou novo neste lugar, então não sei exatamente onde é especificado como contar as pontuações.
pipe
Ah, sério, eu não sabia disso. Eu sou novo aqui tão bem como eu sou também não tenho certeza
Kaundur
Eu acho que você pode encurtar isso para 76 bytes ... Se você estiver usando uma função que eu acredito que retornar a string seja aceitável (veja a resposta JS, poupando 4 bytes para warn), você não precisa de aspas "o"(você pode use uma palavra de barra para outro -2); se você inline o cálculo, $wdeve salvar outro byte ( '_'x($w=3+2*$x)vs. $w=3+2*$x;... '_'x$w) e, por último, pode alterar \npara uma nova linha literal. Espero que ajude!
Dom Hastings
3

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

Obrigado a @Lince Assassino por salvar 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();
}
Marco
fonte
11
Você pode mudar a sua primeira linha dep(char*A){printf(A);}
Lince Assassino
11
Realmente obrigado! Mas é possível reduzir com#define p printf
Marco
3

Goma de canela, 32 bytes

0000000: 6c07 d5f5 7a5d 9cdf 5ae6 52ae 4050 0c35  l...z][email protected]
0000010: 18d9 052f 0082 9b42 e7c8 e422 5fe4 7d9f  .../...B..."_.}.

Não concorrente. Experimente online. A entrada deve estar exatamente no formato, [width,height]sem espaço entre a vírgula e a altura.

Explicação

A cadeia de caracteres descompacta para isso:

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

O primeiro lestágio é mapeado [1,1]para o(o caso especial) e todo o resto para a sequência

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

O backtick então sinaliza o início de um segundo estágio; em vez de emitir essa string, o CG corta o backtick e executa a string. O pmodo repete todos os caracteres dentro do primeiro parâmetro das tildes (largura) vezes e depois repete os caracteres dentro dos segundos sinais de porcentagem do segundo parâmetro (altura). Então, [4,2]isso se transforma nisso:

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

e depois para:

___________
| o o o o |
| o o o o |
-----------
um spaghetto
fonte
3

Lote, 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=--%

Editar: salvou 2 bytes graças a @ CᴏɴᴏʀO'Bʀɪᴇɴ @ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ.

Eu posso salvar 7 bytes se eu puder assumir que a expansão atrasada está ativada.

Neil
fonte
%%o%%em vez de %o%?
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o%seria substituído pelo valor original de ocada vez, de modo que osomente seria igual " o". %%o%%passa como um argumento para callde %o%, que então usa o valor atual de o.
Neil
Por que você não ... apenas do set o=%o% o?
Erik the Outgolfer 01/07/16
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o%é expandido antes que o forloop seja analisado, então o loop lê o for /l %i in (1,1,8) do call set o= oque é obviamente inútil.
Neil
Por que você não do set o=%%o%% o(-5)?
Erik the Outgolfer 01/07/16
3

Vim, 56 pressionamentos de tecla

Parece uma tarefa de edição de texto, então o Vim é a escolha óbvia! Pego a entrada como um arquivo de texto com dois números inteiros separados por espaço e produzo a resposta no mesmo arquivo. Além disso, eu te odeio por ter o caso especial 1x1 ... De qualquer forma:

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

e se não houvesse o caso especial, 35 pressionamentos de tecla

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

Um colapso para pessoas sãs:

"adt l"bD

Exclua os números do buffer em @a e @b (caractere de espaço mantido)

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

Substitua o espaço por "o" e, caso especial, salve e saia

                                Di| |<esc>

Limpe a linha e escreva as bordas do bloco lego

                                          @aio <esc>

Insira @ um monte de "o" para obter uma parte intermediária final

                                                    yy@bP

Arranque a linha e faça @b cópias extras (uma a mais)

                                                         Vr_

Estamos no topo do buffer, substitua a linha extra por sublinhados

                                                            Gp

Ir para o fundo do buffer, puxar a linha que puxamos anteriormente

                                                              Vr-ZZ

Substitua a linha por traços, salve e saia

algmyr
fonte
2

Haskell, 76 bytes

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

Exemplo de uso: 3 # 2fornece uma sequência de linhas múltiplas para um bloco de 3 por 2.

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
MarLinn
fonte
À primeira vista, parecia que deveria ser mais curto unlines, mas não é.
amigos estão dizendo sobre ballesta
2

Groovy, 107 , 98 , 70 , 64

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

Testando:

(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 |
-----
Will Lp
fonte
2

Befunge, 114 113 108 101 bytes

Eu sei que já existem várias soluções Befunge, mas eu tinha certeza de que elas poderiam ser aprimoradas adotando uma abordagem diferente para o layout do código. Suspeito que essa resposta também possa ser jogada mais, mas já é um pouco menor do que qualquer uma das entradas anteriores.

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

Experimente online!

James Holderness
fonte
Você pode explicar por que a string :<|é necessária?
Zacharý
@ Zacharý Aquele ramo vertical na primeira linha nunca se ramifica. O topo da pilha é sempre zero nesse ponto, por isso é um atalho para soltar o topo da pilha e ramificar ao mesmo tempo - essencialmente essa dica .
James Holderness 28/11
1

APL, 46 bytes

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

A guarda: ⍵≡1 1:'o'para o caso especial. Caso contrário, 'o '⍴⍨1 2×⌽⍵cria o conteúdo. E o resto é apenas o boxe.

lstefano
fonte
1

C #, 198 bytes

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

rapido e sujo

Eu tive que escrever uma função que multiplica strings

ungolfed (para sugestões)

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());
}
downrep_nation
fonte
Notei que sua função pode ser otimizada para string s(string m,int u){return string.Join("",new int[u].Select(n => m));}- o .ToArray () é redundante e a string [] também pode ser um int []. No entanto, em vez de string.Join você pode usar agregado:string s(string m, int u){return new int[u].Aggregate("",(t,i)=>t+m);}
Oliver Hallam
11
você pode raspar alguns bytes como este ... (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

Oitava, 97 95 86 bytes

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

Eu usei o método @atlasologist em Python para testar (1, 1):(...,'o')[x<2>y]

Agradecemos a @Luis Mendo por salvar 7 bytes:a=ones(1,w*2+3)*'_' para a=~(1:w*2+3)+95e a./a*'-'para~a+45

Obrigado a @pajonk por salvar 2 bytes:f=

Marco
fonte
11
Este código Matlab não é válido. Você deve rotular apenas como "Octave". Além disso, em vez de a./a*'-'você pode usar ~~a*'-'? Ou até ~a+45?
Luis Mendo
Além disso, provavelmente você pode deixá-lo como uma função anônima (sem f=)
Pajonk