Cetak sepotong Lego


48

Tantangan ini adalah tantangan sederhana . Diberikan dua input, yang menggambarkan tinggi dan lebar karya Lego, Anda telah mencetak representasi seni ASCII untuknya.

Beginilah tampilan potongan-potongan 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

Jika Anda tidak dapat membedakan dari kotak uji, bagian atas dan bawah adalah width*2+3garis bawah dan garis putus-putus, dan setiap baris memiliki pipa untuk sisi-sisinya, ountuk hal-hal kecil, dan semuanya dipisahkan oleh spasi.

Satu-satunya pengecualian untuk ini adalah (1, 1), yang hanya satu o.

Anda tidak akan pernah mendapatkan 0dimensi apa pun.

Ini adalah , jadi kode terpendek dalam byte menang!


2
Apakah mungkin lebar atau tinggi akan lebih besar dari 10? Kisaran apa yang harus kami dukung?
DJMcMayhem

29
Kasing khusus adalah gelandangan nyata.
Conor O'Brien

47
Dalam beberapa tahun ke depan, saya ingin melihat tantangan "Cetak sepotong Lego" lain yang mengharuskan penulisan kode untuk memberi tahu printer 3D untuk menghasilkan Lego.
Kevin - Kembalikan Monica

8
Tunggu, "rentang integer apa saja yang didukung bahasa Anda"? Itu bukan cara kerja LEGO. Batu bata hanya tersedia dalam beberapa dimensi yang sangat spesifik. Bahkan jika Anda menambahkan piring, Anda hanya mendapatkan pasangan lagi. Setiap skrip yang tidak membuang input seperti (1,7) atau (5,3) adalah sampah lengkap.
RegDwight

3
Mengapa bagian tunggal (1,1) tidak memiliki sisi? Ada potongan Lego nyata dengan puting tunggal di atas sebuah kubus.
tcrosley

Jawaban:


53

Befunge , 165 227 byte

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

Tidak sebanyak spasi putih seperti sebelumnya, tetapi masih ada celah. Prinsipnya sama dengan solusi sebelumnya, tetapi tata letaknya berbeda. Kali ini, untuk memeriksa apakah kedua angka 1, saya hanya mengambil produk mereka dan melihat apakah hasilnya lebih besar dari 1.


Solusi lama (227 byte)

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

Dimungkinkan untuk bermain golf lebih banyak. Lihat saja semua ruang putih itu!

Inilah upaya saya yang buruk pada penjelasan dalam bentuk gambar MSPaint: Bagaimana cara Befunge Kode mengalir ke arah panah.


2
oh saya. Allah. Pukulan pikiran saya
lukas.pukenis

25

V , 43, 40, 38 36 byte

Salah satu jawaban V terpanjang yang pernah saya tulis ...

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

Cobalah online!

Karena ini berisi karakter unicode dan tidak patut dicetak, berikut adalah hexdump yang dapat dibalik:

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_

