Drucken Sie ein Legostück

48

Diese Herausforderung ist eine einfache ein. Bei zwei Eingaben, die die Höhe und Breite eines Legostücks beschreiben, müssen Sie eine ASCII-Grafikdarstellung davon drucken.

So sollen die Lego-Teile aussehen:

(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

Wenn Sie nicht von den Testfällen unterscheiden können, sind die oberen und unteren width*2+3Punkte Unterstriche und Bindestriche, und jede Reihe hat Rohre für die Seiten, ofür die kleinen Dinge, und alles wird durch Leerzeichen getrennt.

Die einzige Ausnahme ist (1, 1), dass dies nur eine einzige ist o.

Sie werden nie 0für eine der Dimensionen bekommen.

Das ist , also gewinnt der kürzeste Code in Bytes !

Maltysen
quelle
2
Ist es möglich, dass die Breite oder die Höhe größer als 10 ist? Welchen Bereich sollten wir unterstützen?
DJMcMayhem
29
Der Sonderfall ist ein echter Mist.
Conor O'Brien
47
In den nächsten Jahren möchte ich eine weitere Herausforderung zum "Drucken eines Legostücks" sehen, bei der der Code geschrieben werden muss, damit ein 3D-Drucker einen Lego herstellen kann.
Kevin - Reinstate Monica
8
Warten Sie, "welcher Integer-Bereich von Ihrer Sprache unterstützt wird"? So funktioniert LEGO nicht. Die Steine ​​sind nur in einer Handvoll sehr spezieller Abmessungen erhältlich. Selbst wenn Sie Platten hinzufügen, erhalten Sie nur ein paar mehr. Jedes Skript, das Eingaben wie (1,7) oder (5,3) nicht verwirft, ist kompletter Müll.
RegDwight
3
Warum hat das Einzelstück (1,1) keine Seiten? Es gibt ein echtes Legostück mit einem einzelnen Nippel auf einem Würfel.
Tcrosley

Antworten:

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

Nicht mehr so ​​viel Leerzeichen wie zuvor, aber es gibt immer noch Lücken. Das Prinzip ist das gleiche wie in der vorherigen Lösung, aber das Layout ist anders. Um diesmal zu überprüfen, ob beide Zahlen 1 sind, nehme ich nur ihr Produkt und sehe, ob das Ergebnis größer als 1 ist.


Alte Lösung (227 Bytes)

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

Es könnte möglich sein, mehr Golf zu spielen. Sieh dir nur das ganze Leerzeichen an!

Hier ist mein schlechter Versuch, eine Erklärung in MSPaint-Bildform zu finden: Befunge Code fließt in Pfeilrichtung.


quelle
2
Oh. meine. Gott. Blows my mind
lukas.pukenis
25

V , 43, 40, 38, 36 Bytes

Eine der längsten V-Antworten, die ich je geschrieben habe ...

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

Probieren Sie es online!

Da dies Unicode- und nicht druckbare Zeichen enthält, ist hier ein umkehrbarer Hexdump:

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_

Bei dieser Herausforderung geht es um die Bearbeitung von Text, also perfekt für V! Andererseits ist V schrecklich in Bezug auf Bedingungen und Mathematik, so dass die unterschiedliche Ausgabe für (1, 1) es wirklich vermasselt hat ... :(

Erläuterung:

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

Jetzt haben wir 'Höhen'-Linien mit Zwischenräumen dazwischen.

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

Nicht konkurrierende Version (31 Bytes):

Probieren Sie es online!

Diese Version verwendet mehrere Funktionen, die neuer sind als diese Herausforderung, um 5 Byte kürzer zu sein!

Zweite Erklärung:

ddÀP

Das Wort "Zeile löschen und n- mal einfügen " wird durch ÀÄdas Wort "Diese Zeile n- mal wiederholen " ersetzt. (-2 Bytes)

óo î½o
u

Das war "Ersetze das erste Match dieses Regex; Rückgängig" wurde durch ersetzt

/o î½o

Welches ist nur "Suche nach einer Übereinstimmung dieser Regex" (-1 Byte)

Und schließlich Òist es nur ein einfaches Synonym für Vr"Ersetze jedes Zeichen in dieser Zeile mit 'x'". (-2 Bytes)

DJMcMayhem
quelle
wie kommt es, dass es unten kaputt zu sein scheint mit diesem v.tryitonline.net/…
meterk
2
@meepl Ich habe wirklich keine Ahnung. Es funktioniert auf 50x959, aber wenn Sie die Breite oder Höhe erhöhen, funktioniert es nicht mehr. Ich vermute, es handelt sich höchstwahrscheinlich um eine absichtliche Einschränkung der Website, um zu verhindern, dass extrem große Programme ausgeführt werden.
DJMcMayhem
1
TIO begrenzt die Ausgabe auf 100 KB , hauptsächlich um zu verhindern, dass das Frontend Ihren Browser zum Absturz bringt.
Dennis
22

32 16-Bit-Little-Endian-x86-Maschinencode, 57 54 51 Byte

3 Bytes weniger dank @ninjalj.

Habe den Code heftig umgeschrieben und weitere 3 Bytes gespart

In hex

FCBA6F208D48FFE20492AAEB2389D941D1E14151B05FF3AAEB0BB87C20AB89D992F3AB92AAB00AAA4E7DEF59B02DF3AA91AAC3

Eingabe: BX = Breite, SI = Höhe, DI zeigt auf den Puffer, der das Ergebnis als NULL-terminierte Zeichenfolge mit durch "\ n" getrennten Zeilen empfängt

Demontage:

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
quelle
Wäre kürzer als 16-Bit: -3 Byte für 3 66-Stunden-Präfixe, +1 Byte für "\ r \ n" -Zeilenabschluss.
Ninjalj
Sie sollten aus Gründen der Lesbarkeit Leerzeichen zwischen den durchgestrichenen und den aktuellen Zahlen in Ihre Byteanzahl einfügen.
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]

Gibt eine Zeichenfolge mit einer Bedingung zurück, die den 1,1-Block behandelt.

Vielen Dank an Lynn und Chepner für zwei Bytes

Atlasologe
quelle
lambda x,y:('_'*x*2+'___\n'+etc. speichert ein Byte.
Lynn
1
Knock off ein anderes Byte mit x*'__'anstelle von 2*x*'_'.
Chepner
Schließe dich einfach dieser Community an, entschuldige die Frage. Wie kann ich es laufen sehen? Ich füge es in das Terminal ein und drucke einfach <function <lambda> at 0x......>. Wie kann ich das testen?
Miguel
1
@ Miguel weist es einer Variablen zu. Es wird der Wert der Funktion zurückgegeben:f=lambda x:x+1; print(f(9))
Atlasologe
Noch eine Frage, wenn nicht zu kompliziert zu beantworten. Wie können Sie die Bits so genau verfolgen?
Miguel
13

CJam, 34

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

Probieren Sie es online aus

Erläuterung:

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

Ruby, 59 56 Bytes

Anonyme Funktion, gibt eine mehrzeilige Zeichenfolge zurück. Probieren Sie es online!

-3 Bytes dank eines Tricks von @ El'endiaStarman

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

Java, 318 312 297 294 260 258 Bytes

Dank Cliffroot 15 Bytes gespart !

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

Es funktioniert mit Kommandozeilenargumenten.

Ungolfed In einer für Menschen lesbaren Form:

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

Ja, es ist immer noch schwer zu verstehen, was los ist, auch wenn das Programm nicht voll ist. Hier folgt eine schrittweise Erklärung:

static void main(String[] A)

Die ersten beiden Befehlszeilenargumente -die wir bekommen ABMESSUNGEN können verwenden werden , wie im Programm verwendet werden A[0]und A[1](jeweils).

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

bist die Anzahl der Spalten, Bist die Anzahl der Zeilen und Cist eine Variable, die für die Verwendung in forSchleifen vorgesehen ist.

cist das Legostück. Wir fügen Zeilen hinzu und drucken sie am Ende.

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

Wenn das zu druckende Stück 1x1 ist, sollten sowohl b(Anzahl der Spalten) als auch B(Anzahl der Zeilen) kleiner als 2 sein. Deshalb setzen wir einfach cauf ein einzelnes Stück ound fahren dann mit der Aussage fort, dass System.out.printdas Stück ist, wenn dies der Fall ist.

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

Hier fügen wir (integerValueOfA[0] * 2) + 3Unterstriche an c. Dies ist die oberste Reihe vor allen Löchern.

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

Dies ist die Schleife, in der wir das Stück zeilenweise konstruieren. Was im Inneren vor sich geht, ist ohne Beispiele nicht zu erklären. Nehmen wir an, das Stück ist 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 += "-";

Hier fügen wir (integerValueOfA[0] * 2) + 3dem Stück Bindestriche hinzu. Dies ist die Reihe ganz unten unter allen Löchern.

Das 4x4-Teil, mit dem ich die forSchleife erklärt habe, in der das Teil tatsächlich aufgebaut ist, sieht jetzt so aus:

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

Und zum Schluss drucken wir das Stück!

Dorukayhan
quelle
Wahrscheinlich hat Revision 3 dies zu dem längsten Beitrag gemacht, den ich jemals auf Stack Exchange gemacht habe.
Dorukayhan
2
Sie können CVariablen aus forSchleifen verschieben int b=Byte.valueOf(A[0]),B=Byte.valueOf(A[1]),C. In allen für Schleifen scheint es auch , wie Sie verwenden können , C-->0;Schecks, macht es 298, pastebin.com/uj42JueL
cliffroot
1
einige kreative Verwendung von forSchleifen für wenige Bytes gespeichert - pastebin.com/dhNCpi6n
cliffroot
1
Wenn Sie Ihre Argumente zuerst in Bytes konvertieren, ist die Größe des if(b==1&B==1)
Bausteins
auch für den Fall 1x1 System.out.print('o');return;könnten Sie stattdessen c='o'Logik für verschiedene Bausteine ​​in else-Block setzen und platzieren.
Wenn
9

Minkolang 0,15 , 58 57 56 Bytes

Ja, das ist richtig. Ich golfed aus einem zwei mal ne kleinen Bytes ...

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

Probieren Sie es hier aus!

Erläuterung

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.

Okay, das sind zwei signifikante Änderungen der Erklärung für zwei gespeicherte Bytes. Ich glaube nicht, dass ich mehr aus diesem heraus Golf spielen kann oder werde. : P

El'endia Starman
quelle
3
Das erste Byte ist der schwierigste Schritt ... der Anfang von 1000 Bytes beginnt mit einem einzelnen Bit ...
Conor O'Brien
8

Brainfuck, 391 Bytes

Ich weiß, dass man mehr Golf spielen kann, aber jetzt bin ich froh, dass es funktioniert. Ich werde weiter daran arbeiten, Golf zu spielen.

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

Die Eingabe muss nur zweistellig sein. Wie in, zu tun (8, 2), würden Sie nur eingeben 82.

Probieren Sie es online!

Nervenzusammenbruch:

Legen Sie zuerst die erforderlichen Zeichen auf das Band: (newline)| o_-

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

Sammeln Sie dann die Eingabe in zwei Zellen und subtrahieren Sie jeweils 48 (um den numerischen Wert und nicht das numerische Zeichen zu erhalten).

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

Überprüfen Sie als Nächstes den Sonderfall von (1, 1)(Beachten Sie, dass nur diese Prüfung 109 Byte des Codes ausmacht). Als ob ifes nicht schwer genug wäre, Brainfuck zu machen, haben wir ein verschachteltes if:

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

Die folgende Struktur überprüft, ob eine Zelle x null oder ungleich null ist:

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

In einem verschachtelten ifObjekt müssen jedoch 4 temporäre Zellen vorhanden sein.

Nun kommen wir zum eigentlichen Drucken von Zeichen:

Drucke die obere Leiste und eine neue Zeile:

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

Gib a |, eine Reihe von o's, eine andere |und eine neue Zeile so oft aus, wie es der Höhe entspricht:

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

Und drucken Sie die untere Leiste (hier wird kein Zeilenumbruch benötigt):

>[->++>+<<]>+++[-<<<.>>>]>[-<<+>>]<<
Geschäfts-Katze
quelle
7

Netzhaut , 52 Bytes

Die Anzahl der Bytes setzt die Kodierung nach ISO 8859-1 voraus. Beachten Sie, dass die sechste Zeile ein einzelnes Leerzeichen enthalten soll.

\G1?
$_¶
1* 



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

Probieren Sie es online!

Die Eingabe erfolgt unär, wobei 1als unäres Zeichen das Leerzeichen als Trennzeichen und die Höhe gefolgt von der Breite verwendet werden.

Erläuterung

Alle Stufen in diesem Programm sind reine Substitutionen, gelegentlich mit einem regulären Regex-Modifikator (keine Wiederholung oder Schleifen, keine anderen Arten von Stufen). Abgesehen vom üblichen Alias ​​für Zeilenvorschübe werden nicht einmal Retina-spezifische Substitutionsfunktionen verwendet .

\G1?
$_¶

Der Zweck davon ist, die zwei Eingänge "zu multiplizieren". Unser Ziel ist es, h+2Zeilen mit jeweils w 1s zu erstellen ( h+2damit wir die oberen und unteren Zeilen in _und -später umwandeln können ). Der \GAnker erfordert, dass das Match dort beginnt, wo das letzte aufgehört hat. Das heißt, wenn wir jemals ein Zeichen in der Zeichenfolge nicht finden, werden auch keine weiteren Zeichen gefunden. Wir verwenden dies, um nur die 1s in abzugleichen h, aber nicht, wweil der reguläre Ausdruck nicht zulässt, dass der Raum, der sie trennt, übereinstimmt. Wir machen aber auch das 1optional, so dass wir am Ende ein zusätzliches leeres Match bekommen h. Das ist h+1Streichhölzer. Jedes dieser Zeichen wird durch die gesamte Eingabe ( $_) gefolgt von einem Zeilenvorschub ersetzt.wselbst bleibt unberührt, was uns die h+2nd Kopie gibt. Sagen 11 1111wir die Eingabe war , dann haben wir jetzt:

11 1111
11 1111
11 1111
 1111

Das ist sehr gut. Wir haben ein paar extra Sachen, aber die h+2Kopien wsind da.

1* 

Beachten Sie, dass am Ende der ersten Zeile ein Leerzeichen steht. Dadurch werden diese Präfixe aus den Zeilen entfernt, sodass wir nur noch das ws danach haben.



Naja, das funktioniert nicht wirklich mit der Formatierung von SE ... die erste Zeile ist leer und die zweite Zeile soll ein einzelnes Leerzeichen enthalten. Dies fügt Leerzeichen in jede mögliche Position ein, dh am Anfang und Ende jeder Zeile und zwischen jedem Paar von 1s:

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

Wir werden diese ospäter in s umwandeln

.+
|$&|

Dies umschließt einfach jede Zeile mit einem Paar von |:

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

Jetzt kümmern wir uns um oben und unten:

\G.
_

Zeit \G, wieder zu glänzen. Dies entspricht jedem Zeichen in der ersten Zeile und verwandelt es in ein _.

r`.\G
-

Das Gleiche, aber aufgrund des rModifikators (Modus von rechts nach links) werden die Zeichen in der letzten Zeile abgeglichen und in umgewandelt -. Jetzt haben wir also:

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

Jetzt müssen Sie nur noch zwei Dinge erledigen: Verwandeln Sie diese 1in os, und wenn die Eingabe erfolgte, 1 1verwandeln Sie ostattdessen die gesamte Sache in . Wir können beide mit einer einzigen Stufe bewältigen:

s`^.{17}$|1
o

sist ein regulärer Einzelzeilenmodus (dh es werden .Zeilenvorschübe erstellt). Wenn die Eingabe 1 1das Ergebnis war, hat sie die Mindestgröße von 17 Zeichen, damit wir sie abgleichen ^.{17}$und durch ersetzen können o. Andernfalls passen wir einfach alle 1s an und ersetzen diese durch o.

Martin Ender
quelle
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, nicht konkurrierend

Nun, ich habe eine bessere Box gebaut.

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

Jolf, 38 37 Bytes

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

Einfaches Zeug, wirklich. Ein Byte wurde gespeichert, indem festgestellt wurde, dass (math zeta oder die Abweichung von der Norm) nur 0 ist, wenn beide Argumente 1 sind, und ansonsten (für unseren Fall) falsch.

Conor O'Brien
quelle
6

05AB1E , 33 Bytes

Code:

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

Erläuterung:

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

Verwendet die CP-1252- Codierung. Probieren Sie es online! .

Adnan
quelle
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`

Bearbeiten: 3 Bytes dank @Shaggy gespeichert.

Neil
quelle
Sparen Sie 3 Bytes durch 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
quelle
1
Willkommen bei PPCG! Schöner erster Beitrag!
5.
5

Befunge, 144 Bytes

Am liebsten hätte ich einen Kommentar zu diesem Beitrag abgegeben, aber ich habe noch keinen guten Ruf. Deshalb gebe ich eine eigene Antwort, die ähnlich funktioniert, aber etwas kompakter ist

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

Sie können den Code testen hier

Maliafo
quelle
4

Reng v.4, 82 Bytes, nicht konkurrierend

Ich habe einen Bugfix gepusht, der das Überschreiben von Funktionen durch sich selbst behebt (bitte nicht fragen; meine Sachen werden verfolgt)

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

Nimmt Eingaben als durch Leerzeichen verbundene Zahlen wie 4 2. Probieren Sie es hier aus!

Conor O'Brien
quelle
8
I pushed a bug fix that fixes functions being overwritten by themselves... Nun, das ist ein interessanter Bug
MKII
4

PowerShell v2 +, 76 Byte

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

Übernimmt die Eingabe und überprüft dann eine ifAnweisung. Da Nicht-Null - Werte sind truthy in Power, so lange mindestens eine von $xund $ygleich sind nicht auf 1die ifwird wahr sein.

Im Inneren ifgibt es eine Reihe von String-Multiplikationen. Zuerst konstruieren wir eine Reihe von Unterstrichen, die wir $zfür später speichern . Das wird in die Pipeline gestellt. Als nächstes konstruieren wir unsere Reihe von Seiten und Stiften (mit den Stiften multipliziert mit $x), fertigen $yZeiten und verketten dies mit unseren Gedankenstrichen $z. Dieser String wird dann in der Pipeline platziert und wir exit. Die Pipeline wird geleert und das Drucken ist implizit. Beachten Sie, dass wir den Zeilenumbruch zwischen den Unterstrichen und der ersten Zeile der Stifte kostenlos erhalten, da das Standardtrennzeichen .ToString()für die Array-Ausgabe lautet `n(und wir ein Array von Strings ausgeben).

Wenn das iffalsch ist, befinden wir uns im Sonderfall 1 1, also stellen wir es "o"von selbst in die Pipeline und beenden es, wobei das Drucken erneut implizit erfolgt.

Beispiele

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

Hinweis: Wenn das Lego wirklich Bindestriche für die letzte Zeile enthalten muss, ändern Sie den letzten Ausdruck in

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

und addiere zwei Bytes.


quelle
2
Wäre das nicht ein bisschen kürzer, wenn es nicht in eine Funktion gehüllt wäre? Ich bin auch kein Experte für Bash, aber es sieht so aus, als hätte es etwas mehr Leerzeichen.
DJMcMayhem
Es wäre ~ 170 als (($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
Wenn Sie verwenden (), benötigen Sie das Schlüsselwort nicht function, um eine Funktion zu deklarieren. Es gibt eine alternative forSyntax mit geschweiften Klammern, z for((j=$1;j--;));{ printf o;}. Wie im vorherigen Beispiel gezeigt, können Sie einige Zeichen speichern, indem Sie den forzweiten Ausdruck in dekrementieren und testen . Sie können statt Backticks verwenden $(cmd).
Ninjalj
@ninjalj Danke, ich bin neu im Code Golf - das drückt weitere ~ 17 Bytes weg, der (($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;}
Dollarzeichen sind im arithmetischen Kontext optional. Sie können also ein paar Bytes mehr sparen, indem Sie (($something))auf ((something))durchgehend wechseln . ( $11
Benötigt
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. Mit etwas Hilfe von Dom Hastings

sub l{($x,$y)=@_;$x*$y<2?o:'_'x($w=3+2*$x).('
| '.'o 'x$x."|")x$y.$/.'-'x$w}
Kaundur
quelle
Zuerst war ich verwirrt, warum sich jemand die Mühe macht, warnein Golfprogramm zu verwenden, aber dann wurde mir klar, dass Sie es verwenden, weil es kürzer ist als print. Nett!
Pipe
Ja, ich denke in Perl 6 können Sie ein weiteres Byte
entfernen,
1
Sie können dies auch in Perl 5 tun, nur dass es nicht standardmäßig aktiviert ist. Ich denke, dass Sie das in Code-Golf umgehen können, indem Sie Ihr Skript von der Kommandozeile mit aufrufen, -Eanstatt -ealle Erweiterungen zu aktivieren. Ich bin neu in diesem Bereich, daher weiß ich nicht genau, wo genau angegeben ist, wie die Punkte zu zählen sind.
Rohr
Oh wirklich, das wusste ich nicht. Ich bin auch neu hier, also bin ich mir auch nicht sicher
Kaundur
Ich denke, Sie können dies auf 76 Bytes verkürzen ... Wenn Sie eine Funktion verwenden, von der ich glaube, dass die Rückgabe der Zeichenfolge akzeptabel ist (siehe die Antwort von JS, wobei Sie 4 Bytes sparen warn), brauchen Sie keine Anführungszeichen um die "o"(Sie können) Verwenden Sie ein Bareword für ein anderes -2). Wenn Sie die Berechnung inline setzen $w, sollten Sie ein weiteres Byte ( '_'x($w=3+2*$x)vs. $w=3+2*$x;... '_'x$w) speichern und zuletzt das \nfür eine wörtliche Newline ändern. Ich hoffe, das hilft!
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();}

Vielen Dank an @Lince Assassino für die Einsparung von 11 Bytes!

Ungolfed:

#include <stdio.h>
#define p printf

int i, w, h;

void t(char *c)
{
    for(i=0; p(c), ++i<w*2+3;);
    p("\n");
}

void f()
{
    t("_");
    for(i=0; i<w*h;)
    {
        i%w<1 ? p("| o ") : p("o ");
        i++%w>w-2 && p("|\n");
    }
    t("-");
}

int main()
{
    scanf("%d %d", &w, &h);
    w*h<2 ? p("o") : f();
}
Marco
quelle
1
Sie können Ihre erste Zeile fürp(char*A){printf(A);}
Lince Assassino
1
Wirklich danke dir! Aber es ist möglich, mit#define p printf
Marco
3

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

Nicht konkurrierend. Probieren Sie es online aus. Die Eingabe muss genau in der Form erfolgen und darf [width,height]keinen Abstand zwischen Komma und Höhe haben.

Erläuterung

Die Zeichenfolge wird folgendermaßen dekomprimiert:

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

Die erste lStufe ist [1,1]dem o(Sonderfall) und alles andere der Zeichenfolge zugeordnet

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

Der Backtick signalisiert dann den Beginn einer zweiten Stufe; Anstatt diesen String auszugeben, schneidet CG den Backtick ab und führt den String aus. Der pModus wiederholt dann alle Zeichen im ersten Parameter (Breite) und anschließend die Zeichen im zweiten Parameter (Höhe) des Prozentzeichens. Also für [4,2]ihn in dieser verwandelt:

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

und dann in:

___________
| o o o o |
| o o o o |
-----------
ein Spaghetto
quelle
3

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

Bearbeiten: 2 Bytes dank @ CᴏɴᴏʀO'Bʀɪᴇɴ @ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ gespeichert.

Ich kann 7 Bytes sparen, wenn ich davon ausgehen kann, dass die verzögerte Erweiterung aktiviert ist.

Neil
quelle
%%o%%statt %o%?
Erik der Outgolfer
@EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o%würde ojedes Mal durch Originalwert ersetzt , damit owäre das immer nur gleich " o". %%o%%geht als Argument durch callvon %o%, welches dann den aktuellen Wert von verwendet o.
Neil
Warum gehst du nicht ... einfach do set o=%o% o?
Erik der Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ %o%wird erweitert, bevor die forSchleife analysiert wird. Die Schleife liest also, for /l %i in (1,1,8) do call set o= owas offensichtlich sinnlos ist.
Neil
Warum gehst du do set o=%%o%% odann nicht (-5)?
Erik der Outgolfer
3

Vim, 56 Tastenanschläge

Dies scheint eine Textbearbeitungsaufgabe zu sein, daher ist Vim die naheliegende Wahl! Ich nehme die Eingabe als Textdatei mit zwei durch Leerzeichen getrennten Ganzzahlen und gebe die Antwort in dieselbe Datei aus. Außerdem hasse ich dich dafür, dass du den 1x1-Spezialfall hast ... Wie auch immer:

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

und wenn es für den Sonderfall nicht gegeben hätte, 35 Tastenanschläge

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

Ein Zusammenbruch für gesunde Menschen:

"adt l"bD

Zahlen aus dem Puffer in @a und @b löschen (Leerzeichen bleibt erhalten)

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

Ersetzen Sie das Leerzeichen durch "o" und speichern und beenden Sie es in besonderen Fällen

                                Di| |<esc>

Löschen Sie die Linie und schreiben Sie die Kanten des Legoblocks

                                          @aio <esc>

Fügen Sie @ eine Menge "o" ein, um ein fertiges Mittelteil zu erhalten

                                                    yy@bP

Yank-Linie und mache @b zusätzliche Kopien (eine zu viele)

                                                         Vr_

Wir sind oben im Puffer, ersetzen Sie die zusätzliche Zeile durch Unterstriche

                                                            Gp

Springe zum Ende des Puffers und ziehe die Linie, die wir vorher gezogen haben

                                                              Vr-ZZ

Zeile durch Bindestriche ersetzen, speichern und beenden

Algmyr
quelle
2

Pyth, 38 Bytes

?t*QJEjb+sm\_K+\|+j\o*dhQ\|+mKJsm\-K\o

Testsuite.

Undichte Nonne
quelle
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

Verwendungsbeispiel: 3 # 2Gibt eine mehrzeilige Zeichenfolge für einen 3-mal-2-Baustein an.

Ungolfed:

(#) :: Int -> Int -> String
1     #   1    = "o"
width # height = let longWidth = 2 * width + 3 in -- golfed as 'f'
                      (        longWidth `times` "_"  ++   "\n" )
  ++ height   `times` ( "|" ++     width `times` " o" ++ " |\n" )
  ++                  (        longWidth `times` "-"            )

-- | golfed as (!)
times :: Int -> [a] -> [a]
times n s = concat $ replicate n s
MarLinn
quelle
Auf den ersten Blick sah das so aus, als sollte es kürzer sein unlines, aber das ist es nicht.
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}

Testen:

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

Befunge, 114 113 108 101 Bytes

Ich weiß, dass es bereits eine Reihe von Befunge-Lösungen gibt, aber ich war mir ziemlich sicher, dass sie durch eine andere Herangehensweise an das Layout des Codes verbessert werden könnten. Ich vermute, dass diese Antwort auch noch weiter ausgearbeitet werden kann, aber sie ist bereits ein bisschen kleiner als die beiden vorherigen Einträge.

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

Probieren Sie es online!

James Holderness
quelle
Können Sie erklären, warum der String :<|benötigt wird?
Zacharý
@ Zacharý Dieser vertikale Zweig in der ersten Zeile verzweigt sich eigentlich nie. Die Oberseite des Stapels ist an diesem Punkt immer Null. Dies ist also eine Abkürzung, um die Oberseite des Stapels fallen zu lassen und gleichzeitig nach unten zu verzweigen - im Grunde genommen dieser Tipp .
James Holderness
1

APL, 46 Bytes

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

Die Wache: ⍵≡1 1:'o'für den besonderen Fall. Ansonsten 'o '⍴⍨1 2×⌽⍵baut der Inhalt. Und der Rest ist nur das Boxen.

lstefano
quelle
1

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

schnell und dreckig

Ich musste eine Funktion schreiben, die Zeichenfolgen multipliziert

ungolfed (für Vorschläge)

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
quelle
Ich habe festgestellt, dass Ihre Funktion optimiert werden kann string s(string m,int u){return string.Join("",new int[u].Select(n => m));}- das .ToArray () ist redundant und der String [] kann auch ein int [] sein. Aber statt string.Join können Sie aggregate verwenden:string s(string m, int u){return new int[u].Aggregate("",(t,i)=>t+m);}
Oliver Hallam
1
Sie können ein paar Bytes wie 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));}
folgt
1

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

Ich habe die @ atlasologist -Methode in Python verwendet, um Folgendes zu testen (1, 1):(...,'o')[x<2>y]

Vielen Dank an @Luis Mendo für das Speichern von 7 Bytes: a=ones(1,w*2+3)*'_'to a=~(1:w*2+3)+95und a./a*'-'to~a+45

Vielen Dank an @pajonk für das Speichern von 2 Bytes:f=

Marco
quelle
1
Dies ist kein gültiger Matlab-Code. Sie sollten nur als "Oktave" beschriften. Kannst a./a*'-'du auch anstatt verwenden ~~a*'-'? Oder sogar ~a+45?
Luis Mendo
Wahrscheinlich können Sie es auch als anonyme Funktion lassen (ohne f=)
pajonk