43
\$\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\$
  • \$\begingroup\$ Possible duplicate of Language Design: 2-D Pattern Matching. Problem #5 is the same as this question. \$\endgroup\$ – mbomb007 Jun 6 '17 at 21:40
  • 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\$ – FryAmTheEggman Jun 6 '17 at 22:12
  • 2
    \$\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\$ – ETHproductions Jun 6 '17 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 '17 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 '17 at 17:47

46 Answers 46

19
\$\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\$
  • 1
    \$\begingroup\$ Correct tool for the job! \$\endgroup\$ – Pavel Jun 6 '17 at 17:18
  • 10
    \$\begingroup\$ = "Assert that the result is square" :( \$\endgroup\$ – Erik the Outgolfer Jun 6 '17 at 17:48
  • 5
    \$\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 '17 at 17:51
  • 2
    \$\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 '17 at 17:59
  • 2
    \$\begingroup\$ @iFreilicht It's bad because it outgolfs every other golfing language so far. \$\endgroup\$ – Erik the Outgolfer Jun 7 '17 at 13:24
21
\$\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\$
  • 4
    \$\begingroup\$ I love the fact that this is both golfed and readable. \$\endgroup\$ – jpmc26 Jun 6 '17 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\$ – 12431234123412341234123 Jun 8 '17 at 13:43
  • \$\begingroup\$ @12431234123412341234123 no, it does not work for square strings that contain spaces!!! \$\endgroup\$ – Mr. Xcoder Jun 8 '17 at 13:45
  • \$\begingroup\$ @Mr.Xcoder Must it work with spaces? As i understood there are never spaces in the input. \$\endgroup\$ – 12431234123412341234123 Jun 8 '17 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 '17 at 13:47
14
\$\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\$
  • 3
    \$\begingroup\$ I think you can save a byte with s=>!(s=s.split`\n`).some(x=>x.length-s.length) \$\endgroup\$ – ETHproductions Jun 6 '17 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 '17 at 10:51
9
\$\begingroup\$

Jelly, 7 5 bytes

Ỵ¬⁼Z$

Try it online!

Thanks to FryAmTheEggman for -2

\$\endgroup\$
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
    \$\begingroup\$ I think you can use all for map to cut the and.. \$\endgroup\$ – xnor Jun 6 '17 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\$
  • 1
    \$\begingroup\$ Your TIO link seems to indicate that no trailing newline should be there. \$\endgroup\$ – Pavel Jun 6 '17 at 16:58
  • \$\begingroup\$ @Phoenix fixed / reverted... \$\endgroup\$ – steenbergh Jun 6 '17 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\$ – scatter Jun 8 '17 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 '17 at 17:17
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\$
  • \$\begingroup\$ How in the world are you so fast? \$\endgroup\$ – totallyhuman Jun 6 '17 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\$ – ETHproductions Jun 6 '17 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 '17 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 '17 at 15:59
8
\$\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\$
  • \$\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\$ – Magic Octopus Urn Jun 6 '17 at 16:43
  • \$\begingroup\$ I don't think "Header" is a valid form on input. \$\endgroup\$ – Pavel Jun 6 '17 at 17:13
  • \$\begingroup\$ @Phoenix is that better? \$\endgroup\$ – Magic Octopus Urn Jun 6 '17 at 17:19
  • 1
    \$\begingroup\$ Input can also be taken in with three quotes, like this. \$\endgroup\$ – Adnan Jun 6 '17 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 '17 at 18:34
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\$
  • \$\begingroup\$ Unfortunately, this outputs true for this testcase. \$\endgroup\$ – Cows quack Jun 6 '17 at 16:51
  • \$\begingroup\$ @KritixiLithos I believe the submission requires a trailing newline in input, which is allowed. \$\endgroup\$ – Pavel Jun 6 '17 at 16:52
  • \$\begingroup\$ Also I believe using \S\n; instead of the first line saves one byte \$\endgroup\$ – Cows quack Jun 6 '17 at 16:53
  • \$\begingroup\$ @KritixiLithos Actually replacing . with . saves two, but thanks. \$\endgroup\$ – Neil Jun 6 '17 at 16:53
  • \$\begingroup\$ @Neil That's really clever! \$\endgroup\$ – Cows quack Jun 6 '17 at 17:27
6
\$\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\$
5
\$\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\$
  • \$\begingroup\$ does this ignore the new-line character? \$\endgroup\$ – Khaled.K Jun 6 '17 at 20:39
  • \$\begingroup\$ Yes, newlines are not returned by the .lines method. \$\endgroup\$ – Sean Jun 6 '17 at 20:47
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\$
  • 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\$ – Kevin Cruijssen Jun 7 '17 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\$ – Kevin Cruijssen Jun 7 '17 at 9:23
  • 2
    \$\begingroup\$ Is it not just \n? \$\endgroup\$ – TheLethalCoder Jun 7 '17 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\$ – Olivier Grégoire Jun 8 '17 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\$ – Olivier Grégoire Jun 8 '17 at 14:29
3
\$\begingroup\$

05AB1E, 7 bytes

|€gDgQP

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Kind of cheating imo, that's basically taking n inputs instead of 1 and why my original answer didn't work. \$\endgroup\$ – Magic Octopus Urn Jun 6 '17 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\$ – Erik the Outgolfer Jun 6 '17 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\$
  • \$\begingroup\$ note that inputs need to be wrapped in quotes or this might break on spaces within each line. \$\endgroup\$ – Giuseppe Mar 6 '18 at 14:50
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\$
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\$
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\$

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\$
  • 1
    \$\begingroup\$ Save a character with .split($/,-1); -> .split $/,-1; \$\endgroup\$ – Christopher Lates Jun 8 '17 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 '17 at 7:22
1
\$\begingroup\$

Cheddar, 39 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Curious, what's ⎕ML? \$\endgroup\$ – Pavel Jun 6 '17 at 23:51
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – Adám Jun 6 '17 at 23:55
1
\$\begingroup\$

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')})}
\$\endgroup\$
1
\$\begingroup\$

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.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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