Intaglia un quadrato da una stringa


21

La tua sfida oggi è prendere una stringa multilinea e produrre il quadrato più grande contenuto nella stringa che include l'angolo in alto a sinistra.

Una stringa quadrata è quella in cui:

  • Ogni riga ha lo stesso numero di caratteri
  • Il numero di caratteri su ogni riga è uguale al numero di righe.

Considera la seguente stringa di input possibile:

abcde
fgh
asdf
foobar

Il quadrato più grande che puoi prendere da esso che include il primo carattere (il anell'angolo in alto a sinistra) è questo:

abc
fgh
asd

Non può esserci un quadrato di lunghezza laterale 4, perché la seconda linea non è abbastanza lunga. Ora considera questo potenziale input:

a
bcd
edf
ghi

La piazza più grande qui è giusta a. Il quadrato 3x3 formato nella parte inferiore non contiene il primo carattere e non conta.

Ecco alcuni altri casi di test:

a

a

abc
def
gh

ab
de

ab
cd

ab
cd

abcde
fghij
klm
no

abc
fgh
klm

a
b

a

Potrebbe essere necessario delimitare l'input a scelta tra LF, CR o CRLF.

I caratteri di nuova riga non sono considerati parte della lunghezza della linea.

Potrebbe essere necessario che ci sia o meno una nuova riga finale nell'input, che non conta come una riga aggiuntiva.

L'input è una stringa o array di caratteri 1D; non è un elenco di stringhe.

È possibile supporre che l'input sia non vuoto e tutte le righe non siano vuote e che contenga solo ASCII stampabile, inclusi spazi e nuove righe (per il delimitatore di riga) ma non schede.

Questo è , vince meno byte!



5
+1 per una sfida interessante, -1 per I / O rigoroso
Dennis

@Dennis non tutte le soluzioni devono essere utilizzate, .split('\n')quindi non vedo perché alcuni dovrebbero ottenerlo gratuitamente.
Pavel,

2
Non si tratta (solo) di dover aggiungere byte per noioso boilerplate. Alcuni approcci (ad es. Funzioni ricorsive) diventano completamente poco pratici in presenza di pre o postelaborazione.
Dennis,

@Dennis Non ci avevo pensato in quel modo. Pensi che dovrei cambiarlo ora o è troppo tardi?
Pavel,

Risposte:


5

Brachylog , 11 byte

ṇ⊇ᵐẹa₀ṁcᵐ~ṇ

Provalo online!

Spiegazione

ṇ             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

Ottimo lavoro sulla soluzione più breve (finora), a Brachylog piacciono sicuramente i quadrati, non è vero?
Pavel

@Pavel Il built-in è davvero molto utile!
Fatalizza il

7

Buccia , 13 byte

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

Provalo online!

Spiegazione

►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
Com'è possibile che sia un linguaggio di programmazione? Hai appena incollato alcuni caratteri unicode oscuri! ;)
rapa il

1
@Petar Benvenuti nel mondo dei linguaggi del golf, progettati appositamente per utilizzare il minor numero di byte possibile per svolgere un determinato compito. Parte di questo è avere una tabella codici personalizzata, in modo che ci sia un carattere per ogni possibile byte, invece del solito ASCII 95 stampabile. Ma non preoccuparti, ci sono anche lingue da golf molto più leggibili; per esempio la mia voce MATL [/ autopromozione spudorata]
Sanchises,

5

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

+2 byte per le -rzbandiere. Utilizza caratteri non stampabili NUL e BEL, mostrati come @e #qui. Vedi sotto per un dump xxd.

Grazie a @seshoumara per avermi inviato -z.

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

Provalo online!

Spiegazione

Funziona inserendo due cursori nel testo: uno per scavalcare le linee e uno per scavalcare le colonne. I cursori sono rappresentati rispettivamente da NUL (0x00) e BEL (0x07), ma negli esempi seguenti userò@ e #. Supponiamo di avere questo input:

abcde
fgh
asdf
foobar

Il cursore BEL viene inserito prima della 0a colonna e il cursore BEL prima della 0a riga (qui ho mantenuto le colonne allineate per leggibilità; ma in realtà non c'è riempimento a sinistra):

#@abcde
 @fgh
 @asdf
 @foobar

In un ciclo, i cursori vengono spostati di un carattere a destra e una riga in basso, rispettivamente:

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

Dopo ogni iterazione, controlla due condizioni:

  1. Sulla linea con il cursore di linea, c'è un cursore di colonna e il cursore di colonna può spostarsi a destra?
  2. Sulle linee prima del cursore di linea, ogni cursore di colonna può spostarsi a destra?

Se una delle condizioni è falsa, il ciclo termina. Lo script termina eliminando tutto dopo@ su ogni riga e tutto ciò che segue #nello spazio modello.

discarica 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

Puoi rimuovere il primo ciclo, A, perché l'istruzione dice che devi leggere l'input come una stringa, in modo da poter ricevere "line1 \ nline2 \ nline3" ecc. Anche altre risposte hanno fatto questo. Ciò dovrebbe portare il conteggio al di sotto di 100 :)
seshoumara,

@seshoumara Altre risposte line1\nline2\nline3dove si \ntrova \x5C\x6E? Quale?
Giordania,

Puoi darmi un link? (Fai clic su "condividi" in fondo a qualsiasi risposta.) O mostrami in un TiO cosa intendi? In tutte le risposte di Python e PHP che vedo \nviene interpretato come un carattere di nuova riga ( \x0A, non \x5C\x6E) e non riesco a trovare un modo per fare in modo che sed prenda input con caratteri di nuova riga come una singola riga.
Giordania,

@seshoumara Hah, non importa, mi sono appena ricordato della -zbandiera. Grazie!
Giordania,

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]

