Imprime una pieza de Lego

48

Este desafío es un simple . Dadas dos entradas, que describen la altura y el ancho de una pieza de Lego, tiene impresa una representación de arte ASCII de la misma.

Así es como se supone que deben verse las piezas de Lego:

(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

Si no puede distinguir de los casos de prueba, la parte superior e inferior son width*2+3guiones bajos y guiones, y cada fila tiene tuberías para los lados, opara las pequeñas cosas, y todo está separado por espacios.

La única excepción para esto es (1, 1), que es solo una o.

Nunca obtendrás 0ninguna de las dimensiones.

Este es el , por lo que gana el código más corto en bytes .

Maltysen
fuente
2
¿Es posible que el ancho o la altura sea mayor que 10? ¿Qué rango debemos apoyar?
DJMcMayhem
29
El caso especial es un verdadero fastidio.
Conor O'Brien
47
En los próximos años, quiero ver otro desafío de "Imprimir una pieza de Lego" que requiere escribir el código para decirle a una impresora 3D que produzca un Lego.
Kevin - Restablece a Mónica el
8
Espera, "cualquier rango entero que sea compatible con tu idioma"? Así no es como funciona LEGO. Los ladrillos solo están disponibles en un puñado de dimensiones muy específicas. Incluso si agrega platos, solo obtendrá un par más. Cualquier script que no descarte entradas como (1,7) o (5,3) es basura completa.
RegDwight 01 de
3
¿Por qué la pieza individual (1,1) no tiene lados? Hay una pieza real de Lego con un solo pezón encima de un cubo.
tcrosley

Respuestas:

53

Befunge , 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+^
>:    #^_@

No hay tanto espacio en blanco como antes, pero todavía hay lagunas. El principio es el mismo que en la solución anterior, pero el diseño es diferente. Esta vez, para verificar si ambos números son 1, solo estoy tomando su producto y viendo si el resultado es mayor que 1.


Solución anterior (227 bytes)

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

Podría ser posible jugar más al golf. ¡Solo mira todo ese espacio en blanco!

Aquí está mi pobre intento de explicación en forma de imagen de MSPaint: el Cómo Befunge código fluye en la dirección de la flecha.


fuente
2
Oh. mi. Dios. Blows my mind
lukas.pukenis 01 de
25

V , 43, 40, 38 36 bytes

Una de las respuestas V más largas que he escrito ...

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

Pruébalo en línea!

Como esto contiene caracteres unicode y no imprimibles, aquí hay un hexdump reversible:

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_

Este desafío se trata de manipular texto, ¡perfecto para V! Por otro lado, V es terrible en condicionales y matemáticas, por lo que la salida diferente para (1, 1) realmente lo arruinó ... :(

Explicación:

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

Ahora tenemos líneas de 'Altura' de o con espacios entre ellas.

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

Versión no competitiva (31 bytes):

Pruébalo en línea!

¡Esta versión usa varias características que son más nuevas, entonces este desafío es 5 bytes más corto!

Segunda explicación:

ddÀP

que es "Eliminar línea y pegarla n veces" se reemplaza con ÀÄ"Repita esta línea n veces". (-2 bytes)

óo î½o
u

que era "Reemplazar la primera coincidencia de esta expresión regular; Deshacer" se reemplazó con

/o î½o

Que es solo "Buscar una coincidencia de esta expresión regular" (-1 byte)

Y, por último, Òes un simple sinónimo de Vr"Reemplazar todos los caracteres de esta línea con 'x'". (-2 bytes)

DJMcMayhem
fuente
¿cómo es que parece roto en la parte inferior con este v.tryitonline.net/…
metersk
2
@meepl Realmente no tengo idea. Funciona en 50x959 pero si aumenta el ancho o la altura deja de funcionar. Supongo que es muy probable que sea una restricción colocada intencionalmente en el sitio web para evitar que se ejecuten programas extremadamente grandes.
DJMcMayhem
1
TIO limita la salida a 100 KB , principalmente para evitar que el frontend bloquee su navegador.
Dennis
22

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

3 bytes menos gracias a @ninjalj.

Reescribió fuertemente el código y he logrado eliminar otros 3 bytes

En hex

FCBA6F208D48FFE20492AAEB2389D941D1E14151B05FF3AAEB0BB87C20AB89D992F3AB92AAB00AAA4E7DEF59B02DF3AA91AAC3

Entrada: BX = ancho, SI = altura, DI apunta al búfer que recibe el resultado como una cadena terminada en NULL con líneas separadas por "\ n"

Desmontaje

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
fuente
Sería más corto como 16 bits: -3 bytes para 3 prefijos de 66 h, +1 byte para la terminación de línea "\ r \ n".
ninjalj
Debe poner espacios entre los números tachados y los números actuales en su conteo de bytes, para facilitar la lectura.
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]

Devuelve una cadena, con un condicional para manejar el bloque 1,1.

Gracias a Lynn y Chepner por dos bytes.

atlasólogo
fuente
lambda x,y:('_'*x*2+'___\n'+etc. guarda un byte.
Lynn
1
Elimine otro byte con en x*'__'lugar de 2*x*'_'.
chepner
Solo únete a esta comunidad, perdón por preguntar. ¿Cómo puedo verlo funcionar? Lo pego en el terminal y solo imprime <function <lambda> at 0x......>. ¿Cómo puedo probar esto?
Miguel
1
@Miguel lo asigna a una variable. f=lambda x:x+1; print(f(9))
Devolverá
Una pregunta más si no es complicado de responder. ¿Cómo puedes rastrear los bits con tanta precisión?
Miguel
13

CJam, 34

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

Pruébalo en línea

Explicación:

'_        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
fuente
11

Ruby, 59 56 bytes

Función anónima, devuelve una cadena multilínea. Pruébalo en línea!

-3 bytes gracias a pedir prestado un truco de @ El'endiaStarman

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

Java, 318 312 297 294 260 258 bytes

¡ Ahorró 15 bytes gracias a 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 con argumentos de línea de comando.

Ungolfed En una forma legible 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);
    }
}

