Ukir persegi dari seutas tali


21

Tantangan Anda hari ini adalah mengambil string multiline, dan menampilkan kuadrat terbesar yang terkandung dalam string yang mencakup sudut kiri atas.

String persegi adalah tempat:

  • Setiap baris memiliki jumlah karakter yang sama
  • Jumlah karakter pada setiap baris sama dengan jumlah baris.

Pertimbangkan kemungkinan input string berikut:

abcde
fgh
asdf
foobar

Kotak terbesar yang dapat Anda ambil dari itu yang mencakup karakter pertama ( adi sudut kiri atas) adalah ini:

abc
fgh
asd

Tidak mungkin ada persegi panjang sisi 4, karena baris kedua tidak cukup panjang. Sekarang pertimbangkan input potensial ini:

a
bcd
edf
ghi

Alun-alun terbesar di sini adalah adil a. Kotak 3x3 yang terbentuk di bagian bawah tidak mengandung karakter pertama, dan tidak masuk hitungan.

Berikut beberapa kasus uji lagi:

a

a

abc
def
gh

ab
de

ab
cd

ab
cd

abcde
fghij
klm
no

abc
fgh
klm

a
b

a

Anda mungkin memerlukan input untuk dibatasi oleh LF, CR, atau CRLF pilihan Anda.

Karakter baris baru tidak dianggap sebagai bagian dari panjang garis.

Anda mungkin memerlukan ada atau tidak menjadi baris baru di input, yang tidak dihitung sebagai baris tambahan.

Input adalah string atau array char 1D; ini bukan daftar string.

Anda dapat menganggap input tidak kosong dan semua baris tidak kosong, dan hanya berisi ASCII yang dapat dicetak, termasuk spasi dan baris baru (untuk pembatas baris) tetapi tidak tab.

Ini adalah , byte terkecil menang!



5
+1 untuk tantangan yang menarik, -1 untuk I / O yang ketat
Dennis

@ Dennis tidak semua solusi perlu digunakan .split('\n')jadi saya tidak melihat mengapa beberapa harus mendapatkannya secara gratis.
Pavel

2
Ini bukan (hanya) tentang harus menambahkan byte untuk boilerplate yang membosankan. Beberapa pendekatan (misalnya, fungsi rekursif) menjadi sangat tidak praktis jika ada pra atau pasca pemrosesan.
Dennis

@ Dennis saya tidak memikirkannya seperti itu. Apakah Anda pikir saya harus mengubahnya sekarang, atau sudah terlambat?
Pavel

Jawaban:


5

Brachylog , 11 byte

ṇ⊇ᵐẹa₀ṁcᵐ~ṇ

Cobalah online!

Penjelasan

ṇ             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


@Pavel Built-in memang sangat berguna!
Fatalkan

7

Sekam , 13 byte

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

Cobalah online!

Penjelasan

►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
Bagaimana ini bahkan bahasa pemrograman - Anda baru saja menempelkan beberapa karakter unicode yang tidak jelas! ;)
lobak

1
@Petar Selamat datang di dunia bahasa golf, yang dirancang khusus untuk menggunakan sesedikit mungkin byte untuk melakukan tugas tertentu. Bagian dari ini adalah memiliki halaman kode khusus, sehingga ada karakter untuk setiap byte yang mungkin, alih-alih ASCII yang dapat dicetak. Tapi jangan khawatir, ada juga bahasa golf yang lebih mudah dibaca; misalnya entri MATL saya [/ promosi mandiri yang tidak tahu malu]
Sanchises

5

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

+2 byte untuk -rzbendera. Menggunakan karakter yang tidak patut NUL dan BEL, ditampilkan sebagai @dan di #sini. Lihat di bawah untuk dump xxd.

Terima kasih kepada @seshoumara karena mengirim saya ke jalan menuju -z.

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

Cobalah online!

Penjelasan

