Un défi géométrique

23

Tout le monde aime la géométrie. Alors pourquoi n'essayons-nous pas de coder le golf? Ce défi consiste à saisir des lettres et des chiffres et à créer des formes en fonction de ceux-ci.

L'entrée

L'entrée sera sous la forme de (shapeIdentifier)(size)(inverter).

Mais que sont shapeIdentifier, size et inverter?

L'identifiant de forme est l'identifiant du type de forme que vous allez créer avec l' *art. Voici les identificateurs de forme:

  • s - Carré
  • t - Triangle

La taille sera comprise entre 1-20, et c'est la taille de la figure.

L'onduleur détermine si la forme sera inversée ou non, ce qui est indiqué par a +ou a -. Notez: s3-== (égal) s3+car les carrés sont symétriques. Cependant t5-,! = (N'est pas égal) t5+.

Les espaces de fin sont corrects dans la sortie, mais les espaces de début ne le sont pas.

Exemples de sortie

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

Input: t5+

Output:
  *
 ***
*****

Input: t3-
Output:
***
 *

Notes spéciales

L'entrée du triangle sera toujours un nombre impair, donc les triangles se termineront toujours par 1 *en haut.

La taille du triangle est la taille de la base si l'onduleur est +et est la taille du haut si l'onduleur l'est -.

intboolstring
la source
3
En tant que personne qui prend la géométrie en ce moment (et étudie pour une finale de géométrie), je peux dire avec 100% de certitude: la géométrie n'est absolument pas amusante du tout ... D:
Ashwin Gupta

Réponses:

9

Pyth, 40 36 34 32 octets

-1 octet par @isaacg

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

Un point-virgule à l'intérieur d'un lambda est désormais la valeur globale de la variable lambda, une fonctionnalité qui enregistre un octet.

                         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.

Essayez-le ici .

Suite de tests .

lirtosiast
la source
1
Beaucoup trop long, tout en battant Japt de 15 octets? J'ai hâte de voir comment cela se jouera :)
ETHproductions
Bonne solution! Vous pouvez enregistrer un octet en le remplaçant qez\+par }\+z, car +il ne peut apparaître qu'à la dernière position.
isaacg
6

Pyth, 38 octets

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

Suite de tests

Fondamentalement aussi simple que possible. J'aimerais pouvoir combiner une partie de la logique des deux formes, mais actuellement, c'est séparé.

isaacg
la source
5

JavaScript (ES6), 142 146 147

Modifier 1 octet enregistré thx @ETHproductions Modifier 2 octets sve thx @ 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 (exécuté dans FireFox)

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
la source
\d-> ., car il est garanti qu'il y aura exactement un non-chiffre avant et après
ETHproductions
@ETHproductions à droite, merci
edc65
Agréable. Je pense que c'est l'algorithme optimal dans JS, je ne peux pas en trouver un plus court.
ETHproductions
i.match(/.(.+)(.)/)->i.match`.(.+)(.)`
user81655
@ user81655 bon indice, merci
edc65
5

Python 2, 106 octets

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)

La sortie est un rectangle parfait, avec chaque ligne remplie d'espaces de fin, ce qui, je suppose, est correct sur la base des commentaires dans l'OP.

Remarque: je ne sais toujours pas si inputPython 2 est autorisé pour des problèmes comme ceux-ci ...

Sp3000
la source
4

Japt, 62 60 55 52 51 octets

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

Essayez-le en ligne!

La première chose que nous devons faire est de déterminer la taille de notre forme. C'est assez simple:

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

Maintenant, nous organisons la forme de la sortie:

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.

À ce jour, nous avons pris soin de la taille et de la forme de la sortie. Tout ce qui reste est la rotation. Les triangles sont actuellement pointés, nous devons donc les retourner si le troisième caractère est +:

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

Et avec une sortie implicite, notre travail ici est terminé. :-)

ETHproductions
la source
4

Python 2, 235 193 167 167 157 octets

Mise à jour:

Optimisation significative en utilisant les compréhensions de liste et str.center (). J'ai le sentiment que je peux en faire plus, je vais y jeter un nouveau regard plus tard.

Update 2

10 octets enregistrés avec les suggestions de Sherlock9. Merci beaucoup! :)

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

Ancienne réponse

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

Approche assez directe. Écriture ligne par ligne dans une chaîne que je produis à la fin. Les triangles sont toujours dessinés inversés et inversés si nécessaire. Le fait que vous puissiez multiplier une chaîne avec un entier m'a fait économiser beaucoup d'octets!

J'essaierai de jouer au golf un peu plus tard, j'apprécierais des suggestions en attendant, car je ne suis pas encore très expérimenté avec cela.

edit: Il a beaucoup joué avec l'aide des commentaires et volé le calcul de la taille de l'une des autres réponses python. Je pense que c'est le plus que je puisse faire avec cet algorithme.

Denker
la source
Comment avez-vous compté? Lors de l'utilisation, wccela me donne un nombre d'octets de 235. Ai-je tort?
ბიმო
1
C'est en effet 235 octets. Conseil de golf: utilisez des tabulations au lieu de deux espaces, ce qui est valable en Python 2 et réduira de 5 octets.
Poignée de porte
De plus, vous n'avez pas besoin d'utiliser raw_input, en utilisant inputvous économise 4 octets. De plus, vous n'avez pas besoin des parenthèses dans la deuxième ligne, cela et ne pas utiliser du tout la variable x(en utilisant if"s"in d) vous économise encore 9 octets.
ბიმო
2
@DenkerAffe lors du comptage dans la fenêtre, soustrayez 1 octet pour chaque nouvelle ligne - les nouvelles lignes font 2 octets dans les fenêtres, mais 1 octet dans les autres environnements
edc65
1
Tout d'abord, vous pouvez supprimer les []crochets dans chacun des joinappels de fonction. Deuxièmement, if d<"t"elseest plus court et fonctionne parce "s3+"<"t"<"t3+"qu'en Python. Troisièmement, else"\n".joinet .center(x)for. Pas d'espace. Ce n'est pas obligatoire. Quatrièmement, print o[::-1]if"+"in d else ooù j'ai réorganisé les choses sur deux octets (un espace entre ]et ifet un autre entre ifet "+" .
Sherlock9
3

JavaScript, 220 octets.

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")

Courir avec f(input here)

Essayez-le ici!

Les carrés ont des nouvelles lignes de fin, mais pas les triangles. Explication:

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
la source
La longueur de votre première ligne est de 338 caractères. Il me faut un moniteur et demi pour afficher.
isanae
3
@isanae Il est dit 220 ici.
Loovjo
1
Je ne cliquerai pas sur un lien tinyurl aléatoire, mais vérifiez à nouveau. Dans tous les cas, essayez d'éviter les barres de défilement dans les zones de code, cela rend la lecture beaucoup plus difficile.
isanae
1
@ Loovjo Je pense qu'il veut dire la première ligne de l'explication. Je met généralement en retrait mon explication plutôt que ce style pour les réponses JavaScript, vous n'avez donc pas besoin de faire défiler pour en voir la moitié.
user81655
@ user81655 Oui, je voulais dire dans l'explication. Maintenant je comprends la confusion!
isanae
3

Python 2, 157 132 octets

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)

La première tentative a supposé que la +/-fin était facultative, m'en débarrasser m'a permis de me raser un tas

L'idée ici est de faire une liste qui peut être jetée dans une sortie générique. La partie la plus difficile séparait la longueur de l'entrée.

wnnmaw
la source
Pour obtenir la longueur que j'ai utilisée x=int(d[1]if len(d)<4 else d[1:3])avec d étant la chaîne d'entrée. C'est 5 octets de moins que votre solution. Vous êtes toujours en avance sur mon python-réponse, je dois essayer de comprendre ce que vous y avez fait et vous battre la prochaine fois! :)
Denker
1
En fait, x=int(d[1:-1])c'est beaucoup plus court pour cela, je l'ai vu dans l'autre réponse en python.
Denker
@DenkerAffe, pour une raison quelconque, je me souviens que l'onduleur était optionnel, donc cela ne fonctionnerait pas, mais je suppose que je viens de l'
inventer
2

