Wydrukuj kawałek Lego

48

To wyzwanie jest proste jak na . Biorąc pod uwagę dwa dane wejściowe, opisujące wysokość i szerokość klocka Lego, wydrukowałeś jego grafikę ASCII.

Oto jak powinny wyglądać klocki 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

Jeśli nie możesz stwierdzić na podstawie przypadków testowych, góra i dół to width*2+3podkreślenia i myślniki, a każdy rząd ma rury po bokach, odla drobiazgów, a wszystko jest oddzielone spacjami.

Jedynym wyjątkiem jest to (1, 1), że jest to pojedynczy o.

Nigdy nie dostaniesz 0żadnego z wymiarów.

To jest , więc wygrywa najkrótszy kod w bajtach !

Maltysen
źródło
2
Czy to możliwe, że szerokość lub wysokość będzie większa niż 10? Jaki zakres powinniśmy wspierać?
DJMcMayhem
29
Ten wyjątkowy przypadek to prawdziwy szum.
Conor O'Brien,
47
W ciągu najbliższych kilku lat chcę zobaczyć kolejne wyzwanie „Wydrukuj klocki Lego”, które wymaga napisania kodu informującego drukarkę 3D, aby wyprodukowała klocki Lego.
Kevin - Przywróć Monikę
8
Czekaj, „jaki zakres liczb całkowitych obsługuje Twój język”? To nie tak działa LEGO. Cegły są dostępne tylko w kilku bardzo konkretnych wymiarach. Nawet jeśli dodasz talerze, dostaniesz tylko kilka. Każdy skrypt, który nie odrzuca danych wejściowych, taki jak (1,7) lub (5,3), jest kompletnym śmieciem.
RegDwight,
3
Dlaczego pojedynczy kawałek (1,1) nie ma boków? Na kostce jest prawdziwy klocek Lego z pojedynczym smoczkiem.
tcrosley,

Odpowiedzi:

53

Befunge , 165 227 bajtów

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

Nie tak wiele białych znaków jak wcześniej, ale wciąż są luki. Zasada jest taka sama jak w poprzednim rozwiązaniu, ale układ jest inny. Tym razem, aby sprawdzić, czy obie liczby są równe 1, po prostu biorę ich produkt i sprawdzam, czy wynik jest większy niż 1.


Stare rozwiązanie (227 bajtów)

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

Być może uda się bardziej zagrać w golfa. Spójrz tylko na wszystkie te białe znaki!

Oto moja kiepska próba wyjaśnienia w formie obrazu MSPaint: Jak Befunge Kod płynie w kierunku strzałki.


źródło
2
O. mój. Bóg. Blows my mind
lukas.pukenis
25

V , 43, 40, 38 36 bajtów

Jedna z najdłuższych odpowiedzi V, jakie kiedykolwiek napisałem ...

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

Wypróbuj online!

Ponieważ zawiera znaki Unicode i niedrukowalne, oto odwracalny zrzut heksowy:

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_

