แกะสลักสแควร์จากสตริง


21

ความท้าทายของคุณในวันนี้คือการใช้สตริงหลายบรรทัดและส่งออกสแควร์ที่ใหญ่ที่สุดที่มีอยู่ภายในสตริงที่มีมุมซ้ายด้านบน

สตริงสแควร์เป็นที่ที่:

  • แต่ละบรรทัดมีจำนวนอักขระเท่ากัน
  • จำนวนอักขระในแต่ละบรรทัดเท่ากับจำนวนบรรทัด

พิจารณาสตริงอินพุตที่เป็นไปได้ต่อไปนี้:

abcde
fgh
asdf
foobar

สี่เหลี่ยมจัตุรัสที่ใหญ่ที่สุดที่คุณสามารถเลือกได้จากมันซึ่งรวมถึงตัวอักษรตัวแรก ( aในมุมบน):

abc
fgh
asd

ไม่สามารถมีสี่เหลี่ยมจัตุรัสยาว 4 ข้างได้เนื่องจากบรรทัดที่สองนั้นไม่ยาวพอ พิจารณาอินพุตที่เป็นไปได้นี้:

a
bcd
edf
ghi

aตารางที่ใหญ่ที่สุดที่นี่เป็นเพียง รูปสี่เหลี่ยมขนาด 3x3 ที่อยู่ด้านล่างไม่มีอักขระตัวแรกและไม่นับ

ต่อไปนี้เป็นกรณีทดสอบเพิ่มเติมอีกสองสามข้อ:

a

a

abc
def
gh

ab
de

ab
cd

ab
cd

abcde
fghij
klm
no

abc
fgh
klm

a
b

a

คุณอาจต้องป้อนข้อมูลให้คั่นด้วยตัวเลือก LF, CR หรือ CRLF

อักขระขึ้นบรรทัดใหม่ไม่ถือเป็นส่วนหนึ่งของความยาวของบรรทัด

คุณอาจต้องการให้มีหรือไม่เป็นบรรทัดใหม่ต่อท้ายในการป้อนข้อมูลซึ่งไม่นับเป็นบรรทัดเพิ่มเติม

อินพุตเป็นสตริงหรืออาร์เรย์ถ่าน 1D มันไม่ใช่รายการของสตริง

คุณอาจสมมติว่าอินพุตไม่ว่างเปล่าและทุกบรรทัดไม่ว่างเปล่าและมีเพียง ASCII ที่พิมพ์ได้รวมถึงช่องว่างและบรรทัดใหม่ (สำหรับตัวคั่นบรรทัด) แต่ไม่ใช่แท็บ

นี่คือไบต์ที่น้อยที่สุดชนะ!



5
+1 สำหรับความท้าทายที่น่าสนใจ -1 สำหรับ I / O ที่เข้มงวด
Dennis

@ เดนนิสไม่ใช่โซลูชันทุกตัวที่จำเป็นต้องใช้.split('\n')ดังนั้นฉันจึงไม่เห็นว่าทำไมบางอย่างถึงควรใช้งานได้ฟรี
พาเวล

2
มันไม่ได้เป็นเพียงแค่การเพิ่มไบต์สำหรับแผ่นเหล็กน่าเบื่อ วิธีการบางอย่าง (เช่นฟังก์ชั่นวนซ้ำ) กลายเป็นสิ่งที่ไม่สามารถทำได้อย่างสมบูรณ์หากมีก่อนหรือหลังการประมวลผล
Dennis

@Dennis ฉันไม่ได้คิดแบบนั้น คุณคิดว่าฉันควรเปลี่ยนมันตอนนี้หรือมันจะสายเกินไป?
Pavel

คำตอบ:


5

Brachylogขนาด 11 ไบต์

ṇ⊇ᵐẹa₀ṁcᵐ~ṇ

ลองออนไลน์!

คำอธิบาย

ṇ             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

ทำได้ดีในการแก้ปัญหาที่สั้นที่สุด (จนถึงตอนนี้) Brachylog แน่ใจว่าชอบกำลังสองใช่ไหม?
Pavel

@Pavel ในตัวแน่นอนมีประโยชน์มาก!
ทำให้เสียชีวิต

7

Husk , 13 ไบต์

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

ลองออนไลน์!

คำอธิบาย