Rétine , 102 85 octets

Le nombre d'octets suppose que le code source est codé en ISO 8859-1.

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

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

G`.
T`ts:` *

Essayez-le en ligne.

Je vais essayer de jouer au golf un peu plus tard.

Martin Ender
la source
Notepad ++ dit que votre code est de 89 octets, pas 85. J'ai utilisé l'encodage ISO-8859-1 et je suis allé sur Édition> Conversion EOL> Format UNIX / Linux, à utiliser à la \nplace de \r\n. Base64 du contenu: XGQrCiQwJCo6wrYKXigoXHcpKyk6KDorKQokMSQyJDMkMsK2JDAKbWBzJHw6dAoKKWAoLispwrYtKFxEKikKLSQywrYkMQptYF4uCgpHYC4KVGB0czpgICo=(copie directe depuis Notepad ++). Bizarrement, toute solution en ligne me donne 85 octets ... Hum ...
Ismael Miguel
@IsmaelMiguel Il doit y avoir quelque chose de différent avec la façon dont Notepad ++ compte . Ils sont certainement un seul octet dans ISO 8859-1 (avec la valeur 182).
Martin Ender
2

Sérieusement, 54 octets

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

Essayez-le en ligne

,#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: Tu vois ça #dXdXεj? STRING SLICING ????

quintopie
la source
2

ES6, 178 172 159 159 octets

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`
`)

Cela fonctionne en raison d'une observation intéressante que j'ai faite. Si vous répétez des nespaces et des nastérisques, vous obtenez (par exemple pour n=5) ceci:

     *****

Maintenant, prenez des sous-chaînes avec le même début et la même longueur:

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

Ces sous-chaînes sont exactement les chaînes dont nous avons besoin t5.

Edit: 6 octets enregistrés grâce à @ edc65.

Edit: économisé 13 octets grâce au masquage du u+=vtroisième argument substrqui me permet ainsi de simplifier l'initialisation.

Neil
la source
@ThomasKwa Huh, après avoir corrigé le tcode de manipulation, il s'est avéré quew et uest devenu équivalent et qui m'a sauvé assez d' octets pour me ramener vers le bas à 178!
Neil
[,b,c]=s.match et ensuite s<'t' ... devrait économiser quelques octets (Firefox uniquement)
edc65
@ edc65 Le fait de ne pas enregistrer la correspondance sme permet d'utiliser s<'t'ce qui m'a fait gagner 6 octets, merci.
Neil
2

MATL , 48 octets

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

Utilise la version actuelle (10.1.0) du langage / compilateur.

Le code accepte les caractères d'entrée dans n'importe quel ordre: tous s11+, 11s+et même 1+s1serait des chaînes d'entrée valides.

EDIT (30 juillet 2016): le code lié remplace 1L3$)par Y)pour se conformer aux récents changements de langue

Essayez-le en ligne!

Explication

' *'        % 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
la source
1

C, 259 octets

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

non golfé

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

Les suggestions et critiques sont les bienvenues.

Lince Assassino
la source
1

Rubis, 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))}}

Calcule un carré ou un triangle de hauteur net de largeur moyenne n en ajustant la pente des côtés (donc la largeur calculée du triangle est 2n-1 à la base, 1 à la pointe.) Mais il n'imprime que les lignes qui ne dépassent pas les ncaractères.

non golfé dans le programme de test

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
la source
1

Jolf, 37 octets, sans concurrence

J'ai ajouté des fonctions après la publication de ce défi, donc cela ne peut pas être considéré pour acceptation. Ceci est codé dans ISO-8859-7. Essayez tous les cas de test ici .

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

Partie 1: analyser la chaîne

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)

Partie 2: obtenir le résultat

γ?='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

Partie 3: inverser le résultat

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