Tantangan Geometris

23

Semua orang suka geometri. Jadi mengapa kita tidak mencoba dan membuat kode golf? Tantangan ini melibatkan mengambil huruf dan angka dan membuat bentuk tergantung padanya.

Input

Masukan akan dalam bentuk (shapeIdentifier)(size)(inverter).

Tapi apa itu shapeIdentifier, ukuran, dan inverter?

Pengidentifikasi bentuk adalah pengidentifikasi untuk jenis bentuk yang akan Anda buat dengan *s. Berikut ini adalah pengidentifikasi bentuk:

  • s - Kotak
  • t - Segitiga

Ukurannya akan berada di antara 1-20, dan itu adalah ukuran gambar.

Inverter adalah apakah bentuknya akan terbalik, yang dilambangkan dengan a +atau a -. Perhatikan: s3-== (sama dengan) s3+karena kuadrat simetris. Namun t5-,! = (Tidak sama) t5+.

Trailing whitespace tidak apa-apa dalam output tetapi memimpin whitespace tidak.

Contoh Keluaran

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

Input: t5+

Output:
  *
 ***
*****

Input: t3-
Output:
***
 *

Catatan khusus

Input segitiga akan selalu berupa angka ganjil, sehingga segitiga akan selalu berakhir dengan 1 *di atas.

Ukuran segitiga adalah ukuran dasar jika inverter adalah +dan ukuran atas jika inverter -.

intboolstring
sumber
3
Sebagai seseorang yang mengambil Geometri sekarang, (dan belajar untuk final Geometri), saya dapat mengatakan dengan kepastian 100%: Geometri benar-benar, tidak menyenangkan sama sekali ... D:
Ashwin Gupta

Jawaban:

9

Pyth, 40 36 34 32 byte

-1 byte oleh @isaacg

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

Titik koma di dalam lambda sekarang menjadi nilai global variabel lambda, sebuah fitur yang menyimpan satu 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.

Coba di sini .

Suite uji .

lirtosiast
sumber
1
Terlalu lama, namun mengalahkan Japt by 15 byte? Saya tidak sabar untuk melihat bagaimana ini akan
golf
Solusi bagus! Anda dapat menyimpan byte dengan mengganti qez\+dengan }\+z, karena +dapat hanya muncul di posisi terakhir.
isaacg
6

Pyth, 38 byte

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

Suite uji

Pada dasarnya sejelas mungkin. Saya berharap saya bisa menggabungkan beberapa logika untuk dua bentuk, tetapi saat ini terpisah.

isaacg
sumber
5

JavaScript (ES6), 142 146 147

Sunting 1 byte disimpan thx @ETHproductions Edit 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`
`)

Uji (jalankan di 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
sumber
\d-> ., karena dijamin tepat satu non-digit sebelum dan sesudah
ETHproduksi
@ EHProduk benar, terima kasih
edc65
Bagus. Saya pikir ini adalah algoritma optimal di JS, tidak dapat menemukan yang lebih pendek.
ETHproduk
i.match(/.(.+)(.)/)->i.match`.(.+)(.)`
user81655
@ user81655 petunjuk yang bagus, terima kasih
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)

Outputnya adalah persegi panjang yang sempurna, dengan setiap baris diisi dengan spasi tambahan, yang saya anggap baik-baik saja berdasarkan komentar di OP.

Catatan: Saya masih belum yakin apakah inputdiizinkan menggunakan Python 2 untuk masalah seperti ini ...

Sp3000
sumber
4

Japt, 62 60 55 52 51 byte

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

Cobalah online!

Hal pertama yang perlu kita lakukan adalah mencari tahu seberapa besar bentuk kita perlu. Ini cukup sederhana:

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

Sekarang kita mengatur bentuk 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.

Sekarang, kami telah menangani ukuran dan bentuk output. Yang tersisa hanyalah rotasi. Segitiga saat ini mengarah ke atas, jadi kita perlu membalik mereka jika karakter ketiga adalah +:

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

Dan dengan output implisit, pekerjaan kami di sini selesai. :-)

Produksi ETH
sumber
4

Python 2, 235 193 167 157 Bytes

