55
\$\begingroup\$

A string is considered to be square if the following conditions are met:

  • Each line has the same number of characters
  • The number of characters on each line is equal to the number of lines.

Your task is to write a program or function which determines whether or not a given input string is a square.

You may require input to be delimited by your choice of LF, CR, or CRLF.

The newline character(s) are not considered part of the line's length.

You may require there to be or to not be a trailing newline in input, which doesn't count as an additional line.

Input is a string or 1D char array; it is not a list of strings.

You may assume input is non-empty and only contains printable ASCII, including spaces.

You must output a truthy value for square strings and a falsy one for other strings.

Truthy test cases:

foo
bar
baz
.
.s.
.ss
.s.
(s represents space)
ss
ss
(s represents space)
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa

Falsy test cases:

..
.
.


.
....


....
4444
333
22
333
333
abc.def.ghi

Note extra blank lines in some of the falsy cases.

This is - fewest bytes wins!

\$\endgroup\$
9
  • 1
    \$\begingroup\$ @mbomb007 I feel like the different winning criteria make this not a duplicate? "Golfiness" was one of the voting criteria but I don't think answers to that question will largely reflect on the ones here. \$\endgroup\$ Jun 6, 2017 at 22:12
  • 3
    \$\begingroup\$ @mbomb007 I'm voting to leave this question open because, while it is a subset of the other question, the other question is restricted to languages created specifically for that question. \$\endgroup\$ Jun 6, 2017 at 22:15
  • 2
    \$\begingroup\$ @mbomb007: That's not a duplicate, because that question asks you to design a language for the purpose of answering the question, rather than answering in an existing language. Very few of the answers here would be legal there. \$\endgroup\$
    – user62131
    Jun 6, 2017 at 22:29
  • 1
    \$\begingroup\$ @mbomb007: That's no reason to close this challenge, and give people nowhere to post their answers in pre-existing languages, though. It might potentially be an argument for closing the other challenge (because it's just a more restrictive version of this one), although I'd consider it a poor argument and believe both should be left open. \$\endgroup\$
    – user62131
    Jun 7, 2017 at 17:47
  • 1
    \$\begingroup\$ Technically, the first requirement is redundant as it can never be false if the second is true. \$\endgroup\$
    – Antti29
    Jun 9, 2017 at 9:13

63 Answers 63

23
\$\begingroup\$

Python 2, 52 bytes

x=input().split('\n')
print{len(x)}==set(map(len,x))

Try it online! or Try all test cases

\$\endgroup\$
9
  • 5
    \$\begingroup\$ I love the fact that this is both golfed and readable. \$\endgroup\$
    – jpmc26
    Jun 6, 2017 at 19:00
  • \$\begingroup\$ You do not need the '\n', just leave it empty (since there are no spaces and tabs in the input). \$\endgroup\$ Jun 8, 2017 at 13:43
  • \$\begingroup\$ @12431234123412341234123 no, it does not work for square strings that contain spaces!!! \$\endgroup\$
    – Mr. Xcoder
    Jun 8, 2017 at 13:45
  • \$\begingroup\$ @Mr.Xcoder Must it work with spaces? As i understood there are never spaces in the input. \$\endgroup\$ Jun 8, 2017 at 13:46
  • \$\begingroup\$ You misunderstood the specs: You may assume input is non-empty and only contains printable ASCII., and whitespace (` `) is printable ASCII \$\endgroup\$
    – Mr. Xcoder
    Jun 8, 2017 at 13:47
22
\$\begingroup\$

Brachylog (2), 3 bytes

ṇẹṁ

Try it online!

Full program. Outputs true. for truthy, false. for falsey.

Explanation

ṇẹṁ
ṇ     Split {standard input} into lines
 ẹ    Split {each line} into basic elements {in this case, characters}
  ṁ   Assert that the result is square

I was a bit sceptical about the usefulness of the builtin when it was added, but I can't really deny that it's helpful here…

Brachylog (2), 7 bytes

ṇẹ.\l~l

Try it online!

Non-builtin solution. Still beats all the other entries, as of the time of writing. EDIT: Not quite, the equal-length Jelly entry got in while I was writing this, and beats it via the timestamp tiebreak.

Explanation

ṇẹ.\l~l
ṇ         Split {standard input} into lines
 ẹ        Split {each line} into basic elements {in this case, characters}
   \l     Assert that the result is rectangular, and the number of columns
  .  ~l     is equal to the number of rows
