Wytnij kwadrat ze sznurka

21

Twoim dzisiejszym wyzwaniem jest pobranie ciągu wielowierszowego i wyprowadzenie największego kwadratu zawartego w ciągu, który zawiera lewy górny róg.

Ciąg kwadratowy to taki, w którym:

  • Każda linia ma taką samą liczbę znaków
  • Liczba znaków w każdej linii jest równa liczbie linii.

Rozważ następujący możliwy ciąg wejściowy:

abcde
fgh
asdf
foobar

Największy kwadrat, jaki możesz z niego wziąć, zawierający pierwszą postać ( aw lewym górnym rogu) to:

abc
fgh
asd

Nie może być kwadratu o boku 4, ponieważ druga linia nie jest wystarczająco długa. Teraz rozważ ten potencjalny wkład:

a
bcd
edf
ghi

Największy plac tutaj jest sprawiedliwy a. Utworzony na dole kwadrat 3x3 nie zawiera pierwszego znaku i się nie liczy.

Oto kilka innych przypadków testowych:

a

a

abc
def
gh

ab
de

ab
cd

ab
cd

abcde
fghij
klm
no

abc
fgh
klm

a
b

a

Możesz wymagać ograniczenia danych wejściowych przez wybór LF, CR lub CRLF.

Znaki nowego wiersza nie są uważane za część długości linii.

Możesz wymagać, aby na wejściu pojawiał się znak nowej linii, ale nie jest to dodatkowy wiersz.

Dane wejściowe to tablica znaków lub 1D; nie jest to lista ciągów.

Możesz założyć, że dane wejściowe są niepuste, a wszystkie wiersze są niepuste i że zawiera tylko drukowalny kod ASCII, w tym spacje i znaki nowej linii (dla separatora linii), ale nie tabulatory.

To jest , wygrywa najmniej bajtów!

Pavel
źródło
powiązane
Pavel
5
+1 za ciekawe wyzwanie, -1 za surowe We / Wy
Dennis
@Dennis nie każde rozwiązanie wymaga użycia, .split('\n')więc nie rozumiem, dlaczego niektórzy powinni go otrzymać za darmo.
Pavel
2
Nie chodzi o (tylko) konieczność dodawania bajtów dla nudnej płyty kotłowej. Niektóre podejścia (np. Funkcje rekurencyjne) stają się całkowicie niepraktyczne, jeśli istnieje przetwarzanie wstępne lub końcowe.
Dennis
@Dennis Nie myślałem o tym w ten sposób. Czy uważasz, że powinienem to zmienić teraz, czy jest już za późno?
Pavel

Odpowiedzi:

5

Brachylog , 11 bajtów

ṇ⊇ᵐẹa₀ṁcᵐ~ṇ

Wypróbuj online!

Wyjaśnienie

ṇ             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
Fatalizować
źródło
Dobra robota w najkrótszym (jak dotąd) rozwiązaniu, Brachylog z pewnością lubi kwadraty, prawda?
Pavel
@Pavel Wbudowane narzędzie jest naprawdę przydatne!
Fatalize
7

Łuska , 13 bajtów

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

Wypróbuj online!

Wyjaśnienie

►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.
Zgarb
źródło
1
Jak to jest nawet w języku programowania - właśnie wkleiłeś niektóre nieznane znaki Unicode! ;)
rzepa
1
@Petar Witamy w świecie języków golfowych, które zostały zaprojektowane specjalnie w celu użycia jak najmniej bajtów do wykonania określonego zadania. Częścią tego jest posiadanie niestandardowej strony kodowej, tak aby dla każdego możliwego bajtu był znak, zamiast zwykłego 95 drukowanego ASCII. Ale nie martw się, jest też znacznie więcej czytelnych języków golfowych; na przykład mój wpis MATL [/ bezwstydna autopromocja]
Sanchises
5

GNU sed , 106 + 1 94 + 2 = 96 bajtów

+2 bajty dla -rzflag. Wykorzystuje znaki niedrukowalne NUL i BEL, pokazane jako @i #tutaj. Zobacz poniżej zrzut xxd.

Dzięki @seshoumara za wysłanie mnie ścieżką do -z.

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

Wypróbuj online!

Wyjaśnienie

Działa to poprzez wstawienie do tekstu dwóch kursorów - jednego do przejścia przez linie i jednego do przejścia przez kolumny. Kursory są reprezentowane odpowiednio przez NUL (0x00) i BEL (0x07), ale w poniższych przykładach użyję @i #. Załóżmy, że mamy następujące dane wejściowe:

abcde
fgh
asdf
foobar

Kursor BEL jest wstawiany przed 0 kolumną, a kursor BEL przed 0 linią (tutaj kolumny zostały wyrównane dla czytelności, ale w rzeczywistości nie ma lewej dopełnienia):