To wyzwanie polega na manipulowaniu tekstem, tak idealnym dla V! Z drugiej strony, V jest okropny w przypadku warunkowej i matematycznej, więc różna moc wyjściowa dla (1, 1) naprawdę spieprzyła go ... :(

Wyjaśnienie:

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

Teraz mamy linie „wysokości” znaków z odstępami między nimi.

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

Wersja niekonkurencyjna (31 bajtów):

Wypróbuj online!

Ta wersja wykorzystuje kilka funkcji, które są nowsze niż to wyzwanie, aby być o 5 bajtów krótszym!

Drugie wyjaśnienie:

ddÀP

który jest „Usuń linię i wklej go n razy” zostaje zastąpiony przez ÀÄ„Powtórz tę linię n razy”. (-2 bajty)

óo î½o
u

który brzmiał „Zamień pierwsze dopasowanie tego wyrażenia regularnego; Cofnij” został zastąpiony przez

/o î½o

Który jest po prostu „Wyszukaj dopasowanie tego wyrażenia regularnego” (-1 bajt)

I na koniec, Òjest tylko prostym synonimem Vr, który zarówno „Zamień każdy znak w tej linii na„ x ””. (-2 bajty)

DJMcMayhem
źródło
jak to się wydaje, że jest załamane na dole z tym v.tryitonline.net/…
metres
2
@meepl Naprawdę nie mam pojęcia. Działa na 50x959, ale jeśli zwiększysz szerokość lub wysokość, przestanie działać. Domyślam się, że najprawdopodobniej jest to celowe ograniczenie na stronie internetowej, aby zapobiec uruchamianiu bardzo dużych programów.
DJMcMayhem
1
TIO ogranicza dane wyjściowe do 100 KB , głównie po to, aby zapobiec awariom przeglądarki.
Dennis
22

32 16-bitowy kod maszynowy little-endian x86, 57 54 51 bajtów

3 bajty mniej dzięki @ninjalj.

Mocno przepisałem kod i udało mi się zgolić kolejne 3 bajty

W hex

FCBA6F208D48FFE20492AAEB2389D941D1E14151B05FF3AAEB0BB87C20AB89D992F3AB92AAB00AAA4E7DEF59B02DF3AA91AAC3

Dane wejściowe: BX = szerokość, SI = wysokość, DI wskazuje bufor, który otrzymuje wynik jako ciąg zakończony znakiem NULL z liniami oddzielonymi przez „\ n”

Demontaż:

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
źródło
Byłby krótszy jako 16-bitowy: -3 bajty dla 3 prefiksów 66h, +1 bajt dla zakończenia linii „\ r \ n”.
ninjalj
Powinieneś umieścić spacje między liczbami przekreślonymi a liczbami bieżącymi w swojej liczbie bajtów, aby zapewnić czytelność.
Wartość tuszu
20

Python 2, 75 73 72 bajty

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

Zwraca ciąg z warunkiem do obsługi bloku 1,1.

Dzięki Lynn i Chepner za dwa bajty

atlasolog
źródło
lambda x,y:('_'*x*2+'___\n'+itp. zapisuje bajt.
Lynn
1
Odrzuć kolejny bajt za pomocą x*'__'zamiast 2*x*'_'.
chepner
Dołącz do tej wspólnoty, przepraszam, że pytasz. Jak mogę zobaczyć, jak działa? wklejam go do terminala i po prostu drukuję <function <lambda> at 0x......>. Jak mogę to przetestować?
Miguel
1
@Miguel przypisuje go do zmiennej. f=lambda x:x+1; print(f(9))
Zwróci
Jeszcze jedno pytanie, jeśli odpowiedź nie jest skomplikowana. Jak możesz tak dokładnie śledzić bity?
Miguel
13

CJam, 34

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

Wypróbuj online

Wyjaśnienie:

'_        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
źródło
11

Rubin, 59 56 bajtów

Funkcja anonimowa zwraca ciąg wielowierszowy. Wypróbuj online!

-3 bajty dzięki pożyczeniu sztuczki od @ El'endiaStarman

->w,h{w*h<2??o:?_*(x=2*w+3)+$/+(?|+' o'*w+" |
")*h+?-*x}
Wartość tuszu
źródło
11

Java, 318 312 297 294 260 258 bajtów

Zaoszczędzono 15 bajtów dzięki 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);}}

Działa z argumentami wiersza poleceń.

Ungolfed W formie czytelnej dla człowieka:

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

Tak, nadal trudno jest zrozumieć, co się dzieje, nawet jeśli program nie jest golfisty. Oto wyjaśnienie krok po kroku:

static void main(String[] A)

Pierwsze dwa argumenty wiersza poleceń - których użyjemy do uzyskania wymiarów - mogą być użyte w programie jako odpowiednio ( A[0]i A[1]).

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

bto liczba kolumn, Bliczba wierszy i Czmienna przeznaczona do użycia w forpętlach.

cjest klockiem Lego. Dodamy do niego wiersze, a następnie wydrukujemy na końcu.

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

Jeśli kawałek do wydrukowania ma wartość 1x1, to zarówno b(liczba kolumn), jak i B(liczba wierszy) powinna być mniejsza niż 2. Więc po prostu ustawiamy cna jeden, oa następnie przejdźmy do stwierdzenia, że System.out.printjest to kawałek, jeśli tak jest.

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

Tutaj dołączamy (integerValueOfA[0] * 2) + 3podkreślenia do c. To najwyższy rząd ponad wszystkimi dziurami.

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

Jest to pętla, w której konstruujemy element po jednym rzędzie. To, co dzieje się w środku, nie da się wyjaśnić bez przykładów. Powiedzmy, że ten kawałek to 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 += "-";

Tutaj dołączamy (integerValueOfA[0] * 2) + 3łączniki do utworu. To rząd na samym dole, pod wszystkimi otworami.

Kawałek 4x4, którego użyłem do wyjaśnienia forpętli, w której jest on faktycznie zbudowany, wygląda teraz tak:

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

I w końcu drukujemy kawałek!

dorukayhan
źródło
Prawdopodobnie wersja 3 uczyniła ten najdłuższy post, jaki kiedykolwiek napisałem na Stack Exchange.
dorukayhan
2
Możesz przenosić Czmienne z forpętli int b=Byte.valueOf(A[0]),B=Byte.valueOf(A[1]),C. We wszystkich twoich pętlach for wydaje się również, że możesz używać C-->0;czeków, czyni to 298, pastebin.com/uj42JueL
cliffroot
1
oszczędne wykorzystanie forpętli do zapisania kilku bajtów - pastebin.com/dhNCpi6n
cliffroot
1
jeśli konwertować swoje argumenty do bajtów, potem czek jest wielkość cegły jest 1x1 będzie if(b==1&B==1)która pozwala na zapisanie ponad 20 bajtów
user902383
również w przypadku 1x1 robiąc to System.out.print('o');return;, możesz ustawić c='o'i umieścić logikę dla różnych cegieł w bloku else. a następnie posiadanie pojedynczej instrukcji drukowania i brak zwrotu pozwala zaoszczędzić dodatkowe bajty
użytkownik902383
9

Minkolang 0,15 , 58 57 56 bajtów

Tak to prawda. Grałem w jeden dwa śmierdzące bajki ...

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

Wypróbuj tutaj!

Wyjaśnienie

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.

Okej, to dwa znaczące przepisania objaśnienia dla dwóch zapisanych bajtów. Nie sądzę, żebym mógł lub zagram w coś więcej z tego. : P

El'endia Starman
źródło
3
Pierwszy bajt jest najtrudniejszym krokiem ... początek 1000 bajtów zaczyna się od jednego bitu ...
Conor O'Brien
8

pieprzenie mózgu, 391 bajtów

Wiem, że można to jeszcze bardziej pograć w golfa, ale w tym momencie cieszę się, że to działa. Będę nadal pracował nad golfem.

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

Dane wejściowe należy podać jako dwie cyfry. W tym celu (8, 2)wystarczy wejść 82.

Wypróbuj online!

Awaria:

Najpierw umieść na taśmie niezbędne znaki: (newline)| o_-

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

Następnie zbierz dane wejściowe do dwóch komórek i odejmij 48 od każdej z nich (aby uzyskać wartość liczbową, a nie znak liczbowy)

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

Następnie sprawdź szczególny przypadek (1, 1)(Uwaga: tylko ten czek odpowiada za 109 bajtów kodu). Jakby ifów nie były na tyle trudne do zrobienia w brainfuck mamy zagnieżdżone if:

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

Poniżej przedstawiono strukturę sprawdzania, czy komórka x jest zerowa czy niezerowa:

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

Jednak w zagnieżdżonym ifmusimy mieć 4 komórki tymczasowe.

Teraz dochodzimy do faktycznego drukowania znaków:

Wydrukuj górny pasek i nowy wiersz:

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

Wydrukuj |, rząd o, drugi |i nowy wiersz wiele razy równy wysokości:

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

I wydrukuj dolny pasek (tutaj nie jest potrzebny nowy wiersz):

>[->++>+<<]>+++[-<<<.>>>]>[-<<+>>]<<
Business Cat
źródło
7

Siatkówka , 52 bajty

Liczba bajtów zakłada kodowanie ISO 8859-1. Zauważ, że szósta linia powinna zawierać pojedynczą spację.

\G1?
$_¶
1* 



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

Wypróbuj online!

Dane wejściowe są jednoargumentowe, przy użyciu 1jako cyfra jedności, spacja jako separator i wysokość, po której następuje szerokość.

Wyjaśnienie

Wszystkie etapy tego programu są podstawionymi podstawami, czasami z regularnym modyfikatorem wyrażenia regularnego (bez powtórzeń i pętli, bez innych typów etapów). Nie korzysta nawet z funkcji substytucji specyficznych dla siatkówki, oprócz zwykłego aliasu dla linii.

\G1?
$_¶

Ma to na celu „pomnożenie” dwóch wejść. Naszym celem jest tworzenie h+2wierszy po w 1każdym z nich ( h+2abyśmy mogli zamienić górę i dół na _i -później). \GKotwica wymaga meczu rozpocząć gdzie ostatni skończył. Oznacza to, że jeśli kiedykolwiek nie uda nam się dopasować znaku w ciągu, kolejne znaki również nie będą pasować. Używamy tego, aby dopasować tylko 1s h, ale nie, wponieważ regex nie pozwala na dopasowanie przestrzeni, która je dzieli. Jednak robimy również 1opcjonalne, aby uzyskać dodatkowe puste dopasowanie na końcu h. To h+1pasuje. Każdy z nich jest zastępowany przez całą input ( $_), po której następuje kreska.wsam pozostaje nietknięty, co daje nam h+2drugą kopię. Powiedzmy, że dane wejściowe były 11 1111, a teraz mamy:

11 1111
11 1111
11 1111
 1111

To całkiem nieźle. Mamy dodatkowe rzeczy, ale h+2kopie wsą.

1* 

Zauważ, że na końcu pierwszego wiersza jest spacja. To usuwa te prefiksy z linii, dzięki czemu mamy tylko ws później.



No cóż, to tak naprawdę nie działa z formatowaniem SE ... pierwszy wiersz jest pusty, a drugi wiersz powinien zawierać pojedynczą spację. To wstawia spacje do każdej możliwej pozycji, tj. Na początku i na końcu każdej linii oraz między każdą parą 1s:

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

Zamienimy je opóźniej

.+
|$&|

To po prostu otacza każdą linię w parę |:

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

Teraz dbamy o górę i dół:

\G.
_

Czas \Gznów zabłysnąć. Dopasowuje każdy znak w pierwszym wierszu i zamienia go w znak _.

r`.\G
-

To samo, ale ze względu na rmodyfikator (tryb od prawej do lewej) dopasowuje znaki w ostatnim wierszu i zamienia je w -. Teraz mamy:

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

Pozostały tylko dwie rzeczy do zrobienia: zamień je 1w os, a jeśli dane wejściowe były 1 1wtedy, zamień całą rzecz w o. Możemy obsłużyć oba z jednym etapem:

s`^.{17}$|1
o

sjest zwykłym trybem pojedynczej linii (tzn. powoduje .dopasowanie linii). Jeśli dane wejściowe były 1 1wynikiem, to będzie miał minimalny rozmiar 17 znaków, więc możemy je dopasować ^.{17}$i zastąpić o. W przeciwnym razie, jeśli to się nie powiedzie, po prostu dopasujemy wszystkie 1s i zastąpimy je ozamiast.

Martin Ender
źródło
7

Jolf, 36 bajtów

?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 bajty, niekonkurujący

Cóż, zrobiłem lepsze wbudowane pudełko.

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

Jolf, 38 37 bajtów

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

Proste rzeczy, naprawdę. Zaoszczędzono bajt, zauważając, że (matematyka zeta lub odchylenie stand) wynosi tylko 0, gdy oba argumenty mają wartość 1, a w przeciwnym razie jest falsey (w naszym przypadku).

Conor O'Brien
źródło
6

05AB1E , 33 bajty

Kod:

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

Wyjaśnienie:

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

Wykorzystuje kodowanie CP-1252 . Wypróbuj online! .

Adnan
źródło
6

JavaScript (ES6), 89 86 bajtów

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

Edycja: Zapisano 3 bajty dzięki @Shaggy.

Neil
źródło
Zaoszczędź 3 bajty aliasingiem repeat.
Kudłaty
5

Python 2, 71 bajtów

lambda x,y:('o',x*'__'+'___\n'+'| %s|\n'%('o '*x)*y+'-'*(x*2+3))[x+y>2]
Lulhum
źródło
1
Witamy w PPCG! Miły pierwszy post!
Rɪᴋᴇʀ
5

Befunge, 144 bajtów

Wolałbym skomentować ten post, ale nie mam jeszcze reputacji, więc zamieszczam własną odpowiedź, która działa w podobny sposób, ale jest nieco bardziej zwarta

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

możesz przetestować kod tutaj

Maliafo
źródło
4

Reng v.4, 82 bajty, niekonkurujące

Włączyłem poprawkę błędu, która naprawia same funkcje nadpisywania (proszę nie pytać; moje rzeczy są nawiedzone)

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

Pobiera dane wejściowe jako liczby połączone spacjami, np 4 2. Wypróbuj tutaj!

Conor O'Brien
źródło
8
I pushed a bug fix that fixes functions being overwritten by themselves... Cóż, to interesujący błąd
MKII
4

PowerShell v2 +, 76 bajtów

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

Pobiera dane wejściowe, a następnie sprawdza ifinstrukcję. Ponieważ niezerowe wartości są prawdziwe w PowerShell, tak długo, jak przynajmniej jedna z nich $xi $ynie będą równe 1, ifbędzie to prawdą.

Wewnątrz ifznajduje się seria mnożenia ciągów znaków. Najpierw konstruujemy ciąg znaków podkreślenia, oszczędzając $zna później. Zostanie to umieszczone w rurociągu. Następnie konstruujemy nasz ciąg boków i kołków (z pomnożonymi kołkami $x), wykonanych $yczasów i łączymy to z naszymi $zczasami kresek . Ten ciąg jest następnie umieszczany na rurociągu i my exit. Rurociąg jest opróżniany i drukowanie jest niejawne. Zauważ, że otrzymujemy nowy wiersz między znakami podkreślenia i pierwszym wierszem kołków za darmo, ponieważ domyślnym .ToString()separatorem dla danych wyjściowych tablicy jest `n(i wyprowadzamy tablicę ciągów znaków).

Jeśli ifjest to fałsz, znajdujemy się w specjalnym 1 1przypadku, więc po prostu umieszczamy "o"go w potoku i kończymy , drukując ponownie niejawnie.

Przykłady

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
źródło
4

Bash, 186 , 163 , 156 , 148 , 131 , 130 bajtów

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

Uwaga: Jeśli naprawdę potrzebujesz lego, aby mieć łączniki dla ostatniej linii, zmień ostatni printf na

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

i dodaj dwa bajty.


źródło
2
Czy nie byłoby to nieco krótsze, gdyby nie było opakowane w funkcję? Poza tym nie jestem ekspertem od bash, ale wygląda na to, że ma trochę białych znaków.
DJMcMayhem
Byłoby to ~ 170 jako liniowiec:(($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
Jeśli używasz (), nie potrzebujesz słowa kluczowego, functionaby zadeklarować funkcję. Istnieje alternatywna forskładnia przy użyciu nawiasów klamrowych, np for((j=$1;j--;));{ printf o;}. : Jak pokazano w poprzednim przykładzie, możesz zapisać niektóre znaki, zmniejszając i testując fordrugie wyrażenie. Zamiast tego możesz użyć backicksa $(cmd).
ninjalj
@ninjalj Dzięki, jestem nowy w kodowaniu golfa - to ściska kolejne ~ 17 bajtów, one-liner ma teraz 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;}
Znaki dolara są opcjonalne w kontekście arytmetycznym, więc możesz ogolić jeszcze kilka bajtów, zmieniając (($something))na w ((something))całym. ( $1wciąż potrzebuje znaku dolara, aby odróżnić go od literału 1.)
tripleee
4

Perl 5 - 84 77 bajtów

84 bajtów

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

77 bajtów. Z pewną pomocą Dom Hastings

sub l{($x,$y)=@_;$x*$y<2?o:'_'x($w=3+2*$x).('
| '.'o 'x$x."|")x$y.$/.'-'x$w}
Kaundur
źródło
Najpierw byłem zdezorientowany, dlaczego ktoś miałby się starać użyć warnprogramu golfowego, ale potem zdałem sobie sprawę, że używasz go, ponieważ jest on krótszy niż print. Miły!
rura
Tak, myślę, że w Perlu 6 możesz zdjąć kolejny bajt, używając powiedz zamiast ostrzegać
Kaundur
1
Możesz to zrobić również w Perlu 5, tyle że domyślnie nie jest włączony. Myślę, że można to obejść w golfowym kodzie, wywołując skrypt z wiersza poleceń, -Ezamiast zamiast -e, włączając wszystkie rozszerzenia. Jestem nowy w tym miejscu, więc nie wiem dokładnie, gdzie jest określone, jak liczyć wyniki.
rura
Och, naprawdę, nie wiedziałem o tym. Jestem tu także nowy, więc nie jestem pewien
Kaundur,
Myślę, że możesz to skrócić do 76 bajtów ... Jeśli używasz funkcji, uważam, że zwracanie ciągu jest dopuszczalne (zobacz odpowiedź JS, oszczędzając ci 4 bajty warn), nie potrzebujesz cudzysłowów wokół "o"(możesz użyj słowa bez słowa dla kolejnego -2), jeśli wstawisz obliczenia $w, powinieneś zapisać kolejny bajt ( '_'x($w=3+2*$x)vs. $w=3+2*$x;... '_'x$w) i na koniec możesz zmienić \nna dosłowny nowy wiersz. Mam nadzieję, że to pomaga!
Dom Hastings,
3

C, 202 191 bajtów

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

Dzięki @Lince Assassino za uratowanie 11 bajtów!

Nie golfowany:

#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
źródło
1
Możesz zmienić swój pierwszy wiersz nap(char*A){printf(A);}
Lince Assassino
1
Naprawdę dziękuję! Można jednak skrócić#define p printf
Marco
3

Guma cynamonowa, 32 bajty

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

Nie konkuruje. Wypróbuj online. Dane wejściowe muszą być dokładnie w formie, [width,height]bez odstępu między przecinkiem a wysokością.

Wyjaśnienie

Ciąg dekompresuje się do tego:

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

Pierwszy letap jest mapowany [1,1]na o(przypadek specjalny), a wszystko inne na ciąg

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

Strzałka w tył sygnalizuje następnie rozpoczęcie drugiego etapu; zamiast wyprowadzać ten ciąg, CG odcina backstick i wykonuje ciąg. pTryb następnie powtarza wszystkie znaki wewnątrz tyldy pierwszego parametru (szerokość) razy, a następnie potem powtarza znaki wewnątrz drugiego parametru znakami procentu (wysokość) razy. A więc [4,2]zamienia się w to:

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

a następnie w:

___________
| o o o o |
| o o o o |
-----------
spaghetto
źródło
3

Partia, 172 170 bajtów

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

Edycja: Zapisano 2 bajty dzięki @ CᴏɴᴏʀO'Bʀɪᴇɴ @ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ.

Mogę zapisać 7 bajtów, jeśli założę, że opóźnione rozszerzenie jest włączone.

Neil
źródło
%%o%%zamiast %o%?
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o%będzie zastępowane oryginalną wartością za okażdym razem, więc obędzie to zawsze tylko równe " o". %%o%%przechodzi jako argument callo %o%, które następnie wykorzystuje bieżącą wartość o.
Neil
Dlaczego nie ... tylko do set o=%o% o?
Erik the Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o%rozszerza się przed forprzeanalizowaniem pętli, więc pętla czyta, for /l %i in (1,1,8) do call set o= oco jest oczywiście bezcelowe.
Neil
Dlaczego więc nie do set o=%%o%% o(-5)?
Erik the Outgolfer
3

Vim, 56 klawiszy

To wydaje się być zadaniem do edycji tekstu, więc Vim jest oczywistym wyborem! Pobieram dane wejściowe jako plik tekstowy z dwiema liczbami całkowitymi oddzielonymi spacjami i wysyłam odpowiedź do tego samego pliku. Poza tym nienawidzę cię za posiadanie specjalnej skrzynki 1x1 ... W każdym razie:

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

a gdyby nie było przypadku specjalnego, 35 naciśnięć klawiszy

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

Podział dla zdrowych ludzi:

"adt l"bD

Usuń liczby z bufora do @a i @b (zachowano znak spacji)

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

Zamień spację na „o”, a jeśli jest to specjalny przypadek, zapisz i wyjdź

                                Di| |<esc>

Wyczyść linię i napisz krawędzie klocków lego

                                          @aio <esc>

Wstaw @ wiele „o”, aby uzyskać gotową środkową część

                                                    yy@bP

Yank line i wykonaj dodatkowe kopie @b (jeden za dużo)

                                                         Vr_

Jesteśmy na szczycie bufora, zamień dodatkową linię na podkreślenia

                                                            Gp

Skocz na dół bufora, pociągnij linię, którą wcześniej szarpnęliśmy

                                                              Vr-ZZ

Zamień wiersz na myślniki, zapisz i wyjdź

algmyr
źródło
2

Haskell, 76 bajtów

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

Przykład użycia: 3 # 2daje ciąg wielowierszowy dla klocka 3 na 2.

Nie golfowany:

(#) :: 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
źródło
Na pierwszy rzut oka wyglądało to na krótsze unlines, ale tak nie jest.
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}

Testowanie:

(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
źródło
2

Befunge, 114 113 108 101 bajtów

Wiem, że istnieje już wiele rozwiązań Befunge, ale byłem całkiem pewien, że można je ulepszyć, przyjmując inne podejście do układu kodu. Podejrzewam, że tę odpowiedź można jeszcze pograć w golfa, ale jest ona już nieco mniejsza niż którykolwiek z poprzednich wpisów.

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

Wypróbuj online!

James Holderness
źródło
Czy możesz wyjaśnić, dlaczego ciąg :<|jest potrzebny?
Zacharý
@ Zacharý Ta pionowa gałąź w pierwszym wierszu nigdy nie rozgałęzia się. Wierzchołek stosu w tym momencie jest zawsze równy zero, więc jest to skrót do upuszczenia stosu i rozgałęzienia w tym samym czasie - zasadniczo ta wskazówka .
James Holderness
1

APL, 46 bajtów

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

Strażnik: ⍵≡1 1:'o'do specjalnego przypadku. W przeciwnym razie 'o '⍴⍨1 2×⌽⍵zawartość zostanie zbudowana. A reszta to tylko boks.

lstefano
źródło
1

C #, 198 bajtów

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

szybko i brudno

Musiałem napisać funkcję, która zwielokrotnia ciągi

bez golfa (sugestie)

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
źródło
Zauważyłem, że twoja funkcja może być zoptymalizowana do string s(string m,int u){return string.Join("",new int[u].Select(n => m));}- .ToArray () jest redundantne, a string [] może również być int []. Ale zamiast string.Join możesz użyć agregacji:string s(string m, int u){return new int[u].Aggregate("",(t,i)=>t+m);}
Oliver Hallam
1
możesz ogolić kilka takich bajtów ... (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

Oktawa, 97 95 86 bajtów

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

Użyłem metody @atlasologist w Pythonie do przetestowania (1, 1):(...,'o')[x<2>y]

Dzięki @Luis Mendo za zapisanie 7 bajtów: a=ones(1,w*2+3)*'_'do a=~(1:w*2+3)+95i a./a*'-'do~a+45

Dzięki @pajonk za zapisanie 2 bajtów:f=

Marco
źródło
1
To nie jest poprawny kod Matlaba. Powinieneś oznaczyć tylko jako „Octave”. Zamiast tego a./a*'-'możesz użyć ~~a*'-'? A może nawet ~a+45?
Luis Mendo
Prawdopodobnie możesz zostawić to jako funkcję anonimową (bez f=)
pajonk