Memperbarui:

Membuat beberapa pengoptimalan yang signifikan dengan menggunakan daftar pemahaman dan str.center (). Aku punya perasaan aku bisa melakukan lebih banyak lagi, akan melihat lagi nanti.

Perbarui 2

Disimpan 10 Bytes dengan saran dari Sherlock9. Terima kasih banyak! :)

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

Jawaban lama

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

Pendekatan cukup lurus ke depan. Menulis baris per baris dalam string yang saya output pada akhirnya. Segitiga selalu ditarik terbalik dan dibalik jika diperlukan. Fakta bahwa Anda dapat melipatgandakan string dengan Integer menyelamatkan saya banyak byte!

Saya akan mencoba untuk bermain golf yang sedikit lebih nanti, akan menghargai saran sementara itu, karena saya belum banyak berpengalaman dengan itu.

sunting: Menurunkannya dengan banyak bantuan di komentar dan mencuri perhitungan ukuran dari salah satu jawaban python lainnya. Saya pikir itulah yang paling bisa saya lakukan dengan algoritma ini.

Denker
sumber
Bagaimana Anda menghitung? Saat menggunakan wcini memberi saya hitungan byte 235. Apakah saya salah?
ბიმო
1
Ini memang 235 byte. Saran golf: Gunakan tab alih-alih dua spasi, yang berlaku dalam Python 2 dan akan memangkas 5 byte.
Gagang Pintu
Anda juga tidak perlu menggunakan raw_input, inputmenghemat 4 byte. Selanjutnya Anda tidak memerlukan tanda kurung di baris kedua, ini dan tidak menggunakan variabel xsama sekali (menggunakan if"s"in d) menghemat 9 byte lagi.
ბიმო
2
@DenkerAffe saat menghitung di jendela, kurangi 1 byte untuk setiap baris baru - baris baru 2 byte di windows, tetapi 1 byte di lingkungan lain
edc65
1
Pertama, Anda dapat menghapus []tanda kurung di setiap joinpanggilan fungsi. Kedua, if d<"t"elselebih pendek dan berfungsi karena "s3+"<"t"<"t3+"dalam Python. Ketiga, else"\n".joindan .center(x)for. Tidak ada ruang. Itu tidak wajib. Keempat, di print o[::-1]if"+"in d else omana saya mengatur kembali hal-hal untuk dua byte (satu ruang antara ]dan ifdan yang lain antara ifdan "+".
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")

Jalankan dengan f(input here)

Coba di sini!

Kuadrat memiliki garis baru, tetapi segitiga tidak. Penjelasan:

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
sumber
Panjang baris pertama Anda adalah 338 karakter. Butuh satu setengah monitor untuk ditampilkan.
isanae
3
@ isanae Dikatakan 220 di sini.
Loovjo
1
Saya tidak akan mengklik tautan tinyurl acak, tetapi periksa lagi. Bagaimanapun, cobalah menghindari bilah gulir di kotak kode, itu membuatnya lebih sulit untuk dibaca.
isanae
1
@Loovjo Saya pikir maksudnya adalah baris pertama dari penjelasan. Saya biasanya membuat indentasi penjelasan saya daripada gaya ini untuk jawaban JavaScript sehingga Anda tidak perlu menggulir untuk melihat setengahnya.
user81655
@ user81655 Ya, maksud saya dalam penjelasannya. Sekarang saya mengerti kebingungan!
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)

Upaya pertama menyatakan bahwa +/-pada akhirnya adalah opsional, menyingkirkan itu izinkan saya mencukur banyak

Idenya di sini adalah membuat daftar yang dapat dilemparkan ke dalam keluaran generik. Bagian tersulit adalah memisahkan panjang dari input.

wnnmaw
sumber
Untuk mendapatkan panjang saya gunakan x=int(d[1]if len(d)<4 else d[1:3])dengan d menjadi string input. Thats 5 Bytes lebih pendek dari solusi Anda. Anda masih jauh di depan dari jawaban python saya, harus mencoba memahami apa yang Anda lakukan di sana dan mengalahkan Anda lain kali! :)
Denker
1
Sebenarnya x=int(d[1:-1])jauh lebih pendek untuk itu, lihat saja di jawaban python lainnya.
Denker
@ DenkerAffe, untuk alasan apa pun saya ingat inverter menjadi opsional, sehingga tidak akan berfungsi, tapi saya rasa saya baru saja mengarangnya
wnnmaw
2