#@abcde
 @fgh
 @asdf
 @foobar

W pętli kursory są przesuwane odpowiednio o jeden znak w prawo i jeden wiersz w dół:

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

Po każdej iteracji sprawdza dwa warunki:

  1. Czy w linii z kursorem linii jest kursor kolumny i czy kursor kolumny może przesunąć się w prawo?
  2. Czy na liniach przed kursorem linii każdy kursor kolumny może przesuwać się w prawo?

Jeśli którykolwiek z warunków jest fałszywy, pętla kończy się. Skrypt kończy się usunięciem wszystkiego po @w każdej linii i wszystkiego po #w obszarze wzorców.

zrzut 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
Jordania
źródło
Możesz usunąć pierwszą pętlę A, ponieważ instrukcja mówi, że musisz odczytać dane wejściowe jako ciąg znaków, abyś mógł otrzymać „linia1 \ nline2 \ nline3” itp. Inne odpowiedzi również to zrobiły. To powinno dać wynik poniżej 100 :)
seshoumara,
@seshoumara Inne odpowiedzi czy line1\nline2\nline3gdzie \njest \x5C\x6E? Który?
Jordania
Czy możesz podać mi link? (Kliknij „udostępnij” u dołu dowolnej odpowiedzi.) Lub pokaż mi w TiO, co masz na myśli? We wszystkich odpowiedziach w Pythonie i PHP widzę, że \njest interpretowany jako znak nowej linii ( \x0A, nie \x5C\x6E) i nie mogę znaleźć sposobu, aby sed mógł wprowadzić dane za pomocą znaków nowej linii jako pojedynczą linię.
Jordan
@seshoumara Hah, nieważne, właśnie przypomniałem sobie -zflagę. Dzięki!
Jordan
4

Python 2 , 81 bajtów

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

Wypróbuj online!


Ciekawa metoda, ale o 2 bajty dłużej.

Python 2 , 83 bajty

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

Wypróbuj online!

xnor
źródło
1
Nie inputczyta tylko jednej linii?
Pavel
@Pavel, jeśli spojrzysz na przykład online, możesz zobaczyć, że używa wyraźnych znaków nowej linii, aby utrzymać wprowadzony ciąg jednowierszowy. Prawdopodobnie wybrałbym tę metodę, ponieważ raw_input()dodałby więcej bajtów.
Xavier Dass,
4

JavaScript (ES6), 77 bajtów

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

Rekurencyjnie używa wyrażenia regularnego do wyszukiwania coraz większego kwadratu, dopóki nie zostanie znaleziony.

Wyrażenie regularne byłoby takie dla kwadratu 3x3:

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

Dane wejściowe mają się kończyć znakiem nowej linii, a dane wyjściowe to lista.

Wyjaśnienie:

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

Skrawek:

Rick Hitchcock
źródło
3

Brachylog , 16 bajtów

ṇ{ẹa₀ᵐa₀ṁ}ᶠtcᵐ~ṇ

Wypróbuj online!

Erik the Outgolfer
źródło
Wyjaśnienie, proszę?
Pavel
3

Perl 5 , 84 bajtów

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

Wypróbuj online!

Spełnia "abcde\nfghij\nklm\nno"przypadek testowy.

Xcali
źródło
możesz użyć chopzamiast chompi ++$i<@azamiast$i++<$#a
Nahuel Fouilleul
3

R , 84 83 81 76 bajtów

-5 bajtów przyłączeniowym podejście Dennisa zsum

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

Wypróbuj online!

czyta ze standardowego, drukuje na standardowe bez końcowego nowego wiersza.

Nieznacznie nie golfista:

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

Giuseppe
źródło
3

C (gcc) , 162 159 151 147 144 142 137 bajtów

Gra w golfa wymaga uderzeń ...

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

Wypróbuj online!

cleblanc
źródło
Może !=-1być >-1lub nie getchar()wartości wyjściowe mniejsze niż minus jeden? Czy to w ogóle może być +1?
Jonathan Frech,
Potencjalne 158 bajtów .
Jonathan Frech,
@JathanathanFrech Mogę użyć ~do wykrycia minus jeden.
cleblanc
1
@ RickHitchcock Wydaje się, że działa w najnowszej wersji golfa.
cleblanc
2

Galaretka , 15 bajtów

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

Wypróbuj online!

Jak to działa

ỴÇÇ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.
Dennis
źródło
2

Java 8, 150 bajtów

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

Wyjaśnienie:

Wypróbuj tutaj.

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
Kevin Cruijssen
źródło
2

MATL , 33 bajty

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

Wypróbuj online!

