Eine geometrische Herausforderung

23

Jeder liebt Geometrie. Warum versuchen wir nicht, Golf zu programmieren? Diese Herausforderung besteht darin, Buchstaben und Zahlen aufzunehmen und daraus Formen zu machen.

Die Eingabe

Die Eingabe erfolgt in Form von (shapeIdentifier)(size)(inverter).

Aber was sind ShapeIdentifier, Größe und Inverter?

Der Formbezeichner ist der Bezeichner für den Formtyp, den Sie mit *s erstellen . Im Folgenden sind die Formbezeichner aufgeführt:

  • s - Platz
  • t - Dreieck

Die Größe wird zwischen 1-20und es ist die Größe der Figur.

Der Wechselrichter gibt an, ob die Form auf dem Kopf steht oder nicht, was durch a +oder a gekennzeichnet ist -. Beachten Sie: s3-== (gleich), s3+da die Quadrate symmetrisch sind. Allerdings t5-! = (Nicht gleich) t5+.

Nachgestellte Leerzeichen sind in der Ausgabe in Ordnung, führende Leerzeichen jedoch nicht.

Ausgabebeispiele

Input: s3+
Output:
***
***
***

Input: t5+

Output:
  *
 ***
*****

Input: t3-
Output:
***
 *

Besondere Hinweise

Die Dreieckeingabe ist immer eine ungerade Zahl, sodass die Dreiecke immer mit 1 *oben enden .

Die Größe des Dreiecks ist die Größe der Basis, wenn der Wechselrichter ist, +und die Größe der Oberseite, wenn der Wechselrichter ist -.

intboolstring
quelle
3
Als jemand, der gerade Geometrie nimmt (und für ein Geometrie-Finale lernt), kann ich mit 100% iger Gewissheit sagen: Geometrie ist absolut kein Spaß ... D:
Ashwin Gupta

Antworten:

9

Pyth, 40 36 34 32 Bytes

-1 Byte von @isaacg

JstPz_W}\+zjl#m.[J*\*-J*}\tzyd;J

Ein Semikolon in einem Lambda ist jetzt der globale Wert der Lambda-Variablen, wodurch ein Byte gespart wird.

                         Implicit: z = input
JstPz                    J = size.
_W }\+z                  Reverse if "+" in z
j l# m                J  Join the nonempty lines in map lambda d:... over range(J)
      .[J            ;   Pad the following with spaces (;) to length J
         *\*               "*", this many times:
            -J*}\tzyd        J if "t" not  in z,
                             otherwise the correct number for a triangle.

Probieren Sie es hier aus .

Testsuite .

Lirtosiast
quelle
1
Viel zu lang und doch 15 Byte schneller als Japt? Ich kann es kaum erwarten zu sehen, wie das gespielt wird :)
ETHproductions
Schöne lösung! Sie können ein Byte speichern durch Ersetzen qez\+mit }\+z, denn +nur in der letzten Position angezeigt.
isaacg
6

Pyth, 38 Bytes

