Thử thách hình học


23

Mọi người đều thích hình học. Vậy tại sao chúng ta không thử và viết mã cho nó? Thử thách này liên quan đến việc lấy chữ và số và tạo hình tùy theo nó.

Đầu vào

Các đầu vào sẽ ở dạng (shapeIdentifier)(size)(inverter).

Nhưng hình dạng, kích thước và biến tần là gì?

Mã định danh hình dạng là mã định danh cho loại hình bạn sẽ tạo với *s. Sau đây là các định danh hình dạng:

  • s - Quảng trường
  • t - Tam giác

Kích thước sẽ ở giữa 1-20, và nó là kích thước của hình.

Biến tần là hình dạng sẽ bị lộn ngược, được biểu thị bằng a +hoặc a -. Lưu ý: s3-== (bằng) s3+vì hình vuông là đối xứng. Tuy nhiên , t5-! = (Không bằng) t5+.

Khoảng trắng Trailing là ổn trong đầu ra nhưng khoảng trắng hàng đầu thì không.

Ví dụ đầu ra

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

Input: t5+

Output:
  *
 ***
*****

Input: t3-
Output:
***
 *

Ghi chú đặc biệt

Đầu vào tam giác sẽ luôn là một số lẻ, vì vậy các tam giác sẽ luôn kết thúc bằng 1 *ở trên cùng.

Kích thước của tam giác là kích thước của đế nếu biến tần là +và là kích thước của đỉnh nếu biến tần là -.


3
Là một người đang thi môn Hình học ngay bây giờ, (và đang học cho một trận chung kết Hình học), tôi có thể nói chắc chắn 100%: Hình học là hoàn toàn, không vui chút nào ... D:
Ashwin Gupta

Câu trả lời:


9

Pyth, 40 36 34 32 byte

-1 byte bởi @isaacg

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

Dấu chấm phẩy bên trong lambda giờ là giá trị toàn cầu của biến lambda, một tính năng lưu một 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.

Hãy thử nó ở đây .

Bộ thử nghiệm .


1
Cách quá lâu, nhưng đánh bại Japt 15 byte? Tôi không thể chờ đợi để xem điều này sẽ được đánh gôn như thế nào :)
Sản phẩm ETH

Giải pháp tốt đẹp! Bạn có thể lưu một byte bằng cách thay thế qez\+bằng }\+z, bởi vì +chỉ có thể xuất hiện ở vị trí cuối cùng.
isaacg

6

Bình thường, 38 byte

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

Bộ kiểm tra

Về cơ bản là đơn giản như nó được. Tôi ước tôi có thể kết hợp một số logic cho hai hình dạng, nhưng hiện tại nó tách biệt.


5

JavaScript (ES6), 142 146 147

Chỉnh sửa 1 byte đã lưu thx @ETHproductions Chỉnh sửa 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`
`)

Kiểm tra (chạy trong 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-> ., vì đã được đảm bảo chính xác là một chữ số không có chữ số trước và sau
Sản phẩm ETH

@ETHproductions đúng, cảm ơn
edc65

Tốt đẹp. Tôi nghĩ rằng đây là thuật toán tối ưu trong JS, không thể tìm thấy thuật toán ngắn hơn.
Sản phẩm ETH

i.match(/.(.+)(.)/)->i.match`.(.+)(.)`
dùng81655

@ user81655 gợi ý hay, cảm ơn
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)

Đầu ra là một hình chữ nhật hoàn hảo, với mỗi dòng được đệm bằng các khoảng trắng ở cuối, mà tôi giả sử là ổn dựa trên các nhận xét trong OP.

Lưu ý: Tôi vẫn không bao giờ chắc chắn liệu có inputđược phép trong Python 2 đối với các sự cố như thế này không ...


4

Japt, 62 60 55 52 51 byte

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

Hãy thử trực tuyến!

Điều đầu tiên chúng ta cần làm là tìm ra hình dạng của chúng ta cần phải lớn như thế nào. Điều này khá đơn giản:

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

Bây giờ chúng tôi tổ chức hình dạng của đầu ra:

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.

Đến bây giờ, chúng tôi đã quan tâm đến kích thước và hình dạng của đầu ra. Tất cả chỉ còn lại là vòng quay. Hình tam giác hiện đang được hướng lên, vì vậy chúng ta cần lật chúng nếu char thứ ba là +:

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

Và với đầu ra ngầm, công việc của chúng tôi ở đây được thực hiện. :-)


4

Python 2, 235 193 167 157 byte

Cập nhật:

