Una sfida geometrica


23

Tutti amano la geometria. Quindi perché non proviamo a programmare il golf? Questa sfida consiste nel prendere lettere e numeri e creare forme a seconda di essa.

L'ingresso

L'input sarà nella forma di (shapeIdentifier)(size)(inverter).

Ma cosa sono shapeIdentifier, dimensioni e inverter?

L'identificatore di forma è l'identificatore del tipo di forma che verrà creato con *s. Di seguito sono riportati gli identificatori di forma:

  • s - Piazza
  • t - Triangolo

La dimensione sarà tra 1-20, ed è la dimensione della figura.

L'inverter è se la forma sarà capovolta o meno, che è indicata da a +o a -. Nota: s3-== (uguale a) s3+perché i quadrati sono simmetrici. Tuttavia t5-,! = (Non è uguale) t5+.

Lo spazio bianco finale va bene nell'output ma lo spazio bianco iniziale no.

Esempi di output

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

Input: t5+

Output:
  *
 ***
*****

Input: t3-
Output:
***
 *

Note speciali

L'input del triangolo sarà sempre un numero dispari, quindi i triangoli finiranno sempre con 1 *in alto.

La dimensione del triangolo è la dimensione della base se l'inverter è +ed è la dimensione della parte superiore se l'inverter lo è -.


3
Come qualcuno che sta prendendo Geometry in questo momento, (e studiando per una finale di Geometry), posso dire con certezza al 100%: la Geometria è assolutamente, per niente divertente ... D:
Ashwin Gupta,

Risposte:


9

Pyth, 40 36 34 32 byte

-1 byte di @isaacg

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

Un punto e virgola all'interno di una lambda è ora il valore globale della variabile lambda, una funzione che consente di salvare 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.

Provalo qui .

Suite di test .


1
Troppo a lungo, ma battendo Japt di 15 byte? Non vedo l'ora di vedere come sarà giocato a golf :)
ETHproductions

Bella soluzione! È possibile salvare un byte sostituendolo qez\+con }\+z, poiché +può apparire solo nell'ultima posizione.
Isaacg,

6

Pyth, 38 byte

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

Suite di test

Fondamentalmente il più semplice possibile. Vorrei poter combinare un po 'della logica per le due forme, ma attualmente è separato.


5

JavaScript (ES6), 142 146 147

Modifica 1 byte salvato thx @ETHproductions Modifica 2 byte 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 (eseguito in 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>


\d-> ., dato che è garantito che sia esattamente una non cifra prima e dopo
ETHproductions

@ETHproductions giusto, grazie
edc65

Bello. Penso che questo sia l'algoritmo ottimale in JS, non riesco a trovarne uno più corto.
ETHproductions

i.match(/.(.+)(.)/)->i.match`.(.+)(.)`
user81655

@ user81655 bel suggerimento, grazie
edc65

5

Python 2, 106 byte

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)

L'output è un rettangolo perfetto, con ogni riga riempita con spazi finali, che presumo sia ok sulla base dei commenti nell'OP.

Nota: non sono ancora sicuro se inputsia consentito in Python 2 per problemi come questi ...


4

Japt, 62 60 55 52 51 byte

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

Provalo online!

La prima cosa che dobbiamo fare è capire quanto deve essere grande la nostra forma. Questo è abbastanza semplice:

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

Ora organizziamo la forma dell'output:

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.

Ormai ci siamo occupati delle dimensioni e della forma dell'output. Non resta che la rotazione. I triangoli sono attualmente puntati verso l'alto, quindi dobbiamo capovolgerli se il terzo carattere è +:

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

E con un output implicito, il nostro lavoro qui è finito. :-)


4

Python 2, 235 193 167 157 byte

Aggiornare:

Ho apportato alcune ottimizzazioni significative utilizzando la comprensione dell'elenco e str.center (). Ho la sensazione di poter fare ancora un po ', poi avrò un nuovo sguardo più tardi.

Aggiornamento 2

Salvato 10 byte con i suggerimenti di Sherlock9. Molte grazie! :)

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

Vecchia risposta

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

Approccio piuttosto diretto. Scrivere riga per riga in una stringa che ho prodotto alla fine. I triangoli sono sempre disegnati invertiti e, se necessario, invertiti. Il fatto che tu possa moltiplicare una stringa con un numero intero mi ha salvato un sacco di byte!

Proverò a giocare a golf un po 'più tardi, nel frattempo apprezzerei i suggerimenti, dal momento che non ne sono ancora molto entusiasta.

modifica: risolto molto con l'aiuto nei commenti e rubando il calcolo delle dimensioni da una delle altre risposte di Python. Penso che sia il massimo che posso fare con questo algoritmo.


Come hai contato? Quando si usa wcquesto mi dà un conteggio di byte di 235. Sbaglio?
ბიმო

1
Si tratta in effetti di 235 byte. Consigli per giocare a golf: utilizzare le schede anziché due spazi, che è valido in Python 2 e si raderà di 5 byte.
Maniglia della porta

Inoltre non è necessario utilizzare raw_input, utilizzando inputconsente di risparmiare 4 byte. Inoltre non hai bisogno delle parentesi nella seconda riga, questo e non usare affatto la variabile x(usando if"s"in d) ti fa risparmiare altri 9 byte.
ბიმო

2
@DenkerAffe durante il conteggio in window, sottrai 1 byte per ogni newline - i newline sono 2 byte in windows, ma 1 byte in altri ambienti
edc65