Ini berfungsi dengan memasukkan dua kursor ke dalam teks — satu untuk melangkahi garis dan satu untuk melangkahi kolom. Kursor diwakili oleh NUL (0x00) dan BEL (0x07), masing-masing, tetapi dalam contoh di bawah ini saya akan menggunakan @dan #. Misalkan kita memiliki input ini:

abcde
fgh
asdf
foobar

Kursor BEL disisipkan sebelum kolom ke-0 dan kursor BEL sebelum garis ke-0 (di sini saya telah menjaga kolom tetap selaras untuk keterbacaan; tetapi dalam kenyataannya tidak ada bantalan kiri):

#@abcde
 @fgh
 @asdf
 @foobar

Dalam satu lingkaran, kursor dipindahkan satu karakter ke kanan dan satu baris ke bawah, masing-masing:

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

Setelah setiap iterasi, ia memeriksa dua kondisi:

  1. Pada baris dengan kursor baris, apakah ada kursor kolom dan dapatkah kursor kolom bergerak ke kanan?
  2. Pada baris sebelum kursor baris, dapatkah setiap kursor kolom bergerak ke kanan?

Jika salah satu kondisi salah, loop berakhir. Script selesai dengan menghapus semuanya setelahnya@ pada setiap baris dan semua setelah #dalam ruang pola.

dump 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

Anda dapat menghapus loop pertama, A, karena pernyataan itu mengatakan Anda harus membaca input sebagai string, sehingga Anda dapat menerima "line1 \ nline2 \ nline3" dll. Jawaban lain juga melakukannya. Itu seharusnya mendapatkan hitungan di bawah 100 :)
seshoumara

@seshoumara jawaban lain lakukan line1\nline2\nline3di mana \nadalah \x5C\x6E? Yang?
Jordan

Bisakah Anda memberi saya tautan? (Klik "bagikan" di bagian bawah jawaban apa pun.) Atau tunjukkan dalam TiO apa yang Anda maksud? Dalam semua jawaban Python dan PHP yang saya lihat \nditafsirkan sebagai karakter baris baru ( \x0A, tidak \x5C\x6E) dan saya tidak dapat menemukan cara untuk membuat sed mengambil input dengan karakter baris baru sebagai satu baris.
Jordan

@seshoumara Hah, tidak apa-apa, saya baru ingat -zbenderanya. Terima kasih!
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]

Cobalah online!


Metode yang menarik, tetapi 2 byte lebih lama.

Python 2 , 83 byte

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

Cobalah online!


1
Tidak inputhanya membaca satu baris?
Pavel

@Pavel, jika Anda melihat contoh online, Anda dapat melihatnya menggunakan karakter baris baru eksplisit untuk menjaga input menjadi string satu baris. Mungkin memilih metode ini karena raw_input()akan menambah lebih banyak byte.
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

Secara rekursif menggunakan ekspresi reguler untuk mencari kotak yang lebih besar dan lebih besar sampai tidak ada yang ditemukan.

Ekspresi reguler adalah ini untuk kotak 3x3:

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

Input diharapkan berakhir dengan baris baru, dan output adalah daftar.

Penjelasan:

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

Potongan:



3

Perl 5 , 84 byte

chomp(@a=<>);map$.&&=y///c>$i,@a[0..$i]while$.&&$i++<$#a;say/(.{$i})/ for@a[0..$i-1]

Cobalah online!

Memenuhi "abcde\nfghij\nklm\nno"test case.


Anda bisa menggunakannya chopsebagai ganti chompdan ++$i<@abukannya$i++<$#a
Nahuel Fouilleul

3

R , 84 83 81 76 byte

-5 byte porting pendekatan Dennis dengansum

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

Cobalah online!

membaca dari stdin, mencetak ke stdout tanpa baris baru.

Sedikit tidak berbulu:

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

Pasti ada pukulan untuk bermain golf di sini ...

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

Cobalah online!


Dapat !=-1menjadi >-1atau tidak getchar()nilai output lebih kecil dari minus satu? Mungkinkah itu terjadi +1?
Jonathan Frech


@ JonathanFrech bisa saya gunakan ~untuk mendeteksi minus satu.
cleblanc