Tantangan ini adalah tentang memanipulasi teks, sangat sempurna untuk V! Di sisi lain, V buruk dalam kondisi dan matematika, sehingga output yang berbeda untuk (1, 1) benar-benar mengacaukannya ... :(

Penjelasan:

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

Sekarang kita memiliki garis 'Ketinggian' dengan spasi di antaranya.

ñ                   "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 yang tidak bersaing (31 byte):

Cobalah online!

Versi ini menggunakan beberapa fitur yang lebih baru maka tantangan ini menjadi lebih pendek 5 byte!

Penjelasan kedua:

ddÀP

yang merupakan "Hapus baris, dan rekatkan itu n kali" diganti dengan ÀÄyang "Ulangi baris ini n kali". (-2 byte)

óo î½o
u

yang merupakan "Ganti pertandingan pertama regex ini; Undo" diganti dengan

/o î½o

Yang hanya "Cari kecocokan dari regex ini" (-1 byte)

Dan yang terakhir, Òhanyalah sinonim sederhana untuk Vr, yang keduanya "Ganti setiap karakter pada baris ini dengan 'x'". (-2 byte)


kenapa bisa rusak di bagian bawah dengan ini v.tryitonline.net/...
metersk

2
@meepl Saya benar-benar tidak tahu. Ini bekerja pada 50x959 tetapi jika Anda menambah lebar atau tinggi itu berhenti berfungsi. Saya menduga itu kemungkinan besar pembatasan sengaja ditempatkan di situs web untuk mencegah program yang sangat besar dijalankan.
DJMcMayhem

1
TIO membatasi output hingga 100 KB , terutama untuk mencegah frontend dari crash browser Anda.
Dennis

22

32 -bit bit-endian x86 kode mesin, 57 54 51 byte

3 byte lebih sedikit berkat @ninjalj.

Sangat berat menulis ulang kode dan telah berhasil mencukur 3 byte lagi

Dalam hex

FCBA6F208D48FFE20492AAEB2389D941D1E14151B05FF3AAEB0BB87C20AB89D992F3AB92AAB00AAA4E7DEF59B02DF3AA91AAC3

Input: BX = lebar, SI = tinggi, DI menunjuk ke buffer yang menerima hasil sebagai string yang diakhiri NULL dengan garis yang dipisahkan oleh "\ n"

Membongkar:

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

Akan lebih pendek 16-bit: -3 byte untuk 3 awalan 66 jam, +1 byte untuk terminasi baris "\ r \ n".
ninjalj

Anda harus meletakkan spasi di antara angka yang dicoret dan angka saat ini dalam jumlah byte Anda, agar dapat dibaca.
Nilai Tinta

20

Python 2, 75 73 72 byte

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

Mengembalikan string, dengan kondisi untuk menangani blok 1,1.

Terima kasih untuk Lynn dan Chepner untuk dua byte


lambda x,y:('_'*x*2+'___\n'+dll menghemat satu byte.
Lynn

1
Matikan byte lain dengan x*'__'alih - alih 2*x*'_'.
chepner

Bergabung saja dengan Komunitas ini, maaf sudah bertanya. Bagaimana saya bisa melihatnya berjalan? saya menempelkannya di terminal dan hanya mencetak <function <lambda> at 0x......>. Bagaimana saya bisa menguji ini?
Miguel

1
@Miguel menugaskannya ke variabel. Ini akan mengembalikan nilai fungsi:f=lambda x:x+1; print(f(9))
atlasologist

Satu pertanyaan lagi jika tidak rumit untuk dijawab. Bagaimana Anda bisa melacak bit dengan tepat?
Miguel

13

CJam, 34

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

Cobalah online

Penjelasan:

'_        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 byte

Fungsi anonim, mengembalikan string multiline. Cobalah online!

-3 byte berkat meminjam trik dari @ El'endiaStarman

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

11

Java, 318 312 297 294 260 258 byte

Disimpan 15 byte berkat 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);}}

Ini bekerja dengan argumen baris perintah.

Tidak Digubah dalam bentuk yang dapat dibaca manusia:

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

Ya, masih sulit untuk memahami apa yang sedang terjadi bahkan ketika program tidak ungolfed. Jadi begini penjelasan langkah demi langkah:

static void main(String[] A)

Dua argumen baris perintah pertama - yang akan kita gunakan untuk mendapatkan dimensi - dapat digunakan dalam program sebagai A[0]dan A[1](masing-masing).

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

badalah jumlah kolom, Badalah jumlah baris dan Cmerupakan variabel yang didedikasikan untuk digunakan dalam forloop.

cadalah bagian Lego. Kami akan menambahkan baris ke sana dan kemudian mencetaknya di akhir.

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

Jika bagian yang akan dicetak adalah 1x1, maka keduanya b(jumlah kolom) dan B(jumlah baris) harus lebih kecil dari 2. Jadi kita cukup mengatur cuntuk satu odan kemudian melompat ke pernyataan yang System.out.printmerupakan bagian jika itu yang terjadi.

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