►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
สิ่งนี้เป็นอย่างไรแม้ภาษาการเขียนโปรแกรม - คุณเพิ่งวางตัวอักษรยูนิโค้ดที่คลุมเครือ! ;)
หัวผักกาด

1
@Petar ยินดีต้อนรับสู่โลกแห่งการเล่นกอล์ฟภาษาซึ่งได้รับการออกแบบมาโดยเฉพาะเพื่อใช้งานน้อยที่สุดเท่าที่จะเป็นไปได้ในการทำงานบางอย่าง ส่วนนี้คือการมีหน้ารหัสที่กำหนดเองเพื่อให้มีตัวละครสำหรับแต่ละไบต์ที่เป็นไปได้แทนการพิมพ์ ASCII ปกติ 95 แต่ไม่ต้องกังวลมีภาษากอล์ฟที่อ่านง่ายขึ้นอีกมากมาย ตัวอย่างเช่นรายการ MATL ของฉัน [/ การส่งเสริมตนเองแบบไร้ยางอาย]
Sanchises

5

รุ่น GNU , 106 + 1 94 + 2 = 96 ไบต์

+2 ไบต์สำหรับ-rzแฟล็ก ใช้อักขระที่ไม่สามารถพิมพ์ได้ NUL และ BEL แสดงเป็น@และ#ที่นี่ ดูด้านล่างสำหรับการถ่ายโอนข้อมูล xxd

ขอบคุณ @seshoumara ที่ส่งเส้นทางมาให้-zฉัน

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

ลองออนไลน์!

คำอธิบาย

สิ่งนี้ทำงานโดยการแทรกเคอร์เซอร์สองตัวลงในข้อความ - หนึ่งถึงก้าวข้ามบรรทัดและอีกก้าวหนึ่งเหนือคอลัมน์ เคอร์เซอร์จะแสดงโดย NUL (0x00) และเบล (0x07) ตามลำดับ แต่ในตัวอย่างด้านล่างนี้ผมจะใช้และ@ #สมมติว่าเรามีข้อมูลนี้:

abcde
fgh
asdf
foobar

เคอร์เซอร์ BEL ถูกแทรกไว้ข้างหน้าคอลัมน์ที่ 0 และเคอร์เซอร์ BEL อยู่ข้างหน้าบรรทัดที่ 0 (ที่นี่ฉันได้จัดเรียงคอลัมน์ไว้เพื่อความชัดเจน แต่ในความเป็นจริงไม่มีการเว้นด้านซ้าย):

#@abcde
 @fgh
 @asdf
 @foobar

ในลูปเคอร์เซอร์จะถูกย้ายหนึ่งอักขระไปทางขวาและหนึ่งบรรทัดลงตามลำดับ:

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

หลังจากการทำซ้ำแต่ละครั้งจะตรวจสอบสองเงื่อนไข:

  1. ในบรรทัดที่มีเคอร์เซอร์บรรทัดจะมีเคอร์เซอร์คอลัมน์และเคอร์เซอร์คอลัมน์สามารถเลื่อนไปทางขวาได้หรือไม่?
  2. ที่บรรทัดก่อนเคอร์เซอร์บรรทัดเคอร์เซอร์ทุกคอลัมน์สามารถเลื่อนไปทางขวาได้หรือไม่?

หากเงื่อนไขใดเป็นเท็จการวนซ้ำจะสิ้นสุดลง สคริปต์เสร็จสิ้นโดยการลบทุกอย่างหลังจากที่@ในแต่ละบรรทัดและทุกอย่างหลังจาก#ในพื้นที่รูปแบบ

xxd dump

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

คุณสามารถลบลูปแรก A เนื่องจากคำสั่งระบุว่าคุณต้องอ่านอินพุตเป็นสตริงดังนั้นคุณจึงสามารถรับ "line1 \ nline2 \ nline3" เป็นต้นคำตอบอื่น ๆ ก็ทำได้เช่นกัน ที่ควรจะได้รับการนับต่ำกว่า 100 :)
seshoumara

@seshoumara คำตอบอื่น ๆ ทำline1\nline2\nline3ที่\nเป็น\x5C\x6E? ที่?
จอร์แดน

