Khắc hình vuông từ một chuỗi


21

Thử thách của bạn hôm nay là lấy một chuỗi nhiều dòng và xuất ra hình vuông lớn nhất chứa trong chuỗi bao gồm góc trên cùng bên trái.

Một chuỗi vuông là một trong đó:

  • Mỗi dòng có cùng số ký tự
  • Số lượng ký tự trên mỗi dòng bằng số lượng dòng.

Hãy xem xét chuỗi đầu vào có thể sau đây:

abcde
fgh
asdf
foobar

Hình vuông lớn nhất bạn có thể lấy từ nó bao gồm ký tự đầu tiên ( aở góc topleft) là:

abc
fgh
asd

Không thể có một hình vuông có chiều dài 4 cạnh, bởi vì dòng thứ hai không đủ dài. Bây giờ hãy xem xét đầu vào tiềm năng này:

a
bcd
edf
ghi

Quảng trường lớn nhất ở đây chỉ là a. Hình vuông 3x3 được hình thành ở phía dưới không chứa ký tự đầu tiên và không được tính.

Dưới đây là một vài trường hợp thử nghiệm:

a

a

abc
def
gh

ab
de

ab
cd

ab
cd

abcde
fghij
klm
no

abc
fgh
klm

a
b

a

Bạn có thể yêu cầu đầu vào được phân định bởi sự lựa chọn của bạn về LF, CR hoặc CRLF.

(Các) ký tự dòng mới không được coi là một phần của độ dài của dòng.

Bạn có thể yêu cầu phải có hoặc không có dòng mới trong đầu vào, không được tính là một dòng bổ sung.

Đầu vào là một chuỗi char hoặc 1D; nó không phải là một danh sách các chuỗi

Bạn có thể giả sử đầu vào không trống và tất cả các dòng đều không trống và nó chỉ chứa ASCII có thể in được, bao gồm cả khoảng trắng và dòng mới (đối với dấu phân cách dòng) chứ không phải các tab.

Đây là , ít byte thắng nhất!



5
+1 cho một thử thách thú vị, -1 cho I / O nghiêm ngặt
Dennis

@Dennis không phải mọi giải pháp đều cần sử dụng .split('\n')vì vậy tôi không hiểu tại sao một số người nên nhận nó miễn phí.
Pavel

2
Không phải (chỉ) về việc phải thêm byte cho bản soạn thảo nhàm chán. Một số cách tiếp cận (ví dụ, các hàm đệ quy) trở nên hoàn toàn không thực tế nếu có tiền xử lý hoặc hậu xử lý.
Dennis

@Dennis Tôi đã không nghĩ về nó như thế. Bạn có nghĩ rằng tôi nên thay đổi nó bây giờ, hoặc là quá muộn?
Pavel

Câu trả lời:


5

Brachylog , 11 byte

ṇ⊇ᵐẹa₀ṁcᵐ~ṇ

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

Giải trình

ṇ             Split on linebreaks
 ⊇ᵐ           Take a subset of each line
   ẹ          Split the lines into list of chars
    a₀        Take a prefix of this list of lists of chars
      ṁ       It is a square matrix
       cᵐ     Concatenate the list of chars back into strings
         ~ṇ   Join the strings with linebreaks

Làm tốt với giải pháp ngắn nhất (cho đến nay), Brachylog chắc chắn thích hình vuông, phải không?
Pavel

@Pavel Việc tích hợp thực sự khá tiện dụng!
Gây tử vong

7

Husk , 13 byte

►oΛ≈S+TzṀ↑Nḣ¶

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

Giải trình

►oΛ≈S+TzṀ↑Nḣ¶  Implicit input, say "ab\nc".
            ¶  Split at newlines: ["ab","c"]
           ḣ   Take prefixes: [["ab"],["ab","c"]]
       z  N    Zip with [1,2,3..
        Ṁ↑     by taking that many characters from each row: [["a"],["ab","c"]]
►o             Find rightmost element that satisfies this:
  Λ            all strings in
    S+T        the list concatenated to its transpose
   ≈           have the same length: ["a"]
               Implicitly print separated by newlines.

1
Làm thế nào đây thậm chí là một ngôn ngữ lập trình - bạn vừa dán một số ký tự unicode tối nghĩa! ;)
củ cải