JsPtzj?}\szm*\*JJ_W}\-zm.[J*\*hyd;/hJ2

Testsuite

Grundsätzlich so einfach wie es nur geht. Ich wünschte, ich könnte einen Teil der Logik für die beiden Formen kombinieren, aber derzeit ist sie getrennt.

isaacg
quelle
5

JavaScript (ES6), 142 146 147

Edit 1 Byte gespeichert dank @ETHproductions Edit 2 Byte gespeichert dank @ user81655

i=>([,a,b]=i.match`.(.+)(.)`,Array(l=i<'t'?+a:-~a/2).fill('*'.repeat(a)).map((r,i)=>l-a?(' '.repeat(i=b<'-'?--l:i)+r).slice(0,a-i):r).join`
`)

Test (in FireFox ausführen)

F=i=>(
  [,a,b]=i.match`.(.+)(.)`,
  Array(l=i<'t'?+a:-~a/2).fill('*'.repeat(a))
  .map((r,i)=>l-a?(' '.repeat(i=b<'-'?--l:i)+r).slice(0,a-i):r)
  .join`\n`
)

function test() { O.textContent=F(I.value) }

test()
Input: <input id=I oninput="test()" value="t11-"/>
<pre id=O></pre>

edc65
quelle
\d-> ., da es garantiert genau eine Stelle vor und nach dem gibt
ETHproductions
@ETHproductions richtig, danke
edc65
Nett. Ich denke, dies ist der optimale Algorithmus in JS, ich kann keinen kürzeren finden.
ETHproductions
i.match(/.(.+)(.)/)->i.match`.(.+)(.)`
user81655
@ user81655 netter Hinweis, danke
edc65
5

Python 2, 106 Bytes

s=raw_input()
n=int(s[1:-1])
for i in[range(1,n+1,2),n*[n]][s<'t'][::2*('+'in s)-1]:print('*'*i).center(n)

Die Ausgabe ist ein perfektes Rechteck, wobei jede Zeile mit nachgestellten Leerzeichen aufgefüllt ist. Ich gehe davon aus, dass dies aufgrund der Kommentare im OP in Ordnung ist.

Hinweis: Ich bin mir immer noch nicht sicher, ob inputPython 2 für solche Probleme zugelassen ist ...

Sp3000
quelle
4

Japt, 62 60 55 52 51 Bytes

V=Us1 n;U<'t?Vo ç*pV):0oV2 £S²pY iY'*pV-X})·z2*!Uf-

Probieren Sie es online!

Als erstes müssen wir herausfinden, wie groß unsere Form sein muss. Das ist ziemlich einfach:

      // Implicit: U = input string, S = space
V=    // Set variable V to
Us1   // everything after the first char of U,
n;    // converted to a number. This turns e.g. "12+" into 12.

Nun organisieren wir die Form der Ausgabe:

U<'t?      // If U comes before "t" lexicographically (here, if the first char is "s"),
Vo         //  make a list of V items,
ç*pV)      //  and set each item to V asterisks.
:0oV2      // Otherwise, create the range [0, V) with steps of 2 (e.g. 7 -> [0,2,4,6]),
£       }) //  and map each item X and index Y to:
S²pY       //   Repeat 2 spaces Y times. This creates a string of Y*2 spaces.
iY'*pV-X   //   At position Y in this string (right in the middle), insert V-X asterisks.
·          // Join with newlines.

Inzwischen haben wir uns um die Größe und Form der Ausgabe gekümmert. Alles was übrig bleibt ist die Rotation. Dreiecke sind momentan nach oben gerichtet, also müssen wir sie umdrehen, wenn das dritte Zeichen lautet +:

!Uf-    // Take the logical not of U.match("-").
        // If U contains "-", this returns false; otherwise, returns true.
2*      // Multiply by two. This converts true to 2, false to 0.
z       // Rotate the list 90° that many times.
        // Altogether, this turns the shape by 180° if necessary.

Und mit impliziter Ausgabe ist unsere Arbeit hier erledigt. :-)

ETHproductions
quelle
4

Python 2, 235 193 167 157 Bytes

Aktualisieren:

Einige signifikante Optimierungen mithilfe von Listenverständnissen und str.center () vorgenommen. Ich habe das Gefühl, dass ich noch mehr tun kann, um es mir später noch einmal genauer anzusehen.

Update 2

Sparte 10 Bytes mit den Vorschlägen von Sherlock9. Vielen Dank! :)

d=raw_input()
x=int(d[1:-1])
o="\n".join("*"*x for i in range(x))if d<"t"else"\n".join(("*"*i).center(x)for i in range(x,0,-2))
print o[::-1]if"+"in d else o

Alte Antwort

d=raw_input()
x=int(d[1:-1])
if "s" in d:
 for y in range(x):
    o+="*"*x+"\n"
 o=o[:-1]
else:
 b=0
 while x+1:
    o+=" "*b+"*"*x+" "*b+"\n"
    x-=2
    b+=1
 o=o[:-1]
 if d[-1]=="+":
    o=o[::-1]
print o

Ziemlich geradliniger Ansatz. Zeile für Zeile in eine Zeichenkette schreiben, die ich am Ende ausgegeben habe. Dreiecke werden immer invertiert gezeichnet und bei Bedarf umgekehrt. Die Tatsache, dass Sie eine Zeichenfolge mit einer Ganzzahl multiplizieren können, hat mir viele Bytes erspart!