Sí, aún es difícil entender lo que está sucediendo incluso cuando el programa no está protegido. Así que aquí va una explicación paso a paso:

static void main(String[] A)

Los primeros dos argumentos de la línea de comandos, que usaremos para obtener dimensiones, se pueden usar en el programa como A[0]y A[1](respectivamente).

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

bes el número de columnas, Bes el número de filas y Ces una variable dedicada para su uso en forbucles.

cEs la pieza de Lego. Le agregaremos filas y luego lo imprimiremos al final.

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

Si la pieza que se va a imprimir es 1x1, entonces tanto b(número de columnas) como B(número de filas) deberían ser menores que 2. Por lo tanto, simplemente establecemos cuna sola oy luego saltamos a la declaración que System.out.printes la pieza si ese es el caso.

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

Aquí, agregamos (integerValueOfA[0] * 2) + 3guiones bajos a c. Esta es la fila superior sobre todos los agujeros.

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

Este es el bucle donde construimos la pieza una fila a la vez. Lo que sucede dentro es imposible de explicar sin ejemplos. Digamos que la pieza es 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 += "-";

Aquí, agregamos (integerValueOfA[0] * 2) + 3guiones a la pieza. Esta es la fila en la parte inferior, debajo de todos los agujeros.

La pieza 4x4 que utilicé para explicar el forbucle donde se construye la pieza ahora se ve así:

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

Y finalmente, imprimimos la pieza!

