Is this string a square?

44

6

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!

Pavel

Posted 2017-06-06T16:19:20.313

Reputation: 8 585

Possible duplicate of Language Design: 2-D Pattern Matching. Problem #5 is the same as this question.

– mbomb007 – 2017-06-06T21:40:10.170

1@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. – FryAmTheEggman – 2017-06-06T22:12:36.953

2@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. – ETHproductions – 2017-06-06T22:15:13.490

2@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. – None – 2017-06-06T22:29:10.730

The solutions there are legal here, however. Many of the answers have an exact solution to this challenge contained in them. – mbomb007 – 2017-06-07T01:03:41.227

1@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. – None – 2017-06-07T17:47:45.217

Technically, the first requirement is redundant as it can never be false if the second is true. – Antti29 – 2017-06-09T09:13:25.913

Answers

19

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

user62131

Posted 2017-06-06T16:19:20.313

Reputation:

1Correct tool for the job! – Pavel – 2017-06-06T17:18:38.860

10 = "Assert that the result is square" :( – Erik the Outgolfer – 2017-06-06T17:48:24.700

5There 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. – None – 2017-06-06T17:51:26.147

What does the (2) signify? – Pavel – 2017-06-06T17:58:22.657

2@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. – None – 2017-06-06T17:59:37.003

1The 3 byte solution without the dots under and over the characters (nem) means no in Hungarian :D – Gábor Fekete – 2017-06-07T10:09:54.637

1@EriktheOutgolfer why is that problematic? Or do you just think it's a little boring? – iFreilicht – 2017-06-07T13:22:06.743

2@iFreilicht It's bad because it outgolfs every other golfing language so far. – Erik the Outgolfer – 2017-06-07T13:24:12.687

21

Python 2, 52 bytes

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

Try it online! or Try all test cases

Rod

Posted 2017-06-06T16:19:20.313

Reputation: 17 588

4I love the fact that this is both golfed and readable. – jpmc26 – 2017-06-06T19:00:51.067

You do not need the '\n', just leave it empty (since there are no spaces and tabs in the input). – 12431234123412341234123 – 2017-06-08T13:43:01.660

@12431234123412341234123 no, it does not work for square strings that contain spaces!!! – Mr. Xcoder – 2017-06-08T13:45:04.383

@Mr.Xcoder Must it work with spaces? As i understood there are never spaces in the input. – 12431234123412341234123 – 2017-06-08T13:46:20.013

You misunderstood the specs: You may assume input is non-empty and only contains printable ASCII., and whitespace () is printable ASCII – Mr. Xcoder – 2017-06-08T13:47:46.453

Why not just make a lambda like this?https://tio.run/##K6gsycjPM/5fYRvzPycxNyklUSHHqjonNU8jR7PW1rY4tUQjN7FAAyigk6Op@b@gKDOvRKNCI1opUUFJR0lBQSkWKAoA

– irapsaged – 2017-07-07T12:42:59.693

@irapsaged OP didn't allowed Input is a string or 1D char array; it is not a list of strings. – Rod – 2017-07-07T12:47:18.117

Oh, sorry, my bad. – irapsaged – 2017-07-07T12:51:38.733

@irapsaged np c: – Rod – 2017-07-07T13:00:13.523

14

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>

Shaggy

Posted 2017-06-06T16:19:20.313

Reputation: 24 623

3I think you can save a byte with s=>!(s=s.split`\n`).some(x=>x.length-s.length) – ETHproductions – 2017-06-06T17:58:38.223

Thanks, @ETHproductions. I've a terrible habit of dismissing !some out of hand, simply because it's the same length as every. – Shaggy – 2017-06-07T10:51:23.017

9

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

ETHproductions

Posted 2017-06-06T16:19:20.313

Reputation: 47 880

How in the world are you so fast? – totallyhuman – 2017-06-06T16:23:56.107

@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) – ETHproductions – 2017-06-06T16:24:45.550

Nice :) I knew y was the solution but mine was coming in at a few more bytes. – Shaggy – 2017-06-06T16:28:10.067

"Using some features implemented shortly after this challenge was posted" - You can now post that as your asnwer. – Shaggy – 2017-07-11T15:59:47.840