Di sini, kami menambahkan (integerValueOfA[0] * 2) + 3garis bawah ke c. Ini adalah baris paling atas di atas semua lubang.

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

Ini adalah lingkaran tempat kita membuat potongan satu demi satu. Apa yang terjadi di dalam tidak mungkin dijelaskan tanpa contoh. Katakanlah potongannya 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 += "-";

Di sini, kami menambahkan (integerValueOfA[0] * 2) + 3tanda hubung ke bagian. Ini adalah baris di bagian paling bawah, di bawah semua lubang.

Sepotong 4x4 yang saya gunakan untuk menjelaskan forloop di mana bagian itu sebenarnya dibangun sekarang terlihat seperti ini:

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

Dan akhirnya, kami mencetaknya!


Mungkin Revisi 3 menjadikan ini pos terpanjang yang pernah saya buat di Stack Exchange.
dorukayhan ingin Monica kembali

2
Anda dapat memindahkan Cvariabel dari forloop int b=Byte.valueOf(A[0]),B=Byte.valueOf(A[1]),C. Dalam semua untuk loop Anda, sepertinya Anda dapat menggunakan C-->0;cek, membuatnya 298, pastebin.com/uj42JueL
cliffroot

1
beberapa penggunaan kreatif dari forloop untuk beberapa byte disimpan - pastebin.com/dhNCpi6n
cliffroot

1
jika Anda mengonversi argumen Anda menjadi byte pertama, maka cek Anda adalah ukuran bata adalah 1x1 akan if(b==1&B==1)memungkinkan Anda untuk menyimpan lebih dari 20 byte
user902383

juga untuk kasus 1x1 alih-alih melakukan ini System.out.print('o');return;, Anda dapat mengatur c='o'dan menempatkan logika untuk batu bata yang berbeda di blok lain. kemudian memiliki satu pernyataan cetak dan tidak ada pengembalian memungkinkan Anda untuk menyimpan beberapa byte tambahan
user902383

9

Minkolang 0,15 , 58 57 56 byte

Ya itu betul. Saya bermain golf satu byte kecil dua bau ...

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

Coba di sini!

Penjelasan

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.

Oke, itu dua penulisan ulang penjelasan yang signifikan untuk dua byte yang disimpan. Saya tidak berpikir saya bisa atau akan golf lebih dari yang ini. : P


3
Byte pertama adalah langkah tersulit ... awal 1000 byte dimulai dengan satu bit ...
Conor O'Brien

8

brainfuck, 391 byte

Saya tahu ini bisa bermain golf lebih banyak, tetapi pada titik ini saya senang itu berfungsi. Saya akan terus bekerja untuk menurunkannya.

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

Input perlu diberikan hanya dua digit. Seperti dalam, untuk melakukan (8, 2)Anda hanya akan masuk 82.

Cobalah online!

Kerusakan:

Pertama-tama masukkan karakter yang diperlukan ke dalam rekaman: (newline)| o_-

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

Kemudian kumpulkan input menjadi dua sel dan kurangi 48 dari masing-masing (untuk mendapatkan nilai numerik dan bukan karakter angka)

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

Selanjutnya, periksa untuk kasus khusus (1, 1)(Perhatikan bahwa hanya cek ini menyumbang 109 byte kode). Seolah-olah ifs tidak cukup sulit untuk dilakukan di brainfuck, kami memiliki sarang if:

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

Berikut ini adalah struktur untuk memeriksa apakah sel x nol atau tidak nol:

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

Namun dalam sarang if, kita perlu memiliki 4 sel sementara.

Sekarang kita sampai pada pencetakan karakter yang sebenarnya:

Cetak bilah atas dan baris baru:

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

Cetak a |, baris o's, yang lain, |dan baris baru beberapa kali sama dengan tinggi:

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