dorukayhan quiere a Monica de vuelta
fuente
Probablemente, la Revisión 3 hizo que esta sea la publicación más larga que he hecho en Stack Exchange.
Dorukayhan quiere que Monica regrese el
2
Puede mover Cvariables desde forbucles int b=Byte.valueOf(A[0]),B=Byte.valueOf(A[1]),C. En todos sus bucles for también parece que puede usar C-->0;cheques, lo hace 298, pastebin.com/uj42JueL
cliffroot
1
algunos usos creativos de forbucles para unos pocos bytes guardados - pastebin.com/dhNCpi6n
cliffroot
1
si convierte sus argumentos a bytes primero, entonces su cheque es tamaño de ladrillo será 1x1 lo if(b==1&B==1)que le permitirá guardar más de 20 bytes
user902383
También para el caso 1x1 en lugar de hacer esto System.out.print('o');return;, podría establecer c='o'y colocar la lógica para diferentes ladrillos en el bloque else. luego, tener una sola declaración de impresión y ninguna devolución le permite guardar algunos bytes adicionales
user902383
9

Minkolang 0.15 , 58 57 56 bytes

Si, eso es correcto. Jugué un poco de dos bytes apestosos ...

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

Pruébalo aquí!

Explicación

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.

Bien, son dos reescrituras significativas de la explicación de dos bytes guardados. No creo que pueda o pueda jugar nada más con este. :PAGS

El'endia Starman
fuente
3
El primer byte es el paso más difícil ... el comienzo de 1000 bytes comienza con un solo bit ...
Conor O'Brien
8

brainfuck, 391 bytes

Sé que esto se puede reducir aún más, pero en este punto me alegro de que funcione. Seguiré trabajando para jugar golf.

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

La entrada debe darse como solo dos dígitos. Como en, para hacer (8, 2)simplemente entrarías 82.

Pruébalo en línea!

Descompostura:

Primero ponga los caracteres necesarios en la cinta: (newline)| o_-

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

Luego, recopile la entrada en dos celdas y reste 48 de cada una (para obtener el valor numérico y no el carácter numérico)

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

Luego, verifique el caso especial de (1, 1)(Tenga en cuenta que solo esta verificación representa 109 bytes del código). Como si ifno fuera lo suficientemente difícil de hacer en brainfuck, tenemos un anidado if:

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

La siguiente es la estructura para verificar si una celda x es cero o no es cero:

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

Sin embargo, en un anidado if, necesitamos tener 4 celdas temporales.

Ahora llegamos a la impresión real de los personajes:

Imprima la barra superior y una nueva línea:

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

Imprima una |, una fila de o's, otra |y una nueva línea varias veces igual a la altura:

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

E imprima la barra inferior (no se necesita nueva línea aquí):

>[->++>+<<]>+++[-<<<.>>>]>[-<<+>>]<<
Gato de negocios
fuente
7

Retina , 52 bytes

El recuento de bytes asume la codificación ISO 8859-1. Tenga en cuenta que se supone que la sexta línea contiene un solo espacio.

\G1?
$_¶
1* 



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

Pruébalo en línea!

La entrada está en unario, utilizando 1como dígito unario, el espacio como separador y la altura seguida del ancho.

Explicación

Todas las etapas en este programa son sustituciones simples, ocasionalmente con un modificador regular de expresiones regulares (sin repetición ni bucles, sin otro tipo de etapas). Ni siquiera utiliza características de sustitución específicas de Retina, aparte del alias habitual para avances de línea.

\G1?
$_¶

El propósito de esto es "multiplicar" las dos entradas. Nuestro objetivo es crear h+2filas con w 1s cada una ( h+2para que podamos convertir la parte superior e inferior en _y -más adelante). El \Gancla requiere que el partido comience donde quedó el último. Es decir, si alguna vez no hacemos coincidir un carácter en la cadena, otros caracteres tampoco coincidirán. Usamos esto para hacer coincidir solo las 1s en h, pero no en wporque la expresión regular no permite que coincida el espacio que las separa. Sin embargo, también hacemos el 1opcional, para que obtengamos una coincidencia vacía adicional al final de h. Eso es h+1partidos. Cada uno de ellos se reemplaza con la entrada completa ( $_) seguida de un salto de línea.wpermanece intacto, lo que nos da la h+2copia nd. Digamos que la entrada fue 11 1111, entonces ahora tenemos:

11 1111
11 1111
11 1111
 1111

Eso es bastante bueno. Tenemos algunas cosas extra, pero las h+2copias westán ahí.

1* 