9

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

Magic Octopus Urn

Posted 2017-06-06T16:19:20.313

Reputation: 19 422

@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. – Magic Octopus Urn – 2017-06-06T16:43:30.423

I don't think "Header" is a valid form on input. – Pavel – 2017-06-06T17:13:02.140

@Phoenix is that better? – Magic Octopus Urn – 2017-06-06T17:19:56.560

Probably, IDK 05ab1e – Pavel – 2017-06-06T17:22:15.253

1

Input can also be taken in with three quotes, like this.

– Adnan – 2017-06-06T18:33:21.173

1

If you get the length of each first you can avoid the s. Like this ¶¡€gDgQP

– Riley – 2017-06-06T18:34:41.867

@Riley already got down to 8-bytes by changing the strategy entirely. – Magic Octopus Urn – 2017-06-06T18:38:20.980

@carusocomputing I thought of that too, but it doesn't quite work

– Riley – 2017-06-06T18:39:29.510

@Riley do you want the answer? This was basically all you after a certain point lmao. I feel bad still getting points for it. – Magic Octopus Urn – 2017-06-06T18:46:18.373

@carusocomputing Nah, it's not that far from your original solution. I had enough fun working on it, I don't need the rep or anything. – Riley – 2017-06-06T18:59:17.543

9

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.

steenbergh

Posted 2017-06-06T16:19:20.313

Reputation: 7 772

1Your TIO link seems to indicate that no trailing newline should be there. – Pavel – 2017-06-06T16:58:20.537

@Phoenix fixed / reverted... – steenbergh – 2017-06-06T17:00:42.493

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. – scatter – 2017-06-08T17:06:51.733

@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.. – steenbergh – 2017-06-08T17:17:47.383

9

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.

nimi

Posted 2017-06-06T16:19:20.313

Reputation: 34 639

1I think you can use all for map to cut the and.. – xnor – 2017-06-06T20:30:15.883

9

Jelly, 7 5 bytes

Ỵ¬⁼Z$

Try it online!

Thanks to FryAmTheEggman for -2

Erik the Outgolfer

Posted 2017-06-06T16:19:20.313

Reputation: 38 134

7

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.

Neil

Posted 2017-06-06T16:19:20.313

Reputation: 95 035

Unfortunately, this outputs true for this testcase.

– user41805 – 2017-06-06T16:51:12.303

@KritixiLithos I believe the submission requires a trailing newline in input, which is allowed. – Pavel – 2017-06-06T16:52:04.833

Also I believe using \S\n; instead of the first line saves one byte – user41805 – 2017-06-06T16:53:15.417

@KritixiLithos Actually replacing . with . saves two, but thanks. – Neil – 2017-06-06T16:53:55.003

@Neil That's really clever! – user41805 – 2017-06-06T17:27:16.127

6

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.

Zgarb

Posted 2017-06-06T16:19:20.313

Reputation: 39 083

5

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.

Sean

Posted 2017-06-06T16:19:20.313

Reputation: 4 136

does this ignore the new-line character? – Khaled.K – 2017-06-06T20:39:11.853

Yes, newlines are not returned by the .lines method. – Sean – 2017-06-06T20:47:25.593

5

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

Digital Trauma

Posted 2017-06-06T16:19:20.313

Reputation: 64 644

4

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.

FryAmTheEggman

Posted 2017-06-06T16:19:20.313

Reputation: 16 206

4

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!

Bashful Beluga

Posted 2017-06-06T16:19:20.313

Reputation: 413

@Phoenix Fixed, thank you! :-) – Bashful Beluga – 2017-06-07T00:43:39.480

1You 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. – Kevin Cruijssen – 2017-06-07T09:15:29.133

1Since 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);. – Kevin Cruijssen – 2017-06-07T09:23:11.450

@KevinCruijssen Thanks for saving me several bytes! :-) – Bashful Beluga – 2017-06-07T11:01:06.140

2Is it not just \n? – TheLethalCoder – 2017-06-07T11:01:35.840

@TheLethalCoder String.split() takes a String (a regex) and, optionally, an int (a delimiter) as parameters. Therefore, I thought the backslash had to be escaped. But at the end of the day it worked without escaping, so thanks for saving me 1 byte! :-)