Dan cetak bilah bawah (tidak perlu baris baru di sini):

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

7

Retina , 52 byte

Hitungan byte mengasumsikan penyandian ISO 8859-1. Perhatikan bahwa baris keenam seharusnya berisi satu spasi.

\G1?
$_¶
1* 



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

Cobalah online!

Input dalam bentuk unary, menggunakan 1sebagai digit unary, ruang sebagai pemisah dan tinggi diikuti oleh lebar.

Penjelasan

Semua tahap dalam program ini adalah substitusi telanjang, kadang-kadang dengan pengubah regex reguler (tidak ada pengulangan atau loop, tidak ada jenis tahap lainnya). Bahkan tidak menggunakan fitur substitusi khusus Retina, selain alias biasa untuk linefeeds.

\G1?
$_¶

Tujuannya adalah untuk "melipatgandakan" dua input. Tujuan kami adalah membuat h+2baris dengan w 1masing-masing ( h+2sehingga kami dapat mengubah bagian atas dan bawah menjadi _dan -kemudian). The \Ganchor membutuhkan pertandingan untuk memulai di mana yang terakhir tinggalkan. Artinya, jika kita pernah gagal mencocokkan karakter dalam string, karakter selanjutnya tidak akan cocok. Kami menggunakan ini untuk mencocokkan hanya 1dalam h, tetapi tidak dalam wkarena regex tidak memungkinkan ruang yang memisahkan mereka untuk dicocokkan. Namun, kami juga membuat 1opsional, sehingga kami mendapatkan kecocokan kosong tambahan di akhir h. Itu h+1cocok. Masing-masing diganti dengan seluruh input ( $_) diikuti oleh linefeed.witu sendiri tetap tidak tersentuh yang memberi kita h+2salinan nd. Katakanlah input tadi 11 1111, maka kita sekarang punya:

11 1111
11 1111
11 1111
 1111

Cukup bagus. Kami punya beberapa barang ekstra, tetapi h+2salinannya wada di sana.

1* 

Perhatikan bahwa ada spasi di akhir baris pertama. Ini menghapus awalan-awalan itu dari baris sehingga kita hanya memiliki ws sesudahnya.



Ah, itu tidak benar-benar berfungsi dengan format SE ... baris pertama kosong dan baris kedua seharusnya berisi satu spasi. Ini memasukkan spasi ke dalam setiap posisi yang memungkinkan, yaitu di awal dan akhir setiap baris dan di antara setiap pasangan 1s:

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

Kami akan mengubahnya menjadi onanti

.+
|$&|

Ini hanya membungkus setiap baris dalam sepasang |:

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

Sekarang kami menangani bagian atas dan bawah:

\G.
_

Saatnya \Gbersinar lagi. Ini cocok dengan setiap karakter di baris pertama dan mengubahnya menjadi _.

r`.\G
-

Hal yang sama, tetapi karena rmodifikator (mode kanan-ke-kiri), ini cocok dengan karakter pada baris terakhir dan mengubahnya menjadi -. Jadi sekarang kita punya:

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

Hanya ada dua hal yang harus dilakukan sekarang: ubah 1menjadi os, dan jika inputnya 1 1maka ubahlah semuanya menjadi ogantinya. Kami dapat menangani keduanya dengan satu tahap:

s`^.{17}$|1
o

sadalah mode singleline biasa (yaitu membuat .matchfeed garis) Jika inputnya adalah 1 1hasilnya akan memiliki ukuran minimum 17 karakter sehingga kami dapat mencocokkannya ^.{17}$dan menggantinya dengan o. Kalau tidak, jika gagal, kami hanya akan mencocokkan semua 1dan menggantikannya dengan o.


7

Jolf, 36 byte

?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 byte, tidak bersaing

Yah, aku membuat kotak yang lebih baik.

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

Jolf, 38 37 byte

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