Tenga en cuenta que hay un espacio al final de la primera línea. Esto elimina esos prefijos de las líneas para que solo tengamos la ws después.



Ah, bueno, eso realmente no funciona con el formato de SE ... la primera línea está vacía y se supone que la segunda línea contiene un solo espacio. Esto inserta espacios en todas las posiciones posibles, es decir, al principio y al final de cada línea y entre cada par de 1s:

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

Los convertiremos en os más tarde

.+
|$&|

Esto simplemente envuelve cada línea en un par de |:

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

Ahora nos encargamos de la parte superior e inferior:

\G.
_

Hora de \Gbrillar de nuevo. Esto coincide con cada personaje en la primera línea y lo convierte en un _.

r`.\G
-

Lo mismo, pero debido al rmodificador (modo de derecha a izquierda), esto coincide con los caracteres en la última línea y los convierte en -. Entonces ahora tenemos:

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

Ahora solo quedan dos cosas por hacer: convertirlas 1en os, y si la entrada fue 1 1entonces, convertir todo en su olugar. Podemos manejar ambos con una sola etapa:

s`^.{17}$|1
o

ses el modo regular de una sola línea (es decir, hace avances de .línea coincidentes). Si la entrada fue 1 1el resultado tendrá el tamaño mínimo de 17 caracteres para que podamos combinarlo ^.{17}$y reemplazarlo por o. De lo contrario, si eso falla, solo haremos coincidir todas las 1sy las reemplazaremos con ellas o.

Martin Ender
fuente
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, sin competencia

Bueno, hice una mejor caja incorporada.

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

Jolf, 38 37 bytes

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

Cosas simples, de verdad. Se guardó un byte al observar que (matemática zeta, o la desviación de soporte) es solo 0 cuando ambos argumentos son 1, y es falso de lo contrario (para nuestro caso).

Conor O'Brien
fuente
6

05AB1E , 33 bytes

Código:

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

Explicación:

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

Utiliza la codificación CP-1252 . Pruébalo en línea! .

Adnan
fuente
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: Guardado 3 bytes gracias a @Shaggy.

Neil
fuente
Ahorre 3 bytes aliasing 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
fuente
1
Bienvenido a PPCG! Bonito primer post!
Rɪᴋᴇʀ
5

Befunge, 144 bytes

Hubiera preferido comentar esta publicación, pero aún no tengo la reputación, así que estoy respondiendo por mi cuenta, que funciona de manera similar, pero es un poco más compacta

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

puedes probar el código aquí

Maliafo
fuente
4

Reng v.4, 82 bytes, sin competencia

Empujé una corrección de errores que corrige las funciones que se sobrescriben por sí mismas (por favor no pregunte; mis cosas están embrujadas)

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

Toma datos como números unidos por espacios, como 4 2. Pruébalo aquí!

Conor O'Brien
fuente
8
I pushed a bug fix that fixes functions being overwritten by themselves... Bueno, ese es un error interesante
MKII
4

PowerShell v2 +, 76 bytes

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

Toma entrada, luego verifica una ifdeclaración. Dado que los valores distintos de cero son verdaderos en PowerShell, siempre que al menos uno de $xy $yno sean iguales 1, ifserá verdadero.