Thực hiện một số tối ưu hóa đáng kể bằng cách sử dụng danh sách hiểu và str.center (). Tôi có cảm giác tôi có thể làm thêm một số tho, sẽ có một cái nhìn mới mẻ về nó sau này.

Cập nhật 2

Đã lưu 10 byte với các đề xuất của Sherlock9. Cảm ơn rất nhiều! :)

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

Câu trả lời cũ

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

Cách tiếp cận khá căng thẳng. Viết dòng trên mỗi dòng trong một chuỗi mà tôi xuất ra cuối cùng. Hình tam giác luôn được vẽ ngược và được đảo ngược nếu cần. Việc bạn có thể nhân một chuỗi với Integer đã tiết kiệm cho tôi rất nhiều byte!

Tôi sẽ cố gắng chơi golf sau đó một chút nữa, sẽ đánh giá cao các đề xuất trong thời gian này, vì tôi chưa hết hạn với nó.

chỉnh sửa: Đánh gôn xuống rất nhiều với sự giúp đỡ trong các bình luận và đánh cắp phép tính kích thước từ một trong những câu trả lời của con trăn khác. Tôi nghĩ đó là điều tôi có thể làm nhất với thuật toán này.


Bạn đã tính như thế nào? Khi sử dụng wcđiều này mang lại cho tôi số byte là 235. Tôi có sai không?
ბიმო

1
Đây thực sự là 235 byte. Lời khuyên khi chơi gôn: Sử dụng các tab thay vì hai khoảng trắng, hợp lệ trong Python 2 và sẽ loại bỏ 5 byte.
Doorknob

Ngoài ra, bạn không cần sử dụng raw_input, sử dụng inputgiúp bạn tiết kiệm 4 byte. Hơn nữa, bạn không cần dấu ngoặc trong dòng thứ hai, điều này và không sử dụng biến nào xcả (sử dụng if"s"in d) giúp bạn tiết kiệm thêm 9 byte.
ბიმო

2
@DenkerAffe khi đếm trong cửa sổ, trừ 1 byte cho mỗi dòng mới - dòng mới là 2 byte trong cửa sổ, nhưng 1 byte trong các môi trường khác
edc65

1
Đầu tiên, bạn có thể loại bỏ []dấu ngoặc trong mỗi joinlệnh gọi hàm. Thứ hai, if d<"t"elsengắn hơn và hoạt động vì "s3+"<"t"<"t3+"trong Python. Thứ ba, else"\n".join.center(x)for. Không có không gian. Nó không bắt buộc. Thứ tư, print o[::-1]if"+"in d else onơi tôi sắp xếp lại mọi thứ cho hai byte (một khoảng trống giữa ]ifvà khác giữa if"+".
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")

Chạy với f(input here)

Hãy thử nó ở đây!

Các hình vuông có dòng mới, nhưng hình tam giác thì không. Giải trình:

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

Độ dài của dòng đầu tiên của bạn là 338 ký tự. Nó đưa tôi một màn hình và một nửa để hiển thị.
isanae


1
Tôi sẽ không nhấp vào liên kết tinyurl ngẫu nhiên, nhưng kiểm tra lại. Trong mọi trường hợp, hãy thử tránh các thanh cuộn trong hộp mã, nó sẽ khó đọc hơn nhiều.
isanae

1
@Loovjo Tôi nghĩ rằng anh ấy có nghĩa là dòng đầu tiên của lời giải thích. Tôi thường thụt vào lời giải thích của mình thay vì kiểu này cho các câu trả lời JavaScript vì vậy bạn không cần phải cuộn để xem một nửa.
dùng81655

@ user81655 Vâng, ý tôi là trong phần giải thích. Bây giờ tôi đã hiểu sự nhầm lẫn!
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)

Nỗ lực đầu tiên đã khẳng định rằng +/-kết thúc là không bắt buộc, loại bỏ điều đó cho phép tôi cạo sạch một bó

Ý tưởng ở đây là tạo một danh sách có thể được đưa vào một đầu ra chung. Phần khó nhất là tách ra khỏi chiều dài từ đầu vào.


Để có được độ dài tôi sử dụng x=int(d[1]if len(d)<4 else d[1:3])với d là chuỗi đầu vào. Đó là 5 byte ngắn hơn giải pháp của bạn. Bạn vẫn đang đi trước câu trả lời python của tôi, tôi phải cố gắng hiểu những gì bạn đã làm ở đó và đánh bại bạn lần sau! :)
Denker

1
Trên thực tế x=int(d[1:-1])là ngắn hơn rất nhiều cho điều đó, chỉ cần nhìn thấy nó trong câu trả lời con trăn khác.
Denker