1
@Petar Chào mừng bạn đến với thế giới của các ngôn ngữ chơi gôn, được thiết kế đặc biệt để sử dụng càng ít byte càng tốt để thực hiện một tác vụ nhất định. Một phần của việc này là để có một trang mã tùy chỉnh, sao cho có một ký tự cho mỗi byte có thể, thay vì 95 mã ASCII có thể in thông thường. Nhưng đừng lo lắng, cũng có nhiều ngôn ngữ chơi golf dễ đọc hơn nhiều; ví dụ: mục MATL của tôi [/ tự quảng cáo không biết xấu hổ]
Sanchise

5

GNU sed , 106 + 1 94 + 2 = 96 byte

+2 byte cho -rzcờ. Sử dụng các ký tự không thể in NUL và BEL, được hiển thị như @#ở đây. Xem bên dưới cho một bãi chứa xxd.

Cảm ơn @seshoumara đã gửi tôi xuống con đường đến -z.

s/^/@/gm
s/.*/#&\n/
:B
s/@(.)/\1@/mg
s/#(.+\n)/\1#/m
/#.*@./M!b
/@\n.*#/!bB
:
s/@[^\n]*|#.*//g

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

Giải trình

Điều này hoạt động bằng cách chèn hai con trỏ vào văn bản một để bước qua các dòng và một để bước qua các cột. Các con trỏ được biểu thị bằng NUL (0x00) và BEL (0x07), nhưng trong các ví dụ dưới đây tôi sẽ sử dụng @#. Giả sử chúng ta có đầu vào này:

abcde
fgh
asdf
foobar

Con trỏ BEL được chèn trước cột 0 và con trỏ BEL trước dòng 0 (ở đây tôi đã giữ các cột được căn chỉnh để dễ đọc; nhưng thực tế không có phần đệm bên trái):

#@abcde
 @fgh
 @asdf
 @foobar

Trong một vòng lặp, các con trỏ được di chuyển một ký tự sang phải và một dòng xuống tương ứng:

 a@bcde
#f@gh
 a@sdf
 f@oobar
 ab@cde
 fg@h
#as@df
 fo@obar
 abc@de
 fgh@
 asd@f
#foo@bar

Sau mỗi lần lặp, nó kiểm tra hai điều kiện:

  1. Trên dòng có con trỏ dòng, có con trỏ cột và con trỏ cột có thể di chuyển sang phải không?
  2. Trên các dòng trước con trỏ dòng, mọi con trỏ cột có thể di chuyển sang phải không?

Nếu một trong hai điều kiện là sai, vòng lặp kết thúc. Kịch bản kết thúc bằng cách xóa mọi thứ sau @trên mỗi dòng và mọi thứ sau #trong không gian mẫu.

bãi rác xxd

00000000: 732f 5e2f 002f 676d 0a73 2f2e 2a2f 0726  s/^/./gm.s/.*/.&
00000010: 5c6e 2f0a 3a42 0a73 2f00 282e 292f 5c31  \n/.:B.s/.(.)/\1
00000020: 002f 6d67 0a73 2f07 282e 2b5c 6e29 2f5c  ./mg.s/.(.+\n)/\
00000030: 3107 2f6d 0a2f 072e 2a00 2e2f 4d21 620a  1./m./..*../M!b.
00000040: 2f00 5c6e 2e2a 072f 2162 420a 3a0a 732f  /.\n.*./!bB.:.s/
00000050: 005b 5e5c 6e5d 2a7c 072e 2a2f 2f67       .[^\n]*|..*//g

Bạn có thể xóa vòng lặp đầu tiên, A, vì câu lệnh cho biết bạn phải đọc đầu vào dưới dạng chuỗi, vì vậy bạn có thể nhận được "line1 \ nline2 \ nline3", v.v. Các câu trả lời khác cũng làm điều này. Điều đó sẽ có được số lượng dưới 100 :)
seshoumara