– Bashful Beluga – 2017-06-07T11:04:32.943

1Repeating the a.split("\n") is actually shorter! a->java.util.Arrays.stream(a.split("\n")).allMatch(x->x.length()==a.split("\n").length) – Olivier Grégoire – 2017-06-08T13:33:37.967

@OlivierGrégoire In fact it is 1 char shorter, but for some reason TIO says it is [91 chars, 99 bytes] long (compared to the [90 chars, 90 bytes] of my current answer). – Bashful Beluga – 2017-06-08T14:19:51.577

1Well, it's totally explainable: Stackoverflow add some blank empty unicode characters to cut the long code blocks. This way, the comments aren't taking too much space. It happens quite a lot on this website because of its nature. By the way, I counted 87 chars, not 89 (or 91), and I just double-checked again: 87 chars, not any single more. If you count manually or retype it exactly as is, you'll see that. In this case, the extra characters are between the last . and the last length. – Olivier Grégoire – 2017-06-08T14:26:21.833

2Hmmm... some more are present as well between leng and th(). So apparently, they appear first after the 60th char then every 20 characters. – Olivier Grégoire – 2017-06-08T14:29:48.533

1@OlivierGrégoire I suspected that from the beginning. It makes sense. I re-typed everything on my IDE, pasted on TIO and voilà: 87 bytes! Thank you :-) – Bashful Beluga – 2017-06-08T14:47:35.037

3

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]

Luis Mendo

Posted 2017-06-06T16:19:20.313

Reputation: 87 464

3

05AB1E, 7 bytes

|€gDgQP

Try it online!

Erik the Outgolfer

Posted 2017-06-06T16:19:20.313

Reputation: 38 134

Kind of cheating imo, that's basically taking n inputs instead of 1 and why my original answer didn't work. – Magic Octopus Urn – 2017-06-06T18:37:22.763

@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. – Erik the Outgolfer – 2017-06-06T18:41:34.080

3

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!

Giuseppe

Posted 2017-06-06T16:19:20.313

Reputation: 21 077

3

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.

rturnbull

Posted 2017-06-06T16:19:20.313

Reputation: 3 689

note that inputs need to be wrapped in quotes or this might break on spaces within each line. – Giuseppe – 2018-03-06T14:50:43.733

2

JavaScript (ES6), 48 bytes

s=>(a=s.split`
`,a.every(l=>l.length==a.length))

kamoroso94

Posted 2017-06-06T16:19:20.313

Reputation: 739

2

CJam, 11 bytes

qN/:,_,f=:*

Try it online!

Esolanging Fruit

Posted 2017-06-06T16:19:20.313

Reputation: 13 542

2

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.

user48543

Posted 2017-06-06T16:19:20.313

Reputation:

2

OCaml, 56 bytes

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

Try it online!

juloo65

Posted 2017-06-06T16:19:20.313

Reputation: 81

2

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.

steenbergh

Posted 2017-06-06T16:19:20.313

Reputation: 7 772

2

Pyth, 7 bytes

qCC.z.z

Demonstration

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

isaacg

Posted 2017-06-06T16:19:20.313

Reputation: 39 268

2

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.

IngoAlbers

Posted 2017-06-06T16:19:20.313

Reputation: 121

1Save a character with .split($/,-1); -> .split $/,-1; – Christopher Lates – 2017-06-08T19:58:39.860

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) – G B – 2017-06-09T07:22:30.183

1

Cheddar, 39 bytes