\$\endgroup\$
8
  • 10
    \$\begingroup\$ = "Assert that the result is square" :( \$\endgroup\$ Jun 6, 2017 at 17:48
  • 6
    \$\begingroup\$ There was a challenge a while back where I was struggling to write an assert-square (it'd have been something like .\l~l at the time, except that the backslash command, which among other things asserts that its input is a rectangle, was broken; note that even if we replace with .\l~l, this is still the shortest program here; come to think of it, I'll add that to the post). The backslash command got fixed, but the language author decided to add an assert-square at the same time. I was thinking "surely that's never going to come up again". Apparently I was wrong. \$\endgroup\$
    – user62131
    Jun 6, 2017 at 17:51
  • 3
    \$\begingroup\$ @Phoenix: Version number of the language, this won't work in Brachylog v1. Most people just say "Brachylog" (just like most people say "Perl" rather than "Perl 5"), but I got into the habit a while back because I do use Brachylog v1 on rare occasions. \$\endgroup\$
    – user62131
    Jun 6, 2017 at 17:59
  • 2
    \$\begingroup\$ @EriktheOutgolfer why is that problematic? Or do you just think it's a little boring? \$\endgroup\$
    – iFreilicht
    Jun 7, 2017 at 13:22
  • 2
    \$\begingroup\$ @iFreilicht It's bad because it outgolfs every other golfing language so far. \$\endgroup\$ Jun 7, 2017 at 13:24
16
\$\begingroup\$

JavaScript (ES6), 46 45 bytes

s=>!(s=s.split`
`).some(x=>x.length-s.length)

Explanation

  1. Split the string to an array on newlines.
  2. Loop over the array.
  3. Subtract the length of the array from the length of each line.
  4. If a non-zero (i.e., truthy) value is returned for any line, the string is not square.
  5. Negate the result of the loop to get true for square and false for not.

Try it

f=
s=>!(s=s.split`
`).some(x=>x.length-s.length)
oninput=_=>o.innerText=f(i.value)
o.innerText=f(i.value=`foo
bar
baz`)
<textarea id=i></textarea><pre id=o>

\$\endgroup\$
2
  • 3
    \$\begingroup\$ I think you can save a byte with s=>!(s=s.split`\n`).some(x=>x.length-s.length) \$\endgroup\$ Jun 6, 2017 at 17:58
  • \$\begingroup\$ Thanks, @ETHproductions. I've a terrible habit of dismissing !some out of hand, simply because it's the same length as every. \$\endgroup\$
    – Shaggy
    Jun 7, 2017 at 10:51
11
\$\begingroup\$

Jelly, 7 5 bytes

Ỵ¬⁼Z$

Try it online!

Thanks to FryAmTheEggman for -2

\$\endgroup\$
0
10
\$\begingroup\$

05AB1E, 10 8 bytes

¶¡€gDgQP

Try it online!

-2 thanks to Riley, this is basically his answer ._.

Code       # Explanation                  | Truthy Example          | Falsy Example
-----------#------------------------------+-------------------------+--------------
¶¡         # Split on newlines            | [['aaa','aaa','aaa']]   | [['aa']]
  €g       # Get length of each           | [[3,3,3]]               | [[2]]
    D      # Dupe                         | [[3,3,3],[3,3,3]]       | [[2],[2]]
     g     # Get length                   | [[3,3,3],3]             | [[2],1]
      Q    # Check equality               | [[1,1,1]]               | [[0]]
       P   # Take product                 | 1                       | 0
\$\endgroup\$
10
  • \$\begingroup\$ @Riley ahhh, nice catch, my original idea was more along the lines of what you had but slightly different. Iterated two more times and didn't catch my math error. \$\endgroup\$ Jun 6, 2017 at 16:43
  • \$\begingroup\$ I don't think "Header" is a valid form on input. \$\endgroup\$
    – Pavel
    Jun 6, 2017 at 17:13
  • \$\begingroup\$ @Phoenix is that better? \$\endgroup\$ Jun 6, 2017 at 17:19
  • 1
    \$\begingroup\$ Input can also be taken in with three quotes, like this. \$\endgroup\$
    – Adnan
    Jun 6, 2017 at 18:33
  • 1
    \$\begingroup\$ If you get the length of each first you can avoid the s. Like this ¶¡€gDgQP \$\endgroup\$
    – Riley
    Jun 6, 2017 at 18:34
9
\$\begingroup\$

Haskell, 38 34 bytes

l=length
(all=<<(.l).(==).l).lines

Try it online!

Pointfree version of f s = all ((==length (lines s)).length) (lines s), i.e split the input into lines and check if the length of each line is equal to the number of lines.

Edit: Thanks to @xnor for 4 bytes.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I think you can use all for map to cut the and.. \$\endgroup\$
    – xnor
    Jun 6, 2017 at 20:30
9
\$\begingroup\$

Jelly, 7 bytes

ỴµL;L€E

Try it online!

Explanation

Ỵµ       Split the input on newline and use as input in the second link     
  L      Get the number of list items
   ;     And append to that
    L€   A list with the legth of each list item
      E  Check to see if all items are equal.
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Your TIO link seems to indicate that no trailing newline should be there. \$\endgroup\$
    – Pavel
    Jun 6, 2017 at 16:58
  • \$\begingroup\$ @Phoenix fixed / reverted... \$\endgroup\$
    – steenbergh
    Jun 6, 2017 at 17:00
  • \$\begingroup\$ This just checks to see if all lines are the same length - it actually doesn't take the newline count into account at all. When you reach the E atom, you have a list of line lengths and that's all. \$\endgroup\$ Jun 8, 2017 at 17:06
  • \$\begingroup\$ @Christian fixed and shortened. Sorry 'bout the confusion, I guess something went wrong after I had a working solution and I tried to golf that.. \$\endgroup\$
    – steenbergh
    Jun 8, 2017 at 17:17
9
\$\begingroup\$

Husk, 6 bytes

S≡T'a¶

Takes a string and prints either 1 or 0. Try it online! The first line iterates over the test cases; remove it if you want to test on a single value.

Explanation

Husk is a new functional golfing language created by myself and Leo. It's missing a lot of features and development is ongoing. Its main feature is a rigid type system that allows us to overload higher order functions.

On a high level, the program works like this:

S≡T'a¶  Define a function:
     ¶  split on newlines,
  T'a   transpose and pad to rectangle using character 'a',
 ≡      check if this has the same shape as
S       the split input.

The function actually checks if two arrays have the same shape and the same distribution of truthy elements. In Husk, all characters except the null byte are truthy, and that won't occur in our inputs. Also, S is the S-combinator, a function that takes as inputs two functions, here and T'a, and returns a new function that maps x to ≡(x)(T'a x). The result of S is composed with , and that function is applied to the input implicitly.

How does Husk know that it should apply S to the next function, but should be composed with the function on its left? Simple: it just tries every interpretation and picks the one where the types make sense. This is explained in more detail in the Husk documentation.

\$\endgroup\$
9
\$\begingroup\$

Japt, 9 bytes

=Ur.Q)¥Uy

Test it online!

Explanation

 =Ur.Q)¥ Uy