Dentro del if, hay una serie de multiplicaciones de cuerdas. Primero, construimos nuestra cadena de guiones bajos, guardando $zpara más adelante. Eso se coloca en la tubería. A continuación, construimos nuestra cadena de lados y clavijas (con las clavijas multiplicadas por $x), los $ytiempos terminados y los concatenamos con nuestros $ztiempos de guiones . Esa cadena se coloca en la tubería y nosotros exit. La tubería se vacía y la impresión es implícita. Tenga en cuenta que obtenemos la nueva línea entre los guiones bajos y la primera fila de clavijas de forma gratuita, ya que el .ToString()separador predeterminado para la salida de la matriz es `n(y estamos generando una matriz de cadenas).

Si el valor ifes falso, estamos en el 1 1caso especial , por lo que simplemente nos colocamos "o"en la tubería y salimos , con la impresión nuevamente implícita.

Ejemplos

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
fuente
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: Si realmente necesita que el lego tenga guiones para la última línea, cambie la última impresión a

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

y agrega dos bytes.


fuente
2
¿No sería esto un poco más corto si no estuviera envuelto en una función? Además, no soy un experto en bash, pero parece que tiene algo de espacio en blanco adicional.
DJMcMayhem
Sería ~ 170 como una línea:(($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
Si usa (), no necesita la palabra clave functionpara declarar una función. Hay una alternativa forsintaxis el uso de llaves, por ejemplo: for((j=$1;j--;));{ printf o;}. Como se muestra en el ejemplo anterior, puede guardar algunos caracteres disminuyendo y probando en forla segunda expresión de. Puedes usar backticks en lugar de $(cmd).
ninjalj
@ninjalj Gracias, soy nuevo en el código de golf, que elimina otros ~ 17 bytes, el one-liner ahora es 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;}
Los signos de dólar son opcionales en el contexto aritmético, por lo que puede reducir algunos bytes más cambiando (($something))a ((something))todo. ( $1todavía necesita el signo de dólar para desambiguarlo del literal 1).
triplicado
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. Con algo de ayuda de Dom Hastings

sub l{($x,$y)=@_;$x*$y<2?o:'_'x($w=3+2*$x).('
| '.'o 'x$x."|")x$y.$/.'-'x$w}
Kaundur
fuente
Primero estaba confundido acerca de por qué alguien se esforzaría por usarlo warnen un programa de golf, pero luego me di cuenta de que lo está usando porque es más corto que print. ¡Agradable!
tubería
Sí, creo que en Perl 6 puedes quitar otro byte usando decir en lugar de advertir
Kaundur
1
También puede hacerlo en Perl 5, solo que no está habilitado de forma predeterminada. Creo que puede evitar eso en code-golf llamando a su script desde la línea de comandos con, en -Elugar de -e, habilitando todas las extensiones. Soy nuevo en este lugar, así que no sé exactamente dónde se especifica cómo contar las puntuaciones.
pipa
Oh, realmente, no lo sabía. Soy nuevo aquí también, así que tampoco estoy seguro
Kaundur
Creo que puede acortar esto a 76 bytes ... Si está utilizando una función, creo que devolver la cadena es aceptable (vea la respuesta JS, ahorrándole 4 bytes warn), no necesita comillas alrededor del "o"(puede use una palabra desnuda para otro -2), si alinea el cálculo de $wque debe guardar otro byte ( '_'x($w=3+2*$x)vs. $w=3+2*$x;... '_'x$w) y, por último, puede cambiar el \npara una nueva línea literal. ¡Espero que ayude!
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();}

¡Gracias a @Lince Assassino por guardar 11 bytes!

Sin golf:

#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
fuente
1
Puedes cambiar tu primera línea parap(char*A){printf(A);}
Lince Assassino
1
¡De verdad gracias! Pero es posible acortar con#define p printf
Marco
3

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

No competidor Pruébalo en línea. La entrada debe estar exactamente en la forma [width,height]sin espacio entre la coma y la altura.

Explicación

La cadena se descomprime a esto:

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

La primera letapa se asigna [1,1]a o(el caso especial) y todo lo demás a la cadena

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

El backtick luego señala el inicio de una segunda etapa; en lugar de generar esa cadena, CG corta el backtick y ejecuta la cadena. El pmodo luego repite todos los caracteres dentro del primer parámetro (ancho) de tildes veces y luego repite los caracteres dentro de los signos de porcentaje del segundo parámetro (altura) veces. Entonces, para que [4,2]se convierta en esto:

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

y luego en:

___________
| o o o o |
| o o o o |
-----------
un espagueti
fuente
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: Guardado 2 bytes gracias a @ CᴏɴᴏʀO'Bʀɪᴇɴ @ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ.

Puedo ahorrar 7 bytes si puedo asumir que la expansión retrasada está habilitada.

Neil
fuente
%%o%%en lugar de %o%?
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o%se reemplazaría con el valor original de ocada vez, por lo que osolo sería igual " o". %%o%%pasa como un argumento de callof %o%, que luego usa el valor actual de o.
Neil
¿Por qué no ... solo do set o=%o% o?
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o%se expande antes de foranalizar el bucle, por lo que el bucle lee, lo for /l %i in (1,1,8) do call set o= oque obviamente no tiene sentido.
Neil
¿Por qué no do set o=%%o%% oentonces (-5)?
Erik the Outgolfer
3

Vim, 56 pulsaciones de teclas

Esto parece una tarea de edición de texto, ¡así que Vim es la opción obvia! Tomo la entrada como un archivo de texto con dos enteros separados por espacios y envío la respuesta al mismo archivo. Además, te odio por tener el caso especial 1x1 ... De todos modos:

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

y si no hubiera sido por el caso especial, 35 pulsaciones de teclas

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

Un desglose para personas cuerdas:

"adt l"bD

Eliminar números del búfer en @a y @b (espacio guardado)

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

Reemplace el espacio con "o" y si es un caso especial, guarde y salga

                                Di| |<esc>

Despeja la línea y escribe los bordes del bloque lego

                                          @aio <esc>

Inserte @a un montón de "o" para obtener una parte media terminada

                                                    yy@bP

Yankee la línea y haga @b copias adicionales (una demasiado)

                                                         Vr_

Estamos en la parte superior del búfer, reemplaza la línea adicional con guiones bajos

                                                            Gp

Salta al fondo del búfer, tira de la línea que arrancamos antes

                                                              Vr-ZZ

Reemplace la línea con guiones, guarde y salga

algmyr
fuente
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

Ejemplo de uso: 3 # 2le ofrece una cadena multilínea para un ladrillo de 3 por 2.

Sin golf:

(#) :: 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
Marlin
fuente
A primera vista, parecía que debería ser más corto unlines, pero no lo es.
ballesta25
2

Groovy, 107 , 98 , 70 , 64

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

Pruebas:

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

Befunge, 114 113 108 101 bytes

Sé que ya hay una serie de soluciones Befunge, pero estaba bastante seguro de que podrían mejorarse adoptando un enfoque diferente para el diseño del código. Sospecho que esta respuesta también se puede jugar más, pero ya es un poco más pequeña que cualquiera de las entradas anteriores.

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

Pruébalo en línea!

James Holderness
fuente
¿Puedes explicar por qué :<|se necesita la cuerda ?
Zacharý
@ Zacharý Esa rama vertical en la primera línea en realidad nunca se ramifica. La parte superior de la pila siempre es cero en ese punto, por lo que es un atajo para soltar la parte superior de la pila y ramificarla al mismo tiempo, esencialmente este consejo .
James Holderness
1

APL, 46 bytes

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

El guardia: ⍵≡1 1:'o'para el caso especial. De lo contrario, 'o '⍴⍨1 2×⌽⍵construye el contenido. Y el resto es solo el boxeo.

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

rápido y sucio

Tuve que escribir una función que multiplique cadenas

sin golf (para sugerencias)

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
fuente
Noté que la función de su s puede optimizarse para string s(string m,int u){return string.Join("",new int[u].Select(n => m));}: .ToArray () es redundante y la cadena [] también puede ser un int []. Pero en lugar de string.Join puedes usar agregado:string s(string m, int u){return new int[u].Aggregate("",(t,i)=>t+m);}
Oliver Hallam
1
puede afeitarse unos pocos 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

Octava, 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}

He utilizado el @atlasologist método 's en Python para la prueba (1, 1):(...,'o')[x<2>y]

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

Gracias a @pajonk por guardar 2 bytes:f=

Marco
fuente
1
Este no es un código válido de Matlab. Debe etiquetar como "Octave" solamente. Además, en lugar de a./a*'-'¿puedes usar ~~a*'-'? O incluso ~a+45?
Luis Mendo
Además, probablemente pueda dejarlo como una función anónima (sin f=)
pajonk