Hal-hal sederhana, sungguh. Menyimpan byte dengan mencatat bahwa (matematika zeta, atau penyimpangan stand) hanya 0 ketika kedua argumen adalah 1, dan sebaliknya salah (untuk kasus kami).


6

05AB1E , 33 byte

Kode:

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

Penjelasan:

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

Menggunakan pengkodean CP-1252 . Cobalah online! .


6

JavaScript (ES6), 89 86 byte

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

Sunting: Disimpan 3 byte berkat @Shaggy.


Hemat 3 byte dengan aliasing repeat.
Shaggy

5

Python 2, 71 byte

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

1
Selamat datang di PPCG! Posting pertama yang bagus!
Rɪᴋᴇʀ

5

Befunge, 144 Bytes

Saya lebih suka mengomentari posting ini , tetapi saya belum memiliki reputasi, jadi saya memberikan jawaban saya sendiri, yang bekerja dengan cara yang sama, tetapi sedikit lebih kompak

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

Anda dapat menguji kode di sini


4

Reng v.4, 82 byte, tidak bersaing

Saya mendorong perbaikan bug yang memperbaiki fungsi yang ditimpa sendiri (tolong jangan tanya; barang saya dihantui)

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

Mengambil input sebagai angka yang digabungkan dengan ruang, misalnya 4 2. Coba di sini!


8
I pushed a bug fix that fixes functions being overwritten by themselves... Ya, itu bug yang menarik untuk dimiliki
MKII

4

PowerShell v2 +, 76 byte

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

Mengambil input, lalu memeriksa ifpernyataan. Sejak nol non nilai-nilai truthy di PowerShell, selama setidaknya satu dari $xdan $ytidak sama untuk 1, yang ifakan menjadi kenyataan.

