Schnitzen Sie ein Quadrat aus einer Schnur

21

Ihre heutige Herausforderung besteht darin, eine mehrzeilige Zeichenfolge zu verwenden und das größte in der Zeichenfolge enthaltene Quadrat auszugeben, das die obere linke Ecke enthält.

Eine quadratische Zeichenfolge ist eine Zeichenfolge, bei der:

  • Jede Zeile hat die gleiche Anzahl von Zeichen
  • Die Anzahl der Zeichen in jeder Zeile entspricht der Anzahl der Zeilen.

Berücksichtigen Sie die folgende mögliche Eingabezeichenfolge:

abcde
fgh
asdf
foobar

Das größte Quadrat, das Sie daraus entnehmen können und das das erste Zeichen (das ain der oberen linken Ecke) enthält, ist das folgende:

abc
fgh
asd

Es kann kein Quadrat mit der Seitenlänge 4 geben, da die zweite Zeile nicht lang genug ist. Betrachten Sie nun diese mögliche Eingabe:

a
bcd
edf
ghi

Der größte Platz hier ist gerade a. Das 3x3-Quadrat im unteren Bereich enthält nicht das erste Zeichen und zählt nicht.

Hier noch ein paar Testfälle:

a

a

abc
def
gh

ab
de

ab
cd

ab
cd

abcde
fghij
klm
no

abc
fgh
klm

a
b

a

Möglicherweise müssen Eingaben durch die Auswahl von LF, CR oder CRLF begrenzt werden.

Die Zeilenumbruchzeichen werden nicht als Teil der Zeilenlänge betrachtet.

Möglicherweise muss eine nachgestellte Zeile in der Eingabe vorhanden sein oder nicht, was nicht als zusätzliche Zeile zählt.

Die Eingabe ist eine Zeichenfolge oder ein 1D-Zeichen-Array. Es ist keine Liste von Zeichenfolgen.

Sie können davon ausgehen, dass die Eingabe nicht leer und alle Zeilen nicht leer sind und dass sie nur druckbares ASCII enthält, einschließlich Leerzeichen und Zeilenumbrüchen (für den Zeilentrenner), jedoch keine Tabulatoren.

Das ist , die wenigsten Bytes gewinnen!

Pavel
quelle
Related
Pavel
5
+1 für eine interessante Herausforderung, -1 für strenge I / O
Dennis
@Dennis muss nicht jede Lösung verwenden, .split('\n')deshalb verstehe ich nicht, warum manche es kostenlos bekommen sollten.
Pavel
2
Es geht nicht (nur) darum, Bytes für langweiliges Boilerplate hinzuzufügen. Einige Ansätze (z. B. rekursive Funktionen) werden bei Vor- oder Nachbearbeitung völlig unpraktisch.
Dennis
@Dennis Ich hatte nicht so darüber nachgedacht. Glaubst du, ich sollte es jetzt ändern, oder ist es zu spät?
Pavel

Antworten:

5

Brachylog , 11 Bytes

ṇ⊇ᵐẹa₀ṁcᵐ~ṇ

Probieren Sie es online!

Erläuterung

ṇ             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
Tödlich
quelle
Gute Arbeit auf der kürzesten Lösung (bis jetzt), Brachylog mag sicher Quadrate, nicht wahr?
Pavel
@Pavel Das eingebaute ist ja ganz praktisch!
Fatalize
7

Schale , 13 Bytes

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

Probieren Sie es online!

Erläuterung

►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
quelle
1
Wie ist das überhaupt eine Programmiersprache - Sie haben gerade ein paar obskure Unicode-Zeichen eingefügt! ;)
Rübe
1
@Petar Willkommen in der Welt der Golfsprachen, die speziell darauf ausgelegt sind, so wenig Bytes wie möglich für eine bestimmte Aufgabe zu verwenden. Dazu gehört eine benutzerdefinierte Codepage, sodass für jedes mögliche Byte ein Zeichen vorhanden ist, anstatt der üblichen druckbaren 95-ASCII-Zeichen. Aber keine Sorge, es gibt auch viel besser lesbare Golfsprachen. zum Beispiel mein MATL-Eintrag [/ shameless self-promotion]
Sanchises
5

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

+2 Bytes für -rzFlags. Verwendet die nicht druckbaren Zeichen NUL und BEL, wie @und #hier gezeigt. Siehe unten für einen xxd-Dump.

Vielen Dank an @seshoumara für die Zusendung von -z.

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

Probieren Sie es online!

Erläuterung

Dies funktioniert, indem zwei Cursor in den Text eingefügt werden - einer, um Zeilen zu überspringen, und einer, um Spalten zu überspringen. Die Cursor werden durch NUL (0x00) bzw. BEL (0x07) dargestellt, aber in den folgenden Beispielen werde ich @und verwenden #. Angenommen, wir haben diesen Input:

abcde
fgh
asdf
foobar

Der BEL-Cursor wird vor der 0-ten Spalte und der BEL-Cursor vor der 0-ten Zeile eingefügt (hier habe ich die Spalten aus Gründen der Lesbarkeit ausgerichtet gehalten; tatsächlich gibt es jedoch keinen linken Abstand):

#@abcde
 @fgh
 @asdf
 @foobar

In einer Schleife werden die Cursor um jeweils ein Zeichen nach rechts und eine Zeile nach unten verschoben:

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

Nach jeder Iteration werden zwei Bedingungen überprüft:

  1. Befindet sich in der Zeile mit dem Zeilencursor ein Spaltencursor und kann sich der Spaltencursor nach rechts bewegen?
  2. Kann sich jeder Spaltencursor in den Zeilen vor dem Zeilencursor nach rechts bewegen?

Wenn eine der beiden Bedingungen falsch ist, endet die Schleife. Das Skript wird beendet, indem @in jeder Zeile und danach #im Musterbereich alles gelöscht wird.

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
Jordan
quelle
Sie können die erste Schleife, A, entfernen, da die Anweisung besagt, dass Sie die Eingabe als Zeichenfolge lesen müssen, damit Sie "line1 \ nline2 \ nline3" usw. erhalten. Andere Antworten haben dies ebenfalls getan. Das sollte die Zahl unter 100 bekommen :)
Seshoumara
@seshoumara Andere Antworten tun, line1\nline2\nline3wo \nist \x5C\x6E? Welche?
Jordanien
Kannst du mir einen Link geben? (Klicken Sie unten in einer Antwort auf "Teilen".) Oder zeigen Sie mir in einem TiO, was Sie meinen? In allen Python- und PHP-Antworten, die ich sehe, \nwird es als Zeilenumbruchzeichen interpretiert ( \x0Anicht \x5C\x6E), und ich kann keine Möglichkeit finden, sed dazu zu bringen, Eingaben mit Zeilenumbruchzeichen als einzelne Zeile zu übernehmen.
Jordanien
@seshoumara Hah, egal, ich habe mich gerade an die -zFlagge erinnert . Vielen Dank!
Jordanien
4

Python 2 , 81 Bytes

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

Probieren Sie es online!


Eine interessante Methode, aber 2 Bytes länger.

Python 2 , 83 Bytes

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

Probieren Sie es online!

xnor
quelle
1
Liest nicht inputnur eine Zeile?
Pavel
@Pavel, wenn Sie sich das Online-Beispiel ansehen, sehen Sie, dass explizite Zeilenumbrüche verwendet werden, um die Eingabe in einer einzeiligen Zeichenfolge zu halten. Wenn Sie sich für diese Methode entscheiden, werden wahrscheinlich raw_input()mehr Bytes hinzugefügt.
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

Verwendet rekursiv einen regulären Ausdruck, um nach einem immer größeren Quadrat zu suchen, bis keines gefunden wird.

Der reguläre Ausdruck wäre dies für ein 3x3-Quadrat:

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

Es wird erwartet, dass die Eingabe mit einer neuen Zeile endet, und die Ausgabe ist eine Liste.

Erläuterung:

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

Snippet:

Rick Hitchcock
quelle
3

Perl 5 , 84 Bytes

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

Probieren Sie es online!

Erfüllt den "abcde\nfghij\nklm\nno"Testfall.

Xcali
quelle
Sie könnten chopanstelle von chompund ++$i<@aanstelle von verwenden$i++<$#a
Nahuel Fouilleul
3

R , 84 83 81 76 Byte

-5 Bytes portieren Dennis 'Ansatz mitsum

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

Probieren Sie es online!

Liest von stdin, druckt auf stdout ohne nachfolgende Newline.

Leicht 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

Giuseppe
quelle
3

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

Hier muss es ein paar Schläge geben, um Golf zu spielen ...

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

Probieren Sie es online!

Cleblanc
quelle
Darf oder !=-1darf >-1der getchar()Ausgabewert kleiner als minus eins sein? Könnte es überhaupt sein +1?
Jonathan Frech
Möglicherweise 158 Byte .
Jonathan Frech
@ JonathanFrech kann ich verwenden ~, um minus eins zu erkennen.
Cleblanc
1
@ RickHitchcock Scheint in der neuesten Golfversion zu funktionieren.
Cleblanc
2

Gelee , 15 Bytes

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

Probieren Sie es online!

Wie es funktioniert

ỴÇÇ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
quelle
2

Java 8, 150 Bytes

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

Erläuterung:

Probieren Sie es hier aus.

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
quelle
2