Ich werde versuchen, das etwas später abzuspielen, würde mich in der Zwischenzeit über Anregungen freuen, da ich noch nicht so viel Erfahrung damit habe.

edit: Habe es mit der Hilfe in den Kommentaren viel runtergespielt und die Größenberechnung aus einer der anderen Python-Antworten gestohlen. Ich denke, das ist das Beste, was ich mit diesem Algorithmus machen kann.

Denker
quelle
Wie hast du gezählt? Wenn wcich das benutze, bekomme ich eine Byteanzahl von 235. Irre ich mich?
21.
1
Das sind in der Tat 235 Bytes. Golftipp: Verwenden Sie Tabulatoren anstelle von zwei Leerzeichen. Dies ist in Python 2 gültig und spart 5 Byte.
Türknauf
Außerdem müssen Sie nicht verwenden raw_input, mit inputsparen Sie 4 Bytes. Außerdem brauchen Sie die Klammern in der zweiten Zeile nicht, und wenn Sie die Variable xüberhaupt nicht verwenden (using if"s"in d), sparen Sie weitere 9 Bytes.
21.
2
@DenkerAffe Wenn Sie im Fenster zählen, subtrahieren Sie 1 Byte für jede neue Zeile - Zeilenumbrüche sind 2 Byte in Fenstern, aber 1 Byte in anderen Umgebungen
edc65
1
Zunächst können Sie die []Klammern in jedem joinFunktionsaufruf entfernen . Zweitens if d<"t"elseist kürzer und funktioniert da "s3+"<"t"<"t3+"in Python. Drittens else"\n".joinund .center(x)for. Kein Platz. Es ist nicht erforderlich. Viertens, print o[::-1]if"+"in d else owo ich Dinge für zwei Bytes neu angeordnet habe (ein Leerzeichen zwischen ]und ifund ein anderes zwischen ifund "+".
Sherlock9
3

JavaScript, 220 Byte.

q=s=>+s.slice(1,s.length-1);f=s=>s[0]=="s"?("*".repeat(q(s))+"\n").repeat(q(s)):Array.apply(0,Array(-~(q(s)/2))).map((_,n)=>(s[s.length-1]=="-"?~~(q(s)/2)-n:n)).map(n=>(" ".repeat(q(s)/2-n)+"*".repeat(n*2+1))).join("\n")

Laufen Sie mit f(input here)

Probieren Sie es hier aus!

Die Quadrate haben nachgestellte Zeilenumbrüche, die Dreiecke jedoch nicht. Erläuterung:

q=s=>+s.slice(1,s.length-1);                                                                                                                                                                                                 Define a function, q, that takes returns the argument, without the first and last character, casted into an integer.
                            f=s=>                                                                                                                                                                                            Define a function, f, that takes one argument, s. (This is the main function)
                                 s[0]=="s"?                                                                                                                                                                                  If the first character of s is "s" then...
                                           ("*".repeat(q(s))     )                                                                                                                                                           Repeat the "*" character q(s) times.
                                           (                +"\n")                                                                                                                                                           Append a newline to that
                                                                  .repeat(q(s))                                                                                                                                              Repeat that q(s) times.
                                                                               :                                                                                                                                             Else... (the first character of s isn't "s")
                                                                                Array.apply(0,Array(          ))                                                                                                             Create an array of length...
                                                                                Array.apply(0,Array(-~(q(s)/2)))                                                                                                             floor(q(s)/2)+1
                                                                                                                .map((_,n)=>                                   )                                                             Map each element, _ with index n to...
                                                                                                                .map((_,n)=>(s[s.length-1]=="-"?              ))                                                             If the last element of s is "-" then...
                                                                                                                .map((_,n)=>(s[s.length-1]=="-"?~~(q(s)/2)-n  ))                                                             floor(q(s)/2)-n
                                                                                                                .map((_,n)=>(s[s.length-1]=="-"?            : ))                                                             Else...
                                                                                                                .map((_,n)=>(s[s.length-1]=="-"?             n))                                                             Just n
                                                                                                                                                                .map(n=>                                        )            Map each element into...
                                                                                                                                                                .map(n=>(" ".repeat(q(s)/2-n)                   )            Repeat " ", q(s)/2-n times.
                                                                                                                                                                .map(n=>(                   )+"*".repeat(n*2+1)))            Append "*", repeated 2n+1 times.
                                                                                                                                                                .map(n=>(" ".repeat(        )+"*".repeat(n*2+1))).join("\n") Join with newlines
Loovjo
quelle
Die Länge Ihrer ersten Zeile beträgt 338 Zeichen. Ich brauche anderthalb Monitore für die Anzeige.
Isanae
3
@ Isanae Hier steht 220.
Loovjo
1
Ich klicke nicht auf einen zufälligen winzigen Link, sondern überprüfe es erneut. Vermeiden Sie auf jeden Fall Bildlaufleisten in Codefeldern, da dies das Lesen erheblich erschwert.
Isanae
1
@ Loovjo Ich denke, er meint die erste Zeile der Erklärung. Normalerweise rücke ich meine Erklärung ein und nicht diesen Stil für JavaScript-Antworten, sodass Sie nicht scrollen müssen, um die Hälfte davon zu sehen.
user81655
@ user81655 Ja, das habe ich in der Erklärung gemeint. Jetzt verstehe ich die Verwirrung!
Isanae
3

Python 2, 157 132 Bytes

def f(s):
 S=int(s[1:-1])
 for n in([range(1,S+2,2),range(S,0,-2)]['-'in s],[S]*S)['s'in s]:
  print "{:^{S}}".format('*'*n,S=S)

Der erste Versuch stellte sich heraus, dass das +/-Ende optional war

Die Idee hier ist, eine Liste zu erstellen, die in eine generische Ausgabe geworfen werden kann. Am schwierigsten war es, die Länge von der Eingabe zu trennen.

wnnmaw
quelle
Um die Länge zu ermitteln, habe ich x=int(d[1]if len(d)<4 else d[1:3])d als Eingabezeichenfolge verwendet. Das sind 5 Bytes kürzer als Ihre Lösung. Du bist meiner Python-Antwort immer noch weit voraus, musst versuchen zu verstehen, was du dort getan hast und dich das nächste Mal besiegen! :)
Denker
1
Eigentlich x=int(d[1:-1])ist das viel kürzer, habe es nur in der anderen Python-Antwort gesehen.
Denker
@DenkerAffe, aus welchem ​​Grund auch immer, ich erinnere mich, dass der Wechselrichter optional ist, damit das nicht funktioniert, aber ich denke, ich habe das gerade
erfunden
2

Retina , 102 bis 85 Bytes

Die Byteanzahl setzt voraus, dass der Quellcode als ISO 8859-1 codiert ist.

\d+
$0$*:¶
^((\w)+):(:+)
$1$2$3$2¶$0
m`s$|:t

)`(.+)¶-(\D*)
-$2¶$1
m`^.

G`.
T`ts:` *

Probieren Sie es online aus.

Ich versuche das später noch einmal.

Martin Ender
quelle
Notepad ++ gibt an, dass Ihr Code 89 Byte und nicht 85 Byte umfasst. Ich habe die ISO-8859-1-Codierung verwendet und unter Bearbeiten> EOL-Konvertierung> UNIX / Linux-Format die Option \nverwendet \r\n. Base64 des Inhalts: XGQrCiQwJCo6wrYKXigoXHcpKyk6KDorKQokMSQyJDMkMsK2JDAKbWBzJHw6dAoKKWAoLispwrYtKFxEKikKLSQywrYkMQptYF4uCgpHYC4KVGB0czpgICo=(direkte Kopie von Notepad ++). Komischerweise gibt mir jede Online-Lösung 85 Bytes ... Hum ...
Ismael Miguel
@IsmaelMiguel Da muss etwas dran sein, wie Notepad ++ das zählt . Sie sind definitiv ein einzelnes Byte in ISO 8859-1 (mit dem Wert 182).
Martin Ender
2

Im Ernst, 54 Bytes

,#i's=`≈;'**@½≈";#dXdXεj' +"£n`@`≈;'**n`@Iƒ('-=WXa0WXü

Probieren Sie es online