Di dalam if, ada serangkaian perkalian string. Pertama, kami membuat rangkaian garis bawah, menabung $zuntuk nanti. Itu ditempatkan di saluran pipa. Selanjutnya kita membangun string sisi dan pasak kita (dengan pasak dikalikan dengan $x), dilakukan $ykali, dan menggabungkannya dengan $zkali tanda hubung kita . Tali itu kemudian ditempatkan pada pipa dan kita exit. Pipa disiram dan pencetakan tersirat. Perhatikan bahwa kita mendapatkan baris baru antara garis bawah dan baris pertama pasak secara gratis, karena .ToString()pemisah default untuk output array adalah `n(dan kami mengeluarkan array string).

Jika ifitu salah, kami berada dalam 1 1kasus khusus , jadi kami tinggal memasang "o"pipa dan keluar, dengan mencetak lagi implisit.

Contohnya

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

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
}

Catatan: Jika Anda benar-benar membutuhkan lego untuk memiliki tanda hubung untuk baris terakhir, maka ubah printf terakhir ke

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

dan tambahkan dua byte.


2
Bukankah ini akan sedikit lebih pendek jika tidak dibungkus dalam suatu fungsi? Juga, saya bukan ahli dalam bash tetapi sepertinya punya beberapa spasi tambahan.
DJMcMayhem

Ini akan menjadi ~ 170 sebagai 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;}

1
Jika Anda menggunakan (), Anda tidak perlu kata kunci functionuntuk mendeklarasikan suatu fungsi. Ada alternatif forsintaks menggunakan kawat gigi, misalnya: for((j=$1;j--;));{ printf o;}. Seperti yang diperlihatkan dalam contoh sebelumnya, Anda dapat menyimpan beberapa karakter dengan mengurangi dan menguji forekspresi kedua. Anda dapat menggunakan backticks sebagai ganti $(cmd).
ninjalj

@ninjalj Terima kasih, saya baru mengenal kode golf - yang menekan lagi ~ 17 byte, one-liner sekarang 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;}

Tanda-tanda dolar adalah opsional dalam konteks aritmatika, sehingga Anda bisa mencukur beberapa byte dengan mengubah (($something))ke ((something))seluruh. ( $1Masih membutuhkan tanda dolar untuk memisahkannya dari literal 1.)
tripleee

4

Perl 5 - 84 77 byte

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. Dengan bantuan dari Dom Hastings

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

Pertama saya bingung mengapa seseorang akan berusaha menggunakan warnprogram golf, tapi kemudian saya menyadari Anda menggunakannya karena lebih pendek dari print. Bagus!
pipa

Ya, saya pikir di Perl 6 Anda dapat mengambil byte lagi dengan menggunakan katakan alih-alih memperingatkan
Kaundur

1
Anda dapat melakukannya di Perl 5 juga, hanya saja itu tidak diaktifkan secara default. Saya pikir Anda dapat menyiasatinya dalam kode-golf dengan memanggil skrip Anda dari baris perintah dengan -Ealih - alih -e, mengaktifkan semua ekstensi. Saya baru di tempat ini jadi saya tidak tahu persis di mana itu ditentukan bagaimana menghitung skor.
pipa

Oh sungguh, aku tidak tahu itu. Saya juga baru di sini, jadi saya juga tidak yakin
Kaundur

Saya pikir Anda dapat mempersingkat ini menjadi 76 byte ... Jika Anda menggunakan fungsi saya percaya mengembalikan string dapat diterima (lihat jawaban JS, menghemat 4 byte untuk warn), Anda tidak perlu tanda kutip di sekitar "o"(Anda dapat gunakan bareword untuk -2 lain), jika Anda sebaris perhitungan $wAnda harus menyimpan byte lain ( '_'x($w=3+2*$x)vs. $w=3+2*$x;... '_'x$w) dan terakhir, Anda dapat mengubah \nuntuk baris baru literal. Semoga itu bisa membantu!
Dom Hastings

3

C, 202 191 byte

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

Terima kasih kepada @Lince Assassino karena telah menghemat 11 byte!

Tidak Disatukan:

#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
Anda dapat mengubah baris pertama Anda untukp(char*A){printf(A);}
Lince Assassino

1
Terima kasih sekali! Tetapi mungkin untuk memperpendeknya dengan#define p printf
Marco

3

Cinnamon Gum, 32 byte

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

Non-bersaing. Cobalah online. Input harus tepat dalam bentuk [width,height]tanpa spasi di antara koma dan tinggi.

Penjelasan

String mendekompres ke ini:

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

Pertama ltahap peta [1,1]untuk o(kasus khusus) dan segala sesuatu yang lain ke string

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

Backtick kemudian menandakan dimulainya tahap kedua; alih-alih mengeluarkan string itu, CG memotong backtick dan mengeksekusi string. The pmodus kemudian mengulangi semua karakter di dalam tildes parameter pertama (lebar) kali dan kemudian setelah itu mengulangi karakter di dalam persen tanda-tanda parameter kedua (tinggi) kali. Jadi untuk [4,2]itu berubah menjadi ini:

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

dan kemudian ke:

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

3

Batch, 172 170 byte

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

Sunting: Disimpan 2 byte berkat @ CᴏɴᴏʀO'Bʀɪᴇɴ @ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ.

Saya dapat menyimpan 7 byte jika saya dapat menganggap ekspansi yang tertunda diaktifkan.


%%o%%bukan %o%?
Erik the Outgolfer

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o%akan diganti dengan nilai asli osetiap kali, jadi itu ohanya akan sama " o". %%o%%digunakan sebagai argumen calldari %o%, yang kemudian menggunakan nilai saat ini dari o.
Neil

Kenapa kamu tidak ... saja do set o=%o% o?
Erik the Outgolfer

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o%akan diperluas sebelum forloop diuraikan, sehingga loop membaca for /l %i in (1,1,8) do call set o= oyang jelas tidak ada gunanya.
Neil

Kenapa kamu tidak do set o=%%o%% o(-5)?
Erik the Outgolfer

3

Vim, 56 penekanan tombol

Ini sepertinya tugas pengeditan teks, jadi Vim adalah pilihan yang jelas! Saya mengambil input sebagai file teks dengan dua integer yang dipisahkan spasi dan mengeluarkan jawaban ke dalam file yang sama. Juga, saya benci Anda karena memiliki kasus khusus 1x1 ... Pokoknya:

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

dan jika tidak ada kasus khusus, 35 penekanan tombol

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

Rincian untuk orang waras:

"adt l"bD

Hapus angka dari buffer ke @a dan @b (spasi disimpan)

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

Ganti ruang dengan "o" dan jika ada kasus khusus, simpan dan keluar

                                Di| |<esc>

Kosongkan garis dan tulis tepi blok lego

                                          @aio <esc>

Masukkan @a banyak "o" untuk mendapatkan bagian tengah yang sudah jadi

                                                    yy@bP

Yank line dan buat salinan ekstra @b (satu terlalu banyak)

                                                         Vr_

Kami berada di atas buffer, ganti garis tambahan dengan garis bawah

                                                            Gp

Lompat ke bawah buffer, tarik garis yang telah kita tarik sebelumnya

                                                              Vr-ZZ

Ganti baris dengan tanda hubung, simpan dan keluar



2

Haskell, 76 byte

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

Contoh penggunaan: 3 # 2memberi Anda string multiline untuk bata 3-oleh-2.

Tidak Disatukan:

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

Sekilas yang tampak seperti itu seharusnya lebih pendek unlines, tapi ternyata tidak.
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}

Pengujian:

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

Saya tahu sudah ada sejumlah solusi Befunge, tapi saya cukup yakin mereka bisa diperbaiki dengan mengambil pendekatan yang berbeda dengan tata letak kode. Saya menduga jawaban ini bisa di-pegolf lebih jauh juga, tetapi sudah agak lebih kecil dari salah satu entri sebelumnya.

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

Cobalah online!


Bisakah Anda jelaskan mengapa string :<|dibutuhkan?
Zacharý

@ Zacharý Cabang vertikal di baris pertama tidak pernah benar-benar bercabang. Bagian atas tumpukan selalu nol pada saat itu, jadi ini adalah jalan pintas untuk menjatuhkan bagian atas tumpukan dan bercabang pada saat yang sama - pada dasarnya tip ini .
James Holderness

1

APL, 46 byte

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

Penjaga: ⍵≡1 1:'o'untuk kasus khusus. Kalau tidak, 'o '⍴⍨1 2×⌽⍵buat konten. Dan sisanya hanya tinju.


1

C #, 198 byte

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

cepat dan kotor

Saya harus menulis fungsi yang mengalikan string

ungolfed (untuk saran)

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

Saya perhatikan fungsi s Anda dapat dioptimalkan ke string s(string m,int u){return string.Join("",new int[u].Select(n => m));}- .ToArray () adalah redundan dan string [] mungkin juga menjadi int []. Tetapi alih-alih string. Bergabunglah dengan Anda dapat menggunakan agregat:string s(string m, int u){return new int[u].Aggregate("",(t,i)=>t+m);}
Oliver Hallam

1
Anda dapat mencukur beberapa byte seperti ini ... (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

Oktaf, 97 95 86 byte

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

Saya menggunakan metode @atlasologist dengan Python untuk menguji (1, 1):(...,'o')[x<2>y]

Terima kasih kepada @Luis Mendo karena telah menyimpan 7 byte: a=ones(1,w*2+3)*'_'ke a=~(1:w*2+3)+95dan a./a*'-'ke~a+45

Terima kasih kepada @pajonk karena telah menghemat 2 byte:f=


1
Ini bukan kode Matlab yang valid. Anda harus memberi label sebagai "Oktaf" saja. Juga, bukannya a./a*'-'Anda bisa menggunakan ~~a*'-'? Atau bahkan ~a+45?
Luis Mendo

Juga, mungkin Anda dapat meninggalkannya sebagai fungsi anonim (tanpa f=)
pajonk
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.