@DenkerAffe, vì bất kỳ lý do gì tôi nhớ biến tần là tùy chọn, vì vậy nó sẽ không hoạt động, nhưng tôi đoán tôi đã tạo ra nó
wnnmaw

2

Võng mạc , 102 85 byte

Số lượng byte giả định rằng mã nguồn được mã hóa theo ISO 8859-1.

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

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

G`.
T`ts:` *

Hãy thử trực tuyến.

Tôi sẽ cố gắng chơi golf này một số nữa sau.


Notepad ++ nói rằng mã của bạn là 89 byte, không phải 85. Tôi đã sử dụng mã hóa ISO-8859-1 và tiếp tục Chỉnh sửa> Hội tụ EOL> Định dạng UNIX / Linux, để sử dụng \nthay vì \r\n. Base64 của nội dung: XGQrCiQwJCo6wrYKXigoXHcpKyk6KDorKQokMSQyJDMkMsK2JDAKbWBzJHw6dAoKKWAoLispwrYtKFxEKikKLSQywrYkMQptYF4uCgpHYC4KVGB0czpgICo=(sao chép trực tiếp từ Notepad ++). Thật kỳ lạ, bất kỳ giải pháp trực tuyến nào cũng mang lại cho tôi 85 byte ... Hum ...
Ismael Miguel

@IsmaelMiguel Phải có một cái gì đó khác với cách Notepad ++ đếm . Chúng chắc chắn là một byte đơn trong ISO 8859-1 (với giá trị 182).
Martin Ender

2

Nghiêm túc, 54 byte

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

Dùng thử trực tuyến

,#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: Thấy #dXdXεjchưa? CHUẨN BỊ MẮT ????


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

Điều này hoạt động do một quan sát thú vị tôi đã thực hiện. Nếu bạn lặp lại ndấu cách và ndấu hoa thị bạn nhận được (ví dụ n=5:) này:

     *****

Bây giờ, lấy các chuỗi con có cùng độ bắt đầu và độ dài:

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

Những chuỗi con này chính xác là chuỗi chúng ta cần t5.

Chỉnh sửa: Đã lưu 6 byte nhờ @ edc65.

Chỉnh sửa: Đã lưu 13 byte nhờ ẩn u+=vđối số thứ ba substrdo đó cho phép tôi đơn giản hóa việc khởi tạo.


@ThomasKwa Huh, sau khi tôi sửa tmã xử lý, nó biến thành như vậy wutrở thành tương đương và điều đó đã tiết kiệm cho tôi đủ byte để đưa tôi trở lại xuống 178!
Neil

[,b,c]=s.matchvà sau này s<'t'... nên lưu một số byte (chỉ dành cho Firefox)
edc65

@ edc65 Chỉ cần không lưu trận đấu trong scho phép tôi sử dụng s<'t'mà đã tiết kiệm cho tôi 6 byte, cảm ơn.
Neil

2

MATL , 48 byte

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

Sử dụng phiên bản hiện tại (10.1.0) của ngôn ngữ / trình biên dịch.

Mã này chấp nhận ký tự đầu vào trong bất kỳ thứ tự: tất cả s11+, 11s+và thậm chí 1+s1sẽ là chuỗi đầu vào hợp lệ.

EDIT (ngày 30 tháng 7 năm 2016): mã được liên kết thay thế 1L3$)bằng cách Y)tuân thủ các thay đổi gần đây trong ngôn ngữ

Hãy thử trực tuyến!

Giải trình

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

vô dụng

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

Gợi ý và phê bình rất được hoan nghênh.


1

Hồng ngọc, 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))}}

Tính một hình vuông hoặc tam giác có chiều cao nchiều rộng trung bình n bằng cách tính độ dốc của các cạnh (vì vậy chiều rộng tam giác tính toán là 2n-1 ở đáy, 1 ở đầu.) Nhưng nó chỉ in những hàng không vượt quá nký tự.

vô dụng trong chương trình thử nghiệm

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, không biên dịch

Tôi đã thêm các chức năng sau khi thử thách này được đăng, vì vậy điều này không thể được xem xét để chấp nhận. Điều này được mã hóa theo ISO-8859-7. Hãy thử tất cả các trường hợp thử nghiệm ở đây .

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

Phần 1: phân tích chuỗi

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)

Phần 2: thu được kết quả

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

Phần 3: đảo ngược kết quả

?='-SZiγγ
?='-S     if S is a "-"
     Ziγ   return γ, inverted across its lines
        γ  otherwise, return γ untouched
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.