,#i                                                    Take input, push chars separately
   's=                                   Iƒ            IF the first char is "s":
                                `      `@                run the quoted function
                                 ≈;'**n                  make list of n strings of n *'s
      `                       `@                       ELSE run the quoted function:
       ≈;                                                make two copies of int n
         '**                                             use one to make string of n *'s
            @½≈                                          cut the other in half (e.g. 5->2)
               "           "£n                           run n/2 times the quoted function:
                ;#                                        copy the string as list of chars
                  dXdX                                    discard the last 2 *'s
                      εj                                  join back into string
                        ' +                               prepend a space
                                           ('-=WX 0WX  IF the third character is "-":
                                                 a       invert the stack
                                                     ü pop and print the entire stack

@Mego: Sehen Sie das #dXdXεj? STRING SLICING ????

Quintopie
quelle
2

ES6, 178 172 159 Bytes

s=>(p=s.match(/d+|./g),u=n=+p[1],m=n+1>>1,t=' '.repeat(n)+'*'.repeat(n),v=s<'t'?0:p[2]<'-'?(u=m,1):-1,[...Array(s<'t'?n:m)].map(_=>t.substr(u,u,u+=v)).join`
`)

Dies funktioniert aufgrund einer interessanten Beobachtung, die ich gemacht habe. Wenn Sie nLeerzeichen und nSternchen wiederholen , erhalten Sie (z. B. n=5) Folgendes:

     *****

Nehmen Sie nun Teilzeichenfolgen mit demselben Anfang und derselben Länge:

     |*****| (5)
    | ***| (4)
   |  *| (3)

Diese Teilzeichenfolgen sind genau die Zeichenfolgen, die wir benötigen t5.

Bearbeiten: 6 Bytes dank @ edc65 gespeichert.

Bearbeiten: 13 Bytes gespart, da u+=vdas dritte Argument substrausgeblendet wurde, um die Initialisierung zu vereinfachen.

Neil
quelle
@ThomasKwa Huh, nachdem ich den festen hatte tBehandlungscode es stellte sich heraus , dass wund uwurde gleichwertig und das rettete mich genug Bytes mich zurück zu nehmen bis zu 178!
Neil
[,b,c]=s.matchund später s<'t'... sollten einige Bytes speichern (nur Firefox)
edc65
@ edc65 Nur nicht das Speichern der Übereinstimmung serlaubt es mir zu verwenden, s<'t'was mir 6 Bytes erspart hat , danke.
Neil
2

MATL , 48 Bytes

' *'jt4Y2m)U1$l't'Gm?2MQ2/:1L3$)R!P!R'+'Gm?P]]Q)

Verwendet die aktuelle Version (10.1.0) der Sprache / des Compilers.

Der Code akzeptiert Eingabezeichen in beliebiger Reihenfolge: alle s11+, 11s+und selbst 1+s1würde gültige Eingabezeichenfolgen sein.

EDIT (30. Juli 2016): der verknüpften Code ersetzt 1L3$)durch Y)die jüngsten Änderungen in der Sprache anzupassen

Probieren Sie es online!

Erläuterung

' *'        % push string. Will be indexed into to obtain final result
j           % input string
t           % duplicate
4Y2         % predefined literal string '0123456789'
m           % logical index of digits in input string
)           % index into input string to obtain substring with digits
U           % convert to number
1$l         % generate square of ones with that size
't'         % push character 't'
G           % push input string
m           % true if input string contains 't'
?           % if so...
  2M        % push argument of call to function `l`, i.e. square size
  Q2/       % add 1 and divide by 2. Call result T
  :         % generate vector [1, 2, ... T]
  1L        % predefined literal representing Matlab's `:` index
  3$)       % two dimensional index. Transforms square into rectangle
  R         % remove (set to zero) lower-left corner
  !P!       % flip horizontally
  R         % remove lower-left corner. This gives inverted triangle
  '+'       % push character '+'
  G         % push input
  m         % true if input contains '+'
  ?         % if so...
    P       % flip vertically
  ]         % end if
]           % end if
Q           % add 1. This gives array of values 1 and 2
)           % index string ' *' with this array to produce char array
            % implicitly display that char array
Luis Mendo
quelle
1