@seshoumara câu trả lời khác làm line1\nline2\nline3nơi \n\x5C\x6E? Cái nào?
Jordan

Bạn có thể cho tôi một liên kết? (Nhấp vào "chia sẻ" ở cuối bất kỳ câu trả lời nào.) Hoặc hiển thị cho tôi trong TiO ý của bạn là gì? Trong tất cả các câu trả lời của Python và PHP tôi thấy \nđược hiểu là một ký tự dòng mới ( \x0Akhông phải \x5C\x6E) và tôi không thể tìm ra cách làm cho sed lấy đầu vào với các ký tự dòng mới dưới dạng một dòng.
Jordan

@seshoumara Hah, nevermind, tôi chỉ nhớ -zcờ. Cảm ơn!
Jordan

4

Python 2 , 81 byte

l=input().split('\n')
i=0
while zip(*l[:i+1])[i:]:i+=1
for x in l[:i]:print x[:i]

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


Một phương thức thú vị, nhưng dài hơn 2 byte.

Python 2 , 83 byte

l=input().split('\n')
while len(zip(*l))<len(l):l.pop()
for x in l:print x[:len(l)]

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


1
Không inputchỉ đọc một dòng?
Pavel

@Pavel, nếu bạn nhìn vào ví dụ trực tuyến, bạn có thể thấy nó đang sử dụng các ký tự dòng mới rõ ràng để giữ đầu vào là một chuỗi một dòng. Có lẽ lựa chọn phương pháp này vì raw_input()sẽ thêm nhiều byte hơn.
Xavier Dass

4

JavaScript (ES6), 77 byte

f=(s,i=1,m=s.match(`^${`(.{${i}}).*
`.repeat(i)}`))=>m?f(s,i+1)||m.slice(1):0

Đệ quy sử dụng biểu thức chính quy để tìm kiếm hình vuông lớn hơn và lớn hơn cho đến khi không tìm thấy biểu thức nào.

Biểu thức chính quy sẽ là hình vuông 3x3:

^(.{3}).*
(.{3}).*
(.{3}).*

Đầu vào dự kiến ​​sẽ kết thúc với một dòng mới và đầu ra là một danh sách.

Giải trình:

f = (s,                                            //input
     i = 1,                                        //start searching for a 1x1 square
     m = s.match(`^${`(.{${i}}).*\n`.repeat(i)}`)  //match on the regex
    )=>
    m ? f(s, i+1)                   //if there's a match, recurse on the next-sized square
        || m.slice(1) :             //if there's not a next-sized square, return the match
        0                           //no match for this square, so stop recursing

Đoạn trích:




3

R , 84 83 81 76 byte

-5 byte chuyển cách tiếp cận của Dennis vớisum

cat(substr(x<-readLines(),1,m<-sum(cummin(nchar(x))>=seq(x)))[1:m],sep='\n')

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

đọc từ stdin, in ra thiết bị xuất chuẩn mà không có dòng mới.

Hơi vô dụng:

x <- readLines()                    # read in input one line at a time;
                                    # saved as a vector of strings
minChar <- cummin(nchar(x))         # rolling minimum of all line lengths
lineNum <- seq(x)                   # line number
mins <- minChar>=lineNum            # the min between the line number and the line lengths
m <- sum(mins)                      # the sum of those is the size of the square
cat(substr(x,1,m)[1:m],sep='\n')    # print the first m characters of the first m lines,
                                    # and join with newlines


3

C (gcc) , 162 159 151 147 144 142 137 byte

Phải có một số nét để chơi golf ở đây ...

i,l=9;char*p,s[9][8];main(t){for(p=s;~(*p=getchar());)p=*p<32?*p=0,l=(t=strlen(s+i))<l?t:l,s[++i]:p+1;for(i=0;i<l;puts(s+i++))s[i][l]=0;}

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


!=-1thể >-1hoặc không có getchar()giá trị đầu ra nhỏ hơn trừ một? Nó thậm chí có thể được +1?
Jonathan Frech

Tiềm năng 158 byte .
Jonathan Frech

@JonathanFrech Tôi có thể sử dụng ~để phát hiện một điểm trừ.
cleblanc