U=Ur.Q)==Uy
             // Implicit: U = input string, Q = quotation mark
U=    )      // Set U to
  Ur.Q       //   U with each non-newline (/./g) replaced with a quotation mark.
       ==Uy  // Return U == U transposed. U is padded to a rectangle with spaces before
             // transposing; if U was not a rectangle before, or the sides are not of
             // equal length, the result will not be the same as U.
             // Implicit: output result of last expression

Using some features implemented shortly after this challenge was posted, this can be 6 bytes:

r.Q
¥y

Test it online!

Explanation

       // Implicit: U = input string
r.Q    // Replace each non-newline (/./g) in U with a quotation mark.
       // Newline: set U to the result.
¥      // Return U ==
 y     //   U transposed.
       // Implicit: output result of last expression
\$\endgroup\$
4
  • \$\begingroup\$ How in the world are you so fast? \$\endgroup\$ Jun 6, 2017 at 16:23
  • \$\begingroup\$ @totallyhuman I happened to see the question the instant it was posted, and it took me two minutes to come up with an algorithm. After that it was just implementing and posting. (Also I have things to get back to haha) \$\endgroup\$ Jun 6, 2017 at 16:24
  • \$\begingroup\$ Nice :) I knew y was the solution but mine was coming in at a few more bytes. \$\endgroup\$
    – Shaggy
    Jun 6, 2017 at 16:28
  • \$\begingroup\$ "Using some features implemented shortly after this challenge was posted" - You can now post that as your asnwer. \$\endgroup\$
    – Shaggy
    Jul 11, 2017 at 15:59
7
\$\begingroup\$