Provalo online!


Un metodo interessante, ma 2 byte in più.

Python 2 , 83 byte

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

Provalo online!


1
Non inputlegge solo una riga?
Pavel

@Pavel, se guardi l'esempio online, puoi vedere che sta usando caratteri espliciti newline per mantenere l'input una stringa di una riga. Probabilmente optando per questo metodo perché raw_input()aggiungerebbe più 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

Utilizza ricorsivamente un'espressione regolare per cercare un quadrato sempre più grande fino a quando non viene trovato nessuno.

L'espressione regolare sarebbe questa per un quadrato 3x3:

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

L'input dovrebbe terminare con una nuova riga e l'output è un elenco.

Spiegazione:

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

Frammento:



3

Perl 5 , 84 byte

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

Provalo online!

Soddisfa il "abcde\nfghij\nklm\nno"caso di test.


potresti usare chopinvece di chompe ++$i<@ainvece di$i++<$#a
Nahuel Fouilleul

3

R , 84 83 81 76 byte

-5 byte porting approccio di Dennis consum

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

Provalo online!

legge da stdin, stampa su stdout senza una nuova riga finale.

Leggermente non golfato:

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 (cc) , 162 159 151 147 144 142 137 byte

Ci devono essere alcuni colpi per giocare a golf qui ...

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

Provalo online!


Possono !=-1essere >-1o getchar()i valori di output sono inferiori a meno uno? Potrebbe anche essere +1?
Jonathan Frech,

Potenziali 158 byte .
Jonathan Frech,

@JonathanFrech Posso usare ~per rilevare meno uno.
Cleblanc,

1
@RickHitchcock Sembra funzionare nell'ultima versione del golf.
Cleblanc,

2

Gelatina , 15 byte

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

Provalo online!

Come funziona

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

Spiegazione:

Provalo qui.

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

Provalo online!

Il mio senso spidey mi dice che probabilmente c'è un modo più breve (sto pensando qualcosa con Ybodiritto fin dall'inizio) ... Richiede una nuova riga alla fine. (Nota: l'ho sovrastimato un po ', poiché gestirà anche le righe vuote, il che non è necessario. Vedrò se posso ridurre il bytecount, perché nel code golf non è una funzionalità, ma un bug)


1
@Pavel Guiseppe si riferiva a un'altra versione, che ho ripristinato perché aveva effettivamente un 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>

Richiede una nuova riga finale in input.



1

APL (Dyalog) , 25 byte *

Funzione prefisso tacita. Restituisce una matrice.

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

Provalo online!

È davvero una cima di due funzioni indipendenti, vale a dire ⎕AV[3]∘≠⊆⊢che si occupa del formato di input scomodo e ↑↑⍨2⍴(⌊/≢,≢¨)che svolge il lavoro effettivamente interessante.

⎕AV[3]∘≠ differenza LF (il terzo elemento del A Tomic V ector - il set di caratteri)

 partizioni (sottostringhe che iniziano con valori maggiori del loro predecessore e scendono a 0s)

 l'argomento

(... ) applica la seguente funzione tacita:

2⍴(... ) rimodella quanto segue per la lunghezza 2:

  ⌊/ il minimo di

   il numero di stringhe

  , seguito da

  ≢¨ il numero di caratteri in ciascuna stringa

↑⍨ prendere che molte righe e colonne da

 le stringhe mescolate insieme per formare una matrice (imbottitura con spazi)


* In classico con ⎕ML( M igration L evel) 3(impostazione predefinita su molti sistemi) e sostituzione per e per l'estrema sinistra . Tio!


Se è la stessa lunghezza in Dyalog Classic potresti anche dire che è Dyalog Classic e non usare la nota a piè di pagina.
Pavel

@Pavel Sia classico che ⎕ML←3obsoleto, quindi preferirei mostrare la lingua come apparirebbe normalmente. In effetti, quasi tutte le mie soluzioni Dyalog APL assumono Classic solo perché contiamo byte anziché caratteri, sebbene anche la versione Unicode assegni un significato a meno di 256 caratteri.
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),"
";

richiede PHP 5.4, 5.5 o 5.6. Sostituisci splitconexplode per PHP successivo.

Corri con php -nr '<code> '<string>'
o provalo online . (Assicurati di selezionare una versione PHP adatta!)



1

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

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

Provalo online

  • L'ultima riga di input deve terminare con una nuova riga nel caso in cui appartenga all'output.
  • Nel caso di due newline consecutive, l'opzione -00 può essere modificata di -0777.

Sono possibili due newline consecutive, quindi ne avrai bisogno -0777. Cosa fare -00e -0777fare, comunque.
Pavel,

-0è specificare il separatore di record in formato ottale 777è un valore speciale per indicare nessun separatore, quindi l'intero file viene letto, 0è un altro valore speciale per indicare "modalità paragrafo", il separatore è più di 1 newline consecutive
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("
")

Provalo online!

Evviva la mia prima risposta al Perl 6. Giocherò con alcune opzioni della riga di comando per vedere se posso giocare a golf un po 'di più. Tutto l'aiuto per salvare byte è il benvenuto!


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

Provalo online!

Giocare a golf per la prima volta in questa lingua, quindi forse non il massimo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.