1
@RickHitchcock Có vẻ như hoạt động trong phiên bản golf mới nhất.
sứt mẻ

2

Thạch , 15 byte

L€«\‘>Jx@Z
ỴÇÇY

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

Làm thế nào nó hoạt động

ỴÇÇY        Main link. Argument: s (string)

Ỵ           Split s at linefeeds, yielding a string array.
 Ç          Apply the helper link.
  Ç         Apply the helper link again.
   Y        Join, separating by linefeeds.


L€«\‘>Jx@Z  Helper link. Argument: A (string array/2D character array)

L€          Compute the length of each row/line.
  «\        Take the cumulative minimum.
    ‘       Increment each minimum.
      J     Indices; yield [1, ..., len(A)].
     >      Perform elementwise comparison. If the output should have n lines, this
            yields an array of n ones and len(A)-n zeroes.
         Z  Zip/transpose A.
       x@   For each string t in the result to the right, repeat its characters as
            many times as indicated in the result to the left, discarding all but
            the first n characters.

2

Java 8, 150 byte

s->{String q[]=s.split("\n"),r="";int l=q[0].length(),i=0,t;for(;i<l;l=t<l?t:l)t=q[i++].length();for(i=0;i<l;)r+=q[i++].substring(0,l)+"\n";return r;}

Giải trình:

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

s->{                          // Method with String as both parameter and return-type 
  String q[]=s.split("\n"),   //  Split the input on new-lines, and put it in an array
         r="";                //  Result-String, starting empty
  int l=q[0].length(),        //  Length of the lines, starting at the length of line 1
      i=0,                    //  Index-integer, starting at 0
      t;                      //  Temp integer
  for(;i<l;                   //  Loop (1) from 0 to `l` (exclusive)
      l=t<l?                  //    After every iteration: if `t` is smaller than `l`:
         t                    //     Change `l` to `t`
        :                     //    Else:
         l)                   //     Leave `l` the same
    t=q[i++].length();        //   Set `t` to the length of the current line
                              //  End of loop (1) (implicit / single-line body)
  for(i=0;i<l;                //  Loop (2) from 0 to `l` (the determined square dimension)
    r+=                       //   Append the result-String with:
       q[i++].substring(0,l)  //    The current row chopped at `l-1`
       +"\n"                  //    + a new-line
  );                          //  End of loop (2)
  return r;                   //  Return the result-String
}                             // End of method

2

MATL , 33 byte

10-~ft1)wdhqY<tn:vX<X>:GYbowt3$)c

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

Ý thức cá nhân của tôi nói với tôi rằng có lẽ có một cách ngắn hơn (tôi đang suy nghĩ điều gì đó Ybongay từ đầu) ... Yêu cầu một dòng mới ở cuối. (Lưu ý: Tôi đã thiết kế quá mức điều này một chút, vì điều này cũng sẽ xử lý các dòng trống, điều này là không bắt buộc. Tôi sẽ xem liệu tôi có thể giảm số lượng byte không, bởi vì trong golf code, nó không phải là một tính năng, mà là một lỗi)


1
@Pavel Guiseppe đã đề cập đến một phiên bản khác, tôi đã quay lại vì nó thực sự có lỗi.
Sanchise



1

JavaScript (ES6), 95 byte

f=
s=>(g=s=>s.slice(0,a.findIndex((e,i)=>a.some((s,j)=>j<=i&!s[i]))))(a=s.split`
`).map(g).join`
`
<textarea oninput=o.textContent=f(this.value+`\n`)></textarea><pre id=o>

Yêu cầu một dòng mới trong đầu vào.



1

APL (Dyalog) , 25 byte *

Hàm tiền tố ngầm. Trả về một ma trận.

(↑↑⍨2⍴(⌊/≢,≢¨))⎕AV[3]∘≠⊆⊢

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

Nó thực sự là một đỉnh của hai chức năng độc lập, cụ thể là ⎕AV[3]∘≠⊆⊢liên quan đến định dạng đầu vào vụng về và ↑↑⍨2⍴(⌊/≢,≢¨)công việc thực sự thú vị.

