Un desafío geométrico

23

Todos aman la geometría. Entonces, ¿por qué no intentamos codificar el golf? Este desafío implica tomar letras y números y hacer formas dependiendo de ello.

La entrada

La entrada será en forma de (shapeIdentifier)(size)(inverter).

Pero, ¿qué son shapeIdentifier, size e inverter?

El identificador de forma es el identificador del tipo de forma que creará con *s. Los siguientes son los identificadores de forma:

  • s - Cuadrado
  • t - triángulo

El tamaño estará entre 1-20, y es el tamaño de la figura.

El inversor es si la forma estará invertida o no, lo que se denota con a +o a -. Tenga en cuenta: s3-== (igual) s3+porque los cuadrados son simétricos. Sin embargo t5-,! = (No es igual) t5+.

Los espacios en blanco finales están bien en la salida, pero los espacios en blanco iniciales no lo están.

Ejemplos de salida

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

Input: t5+

Output:
  *
 ***
*****

Input: t3-
Output:
***
 *

Notas especiales

La entrada del triángulo siempre será un número impar, por lo que los triángulos siempre terminarán con 1 *en la parte superior.

El tamaño del triángulo es el tamaño de la base si el inversor lo es +y es el tamaño de la parte superior si el inversor lo es -.

intboolstring
fuente
3
Como alguien que está tomando Geometría en este momento, (y estudiando para una final de Geometría), puedo decir con 100% de certeza: La geometría es absolutamente, no es nada divertida ... D:
Ashwin Gupta

Respuestas:

9

Pyth, 40 36 34 32 bytes

-1 byte por @isaacg

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

Un punto y coma dentro de una lambda es ahora el valor global de la variable lambda, una característica que guarda un byte.

                         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.

Probarlo aquí .

Banco de pruebas .

lirtosiast
fuente
1
¿Demasiado tiempo, pero superando a Japt por 15 bytes? No puedo esperar para ver cómo se jugará esto :)
ETHproductions
Buena solución! Puede guardar un byte reemplazándolo qez\+con }\+z, porque +solo puede aparecer en la última posición.
isaacg
6

Pyth, 38 bytes

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

Banco de pruebas

Básicamente tan sencillo como se pone. Desearía poder combinar parte de la lógica de las dos formas, pero actualmente está separada.

isaacg
fuente
5

JavaScript (ES6), 142146147

Editar 1 byte guardado thx @ETHproductions Editar 2 bytes 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`
`)

Prueba (ejecutar en 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
fuente
\d-> ., ya que se garantiza que habrá exactamente un no dígito antes y después
ETHproductions
@ETHproductions bien, gracias
edc65
Agradable. Creo que este es el algoritmo óptimo en JS, no puedo encontrar uno más corto.
ETHproductions
i.match(/.(.+)(.)/)->i.match`.(.+)(.)`
user81655
@ user81655 buena pista, gracias
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)

El resultado es un rectángulo perfecto, con cada línea rellenada con espacios finales, lo que supongo que está bien según los comentarios en el OP.

Nota: Todavía no estoy seguro de si inputestá permitido en Python 2 para problemas como estos ...

Sp3000
fuente
4

Japt, 62 60 55 52 51 bytes

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

Pruébalo en línea!

Lo primero que debemos hacer es descubrir qué tan grande debe ser nuestra forma. Esto es bastante 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.

Ahora organizamos la forma de la salida:

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.

Por ahora, nos hemos ocupado del tamaño y la forma de la salida. Todo lo que queda es la rotación. Los triángulos están actualmente apuntados hacia arriba, por lo que debemos voltearlos si el tercer carácter es +:

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

Y con salida implícita, nuestro trabajo aquí está hecho. :-)

ETHproducciones
fuente
4

Python 2, 235 193 167 157 Bytes

Actualizar:

Se realizó una optimización significativa mediante el uso de comprensiones de listas y str.center (). Tengo la sensación de que puedo hacer un poco más, pero luego tendré una nueva mirada.

Actualización 2

Guardado 10 bytes con las sugerencias de Sherlock9. ¡Muchas gracias! :)

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

Vieja respuesta

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

Enfoque bastante sencillo. Escribir línea por línea en una cadena que saqué al final. Los triángulos siempre se dibujan invertidos y se invierten si es necesario. ¡El hecho de que puedas multiplicar una cadena con un entero me salvó muchos bytes!

Intentaré jugar golf un poco más tarde, agradecería sugerencias mientras tanto, ya que todavía no he experimentado tanto.

editar: Golfed mucho con la ayuda en los comentarios y robando el cálculo del tamaño de una de las otras respuestas de Python. Creo que eso es lo máximo que puedo hacer con este algoritmo.

Denker
fuente
Como contabas Cuando uso wcesto me da un conteo de bytes de 235. ¿Me equivoco?
ბიმო
1
Esto es de hecho 235 bytes. Consejo de golf: use pestañas en lugar de dos espacios, lo cual es válido en Python 2 y reducirá 5 bytes.
Pomo de la puerta
Además, no necesita usarlo raw_input, el uso le inputahorra 4 bytes. Además, no necesita los corchetes en la segunda línea, esto y no usar la variable x(usar if"s"in d) le ahorra otros 9 bytes.
ბიმო
2
@DenkerAffe al contar en la ventana, reste 1 byte para cada nueva línea: las nuevas líneas son de 2 bytes en las ventanas, pero 1 byte en otros entornos
edc65
1
Primero, puede quitar los []corchetes en cada una de las joinllamadas a funciones. En segundo lugar, if d<"t"elsees más corto y funciona porque "s3+"<"t"<"t3+"en Python. Tercero, else"\n".joiny .center(x)for. Sin espacio. No es requerido Cuarto, print o[::-1]if"+"in d else odonde reorganicé las cosas por dos bytes (un espacio entre ]y ify otro entre ify "+".
Sherlock9
3