คุณสามารถให้ลิงค์ฉันได้ไหม (คลิกที่ "แบ่งปัน" ที่ด้านล่างของคำตอบใด ๆ ) หรือแสดงให้ฉันใน TiO สิ่งที่คุณหมายถึงอะไร ในคำตอบ Python และ PHP ทั้งหมดที่ฉันเห็น\nถูกตีความว่าเป็นอักขระขึ้นบรรทัดใหม่ ( \x0Aไม่ใช่\x5C\x6E) และฉันไม่สามารถหาวิธีที่จะทำให้การป้อนข้อมูลด้วยอักขระขึ้นบรรทัดใหม่เป็นบรรทัดเดียวได้
จอร์แดน

@seshoumara ฮะไม่เป็นไรฉันจำ-zธงได้แล้ว ขอบคุณ!
จอร์แดน

4

Python 2 , 81 ไบต์

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

ลองออนไลน์!


วิธีการที่น่าสนใจ แต่ยาวกว่า 2 ไบต์

Python 2 , 83 ไบต์

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

ลองออนไลน์!


1
ไม่inputเพียงอ่านหนึ่งบรรทัด?
Pavel

@Pavel หากคุณดูตัวอย่างออนไลน์คุณสามารถดูได้โดยใช้อักขระบรรทัดใหม่ที่ชัดเจนเพื่อให้อินพุตเป็นสตริงหนึ่งบรรทัด อาจเลือกใช้วิธีนี้เพราะraw_input()อาจเพิ่มจำนวนไบต์ได้มากขึ้น
Xavier Dass

4

JavaScript (ES6), 77 ไบต์

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

ใช้นิพจน์ทั่วไปแบบซ้ำ ๆ เพื่อค้นหาสี่เหลี่ยมจัตุรัสที่ใหญ่ขึ้นเรื่อย ๆ จนกระทั่งไม่พบ

นิพจน์ทั่วไปน่าจะเป็นนี่สำหรับจตุรัส 3x3:

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

อินพุตคาดว่าจะจบด้วยการขึ้นบรรทัดใหม่และเอาต์พุตเป็นรายการ

คำอธิบาย:

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

ตัวอย่างข้อมูล:




3

R , 84 83 81 76 76 ไบต์

-5 ไบต์ย้ายวิธีการของเดนนิสด้วยsum

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

ลองออนไลน์!

อ่านจาก stdin พิมพ์ไปยัง stdout โดยไม่ขึ้นบรรทัดใหม่

ungolfed เล็กน้อย:

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 ไบต์

จะต้องมีจังหวะการตีกอล์ฟที่นี่ ...

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;}

ลองออนไลน์!


สามารถ!=-1เป็นได้>-1หรือไม่หรือgetchar()เอาท์พุทค่าน้อยกว่าหนึ่ง มันอาจเป็นไปได้ยัง+1?
Jonathan Frech

ที่อาจเกิดขึ้น158 ไบต์
Jonathan Frech

@ JonathanFrech ฉันสามารถใช้~เพื่อตรวจจับลบได้
cleblanc

1
@ RickHitchcock ดูเหมือนว่าจะทำงานในเวอร์ชั่นกอล์ฟล่าสุด
cleblanc

2

เยลลี่ 15 ไบต์

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

ลองออนไลน์!

มันทำงานอย่างไร

ỴÇÇ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 ไบต์

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;}

คำอธิบาย:

ลองที่นี่

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 ไบต์

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

ลองออนไลน์!

ความรู้สึกถี่ถ้วนของฉันบอกฉันว่าอาจจะมีวิธีที่สั้นกว่า (ฉันกำลังคิดบางอย่างYboตั้งแต่เริ่มต้น) ... ต้องขึ้นบรรทัดใหม่ในตอนท้าย (หมายเหตุ: ฉันทำ over-engine นี้เล็กน้อยเนื่องจากจะจัดการกับบรรทัดว่างได้เช่นกันซึ่งไม่จำเป็นฉันจะดูว่าฉันสามารถลดจำนวน bytecount ได้หรือไม่เพราะใน code golf ไม่ใช่คุณสมบัติ แต่เป็นข้อผิดพลาด)


1
@Pavel Guiseppe ได้อ้างถึงรุ่นอื่นซึ่งฉันย้อนกลับเพราะมันมีข้อผิดพลาด
Sanchises



1

JavaScript (ES6), 95 ไบต์

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>

ต้องขึ้นบรรทัดใหม่ในอินพุต



1

APL (Dyalog) 25 ไบต์ *

ฟังก์ชั่นนำหน้า Tacit ส่งคืนเมทริกซ์

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

ลองออนไลน์!