Mój paskudny zmysł mówi mi, że prawdopodobnie jest krótsza droga (myślę, że coś jest Ybood samego początku) ... Wymaga nowej linii na końcu. (Uwaga: trochę to przeprojektowałem, ponieważ poradzi sobie również z pustymi liniami, co nie jest wymagane. Zobaczę, czy mogę zmniejszyć liczbę bajtów, ponieważ w kodzie golfowym nie jest to cecha, ale błąd)

Sanchises
źródło
1
@Pavel Guiseppe odnosił się do innej wersji, którą wycofałem, ponieważ rzeczywiście miał błąd.
Sanchises,
1

Python 2 , 132 bajty

def f(s):s=s.split("\n");return["\n".join([l[:j+1]for l in s[:j+1]])for j,v in enumerate(s[0])if all(len(l)>j for l in s[:j+1])][-1]

Wypróbuj online!

Jonathan Frech
źródło
1

Python 2 , 103 bajty

def f(i):
 i=i.split('\n');x=0
 while all(v[x:]for v in i[:x+1])*i[x:]:x+=1
 for v in i[:x]:print v[:x]

Wypróbuj online!

ovs
źródło
1

JavaScript (ES6), 95 bajtów

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>

Wymaga wejścia nowego wiersza w danych wejściowych.

Neil
źródło
1

APL (Dyalog) , 25 bajtów *

Funkcja ukrytego przedrostka. Zwraca macierz.

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

Wypróbuj online!

Jest to naprawdę jedna z dwóch niezależnych funkcji, a mianowicie ta, ⎕AV[3]∘≠⊆⊢która zajmuje się niezręcznym formatem wejściowym i ↑↑⍨2⍴(⌊/≢,≢¨)która wykonuje naprawdę interesującą pracę.

⎕AV[3]∘≠ Różnica w LF (trzeci element A TOMIC V wtryskiwacza - zestaw znaków)

 partycje (podciągi zaczynające się od wartości większych niż ich poprzednik i upuszczane w 0)

 argument

() Zastosuj następującą funkcję ukrytą:

2⍴() Przekształć następujące elementy w długość 2:

  ⌊/ minimum

   liczba ciągów

  , śledzony przez

  ≢¨ liczba znaków w każdym ciągu

↑⍨ weź tyle wierszy i kolumn z

 sznurki zmieszane razem, tworząc matrycę (wypełnienie spacjami)


* W klasycznym z ⎕ML( M igration L evel) 3(domyślnie w wielu systemach) i zastępując do i w skrajnej lewej . Tio!

Adám
źródło
Jeśli ma taką samą długość w Dyalog Classic, równie dobrze możesz powiedzieć, że to Dyalog Classic i nie używać przypisu.
Pavel
@Pavel Zarówno Classic, jak i ⎕ML←3są przestarzałe, więc wolę pokazać język w normalnym stylu. W rzeczywistości prawie wszystkie moje rozwiązania APL Dyalog zakładają Classic tylko dlatego, że liczymy bajty zamiast znaków, chociaż nawet wersja Unicode przypisuje znaczenie mniej niż 256 znaków.
Adám
1

PHP, 123 bajty

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

wymaga PHP 5.4, 5.5 lub 5.6. wymienić splitzexplode do późniejszego PHP.

Uruchom php -nr '<code> '<string>'
lub wypróbuj online . (Upewnij się, że wybierasz odpowiednią wersję PHP!)

Tytus
źródło
1

Perl 5, 60 +5 (-0777p) bajtów

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

Wypróbuj online

  • Ostatni wiersz danych wejściowych musi kończyć się nową linią, jeśli należy do danych wyjściowych.
  • W przypadku dwóch kolejnych nowych linii -00 można zmienić opcję o -0777.
Nahuel Fouilleul
źródło
Możliwe są dwa kolejne znaki nowej linii, więc będziesz potrzebować -0777. Co zresztą robią -00i -0777robią.
Pavel
-0jest określenie separatora rekordów w formacie ósemkowym 777jest specjalną wartością wskazującą brak separatora, więc cały plik jest czytany, 0jest kolejną specjalną wartością wskazującą „tryb akapitowy”, separator jest więcej niż 1 kolejną
nową linią
1

Perl 6 , 158 140 bajtów

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

Wypróbuj online!

Brawo dla mojej pierwszej odpowiedzi w Perlu 6. Będę się bawić z kilkoma opcjami wiersza poleceń, aby sprawdzić, czy mogę trochę więcej zagrać w golfa. Zapraszamy do pomocy w oszczędzaniu bajtów!

Luke
źródło
1

Scala , 201 bajtów

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

Wypróbuj online!

Po raz pierwszy gra w golfa w tym języku, więc może nie jest najlepszy.

TheInitializer
źródło