⎕AV[3]∘≠ khác biệt so với LF (yếu tố thứ ba của A tomic V ector - bộ ký tự)

 phân vùng (các chuỗi con bắt đầu ở các giá trị lớn hơn giá trị trước và giảm xuống 0)

 tranh luận

(... ) áp dụng các chức năng ngầm như sau:

2⍴(... ) định hình lại những điều sau đây theo chiều dài 2:

  ⌊/ tối thiểu

   số lượng chuỗi

  , theo dõi bởi

  ≢¨ số lượng ký tự trong mỗi chuỗi

↑⍨ lấy nhiều hàng và cột từ

 các chuỗi trộn với nhau để tạo thành một ma trận (đệm với khoảng trắng)


* Trong Classic với ⎕ML( M igration L evel ) 3(mặc định trên nhiều hệ thống) và thay thế cho ngoài cùng bên trái . Tio!


Nếu nó có cùng độ dài trong Dyalog Classic, bạn cũng có thể nói đó là Dyalog Classic và không sử dụng chú thích.
Pavel

@Pavel Cả cổ điển và ⎕ML←3không được dùng nữa, vì vậy tôi muốn hiển thị ngôn ngữ như bình thường. Trên thực tế, hầu như tất cả các giải pháp APL Dyalog của tôi đều giả sử Cổ điển chỉ vì chúng tôi đếm byte thay vì ký tự, mặc dù ngay cả phiên bản Unicode cũng gán ý nghĩa cho ít hơn 256 ký tự.
Adám

1

PHP, 123 byte

for(;preg_match("#^(\S{".++$i."}.*
){"."$i}#",$s="$argv[1]
"););while($k<$i-1)echo substr(split("
",$s)[+$k++],0,$i-1),"
";

yêu cầu PHP 5.4, 5.5 hoặc 5.6. Thay thế splitbằng explodecho PHP sau này.

Chạy với php -nr '<code> '<string>'
hoặc thử trực tuyến . (Hãy chắc chắn rằng bạn chọn một phiên bản PHP phù hợp!)



1

Perl 5, 60 +5 (-0777p) byte

$.++while/^(.{$.}.*
){$.}/;$_=join"
",(/.{$.}/gm)[0..--$.-1]

Dùng thử trực tuyến

  • Dòng đầu vào cuối cùng phải kết thúc bằng một dòng mới trong trường hợp nó thuộc về đầu ra.
  • Trong trường hợp hai dòng mới liên tiếp -00 có thể thay đổi tùy chọn bằng -0777.

Hai dòng mới liên tiếp là có thể, vì vậy bạn sẽ cần -0777 . Làm gì -00-0777làm gì, dù sao đi nữa.
Pavel

-0là chỉ định dấu phân cách bản ghi ở định dạng bát phân 777là một giá trị đặc biệt để chỉ ra không có dấu phân cách để toàn bộ tệp được đọc, 0là một giá trị đặc biệt khác để chỉ "chế độ đoạn", dấu phân cách có nhiều hơn 1 dòng mới
Nahuel Fouilleul

1

Perl 6 , 158 140 byte

my$c;for ^(my@b=lines).elems {any(@b.head(++$c).map({.substr(0,$c).chars <$c}))&&$c--&&last;};say @b.head($c).map({.substr(0,$c)}).join("
")

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

Hoan hô cho câu trả lời Perl 6 đầu tiên của tôi. Tôi sẽ chơi xung quanh với một số tùy chọn dòng lệnh để xem liệu tôi có thể chơi golf này nhiều hơn một chút không. Tất cả các trợ giúp tiết kiệm byte đều được chào đón!


1

Scala , 201 byte

type S=String
def c(s:S):S={val? =s split "\n"
var(z,q:Seq[S])=(Seq(?size,?(0).size).min,Nil)
while(1<2){?map(i=>{if(i.size>=z)q=q:+i.take(z)
if(q.size==z)return q mkString "\n"})
q=Nil;z-=1}
return""}

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

Lần đầu tiên chơi golf trong ngôn ngữ này, vì vậy có lẽ không phải là tốt nhất.

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.