从弦上雕刻一个正方形


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来分隔输入。

换行符不视为行长度的一部分。

您可能需要在输入中包含或不包含尾随换行符,这不会算作附加行。

输入是字符串或一维char数组;它不是字符串列表。

您可以假设输入为非空且所有行均为非空,并且它仅包含可打印的ASCII,包括空格和换行符(用于行定界符),但不包含制表符。

这是,最少字节获胜!



5
+1代表有趣的挑战,-1代表严格的I / O
Dennis

@Dennis并非每个解决方案都需要使用,.split('\n')因此我不明白为什么有些解决方案应免费获得。
帕维尔

2
这不是(只是)关于为无聊的样板添加字节。如果存在预处理或后处理,则某些方法(例如,递归函数)将变得完全不切实际。
丹尼斯,

@丹尼斯我还没想到这样。您认为我现在应该更改它,还是为时已晚?
帕维尔

Answers:


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


@Pavel 内置确实很方便!
致命

7

外壳,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
哪怕是一种编程语言,您也只是粘贴了一些晦涩的unicode字符!;)
萝卜

1
@Petar欢迎来到高尔夫球语言的世界,这些语言专门设计用于使用最少的字节来完成特定的任务。其中的一部分是拥有一个自定义代码页,以便每个可能的字节都有一个字符,而不是通常的95个可打印ASCII。但是不用担心,高尔夫语言也更加清晰易懂。例如我的MATL条目[/无耻的自我促进]
桑契斯(Sanchises)

5

GNU sed106 + 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)和BEL(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转储

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),并且我找不到让sed将换行符输入作为一行的方法。
乔丹

@seshoumara Hah,没关系,我只是记得那面-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

Perl 5,84个字节

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

在线尝试!

完成"abcde\nfghij\nklm\nno"测试用例。


您可以使用chop代替chomp++$i<@a代替$i++<$#a
Nahuel Fouilleul

3

R84 83 81 76字节

-5字节移植丹尼斯的方法sum

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

在线尝试!

从stdin读取,打印到stdout,不带换行符。

稍微松了一下:

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),


@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从一开始就在考虑正确的事情)...最后需要换行符。(注意:我对此做了一些过度设计,因为它也可以处理空行,这不是必需的。我会看看是否可以减少字节数,因为在代码高尔夫中,这不是功能,而是一个错误)


1
@Pavel Guiseppe指的是另一个版本,我回滚了因为它确实存在错误。
桑奇斯



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字节*

隐式前缀功能。返回一个矩阵。

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

在线尝试!

它实际上是两个独立功能的顶峰,即⎕AV[3]∘≠⊆⊢处理笨拙的输入格式和↑↑⍨2⍴(⌊/≢,≢¨)完成实际有趣的工作。

⎕AV[3]∘≠ 从LF(所述的第三个元素差托米奇V -字符集厄克托)

 分区(子字符串的起始值大于其前任值,并在0s处下降)

 论点

() 应用以下默认功能:

2⍴()  将以下内容重塑为长度2:

  ⌊/ 最小值

   弦数

  , 其次是

  ≢¨ 每个字符串中的字符数

↑⍨ 取那么多的行和列

 字符串混合在一起形成矩阵(用空格填充)


*在用经典⎕ML中号 igration 大号伊维尔基尼)3(在许多系统默认值),而代以用于最左边io!


如果在Dyalog Classic中它的长度相同,您可能会说它是Dyalog Classic,而不要使用脚注。
Pavel

@Pavel Classic和⎕ML←3不推荐使用,因此我宁愿显示通常显示的语言。实际上,几乎所有我的Dyalog APL解决方案都采用Classic,只是因为我们计算字节数而不是字符数,即使Unicode版本也将含义分配给少于256个字符。
–Adám17年

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。更换splitexplode了以后PHP。

运行php -nr '<code> '<string>'
在线尝试。(确保选择合适的PHP版本!)



1

Perl 5、60 +5(-0777p)字节

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

在线尝试

  • 输入的最后一行必须以换行符结尾,以防它属于输出。
  • 如果有两个连续的换行符,则-77可以更改-00选项。

可以使用两个连续的换行符,因此您需要-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("
")

在线尝试!

Hooray为我的第一个Perl 6答案。我将尝试一些命令行选项,看看是否可以再打些高尔夫。欢迎所有节省字节的帮助!


1

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

在线尝试!

第一次用这种语言打高尔夫球,所以也许不是最棒的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.