Retina, 33 31 bytes

.
.
^(.(.)*)(?<-2>¶\1)*$(?(2).)

Try it online! Explanation: The first stage simply changes all printable ASCII into the same character to make it easier to match. (It could be done without, but this is code golf, not code challenge.) The second stage then matches at least one character on the first line. However, for each additional character on the first line, it then optionally matches a newline followed by a copy of the first line. The final part of the expression causes the match to fail if there are more columns than rows.

\$\endgroup\$
5
  • \$\begingroup\$ Unfortunately, this outputs true for this testcase. \$\endgroup\$
    – user41805
    Jun 6, 2017 at 16:51
  • \$\begingroup\$ @KritixiLithos I believe the submission requires a trailing newline in input, which is allowed. \$\endgroup\$
    – Pavel
    Jun 6, 2017 at 16:52
  • \$\begingroup\$ Also I believe using \S\n; instead of the first line saves one byte \$\endgroup\$
    – user41805
    Jun 6, 2017 at 16:53
  • \$\begingroup\$ @KritixiLithos Actually replacing . with . saves two, but thanks. \$\endgroup\$
    – Neil
    Jun 6, 2017 at 16:53
  • \$\begingroup\$ @Neil That's really clever! \$\endgroup\$
    – user41805
    Jun 6, 2017 at 17:27
6
\$\begingroup\$

Pure bash (no utilities), 55