Retina , 102 85 byte

Hitungan byte mengasumsikan bahwa kode sumber dikodekan sebagai ISO 8859-1.

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

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

G`.
T`ts:` *

Cobalah online.

Saya akan mencoba golf ini lagi nanti.

Martin Ender
sumber
Notepad ++ mengatakan bahwa kode Anda adalah 89 byte, bukan 85. Saya telah menggunakan pengkodean ISO-8859-1, dan melanjutkan dengan Edit> Konversi EOL> Format UNIX / Linux, untuk digunakan \nsebagai pengganti \r\n. Base64 konten: XGQrCiQwJCo6wrYKXigoXHcpKyk6KDorKQokMSQyJDMkMsK2JDAKbWBzJHw6dAoKKWAoLispwrYtKFxEKikKLSQywrYkMQptYF4uCgpHYC4KVGB0czpgICo=(salinan langsung dari Notepad ++). Cukup aneh, setiap solusi online memberi saya 85 byte ... Hum ...
Ismael Miguel
@IsmaelMiguel Pasti ada yang salah dengan cara Notepad ++ menghitung . Mereka jelas merupakan byte tunggal di ISO 8859-1 (dengan nilai 182).
Martin Ender
2

Serius, 54 byte

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

Cobalah secara 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: Lihat itu #dXdXεj? STRING SLICING ????

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

Ini berhasil karena pengamatan menarik yang saya buat. Jika Anda mengulangi nspasi dan ntanda bintang, Anda mendapatkan (mis. Untuk n=5) ini:

     *****

Sekarang, ambil substring dengan awal dan panjang yang sama:

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

Substring ini adalah persis string yang kita butuhkan t5.

Sunting: Disimpan 6 byte berkat @ edc65.

Sunting: Disimpan 13 byte karena menyembunyikan u+=vargumen ketiga substrsehingga memungkinkan saya untuk menyederhanakan inisialisasi.

Neil
sumber
@ThomasKwa Huh, setelah saya memperbaiki tkode penanganan ternyata wdan umenjadi setara dan yang menyelamatkan saya cukup byte untuk membawa saya kembali ke 178!
Neil
[,b,c]=s.matchdan yang lebih baru s<'t'... harus menyimpan beberapa byte (hanya Firefox)
edc65
@ edc65 Tidak hanya menyimpan kecocokan di smemungkinkan saya untuk menggunakan s<'t'yang menyelamatkan saya 6 byte, terima kasih.
Neil
2

MATL , 48 byte

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

Menggunakan versi saat ini (10.1.0) dari bahasa / kompiler.

Kode menerima karakter input dalam urutan apa pun: semua s11+, 11s+dan bahkan 1+s1akan menjadi string input yang valid.

EDIT (30 Juli 2016): kode tertaut menggantikan 1L3$)dengan Y)agar sesuai dengan perubahan terbaru dalam bahasa

Cobalah online!

Penjelasan

' *'        % 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
sumber
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("");
    }
}

Saran dan kritik sangat kami harapkan.

Lince Assassino
sumber
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))}}

Menghitung kuadrat atau segitiga tinggi ndan lebar rata - ratan dengan memperhatikan kemiringan sisi (sehingga lebar segitiga yang dihitung adalah 2n-1 di pangkalan, 1 di ujung.) Tetapi hanya mencetak baris yang tidak melebihi nkarakter.

ungolfed dalam program tes

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

Jolf, 37 byte, tidak bersaing

Saya menambahkan fungsi setelah tantangan ini diposting, jadi ini tidak dapat dipertimbangkan untuk diterima. Ini dikodekan dalam ISO-8859-7. Coba semua test case di sini .

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

Bagian 1: parsing string

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)

Bagian 2: memperoleh hasilnya

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

Bagian 3: membalikkan hasilnya

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