JavaScript, 220 bytes.

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

Corre con f(input here)

Intentalo aquí!

Los cuadrados tienen líneas nuevas al final, pero los triángulos no. Explicación:

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
fuente
La longitud de su primera línea es de 338 caracteres. Me lleva un monitor y medio para mostrar.
isanae
3
@isanae Aquí dice 220.
Loovjo
1
No haré clic en un enlace de tinyurl al azar, pero verifique nuevamente. En cualquier caso, intente evitar las barras de desplazamiento en los cuadros de código, ya que es mucho más difícil de leer.
isanae
1
@Loovjo Creo que se refiere a la primera línea de la explicación. Por lo general, sangro mi explicación en lugar de este estilo para las respuestas de JavaScript, por lo que no necesita desplazarse para ver la mitad.
user81655
@ user81655 Sí, quise decir en la explicación. Ahora entiendo la confusión!
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)

El primer intento confirmó que el +/- final era opcional, deshacerme de eso me permitió afeitarme un montón

La idea aquí es hacer una lista que pueda incluirse en una salida genérica. La parte más difícil fue separar la longitud de la entrada.

wnnmaw
fuente
Para obtener la longitud que usé x=int(d[1]if len(d)<4 else d[1:3])con d como la cadena de entrada. Eso es 5 bytes más corto que su solución. ¡Todavía estás muy por delante de mi respuesta de Python aunque, tengo que tratar de entender lo que hiciste allí y vencerte la próxima vez! :)
Denker
1
En realidad x=int(d[1:-1])es mucho más corto para eso, solo lo vi en la otra respuesta de Python.
Denker
@DenkerAffe, por cualquier razón, recuerdo que el inversor es opcional, por lo que eso no funcionaría, pero supongo que lo
inventé
2

Retina , 102 85 bytes

El recuento de bytes supone que el código fuente está codificado como ISO 8859-1.

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

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

G`.
T`ts:` *

Pruébalo en línea.

Intentaré jugar al golf un poco más tarde.

Martin Ender
fuente
Notepad ++ dice que su código es de 89 bytes, no 85. Utilicé la codificación ISO-8859-1 y seguí en Edición> Conversión EOL> Formato UNIX / Linux, para usar en \nlugar de \r\n. Base64 del contenido: XGQrCiQwJCo6wrYKXigoXHcpKyk6KDorKQokMSQyJDMkMsK2JDAKbWBzJHw6dAoKKWAoLispwrYtKFxEKikKLSQywrYkMQptYF4uCgpHYC4KVGB0czpgICo=(copia directa desde Notepad ++). Por extraño que parezca, cualquier solución en línea me da 85 bytes ... Hum ...
Ismael Miguel
@IsmaelMiguel Debe haber algo extraño con la forma en que Notepad ++ cuenta . Definitivamente son un solo byte en ISO 8859-1 (con valor 182).
Martin Ender
2

En serio, 54 bytes

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

Pruébalo en línea

,#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: ¿Ves eso #dXdXεj? CUERDA EN LAMINAS ????

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

Esto funciona debido a una observación interesante que hice. Si repite nespacios y nasteriscos, obtiene (por ejemplo, para n=5) esto:

     *****

Ahora, tome subcadenas con el mismo inicio y longitud:

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

Estas subcadenas son exactamente las cadenas que necesitamos para t5 .

Editar: Guardado 6 bytes gracias a @ edc65.

Editar: ahorré 13 bytes gracias a ocultar el u+=vtercer argumento, substrlo que me permitió simplificar la inicialización.

Neil
fuente
@ThomasKwa Huh, después de haber arreglado el tcódigo de manejo resultó que wy use convirtieron en equivalentes y que me salvó suficientes bytes que me lleve de vuelta a 178!
Neil
[,b,c]=s.matchy más tarde s<'t'... debería guardar algunos bytes (solo Firefox)
edc65
@ edc65 Simplemente no guardar la coincidencia sme permite usar lo s<'t'que me ahorró 6 bytes, gracias.
Neil
2

MATL , 48 bytes

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

Usos la versión actual (10.1.0) del lenguaje / compilador.

El código de caracteres de entrada acepta en cualquier orden: todos s11+, 11s+e incluso1+s1 serían cadenas de entrada válidas.

EDITAR (30 de julio de 2016): el código vinculado reemplaza 1L3$)por Y)para ajustarse a los cambios recientes en el idioma

Pruébalo en línea!

Explicación

' *'        % 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
fuente
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}

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

Sugerencias y críticas son bienvenidas.

Lince Assassino
fuente
1

Rubí, 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))}}

Calcula un cuadrado o triángulo de altura ny ancho promedio n marcando la pendiente de los lados (por lo que el ancho del triángulo calculado es 2n-1 en la base, 1 en la punta). Pero solo imprime las filas que no excedenn caracteres.

sin golf en el programa de prueba

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
fuente
1

Jolf, 37 bytes, sin competencia

Agregué funciones después de que se publicó este desafío, por lo que no se puede considerar su aceptación. Esto está codificado en ISO-8859-7. Pruebe todos los casos de prueba aquí .

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

Parte 1: analizar la cadena

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)

Parte 2: obtener el resultado

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

Parte 3: invirtiendo el resultado

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