มันเป็นยอดจริงของสองฟังก์ชั่นอิสระคือ⎕AV[3]∘≠⊆⊢ที่เกี่ยวข้องกับรูปแบบการป้อนข้อมูลที่น่าอึดอัดใจและ↑↑⍨2⍴(⌊/≢,≢¨)การทำงานที่น่าสนใจจริง

⎕AV[3]∘≠ แตกต่างจาก LF (องค์ประกอบที่สามของA tomic V ector - ชุดอักขระ)

 พาร์ติชัน (สตริงย่อยเริ่มต้นที่ค่าที่มีขนาดใหญ่กว่ารุ่นก่อนและลดลงที่ 0s)

 อาร์กิวเมนต์

(... ) ใช้ฟังก์ชัน tacit ต่อไปนี้:

2⍴() ก่อร่างใหม่ตามความยาว 2:

  ⌊/ ขั้นต่ำของ

   จำนวนของสตริง

  , ติดตามโดย

  ≢¨ จำนวนอักขระในแต่ละสตริง

↑⍨ รับแถวและคอลัมน์จำนวนมากจาก

 สตริงที่ผสมเข้าด้วยกันเพื่อสร้างเมทริกซ์ (การเว้นช่องว่าง)


* ในคลาสสิกกับ⎕ML( M igration L Evel) 3(ค่าเริ่มต้นในระบบมาก) และแทนสำหรับและสำหรับซ้ายสุด ติ้ว!


หากความยาวเท่ากันใน Dyalog Classic คุณอาจบอกว่าเป็น Dyalog Classic และไม่ใช้เชิงอรรถ
Pavel

@Pavel ทั้งคลาสสิกและ⎕ML←3เลิกใช้แล้วดังนั้นฉันจึงควรแสดงภาษาตามปกติ ในความเป็นจริงโซลูชัน Dyalog APL เกือบทั้งหมดของฉันถือว่าคลาสสิกเพียงเพราะเรานับจำนวนไบต์แทนตัวอักษรถึงแม้ว่ารุ่น Unicode จะกำหนดความหมายให้เหลือน้อยกว่า 256 อักขระ
Adám

1

PHP, 123 ไบต์

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

ต้องการ PHP 5.4, 5.5 หรือ 5.6 แทนที่splitด้วยexplode PHP ในภายหลัง

ทำงานด้วยphp -nr '<code> '<string>'
หรือลองออนไลน์ (ตรวจสอบให้แน่ใจว่าคุณเลือกเวอร์ชัน PHP ที่เหมาะสมสำหรับคุณ!)



1

Perl 5, 60 +5 (-0777p) ไบต์

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

ลองออนไลน์

  • บรรทัดสุดท้ายของอินพุตจะต้องลงท้ายด้วยการขึ้นบรรทัดใหม่ในกรณีที่มันเป็นของเอาท์พุท
  • ในกรณีที่มีการขึ้นบรรทัดใหม่สองบรรทัด -00 ตัวเลือกอาจเปลี่ยนแปลงได้โดย -0777

-0777สองบรรทัดใหม่ติดต่อกันเป็นไปได้ดังนั้นคุณจะต้อง ทำอะไร-00และ-0777ทำอย่างไร
Pavel

-0คือการระบุตัวคั่นเร็กคอร์ดในรูปแบบฐานแปด777เป็นค่าพิเศษเพื่อระบุว่าไม่มีตัวคั่นดังนั้นจึงอ่านไฟล์ทั้งหมด0เป็นอีกค่าพิเศษเพื่อระบุ "โหมดย่อหน้า" ตัวคั่นเป็นมากกว่าหนึ่งบรรทัดใหม่ต่อเนื่อง
Nahuel Fouilleul

1

Perl 6 , 158 140 ไบต์

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

ลองออนไลน์!

ไชโยสำหรับ Perl 6 คำตอบแรกของฉัน ฉันจะเล่นกับตัวเลือกบรรทัดคำสั่งบางอย่างเพื่อดูว่าฉันสามารถเล่นกอล์ฟนี้อีกเล็กน้อย ยินดีต้อนรับช่วยประหยัดไบต์!


1

สกาลา , 201 ไบต์

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

ลองออนไลน์!

ครั้งแรกที่เล่นกอล์ฟในภาษานี้ดังนั้นอาจไม่ใช่สิ่งที่ดีที่สุด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.