@.split("
").all((i,j,k)->i.len==k.len)

Try it online!

Leaky Nun

Posted 2017-06-06T16:19:20.313

Reputation: 45 011

1

Clojure, 58 bytes

#(let[s(re-seq #"[^\n]+"%)c count](apply =(c s)(map c s)))

Requires a trailing newline, looking forward to seeing something more magical.

NikoNyrh

Posted 2017-06-06T16:19:20.313

Reputation: 2 361

1

APL (Dyalog), 17 bytes

Requires ⎕ML←3 which is default on many systems. Uses CR.

↓∘⎕FMT≡⎕TC[2]∘≠⊂⊢

Try it online!

↓∘⎕FMT [is the] split-into-lines Formatted-into-a-square argument

 identical to

⎕TC[2]∘≠ the into-groups-of-non-newline*-characters

 partitioned

 argument?

* the second element of the list of Terminal Control characters.


In version 16.0, one can write ↓∘⎕FMT≡⎕TC[3]∘≠⊆⊢ with ⎕ML←1.

Adám

Posted 2017-06-06T16:19:20.313

Reputation: 37 779

Curious, what's ⎕ML? – Pavel – 2017-06-06T23:51:55.710

1

@Phoenix In Dyalog APL and APL+, Migration Level is a rough measure for the dialectical movement in direction of IBM's APL2. The higher the number, the more APL2-like does the language become. People migrating from APL2 to other APLs tend to run with a high ⎕ML, while people who started with the other APLs tend to run with a low ⎕ML.

– Adám – 2017-06-06T23:55:30.327

1

PowerShell, 64 bytes

The same (split, line lengths, number of lines) approach as other non-golf language answers, but there's no nice map() equivalent, so it's an array of line lengths with the number of lines tagged onto the end, then that array is grouped. Squares come out like 3,3,3,3 -> 1 group, all line lengths and line count were equal and non-squares come out like 3,2,1 -> 3 groups, something was unequal in the square:

$f={@(@(($L="$args"-split"`n")|% le*)+$L.Count|group).Count-eq1}

Requires newline Linux-style endings, no trailing newline. e.g.

$Ttests = @(@'
foo
bar
baz
'@,
'.',
@'
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
'@
)
$Ttests = $Ttests | foreach {$_ -replace "`r"}

$Ttests | % { & $f $_ }

(And you can do similar for the false tests, but I won't put it here as there's more of them). The couple of @ symbols are required for when the input is the single '.' otherwise splitting it doesn't make an array of one string it just makes one string, and then the array concatenation doesn't output 1,1 it outputs 2.

I hoped it might be shorter to replace all the characters with 'a', and then brute force from 1 to Input Length all the squares 'a' and see if any matched the input. Once I got past param() and .Length and -join and -replace it ends up much longer at 81 bytes:

$f={param($s)!!(1..$s.Length|?{,('a'*$_)*$_-join"`n"-eq($s-replace"[^`n]",'a')})}

TessellatingHeckler

Posted 2017-06-06T16:19:20.313

Reputation: 2 412

1

Grime, 11 bytes

e`.|_./+/.+

Prints 1 for squares and 0 for non-squares. Try it online!

Explanation

A detailed explanation can be found on the Grime tutorial page, which happens to contain this exact program as an example.

e`.|_./+/.+
e`            Match entire input against pattern:
  .           A single character
   |          OR
    _         a recursive match of this pattern
     ./+      with one column of characters on its right
        /     and below that
         .+   one row of characters.

Zgarb

Posted 2017-06-06T16:19:20.313

Reputation: 39 083

1

C#, 73 bytes

using System.Linq;s=>s.Split('\n').All(l=>l.Length==s.Split('\n').Length)

Explanation:

using System.Linq;    //Import Linq
s=>                   //Take input
s.Split('\n')         //Split the input stirng by line feeds
.All(l=>              //Make sure All lines in the array return true for:
l.Length              //The length of the line
==                    //Equaling
s.Split('\n').Length) //The length of the array split again by line feeds

TheLethalCoder

Posted 2017-06-06T16:19:20.313

Reputation: 6 930

1

Dart - 54 chars

q(s)=>!(s=s.split('\n')).any((x)=>x.length!=s.length);

(Expects input separated by newlines and not terminated by one)

Try it online

lrn

Posted 2017-06-06T16:19:20.313

Reputation: 521

1

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 @+.

Dada

Posted 2017-06-06T16:19:20.313

Reputation: 8 279

1

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.

Digital Trauma

Posted 2017-06-06T16:19:20.313

Reputation: 64 644

1

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.

Robert Benson

Posted 2017-06-06T16:19:20.313

Reputation: 1 339

1

Clojure, 42 chars

#(every?(fn[x](=(count %)x))(map count %))

MattPutnam

Posted 2017-06-06T16:19:20.313

Reputation: 521

1

><>, 76 bytes

This should work, next step is trying to golf it more!

0v      0   <
 >i:0)?!va=?^1+
:0)?v1n;\~l:   >
    >r:@=?!vr1-^
        ;n0<

Try it online! Or more more fun, try some examples using this animated interpreter.

printf "aaa\naas\naaa" | fish _square.fish --tick 0.1 --play

Explanation

The idea is roughly as follows.

  1. Fill the stack with the number of characters on each line.
  2. Push the length of the stack, corresponding to the number of lines (n).
  3. Do n times:
    • Check if bottom two elements are equal.
    • Remove deepest element.

Examples

For

aaa
aaa
aaa

we get [3, 3, 3, 3] after the first two steps and we can see that all three length 2 subsequences are equal. However, for

aaa
aa
a

we get [3, 2, 1, 3] and not all sequences are equal. For the last falsy case

`abc.def.ghi`

we get [11, 1] so there is only subpair we can check, but it is unequal so we return falsy.

PidgeyUsedGust

Posted 2017-06-06T16:19:20.313

Reputation: 631

1

Charcoal, 20 bytes

A⁺№θ¶¹αF⪪θ¶A×α⁼αLιαα

Try it online! Prints - repeated by the side length as truthy, nothing as falsy.

ASCII-only

Posted 2017-06-06T16:19:20.313

Reputation: 4 687

1

Add++, 45 bytes

D,g,@,bU10C€=sVcG1+V10CAtbU€bLB]db=$bM*G=

Try it online!

How it works

Boy this was a long one (not even counting the footer)

D,g,@,		; Declare a monadic function 'g'
		; Example argument:    		 ['foo\nbar\nbaz']
	bU	; Unpack;		 STACK = ['f' 'o' 'o' '\n' 'b' 'a' 'r' '\n' 'b' 'a' 'z']
	10C€=s	; Count newlines;	 STACK = ['f' 'o' 'o' '\n' 'b' 'a' 'r' '\n' 'b' 'a' 'z' 2]
	VcG	; Keep last value;	 STACK = [2]
	1+V	; Increment and save;	 STACK = []			; STORE = 3
	10CAt	; Split arg on newlines; STACK = [['foo' 'bar' 'baz']]
	bU€bLB]	; Length of €ach;	 STACK = [[3 3 3]]
	db=	; Are they all equal?	 STACK = [[3 3 3] 1]
	$bM	; Max value;		 STACK = [1 3]
	*	; Logical AND;		 STACK = [3]
	G=	; Equals STORE?		 STACK = [1]

Try it online!

caird coinheringaahing

Posted 2017-06-06T16:19:20.313

Reputation: 13 702

1

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

Weijun Zhou

Posted 2017-06-06T16:19:20.313

Reputation: 3 396

1

PHP, 65 bytes

while(~$c=$argv[1][$p++])$w+=":"^$c||$w=!$$w+=!!++$h;echo$$h==$h;

expects linux style line endings (\n) and a trailing newline; prints 1 for truthy, nothing for falsy.
Run with php -nr '<code>' '<input>' or try it online.


Btw: The naive approach takes 82 bytes:

<?=count($a=explode("
",$argv[1]))==min($m=array_map(strlen,$a))&min($m)==max($m);

expects linebreaks as on compile system and no trailing newline; prints 1 or 0.
Run with php -nR '<code>' '<input>'.

Titus

Posted 2017-06-06T16:19:20.313

Reputation: 13 814

1

Python 3, 79 bytes

lambda a:len(set([len(list(i))for i in a.split('\n')]+[len(a.split('\n'))]))==1

Dat

Posted 2017-06-06T16:19:20.313

Reputation: 879

1

Swift 3, 134 bytes

import Foundation;func r(s:String)->Bool{let i=s.components(separatedBy:"\n");return i.filter{$0.characters.count != i.count}.isEmpty}

Try it online!

Tamás Sengel

Posted 2017-06-06T16:19:20.313

Reputation: 211

1

PowerShell, 48 bytes

($a=$args-split'
'|%{$_.Length}).Count-eq($a|gu)

Test script:

$f = {

($a=$args-split'
'|%{$_.Length}).Count-eq($a|gu)

}

@(

,($true,@"
foo
bar
baz
"@)

,($true,@"
.
"@)

,($true,@"
. .
.  
. .
"@)

,($true,@"


"@)

,($true,@"
aaaaa
aaaaa
aaaaa
aaaaa
aaaaa
"@)

,($false,@"
..
.
"@)

,($false,@"
.

"@)

,($false,@"

.
"@)

,($false,@"
....


....
"@)

,($false,@"
4444
333
22
"@)

,($false,@"
333
333
"@)

,($false,@"
abc.def.ghi
"@)

) | % {
    $expected,$s = $_
    $result = &$f $s
    "$($result-eq$expected): $result"
}

Output:

True: True
True: True
True: True
True: True
True: True
True: False
True: False
True: False
True: False
True: False
True: False
True: False

Explanation:

  • $args-split"``n"|%{$_.Length} creates an array of length of each line.
  • $a.Count counts elements of the array
  • $a|gu apply Get-Unique to the array. The result is one integer element if all lines has same length.
  • $a.Count-eq($a|gu) compares Count of element with result of the Get-Unique. It's true if all lines has same length and this length equals to Count.

mazzy

Posted 2017-06-06T16:19:20.313

Reputation: 4 832

1

Wren, 76 61 bytes

Fn.new{|a|a.split("\n").all{|x|x.count==a.split("\n").count}}

Try it online!

Old answer

The algorithm is essentially just copied from a 05AB1E answer.

Fn.new{|a|
var b=a.split("\n").map{|i|i.count}
return b.all{|i|i==b.count}
}

Try it online!

user85052

Posted 2017-06-06T16:19:20.313

Reputation:

1

Red, 73 bytes

func[s][all collect[foreach b a: split s lf[keep(length? b)= length? a]]]

Try it online!

{abcd efg} represents true multiline string and not a list of strings, hence I need split s lf

Galen Ivanov

Posted 2017-06-06T16:19:20.313

Reputation: 13 815

0

SnakeEx, 50 bytes

This is BMac's solution to the problem for the 2D regex language design challenge.

m:{v<R>1}{h<>1}
v:${c<L>A1}+$
h:${c<R>A1}+$
c:$.+$

Try it online

mbomb007

Posted 2017-06-06T16:19:20.313

Reputation: 21 944

0

J, 12 bytes

(*./=#)#;._2

Input requires trailing LF or CR.

Explanation:

  • ;._2 split into intervals and discard trailing atom
  • # count each group
  • (*./=#) is a fork which returns 0 (false) or 1 (true) if the LCM of the count of each group is equal to the count-of-counts

Tests

(*./=#)#;._2 'abc', LF, 'def', LF, 'ghi', LF   NB. 1 for well-formed input
(*./=#)#;._2 'abc', LF, 'def', LF, 'ghi'       NB. 0 because no trailing LF

hoosierEE

Posted 2017-06-06T16:19:20.313

Reputation: 760

How does it determine what the delimiter is..? And by the way, abc.def.ghi. should be falsy, so while clever, the delimiter trick is actually invalid. – Pavel – 2017-06-08T16:15:16.317

@Phoenix A test case to reflect that would be beneficial – Conor O'Brien – 2017-06-09T04:53:21.163

@Phoenix My answer used to just say "requires trailing delimiter" but I edited it to specifically call out either LF or CR.

abc.def.ghi. would be truthy but abc.def.ghi.LF (trailing LF) would be falsy. – hoosierEE – 2017-06-09T19:28:46.010

abc.def.ghi. Is not a square string and should not be accepted. – Pavel – 2017-06-09T21:37:35.840

The way I read the rules, since I can require that all inputs end in LF, then my program should never have the chance to either accept or reject inputs which don't end in LF. – hoosierEE – 2017-06-19T16:13:37.333

115 Bytes for */(=#)#@>@cutLF, which only accepts LF as a delimiter, and does not require a trailing LF: */(=#)#@>@cutLF 'abc', LF, 'def', LF, 'ghi' returns 1 – Bolce Bussiere – 2018-03-22T17:53:44.710