1
@RickHitchcock Tampaknya berfungsi di versi golf terbaru.
cleblanc

2

Jelly , 15 byte

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

Cobalah online!

Bagaimana itu bekerja

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

Penjelasan:

Coba di sini.

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

Cobalah online!

Perasaan spidey saya memberi tahu saya bahwa mungkin ada cara yang lebih pendek (saya memikirkan sesuatu dengan Ybobenar sejak awal) ... Membutuhkan baris baru di akhir. (Catatan: Saya sedikit over-engineered, karena ini akan menangani garis kosong juga, yang tidak diperlukan. Saya akan melihat apakah saya dapat mengurangi bytecount, karena dalam kode golf, ini bukan fitur, tetapi bug)


1
@Pavel Guiseppe merujuk ke versi lain, yang saya putar kembali karena memang ada bug.
Sanchises



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>

Membutuhkan jalur baru yang tertinggal dalam input.



1

APL (Dyalog) , 25 byte *

Fungsi awalan Tacit. Mengembalikan matriks.

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

Cobalah online!

Ini benar-benar di atas dua fungsi independen, yaitu ⎕AV[3]∘≠⊆⊢yang berkaitan dengan format input canggung dan↑↑⍨2⍴(⌊/≢,≢¨) yang melakukan pekerjaan menarik yang sebenarnya.

⎕AV[3]∘≠ perbedaan dari LF (elemen ketiga dari A tomic V ector - set karakter)

 partisi (substring dimulai pada nilai yang lebih besar dari pendahulunya dan turun pada 0s)

 argumen

(... ) terapkan fungsi diam-diam berikut:

2⍴(... ) bentuk ulang yang berikut ini untuk panjang 2:

  ⌊/ minimum

   jumlah string

  , diikuti oleh

  ≢¨ jumlah karakter dalam setiap string

↑⍨ ambil banyak baris dan kolom dari

 string dicampur bersama untuk membentuk matriks (padding dengan spasi)


* Dalam klasik dengan ⎕ML( M igration L Evel) 3(default pada banyak sistem) dan menggantikannya untuk dan untuk yang paling kiri . Tio!


Jika panjangnya sama dengan Dyalog Classic Anda bisa mengatakan itu Dyalog Classic dan tidak menggunakan catatan kaki.
Pavel

@Pavel Keduanya Klasik dan ⎕ML←3sudah usang, jadi saya lebih suka menunjukkan bahasa seperti yang biasanya muncul. Faktanya, hampir semua solusi APL Dyalog saya mengasumsikan Classic hanya karena kami menghitung byte alih-alih karakter, meskipun bahkan versi Unicode memberikan arti kurang dari 256 karakter.
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),"
";

membutuhkan PHP 5.4, 5.5 atau 5.6. Ganti splitdenganexplode untuk nanti PHP.

Jalankan dengan php -nr '<code> '<string>'
atau coba online . (Pastikan Anda memilih versi PHP yang cocok!)



1

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

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

Cobalah online

  • Baris input terakhir harus diakhiri dengan baris baru jika itu milik output.
  • Dalam hal dua baris baru berturut-turut -00 opsi dapat diubah oleh -0777.

Mungkin ada dua baris baru berturut-turut, jadi Anda harus -0777. Apa yang harus dilakukan -00dan -0777dilakukan.
Pavel

-0adalah untuk menentukan pemisah rekaman dalam format oktal 777adalah nilai khusus untuk menunjukkan tidak ada pemisah sehingga seluruh file dibaca, 0adalah nilai khusus lain untuk menunjukkan "mode paragraf", pemisah lebih dari 1 baris baru berturut-turut
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("
")

Cobalah online!

Hore untuk jawaban Perl 6 pertama saya. Saya akan bermain-main dengan beberapa opsi baris perintah untuk melihat apakah saya bisa bermain golf ini sedikit lebih. Semua bantuan menghemat byte diterima!


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

Cobalah online!

Pertama kali bermain golf dalam bahasa ini, jadi mungkin bukan yang terbaik.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.