C 259 Bytes

#define x(y);)putchar(y)
#define m(n)for(n=0;n++<
#define T {m(q)i x(32);m(q)s-i*2 x(42);puts("");}
main(q,v,i,s)char**v;{s=atoi(v[1]+1);if(*v[1]=='s')m(i)s*s x(42)&&!(i%s)&&puts("");else if(strchr(v[1],'+'))for(i=s/2+1;i-->0;)T else for(i=-1;i++<s/2+1;)T}

ungolfed

main(q,v,i,size)char**v; // neat way of declaring variables
{
    size=atoi(v[1]+1);
    if(*v[1]=='s')
    {
        for(i=0;i++<size*size;)
        {
            putchar(42); // returns 42 (true)
            if(!(i%size))
                puts("");
        }
    }
    else if(strchr(v[1],'+')) // if finds plus sign
    {
        for(i=size/2+1;i-->0;) // iterate the height of the triangle
        {
            for(q=0;q++<i;)putchar(32); // conveniently i is the number os spaces before each line
            for(q=0;q++<size-i*2;) putchar(42);
            puts("");
        }
    }
    else for(i=-1;i++<size/2+1;) // does the same as above but inverted order
    {
        for(q=0;q++<i;)putchar(32);
        for(q=0;q++<size-i*2;)putchar(42);
        puts("");
    }
}

Anregungen und Kritik sind sehr willkommen.

Lince Assassino
quelle
1

Rubin, 99

->s{n=s[1,2].to_i
n.times{|i|d=(s.ord-115)*(s[-1]<=>?,)*(n-1-i*2)
d<1&&puts((?**(n+d)).center(n))}}

Berechnet ein Quadrat oder ein Dreieck mit der Höhe nund mittlerer Breite n von verying die Neigung der Seiten (so das berechnete Breite Dreieck 2n-1 ist an der Basis 1 an der Spitze.) , Aber es nur druckt die Zeilen , die nicht überschreiten nZeichen.

im Testprogramm ungolfed

f=->s{                         #take a string as an argument
  n=s[1,2].to_i                #take 2 characters starting at index 1 and convert to a number for the size
  n.times{|i|                  #iterate through n rows    
    d=                         #calculate how many stars "MORE THAN" n we need on a row
    (s.ord-115)*               #ascii code for 1st character of string - 115 : s-->0, t-->1
    (s[-1]<=>?,)*              #compare last character of input with comma character - --> +1 + --> -1
    (n-1-i*2)                  #row number * 2: 0 at centre, positive above it, negative below it
    d<1&&                      #only output if d is nonpositive (i.e we need less than n or exactly n stars)
    puts((?**(n+d)).center(n)) #print n+d stars, centred in a field of n characters padded by whitespace
  }
}

f[gets.chomp]
Level River St
quelle
1

Jolf, 37 Bytes, nicht konkurrierend

Ich habe Funktionen hinzugefügt, nachdem diese Herausforderung veröffentlicht wurde, sodass dies nicht für die Annahme berücksichtigt werden kann. Dies ist in ISO-8859-7 kodiert. Probieren Sie hier alle Testfälle aus .

onFiΒ€ioSgiγ?='sn―sΒ'*―TΒ1'*?='-SZiγγ

Teil 1: Analysieren der Zeichenfolge

onFiΒ€ioSgi
on          set n to
  Fi         the first entity of i (the shape identifier)
    Β       set Β (beta) to
     €i      the "inside" of i (in this case, the size) as a number
       oS   set S to
         gi  the last entity of i (the inverter)

Teil 2: Das Ergebnis erhalten

γ?='sn―sΒ'*―TΒ1'*
γ                 set γ (gamma) to the result of the following expression
 ?='sn             if n is the character s,
      ―sΒ'*         then return a pattern "s" (a square) made with "*"s
           ―TΒ1'*    otherwise, return a pattern "T" (triangle) that is centered and
                     has a scale factor of 1, made with "*"s

Teil 3: Invertieren des Ergebnisses

?='-SZiγγ
?='-S     if S is a "-"
     Ziγ   return γ, inverted across its lines
        γ  otherwise, return γ untouched
Conor O'Brien
quelle