줄에서 사각형을 새기다


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를 선택하여 입력을 구분해야 할 수도 있습니다.

줄 바꾸기 문자는 줄 길이의 일부로 간주되지 않습니다.

추가 줄로 계산되지 않는 입력 줄에 줄 바꿈이 있거나 없을 것을 요구할 수 있습니다.

입력은 문자열 또는 1D 문자 배열입니다. 문자열 목록이 아닙니다.

입력이 비어 있지 않고 모든 행이 비어 있지 않은 것으로 가정 할 수 있으며 공백과 줄 바꿈 (줄 구분 기호의 경우)을 포함하지만 탭이 아닌 인쇄 가능한 ASCII 만 포함합니다.

이것은 이며 가장 적은 바이트 수입니다!



5
흥미로운 도전에 +1, 엄격한 I / O에 -1
Dennis

@Dennis는 모든 솔루션을 사용할 필요 .split('\n')는 없으므로 일부는 무료로 제공 해야하는 이유를 모르겠습니다.
Pavel

2
지루한 상용구에 바이트를 추가해야하는 것은 아닙니다. 사전 처리 또는 사후 처리가있는 경우 일부 접근 방식 (예 : 재귀 함수)은 완전히 비실용적입니다.
Dennis

@Dennis 나는 그렇게 생각하지 않았습니다. 내가 지금 바꿔야한다고 생각합니까, 아니면 너무 늦습니까?
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
프로그래밍 언어조차 어떻습니까? 방금 모호한 유니 코드 문자를 붙여 넣었습니다! ;)
순무

1
@Petar 골프 언어의 세계에 오신 것을 환영합니다. 골프 언어는 특정 작업을 위해 가능한 한 적은 바이트를 사용하도록 설계되었습니다. 이것의 일부는 일반적인 95 인쇄 가능한 ASCII 대신 가능한 각 바이트에 대한 문자가 있도록 사용자 정의 코드 페이지를 갖는 것입니다. 그러나 훨씬 더 읽기 쉬운 골프 언어가 있습니다. 예를 들어 내 MATL 항목 [/ shameless self-promotion]
Sanchises

5

GNU sed , 106 + 1 94 + 2 = 96 바이트

-rz플래그의 경우 +2 바이트 로 표시 인쇄 할 수없는 문자 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

명령문에서 입력을 문자열로 읽어야하므로 "line1 \ nline2 \ nline3"등을 수신 할 수 있으므로 첫 번째 루프 A를 제거 할 수 있습니다. 다른 답변도이 작업을 수행했습니다. 즉 : (100) 아래의 수를 얻어야한다
seshoumara

@seshoumara 다른 답변 할 line1\nline2\nline3\n이다 \x5C\x6E? 어느?
Jordan

나에게 링크를 줄 수 있습니까? (대답의 맨 아래에있는 "공유"를 클릭하십시오.) 또는 TiO로 나에게 무슨 뜻인지 알려주세요. 모든 Python 및 PHP 답변 \n에서 줄 바꿈 문자 ( \x0A, not \x5C\x6E) 로 해석되며 sed가 줄 바꿈 문자를 한 줄로 입력하는 방법을 찾을 수 없습니다.
Jordan

@seshoumara Hah, 신경 쓰지 마, 나는 방금 -z깃발을 기억했다 . 감사!
Jordan

4

파이썬 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 바이트 더 깁니다.

파이썬 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

자바 스크립트 (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

R , 84 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

잠재적 인 158 바이트 .
Jonathan Frech

@JonathanFrech ~빼기 1을 감지하는 데 사용할 수 있습니다 .
클레 블랑

1
@RickHitchcock 최신 골프 버전에서 작동하는 것 같습니다.
클레 블랑

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

자바 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는 다른 버전을 언급하고 있었는데 실제로 버그가 있었기 때문에 롤백했습니다.
Sanchises



1

자바 스크립트 (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 ( A tomic V 의 세 번째 요소) 와의 차이 ector – 문자 집합)

 파티션 (전 행자보다 큰 값에서 시작하여 0에서 삭제되는 하위 문자열)

 논쟁 거리

() 다음 암묵적 기능을 적용하십시오.

2⍴() 다음을 길이 2로 바꿉니다.

  ⌊/ 최소

   문자열 수

  , 뒤에

  ≢¨ 각 문자열의 문자 수

↑⍨ 많은 행과 열을 가져옵니다

 문자열을 혼합하여 행렬을 만듭니다 (공백으로 채워짐)


*와 고전 ⎕ML( M igration의 L의 레벨 레벨) 3(많은 시스템에서 기본) 및 대체 에 대한 그리고 가장 왼쪽에 대해 . 티오!


Dyalog Classic에서 길이가 같으면 Dyalog Classic이라고 말하고 각주를 사용하지 마십시오.
Pavel

@Pavel Both Classic ⎕ML←3은 더 이상 사용되지 않으므로 일반적으로 나타나는 언어를 표시하고 싶습니다. 실제로 거의 모든 Dyalog APL 솔루션은 문자 대신 바이트 수를 계산하기 때문에 Classic을 가정하지만 유니 코드 버전에서도 256 문자 미만으로 의미를 할당합니다.
Adám

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]

온라인으로 사용해보십시오

  • 마지막 입력 줄은 출력에 속할 경우 줄 바꿈으로 끝나야합니다.
  • 두 개의 연속적인 줄 바꿈이있는 경우 -00은 옵션을 -0777로 변경할 수 있습니다.

두 개의 연속적인 줄 바꿈이 가능하므로 -0777. 어쨌든 무엇을 -00하고 무엇을 하는가 -0777.
Pavel

-0진수 형식으로 레코드 분리가 지정하는 것입니다 777전체 파일을 읽을 수 있도록 구분자를 나타 내기 위해 특별한 값, 0"문단 모드"를 표시하기 위해 다른 특별한 값은, 분리가 1 개 이상 연속 줄 바꿈입니다
나우 Fouilleul

1

Perl 6 , 158140 바이트

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

온라인으로 사용해보십시오!

나의 첫번째 Perl 6 답변을위한 Hooray. 골프를 좀 더 할 수 있는지 알아보기 위해 몇 가지 명령 줄 옵션을 가지고 놀 것입니다. 바이트 절약에 대한 모든 도움을 환영합니다!


1

스칼라 , 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""}

온라인으로 사용해보십시오!

이 언어로 처음 골프를 타는 것이 가장 큰 것은 아닐 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.