MATL , 33 Bytes

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

Probieren Sie es online!

Mein spidey sense sagt mir, dass es wahrscheinlich einen kürzeren Weg gibt (ich denke Ybovon Anfang an etwas mit ) ... Benötigt eine neue Zeile am Ende. (Hinweis: Ich habe dies ein wenig überarbeitet, da dies auch leere Zeilen handhabt, was nicht erforderlich ist. Ich werde sehen, ob ich den Bytecount reduzieren kann, da es im Codegolf keine Funktion ist, sondern ein Fehler.)

Sanchises
quelle
1
@Pavel Guiseppe bezog sich auf eine andere Version, die ich zurückgesetzt habe, weil sie tatsächlich einen Fehler hatte.
Sanchises
1

Python 2 , 132 Bytes

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]

Probieren Sie es online!

Jonathan Frech
quelle
1

Python 2 , 103 Bytes

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]

Probieren Sie es online!

ovs
quelle
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>

Erfordert eine nachgestellte Zeile in der Eingabe.

Neil
quelle
1

APL (Dyalog) , 25 Byte *

Tacit-Präfix-Funktion. Gibt eine Matrix zurück.

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

Probieren Sie es online!

Es ist wirklich eine Spitze von zwei unabhängigen Funktionen, nämlich ⎕AV[3]∘≠⊆⊢welche sich mit dem umständlichen Eingabeformat befassen und ↑↑⍨2⍴(⌊/≢,≢¨)welche die eigentliche interessante Arbeit erledigen.

⎕AV[3]∘≠ Unterschied zu LF (das dritte Element des A tomic V ector - der Zeichensatz)

 Partitionen (Teilfolgen, die bei Werten beginnen, die größer sind als ihre Vorgänger und bei Nullen fallen)

 das Argument

() Wenden folgende stillschweigende Funktion an:

2⍴() Das Folgende in Länge 2 umformen:

  ⌊/ das Minimum von

   die Anzahl der Saiten

  , gefolgt von

  ≢¨ die Anzahl der Zeichen in jeder Zeichenfolge

↑⍨ nimm so viele Zeilen und Spalten aus

 die Saiten werden zu einer Matrix gemischt (Auffüllen mit Leerzeichen)


* In der Classic mit ⎕ML( M igration L evel) 3(Standard auf vielen Systemen) und Substitution für und für die ganz links . Tio!

Adam
quelle
Wenn es in Dyalog Classic dieselbe Länge hat, können Sie es auch als Dyalog Classic bezeichnen und nicht die Fußnote verwenden.
Pavel
@Pavel Sowohl Classic als auch ⎕ML←3sind veraltet, daher zeige ich die Sprache lieber so, wie sie normalerweise angezeigt wird. Tatsächlich übernehmen fast alle meine Dyalog APL-Lösungen Classic, nur weil wir Bytes anstelle von Zeichen zählen, obwohl selbst die Unicode-Version weniger als 256 Zeichen Bedeutung zuweist.
Adám
1

PHP, 123 Bytes

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

benötigt PHP 5.4, 5.5 oder 5.6. Ersetzen Sie splitmit explodefür späteres PHP.

Laufen Sie mit php -nr '<code> '<string>'
oder versuchen Sie es online . (Stellen Sie sicher, dass Sie eine passende PHP-Version auswählen!)

Titus
quelle
1

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

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

Probieren Sie es online aus

  • Die letzte Eingabezeile muss mit einem Zeilenumbruch enden, falls sie zur Ausgabe gehört.
  • Bei zwei aufeinanderfolgenden Zeilenumbrüchen kann die Option -00 durch -0777 geändert werden.
Nahuel Fouilleul
quelle
Es sind zwei aufeinanderfolgende Zeilenumbrüche möglich -0777. Was tun -00und -0777tun ?
Pavel
-0ist der Rekord - Separator in Oktalformat angeben , 777um anzuzeigen , keinen Separator , so dass die gesamte Datei lesen, ein besonderer Wert 0ist ein weiterer besonderer Wert anzuzeigen „Absatz - Modus“, Separator ist mehr als 1 aufeinanderfolgende Zeilenumbrüche
Nahuel FOUILLEUL
1

Perl 6 , 158 140 Bytes

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

Probieren Sie es online!

Hurra für meine erste Perl 6-Antwort. Ich werde ein paar Kommandozeilenoptionen ausprobieren, um zu sehen, ob ich noch ein bisschen mehr Golf spielen kann. Alle Hilfe beim Speichern von Bytes ist willkommen!

Luke
quelle
1

Scala , 201 Bytes

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

Probieren Sie es online!

Zum ersten Mal Golfspielen in dieser Sprache, also vielleicht nicht die beste.

DerInitializer
quelle