1
Innanzitutto, è possibile rimuovere le []parentesi in ciascuna delle joinchiamate di funzione. Secondo, if d<"t"elseè più breve e funziona perché "s3+"<"t"<"t3+"in Python. Terzo, else"\n".joine .center(x)for. Nessuno spazio. Non è richiesto. In quarto luogo, print o[::-1]if"+"in d else odove ho riordinato le cose per due byte (uno spazio tra ]e ife un altro tra ife "+".
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")

Corri con f(input here)

Provalo qui!

I quadrati hanno nuove linee finali, ma i triangoli no. Spiegazione:

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

La lunghezza della prima riga è di 338 caratteri. Mi ci vuole un monitor e mezzo per la visualizzazione.
Isanae,

3
@isanae Qui dice 220.
Loovjo,

1
Non farò clic su un collegamento casuale tinyurl, ma ricontrollerò. In ogni caso, prova ad evitare le barre di scorrimento nelle caselle di codice, rende molto più difficile la lettura.
Isanae,

1
@Loovjo Penso che significhi la prima riga della spiegazione. Di solito indico la mia spiegazione piuttosto che questo stile per le risposte JavaScript, quindi non è necessario scorrere per vederne la metà.
user81655

@ user81655 Sì, intendevo nella spiegazione. Ora capisco la confusione!
Isanae,

3

Python 2, 157 132 byte

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)

Il primo tentativo prevedeva che la +/-parte finale fosse facoltativa, liberandomi di ciò mi permettevo di radere un mucchio

L'idea qui è di creare un elenco che può essere gettato in un output generico. La parte più difficile era separare la lunghezza dall'input.


Per ottenere la lunghezza che ho usato x=int(d[1]if len(d)<4 else d[1:3])con d come stringa di input. Quello è 5 byte più corto della tua soluzione. Sei ancora molto avanti rispetto alla mia risposta in pitone, devo cercare di capire cosa hai fatto lì e batterti la prossima volta! :)
Denker il

1
In realtà x=int(d[1:-1])è molto più breve per quello, appena visto nell'altra risposta di Python.
Denker,

@DenkerAffe, per qualsiasi motivo ricordo che l'inverter era opzionale, quindi non avrebbe funzionato, ma immagino di averlo appena
inventato

2

Retina , 102 85 byte

Il conteggio dei byte presuppone che il codice sorgente sia codificato come ISO 8859-1.

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

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

G`.
T`ts:` *

Provalo online.

Proverò a giocare ancora un po 'più tardi.


Notepad ++ dice che il codice è di 89 byte, non 85. Ho usato la codifica ISO-8859-1, e sono andato su Modifica> EOL Convertion> Formato UNIX / Linux, da usare \nal posto di \r\n. Base64 del contenuto: XGQrCiQwJCo6wrYKXigoXHcpKyk6KDorKQokMSQyJDMkMsK2JDAKbWBzJHw6dAoKKWAoLispwrYtKFxEKikKLSQywrYkMQptYF4uCgpHYC4KVGB0czpgICo=(copia diretta da Notepad ++). Stranamente, qualsiasi soluzione online mi dà 85 byte ... Hum ...
Ismael Miguel,

@IsmaelMiguel Dev'esserci qualcosa su come Notepad ++ conta . Sono sicuramente un singolo byte in ISO 8859-1 (con valore 182).
Martin Ender,

2

Scherzi a parte, 54 byte

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

Provalo 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: lo vedi #dXdXεj? AFFETTARE IL AFFETTARE ????


2

ES6, 178 172 159 byte

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

Questo funziona a causa di un'interessante osservazione che ho fatto. Se ripetin spazi e nasterischi ottieni (ad esempio per n=5) questo:

     *****

Ora, prendi sottostringhe con lo stesso inizio e lunghezza:

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

Queste sottostringhe sono esattamente le stringhe di cui abbiamo bisogno t5.

Modifica: salvato 6 byte grazie a @ edc65.

Modifica: salvato 13 byte grazie a nascondere u+=vil terzo argomento substrper consentirmi di semplificare l'inizializzazione.


@ThomasKwa Eh, dopo che avevo fissato il tcodice di gestione si è scoperto che we udiventato equivalenti e che mi ha salvato abbastanza byte di riportarmi giù a 178!
Neil,

[,b,c]=s.matche in seguito s<'t'... dovrebbe salvare alcuni byte (solo Firefox)
edc65

@ edc65 Il solo fatto di non salvare la partita smi consente di utilizzare il s<'t'che mi ha salvato 6 byte, grazie.
Neil,

2

MATL , 48 byte

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

Utilizza la versione corrente (10.1.0) della lingua / compilatore.

Il codice accetta i caratteri di input in qualsiasi ordine: all s11+, 11s+e perfino 1+s1sarebbe stringhe di input valide.

EDIT (30 luglio 2016): il codice collegato sostituisce 1L3$)con Y)per conformarsi alle recenti modifiche nella lingua

Provalo online!

Spiegazione

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

1

C, 259 byte

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

Suggerimenti e critiche sono i benvenuti.


1

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

Calcola un quadrato o un triangolo di altezza ne larghezza media n calcolando la pendenza dei lati (quindi la larghezza del triangolo calcolata è 2n-1 alla base, 1 sulla punta). Ma stampa solo quelle righe che non superano i ncaratteri.

non golfato nel programma di 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]

1

Jolf, 37 byte, non competitivo

Ho aggiunto funzioni dopo che questa sfida è stata pubblicata, quindi questo non può essere considerato per l'accettazione. Questo è codificato in ISO-8859-7. Prova tutti i casi di test qui .

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

Parte 1: analisi della stringa

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: ottenere il risultato

γ?='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: invertire il risultato

?='-SZiγγ
?='-S     if S is a "-"
     Ziγ   return γ, inverted across its lines
        γ  otherwise, return γ untouched
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.