mapfile -t a
for l in ${a[@]};{
((c+=${#l}^${#a[@]}))
}
  • mapfile reads the input into array a
  • then the number of elements of the array is XORed with each line length, and the sum taken. For a perfect square, each XOR result (and thus the sum) will be 0. For anything else, the result will be >0.

The opposite sense of this is returned as a shell return code (examine with echo $?) - perfect square is 1, anything else is 0.

Try it online (truthy).

Try it online (falsy).


Previous answer using eval-escape-expansion hell, 78:

mapfile -t a
echo $[0$(eval eval echo +\\$\{#a[{0..$[${#a[@]}-1]}]}^${#a[@]})]

Try it online (truthy).

Try it online (falsy).

\$\endgroup\$
5
\$\begingroup\$

Perl 6, 27 bytes

{.lines==all .lines».comb}

Tests whether the number of lines in the input string is equal to the number of characters on each line.

\$\endgroup\$
2
  • \$\begingroup\$ does this ignore the new-line character? \$\endgroup\$
    – Khaled.K
    Jun 6, 2017 at 20:39
  • \$\begingroup\$ Yes, newlines are not returned by the .lines method. \$\endgroup\$
    – Sean
    Jun 6, 2017 at 20:47
5
\$\begingroup\$

Jelly, 4 bytes

Ỵ¬zƑ

Try it online!

Input via command-line argument. The input must be given with no trailing newline (otherwise the program sees a blank line at the end, which isn't the same length as the others); this I/O format is explicitly allowed by the question.

So far, the shortest answer that doesn't use an "is a square" builtin. (There's an existing 5-byte Jelly answer that works on similar principles, but is wrong, incorrectly considering "aa\na" to be square – this answer is not only shorter, it also fixes that issue.)

Explanation

Ỵ¬zƑ
Ỵ      split {the input} on newlines
 ¬     replace every truthy character (i.e. all of them) with 0
   Ƒ   does that remain unchanged, after
  z      a ragged transpose that pads to a rectangle using {the input}?

There are two main cases:

  • The string is not even a rectangle. In this case, the "transpose and pad to rectangle" builtin z will pad the string to a rectangle, but uses copies of the user input as the padding, which are not zeroes (even if the input uses the character '0', this compares unequal to the integer 0). So there's no way the ragged transpose can leave the split-and-zeroed version of the input unchanged.
  • The string is a rectangle. In this case, the ragged transpose won't apply any padding, but will produce a rectangle of zeroes with the number of rows and columns swapped from the transpose input. The only way the input and output can match is therefore if the number of rows equals the number of columns, i.e. the input is a square. (If the input is a square, the transpose will leave it unchanged because, as every element is a zero, all the elements will be the same and thus it doesn't matter that the transpose swaps some of them.)
\$\endgroup\$
4
\$\begingroup\$

Pyth, 7 bytes

CImL1.z

Try it here

Requires no trailing newline. Replaces the input with a 2D array of 1s where a 1 represents any character in the original input. Then we check whether that array is unchanged after transposing it (replacing columns with rows). Only a square will return true in such a situation.

\$\endgroup\$
4
\$\begingroup\$

Java (OpenJDK 8), 96 91 90 87 bytes

-5 bytes thanks to @KevinCruijssen
-1 byte thanks to @TheLethalCoder
-2 bytes thanks to @OlivierGrégoire

a->java.util.Arrays.stream(a.split("\n")).allMatch(x->x.length()==a.split("\n").length)

Try it online!

\$\endgroup\$
11
  • 1
    \$\begingroup\$ You can remove the space at String[]s and you can remove the ,0 in the .split("\\n"); for -3 bytes. And the semicolon/; at the very end you won't have to count, so that another -1. Oh, and you have to include the java.util. in front of the Arrays I'm afraid. Imports/usings are part of the byte-count as well. \$\endgroup\$ Jun 7, 2017 at 9:15
  • 1
    \$\begingroup\$ Since you forgot to include the java.util., just a regular for-loop like this for(String x:s)if(x.length()!=s.length)return 0>1;return 1>0; seems to be shorter than return java.util.Arrays.stream(s).anyMatch(l->l.length()!=s.length);. \$\endgroup\$ Jun 7, 2017 at 9:23
  • 2
    \$\begingroup\$ Is it not just \n? \$\endgroup\$ Jun 7, 2017 at 11:01
  • 1
    \$\begingroup\$ Repeating the a.split("\n") is actually shorter! a->java.util.Arrays.stream(a.split("\n")).allMatch(x->x.length()==a.split("\n").length) \$\endgroup\$ Jun 8, 2017 at 13:33
  • 2
    \$\begingroup\$ Hmmm... some more are present as well between leng and th(). So apparently, they appear first after the 60th char then every 20 characters. \$\endgroup\$ Jun 8, 2017 at 14:29
3
\$\begingroup\$

05AB1E, 7 bytes

|€gDgQP

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Kind of cheating imo, that's basically taking n inputs instead of 1 and why my original answer didn't work. \$\endgroup\$ Jun 6, 2017 at 18:37
  • \$\begingroup\$ @carusocomputing No, | means "take the rest of the input and split by newlines" which is in no way taking multiple inputs. You just have to treat STDIN as a single input. \$\endgroup\$ Jun 6, 2017 at 18:41
3
\$\begingroup\$

R, 57 bytes

function(s)all(nchar(n<-strsplit(s,'
')[[1]])==length(n))

An anonymous function; Splits on newlines, computes the length of each line, and checks if all are the same as the number of lines.

Try it online!

\$\endgroup\$
3
\$\begingroup\$

MATL, 14 12 bytes

10H&XXot&n=h

The input string is defined using string concatenation ([...]) and with the code point 10 to represent LF. For example, ['aaa' 10 'bb'] is interpreted in MATL as string 'aaa' concatenated with the character with code point 10 concatenated with string 'bb'.

The output is a non-empty numeric vector, which is truthy if and only if all its entries are non-zero.

Try it online!

Explanation

Consider input ['4444' 10 '333' 10 '22'].

10H   % Push 10 (code point of LF). Push 2
      % STACK: 10, 2
&XX   % Regexp with three arguments. First argument is implicit input (string);
      % second is 2, which indicates that we want to split the input; third is
      % 10, which is the character to split on. The result is a cell array of
      % matched strings
      % STACK: {'4444', '333', '22'}
o     % Concatenate into a numeric 2D array of code points, right-padding with
      % zeros if needed
      % STACK: [52 52 52 52; 51 51 51 0; 50 50 0 0]
t&n   % Duplicate. Push number of rows and number of columns
      % STACK: [52 52 52 52; 51 51 51 0; 50 50 0 0], 3, 4
=     % Are they equal?
      % STACK: [52 52 52 52; 51 51 51 0; 50 50 0 0], 0
h     % Concatenate into a row vector (in column-major order). Implicit display
      % STACK: [52 51 50 52 51 50 52 51 0 52 0 0 0]
\$\endgroup\$
3
\$\begingroup\$

R, 35 bytes

all(nchar(x<-scan(,""))==length(x))

Takes input from stdin. Checks that the number of characters in each line is equal to the total number of lines. Returns TRUE or FALSE as appropriate.

\$\endgroup\$
1
  • \$\begingroup\$ note that inputs need to be wrapped in quotes or this might break on spaces within each line. \$\endgroup\$
    – Giuseppe
    Mar 6, 2018 at 14:50
3
\$\begingroup\$

Ruby, 50 bytes

s=$<.read.split $/,-1;p [s.size]==s.map(&:size)|[]

Try it online!

Explanation

  1. Split input into array on newline.
  2. Assert that an array containing only the size of this array is equal to an array containing all uniq (set union with empty array) sizes of all elements in this array.
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Save a character with .split($/,-1); -> .split $/,-1; \$\endgroup\$ Jun 8, 2017 at 19:58
  • \$\begingroup\$ Save more by using lines instead of read and then split (but then you have to add 1 to size because the lines include the trailing newline) \$\endgroup\$
    – G B
    Jun 9, 2017 at 7:22
  • \$\begingroup\$ 45 bytes: Try it online! \$\endgroup\$
    – Jonah
    Jul 30, 2022 at 22:45
2
\$\begingroup\$

JavaScript (ES6), 48 bytes

s=>(a=s.split`
`,a.every(l=>l.length==a.length))
\$\endgroup\$
2
\$\begingroup\$

CJam, 11 bytes

qN/:,_,f=:*

Try it online!

\$\endgroup\$
2
\$\begingroup\$

OCaml, 56 bytes

let f t=List.(for_all(fun l->String.length l=length t)t)

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Pyth, 12 10 bytes

!fnl.zlT.z

Saved 2 bytes thanks to @FryAmTheEggman.

Try it online

Explanation

!fnl.zlT.z
 f     T.z     Filter lines of the input
  nl.zl        whose length is not the number of lines
!              and return whether there are no such lines.
\$\endgroup\$
0
2
\$\begingroup\$

QBIC, 43 bytes

{_?~_lA||h=h+1┘g=g+_lA|~g%_lA||_Xp]\_xg/h=h

Me, I'm happy with how short a QBasic derivative got to go on this challenge.

Explanation:

{_?       DO infinitely: ask the user for input, store as A$
~    |    IF
 _lA|       The length of A$   (implicitly <> 0)
h=h+1     Add 1 to our line counter
┘         (syntactic linebreak)
g=g+_lA|  Add the length of this line to the running total of line lengths
~      |  IF
 g%_lA|     The length of the running total modulo the length of the last string
            yields anything but 0, there is a discrepancy between earlier line
            lengths and this one.
_Xp]      THEN QUIT, printing 0, end IF
\         ELSE (refers to the LEN(A$), user didn't input anything.
_xg/h=h   QUIT (the inf. loop) printing -1 if the root of the chars is the row count
            or 0 if not.
\$\endgroup\$
0
2
\$\begingroup\$

Pyth, 7 bytes

qCC.z.z

Demonstration

Transpose the input with truncation twice, then check if the result is the same as the original.

\$\endgroup\$
2
\$\begingroup\$

Perl 5, 31 bytes

29 bytes of code + -p0 flags.

/.*/;$_=/^(.{@{+}}
){@{+}}\z/

Try it online!

Explanations:
/.*/ matches the first line, and thus makes @+ contain the length of the first line. Then the regex checks whether the string contains @+ lines of length @+.

\$\endgroup\$
2
\$\begingroup\$

MacOS Bash, 34

rs -EH|awk '{print $1}'|uniq|wc -l

rs is part of the default MacOS image. This will also work on Linux if rs is installed; it is on TIO.

  • rs -EH lists the length of each line, along with the number of lines
  • awk strips out extraneous info
  • uniq outputs one line if the line lengths and number of lines are all the same, but more otherwise
  • wc -l outputs 1 if the input is square or a greater number otherwise.

Try it online: Truthy, Falsey.

\$\endgroup\$
2
\$\begingroup\$

AWK, 49 bytes

{s=length($0)}L{x+=L!=s}{L=s}END{print x?0:L==NR}

Try it online!

Could also have used a BEGIN block to set FS="" but that would be the same byte-count. For some reason using the -F"" argument never seems to work.

\$\endgroup\$
2
\$\begingroup\$

Stax, 9 bytes

éΘ┌«■/ÉW(

Run and debug online!

Turns out that due to way pairwise difference is calculated, I don't need to worry about the equivalence of k and x-k here. Saving 5 bytes.

Uses the unpacked version to explain.

Lc{%mc%+:u
L             Collect rows in a list
 c{%m         List of length of each row
     c%+      Append number of rows to the list
        :u    All elements in the list are equal
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.