10
\$\begingroup\$

Background:

Here's a little simple challenge. You want to be able to find out whether the arrays inside an array have the same length.

Input:

Your input should consist of exactly one array (this is the value passed to the function, not a user input). Your function takes exactly 1 parameter. It could contain arrays or be empty. No error checking needed, assume only list is ever passed in. Assume a 1-D array such as [1] or [1,2,3,4,5] is never passed in.

Output:

Return true if all the list elements have the same length, false if they don't, and the parameter itself if the list is empty (or null if your language doesn't support multiple return types).

Some test cases:

List: [] - [] (or null/your language equivalent)
List: [[1], [1], [2]] - True
List: [[1]] - True
List: [[1, 2, 3, 4]] - True
List: [[1, 2, 3, 4, 5], [2], [12, 314123]] - False
List: [[1, 2, 3, 4], [1]] - False

No std(in/out) input/output needed (however, it is allowed, just not required!), the function only needs to return boolean values true or false; or the parameter itself if the function is passed an empty list (or null/your language equivalent). Only one return value is returned.

Rules:

Shortest byte count wins, only function is necessary (full programs are allowed if you desire).

asked Jun 9, 2016 at 20:59
\$\endgroup\$
18
  • 1
    \$\begingroup\$ what if we can't return different types (Arrays / Booleans)? \$\endgroup\$ Commented Jun 9, 2016 at 21:51
  • 1
    \$\begingroup\$ As the parameter is only returned when it is empty, how about some kind of option type like Haskell's Maybe, i.e. Nothing for the empty list and Just True/Just False else? Or Either -> Left [] / Right True. Basically any wrapper that can combine two types. \$\endgroup\$ Commented Jun 9, 2016 at 22:14
  • 1
    \$\begingroup\$ Are the sublist elements always going to be positive integers? \$\endgroup\$ Commented Jun 9, 2016 at 23:26
  • 8
    \$\begingroup\$ The special-case output for the empty list, especially one of a different type, is an extraneous task that makes solutions needlessly uglier. \$\endgroup\$ Commented Jun 10, 2016 at 3:11
  • 1
    \$\begingroup\$ Welcome to PPCG! Usually we first post a question in the Sandbox for Proposed Challenges. That way we can first get feedback and discussions to make the question close to perfect before posting it here. It's advisable to keep it in the Sandbox for ±72 hours so enough people can give recommendations, remarks and ask questions regarding your challenge. More info can be found in the Sandbox itself. (That being said, it looks like a good question, but in the Sandbox people often ask about edge/cases.) \$\endgroup\$ Commented Jun 10, 2016 at 7:31

25 Answers 25

9
\$\begingroup\$

Python 2, 31

lambda l:l and l==zip(*zip(*l))

This requires the lists to be lists of tuples. zip Drops extra elements if the input was ragged, so double zipping is only a noop if the lists all have the same length.

Try it here

answered Jun 9, 2016 at 21:47
\$\endgroup\$
6
\$\begingroup\$

Pyth - (削除) 7 (削除ここまで) 5 bytes

Saved 2 bytes thanks to @FryAmTheEggman.

And I was the one who told @issacg to remove the q default...

?QqCC

Test Suite.

answered Jun 9, 2016 at 21:12
\$\endgroup\$
2
  • \$\begingroup\$ I think ?QqCC works. \$\endgroup\$ Commented Jun 9, 2016 at 21:19
  • \$\begingroup\$ @FryAmTheEggman nice! \$\endgroup\$ Commented Jun 9, 2016 at 21:20
4
\$\begingroup\$

Jelly, 5 bytes

L€E8ȧ

Try it online!

How it works

L€E8ȧ Monadic link. Argument: A (list)
L€ Map length over the list.
 E Test if all elements are equal.
 8ȧ Take the logical AND of A and the resulting Boolean.
answered Jun 9, 2016 at 21:20
\$\endgroup\$
0
4
\$\begingroup\$

Perl 6, 17 bytes

{$_??[==] $_!!$_}

[==] $_ does a reduce of the input ($_) with &infix:<==>. &infix:<==> is a Numeric operator so it coerces its inputs to Numeric. The rest is just the ternary operator ?? !!.

This is roughly equivalent to

sub ( $_ ) {
 if $_ {
 # the 「map」 is for clarity, it is not needed
 $_.map(*.elems).reduce(&infix:<==>)
 # 「[OP] List」 is actually smarter than 「List.reduce(&infix:«OP»)」
 # as it takes into account operator chaining, and associativity
 } else {
 $_
 }
}

Test:

#! /usr/bin/env perl6
use v6.c;
use Test;
# put it into the lexical namespace for clarity
my &same-elems = {$_??[==] $_!!$_}
my @tests = (
 [] => [],
 [[1], [1], [2]] => True,
 [[1],] => True,
 [[1, 2, 3, 4],] => True,
 [[1, 2, 3, 4, 5], [2], [12, 314123]] => False,
 [[1, 2, 3, 4], [1]] => False,
);
plan +@tests;
for @tests -> ( :key(@input), :value($expected) ) {
 is same-elems(@input), $expected, @input.perl
}
1..6
ok 1 - []
ok 2 - [[1], [1], [2]]
ok 3 - [[1],]
ok 4 - [[1, 2, 3, 4],]
ok 5 - [[1, 2, 3, 4, 5], [2], [12, 314123]]
ok 6 - [[1, 2, 3, 4], [1]]
answered Jun 10, 2016 at 3:09
\$\endgroup\$
4
\$\begingroup\$

Javascript ES6, (削除) 44 (削除ここまで) (削除) 43 (削除ここまで) 42 bytes

Saved 1 byte thanks to @Neil

a=>a[0]?!a.some(b=>b.length-a[0].length):a

Alternative solutions

a=>a[0]?a.every(b=>b.length==a[0].length):a // 43
a=>a[0]?new Set(a.map(b=>b.length)).size==1:a // 45
a=>a[0]?Math.max(...a.map(b=>b.length))==a[0].length:a // 54
a=>a[0]?[a[0].length,...a].reduce((b,d)=>b==d.length):a // 55, doesn't work as intended

Somehow the stacksnippet doesn't print [], try it in your console for the actual result.

f=
a=>a[0]?a.every(b=>b.length==a[0].length):a
z.innerHTML = [
 [],
 [[1], [1], [2]],
 [[1]],
 [[1, 2, 3, 4]],
 [[1, 2, 3, 4, 5], [2], [12, 314123]],
 [[1, 2, 3, 4], [1]]
].map(m=>JSON.stringify(f(m))).join`<br>`
<pre id=z>

(yay for crossed out 44)

answered Jun 9, 2016 at 21:17
\$\endgroup\$
6
  • \$\begingroup\$ Your second alternative won't work, reduce uses the result of the previous function call as the first parameter to the next. Even if it did work, c costs you a byte. c costs you 4 bytes in your third alternative, since it's an unused variable. \$\endgroup\$ Commented Jun 9, 2016 at 23:32
  • \$\begingroup\$ I think I shaved off a byte: a=>a[0]?!a.some(b=>b.length-a[0].length):a \$\endgroup\$ Commented Jun 9, 2016 at 23:33
  • 1
    \$\begingroup\$ "Somehow" == in JavaScript [].toString() returns an empty string. \$\endgroup\$ Commented Jun 10, 2016 at 0:18
  • \$\begingroup\$ Array.prototype.toString() is equivalent to Array.prototype.join() with no arguments, that's why. \$\endgroup\$ Commented Jun 10, 2016 at 3:57
  • \$\begingroup\$ Try wrapping the array in JSON.stringify to display it correctly. \$\endgroup\$ Commented Jun 10, 2016 at 15:43
3
\$\begingroup\$

Swift 3 - 47 Bytes

{0ドル.isEmpty ?nil:Set(0ドル.map{0ドル.count}).count<2}

To invoke, first assign it to a variable:

 let f: ([[Any]]) -> Bool? = {0ドル.isEmpty ?nil:Set(0ドル.map{0ドル.count}).count<2}
 f([[1], [1,2], [1,2,3]])
answered Jun 9, 2016 at 21:06
\$\endgroup\$
2
  • \$\begingroup\$ Is the initial space required? \$\endgroup\$ Commented Jun 10, 2016 at 0:40
  • \$\begingroup\$ Nope, that was just a typo. It wasn't in my letter count anyway \$\endgroup\$ Commented Jun 10, 2016 at 14:52
2
\$\begingroup\$

Mathematica, 22 bytes

a@{}={};a@b_:=ArrayQ@b

The requirement of a[{}] == {} ruins everything and prevents a 6 byte solution of the built-in ArrayQ, since in Mathematica a zero length array is also an array.

answered Jun 9, 2016 at 21:55
\$\endgroup\$
7
  • \$\begingroup\$ I don't have my mathematica rpi running atm, but IIRC, you can save by special casing {} by doing a@b_:=b&&ArrayQ@b \$\endgroup\$ Commented Jun 9, 2016 at 22:12
  • \$\begingroup\$ @Maltysen That doesn't seem to work, it'll always return the array if it is an array then (b&&c will always return b if c evaluates to True). \$\endgroup\$ Commented Jun 9, 2016 at 22:17
  • \$\begingroup\$ why does it do that? shouldn't it return c if b is true? \$\endgroup\$ Commented Jun 9, 2016 at 22:18
  • \$\begingroup\$ @Maltysen Your statement is the inverse of mine and is also true. I'm referring to a@{} -> {} && ArrayQ@{} -> {} && True -> {}. This is desirable. But let b = {{1},{2},{3}}, then a@b -> b && ArrayQ@b -> b && True -> b -> {{1},{2},{3}} whereas we need True here. \$\endgroup\$ Commented Jun 9, 2016 at 22:21
  • \$\begingroup\$ oic, can you do instead then {}&&stuff? \$\endgroup\$ Commented Jun 9, 2016 at 22:24
2
\$\begingroup\$

Julia, 33 bytes

!x=[]==x?x:diff(map(endof,x))⊆0

Try it online!

How it works

We redefine the unary operator ! for this task.

If x is the empty array, we simply return x.

Else, we map endof (equivalent to length) over the arrays in x and compute the differences of consecutive lengths with diff. If all length are equal, this will generate an array of 0's. Otherwise, there will be non-zero numbers in the result.

Finally, ⊆0 tests if all differences are 0 and return the corresponding Boolean.

answered Jun 9, 2016 at 23:40
\$\endgroup\$
2
\$\begingroup\$

Brachylog, 9 bytes

.v|:ladl1

Returns true or false or the empty list.

Explanation

.v Unify the output with the input if it's the empty list
| Or
:la Apply length to each element of the input
 d Remove all duplicates
 l1 The length of the resulting list is 1
answered Jun 10, 2016 at 6:41
\$\endgroup\$
2
\$\begingroup\$

Ruby, 27 bytes

->i{!i.map(&:size).uniq[1]}

Test:

s = ->i{!i.map(&:size).uniq[1]}
s[[[1, 2, 3, 4], [1]]]
=> false
s[[[1, 2, 3, 4]]]
=> true
answered Jun 10, 2016 at 7:17
\$\endgroup\$
2
\$\begingroup\$

PowerShell v2+, 53 bytes

param($a)if($a){($a|%{$_.count}|select -u).count-eq1}

This presumes that standard I/O methods and both programs and functions are allowed. Additionally, in PowerShell, the concept of "returning" an empty array is meaningless -- it's converted to $null as soon as it leaves scope -- and so it is the equivalent of returning nothing, which is what is done here.

We take input $a, and if it's non-empty we collect all the .counts of each sub-array. We pipe that to Select-Object with the -unique flag, take that .count and verify that it's -equal to 1. Returns Boolean $true or $false. If the input is the empty array, returns nothing (i.e., $null).

Examples

PS C:\Tools\Scripts\golfing> .\same-length-sub-arrays.ps1 ((1),(2),(3))
True
PS C:\Tools\Scripts\golfing> .\same-length-sub-arrays.ps1 ((1),(2),(3,4))
False
PS C:\Tools\Scripts\golfing> .\same-length-sub-arrays.ps1 @()
PS C:\Tools\Scripts\golfing> (.\same-length-sub-arrays.ps1 @()).GetType()
You cannot call a method on a null-valued expression.
At line:1 char:1
+ (.\same-length-sub-arrays.ps1 @()).GetType()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 + CategoryInfo : InvalidOperation: (:) [], RuntimeException
 + FullyQualifiedErrorId : InvokeMethodOnNull
PS C:\Tools\Scripts\golfing> (.\same-length-sub-arrays.ps1 @())-eq$null
True
answered Jun 10, 2016 at 13:05
\$\endgroup\$
2
\$\begingroup\$

Haskell, (削除) 48 (削除ここまで) 46 bytes

f[]=Nothing
f x|h:t<-length<$>x=Just$all(==h)t

Wraps the result in the Maybe type and returns Nothing if the input is the empty list and Just True/Just False otherwise.

Usage example:

*Main> map f [[],[[1],[2],[3]],[[1]],[[1,2,3,4]],[[1,2,3,4,5],[2],[12,314123]],[[1,2,3,4],[1]]]
[Nothing,Just True,Just True,Just True,Just False,Just False]

How it works:

f[]=Nothing -- empty input
f x -- otherwise
 |(h:t)<-length<$>x -- map length function over the input and bind h
 -- to the first element and t to rest of the list
 = all(==h)t -- return whether all values in t equal h
 Just$ -- wrapped in the Maybe type 

Edit: @Lynn saved two bytes. Thanks!

answered Jun 10, 2016 at 4:32
\$\endgroup\$
2
  • \$\begingroup\$ Looks like can drop the parens around h:t. \$\endgroup\$ Commented Jun 23, 2016 at 19:37
  • \$\begingroup\$ @Lynn: Wow. I don't think I've ever tried to drop parens in a pattern match. \$\endgroup\$ Commented Jun 23, 2016 at 21:03
2
\$\begingroup\$

Java 10, (削除) 145 (削除ここまで) (削除) 129 (削除ここまで) (削除) 107 (削除ここまで) (削除) 106 (削除ここまで) (削除) 103 (削除ここまで) (削除) 93 (削除ここまで) 77 bytes

Loads of bytes saved thanks to @Frozn, and by using Object as return-type, we can comply with OP's rules of returning the input-array when the array is empty, despite Java's one-return-type-only nature regarding methods.

m->{int f=1;for(var a:m)f=m[0].length!=a.length?0:f;return m.length<1?m:f>0;}

Try it online.

Explanation:

m->{ // Method with integer-matrix parameter and Object return-type
 int f=1; // Flag-integer, starting at 1
 for(var a:m) // Loop over the rows of the matrix
 f=m[0].length!=a.length?
 // If the length of the first and current row aren't the same:
 0 // Change `f` to 0
 : // Else:
 f; // Leave `f` the same
 return m.length<1? // If there is only one row:
 m // Return the input-matrix as result
 : // Else:
 f>0;} // Return whether the flag `f` is still 1 as boolean
answered Jun 10, 2016 at 7:47
\$\endgroup\$
8
  • 1
    \$\begingroup\$ I don't understand why the p = a[x].length is necessary as it seems to don't change the value of p \$\endgroup\$ Commented Jun 10, 2016 at 9:15
  • \$\begingroup\$ @Frozn Ah, you're completely right, I screwed up!.. I've removed it. Thanks. \$\endgroup\$ Commented Jun 10, 2016 at 9:28
  • 1
    \$\begingroup\$ Alright, I think you can get rid of some characters by changing the for-loop to a for each. Didn't tested it just wrote it on a piece of paper and it looked a bit shorter. Oh and in addition you can remove l so it will get even shorter. \$\endgroup\$ Commented Jun 10, 2016 at 9:43
  • 1
    \$\begingroup\$ It's me again, I claim you can change the return type to Object to save an additional character. Also with the forearm loop you can remove the first if statement and move it to the end of the function as a ternary like return a.length < 0 ? null : 1 > 0 \$\endgroup\$ Commented Jun 10, 2016 at 16:00
  • 1
    \$\begingroup\$ As the OP allows to return the parameter itself you can replace the return of null with a. This will save some more characters, so you could come down to 93. \$\endgroup\$ Commented Jun 10, 2016 at 19:02
1
\$\begingroup\$

Python, 45 bytes

lambda x:x and min(x,key=len)==max(x,key=len)
answered Jun 9, 2016 at 21:32
\$\endgroup\$
4
  • 2
    \$\begingroup\$ 5 bytes shorter: f=lambda x:x and len(set(map(len,x)))<2 \$\endgroup\$ Commented Jun 9, 2016 at 21:36
  • \$\begingroup\$ also, yours doesn't work on [] \$\endgroup\$ Commented Jun 9, 2016 at 21:37
  • \$\begingroup\$ You should return the array if it's empty. \$\endgroup\$ Commented Jun 9, 2016 at 21:37
  • \$\begingroup\$ @Maltysen Thanks for the tip. Feel free to post that as an answer, since it's a totally different approach and I didn't come up with it. \$\endgroup\$ Commented Jun 9, 2016 at 21:40
1
\$\begingroup\$

Octave, 51 bytes

@(x)repmat(2>n(unique(cellfun(n=@numel,x))),n(x)>0)

Online Demo

Explanation

Loops through the input (a cell array) and determines the number of elements in each entry numel, then from this array of the number of elements, we ensure that there is only one unique value: 2 > numel(unique(numberOfElements)). This will give us the boolean we want. Unfortunately, it is difficult to yield an empty array efficiently so in order to deal with the case of an empty input, we use repmat to repeat this boolean value N times where N is the number of subarrays in the input. If the input is empty this repeats the boolean value 0 times leading to [].

answered Jun 9, 2016 at 23:05
\$\endgroup\$
1
\$\begingroup\$

Actually, 18 bytes

`♂l╔l;Y"[].⌂"£n=1`

Try it online! (calls the function with ƒ)

Explanation:

`♂l╔l;Y"[].⌂"£n=1` push a function:
 ♂l map length over input
 ╔l uniquify
 ;Y 1 if list is empty else 0
 "[].⌂"£n call this function that many times:
 []. print an empty list
 ⌂ exit
 =1 1 if length of unique list equals 1 else 0

If the function-only requirement is lifted, the equivalent program works for 15 bytes:

♂l╔l;Y`[].⌂`n=1

Try it online!

answered Jun 10, 2016 at 9:21
\$\endgroup\$
1
\$\begingroup\$

05Ab1E, 12 bytes

Dg0Qië€gÙg1Q

Explained

Dg0Qi # if empty list, return input
 ë # else
 €g # map length over list
 Ùg1Q # check if length of uniquified list is 1

Try it online

answered Jun 10, 2016 at 9:41
\$\endgroup\$
1
\$\begingroup\$

F#, 78 bytes

function
|[]->None
|x->Seq.forall(fun y->Seq.length y=Seq.length x.[0])x|>Some

Output is the F# Option type. If the input is empty output is None, else it's Some bool, where the bool value indicates whether all the sub-arrays are of equal length.

// F# Interactive
let f = 
 function
 |[]->None
 |x->Seq.forall(fun y->Seq.length y=Seq.length x.[0])x|>Some;;
val f : _arg1:#seq<'b> list -> bool option
> f [[0;1];[2];[3]];;
val it : bool option = Some false
> f [[0;1];[2;3];];;
val it : bool option = Some true
> f [];;
val it : bool option = None
answered Jun 10, 2016 at 14:15
\$\endgroup\$
1
\$\begingroup\$

J, 26 bytes

]`(1=[:#@~.#@>@>)@.(*@#@>)

Since J doesn't support ragged arrays, I will use boxed arrays instead. It returns 1 for true, 0 for false, and the input if empty.

Usage

 f =: ]`(1=[:#@~.#@>@>)@.(*@#@>)
 NB. Boxed array representing [[1, 2, 3, 4, 5], [2], [12, 314123]]
 < 1 2 3 4 ; 2 ; 12 314123
┌─────────────────────┐
│┌───────┬─┬─────────┐│
││1 2 3 4│2│12 314123││
│└───────┴─┴─────────┘│
└─────────────────────┘
 f < 1 2 3 4 ; 2 ; 12 314123
0
 NB. The empty list
 a:
┌┐
││
└┘
 f a:
┌┐
││
└┘
 f < 1 ; 1 ; 2
1
 f < < 1
1
 f < < 1 2 3 4
1
 f < 1 2 3 4 ; 1
0
answered Jun 13, 2016 at 1:41
\$\endgroup\$
1
\$\begingroup\$

Retina, 35 bytes

If only [] could return true or false. Returning a 3rd value makes it so much longer.

\[]
xx
\d|],
M`^\[(\[,*)1円*]]|x
2

Try it online

This is the core program. It removes digits and occurrences of ],, then matches if the number of commas is the same after each [. It would return 0 for []. The code above varies because I added a check for an empty list to make it match twice, then I replace 2 with nothing for a null return.

\d|],
^\[(\[,*)1円*]]
answered Jun 21, 2016 at 17:19
\$\endgroup\$
1
\$\begingroup\$

APL, 13 bytes

1=(×ばつ∘⍴⍴≢)∪≢ ̈⎕

In English:

  • compute the unique of the tallies of each of the subarrays;
  • reshape the result with the signum of its shape: if its an empty vector, it remains an empty vector;
  • is it equal to 1?
answered Jun 23, 2016 at 8:48
\$\endgroup\$
2
  • \$\begingroup\$ There's a bug: if the input is the empty list, you should return the empty list instead of 0 or 1. This returns 0. \$\endgroup\$ Commented Jun 23, 2016 at 16:49
  • \$\begingroup\$ @marinus, you are absolutely right: I didn't read carefully enough the specs. Let's see if it's worth trying to fix it... \$\endgroup\$ Commented Jun 23, 2016 at 17:30
0
\$\begingroup\$

C#, 80 bytes

Im checking length 4 times in this golf. i wish there was a better way to be honest.

bool f(List<int[]>a){return a.Where(m=>m.Length==a[0].Length).Count()==a.Count;}

alternative version also 80 bytes..

bool f(List<int[]>a){return a.Where(m=>m.Length==a[0].Length).SequenceEqual(a);}
answered Jun 11, 2016 at 18:23
\$\endgroup\$
0
\$\begingroup\$

Prolog, 40

m([],L).
m([H|T],L):-length(H,L),m(T,L).

Provide a true/false answer when calling m(X,L) for some input X.

answered Jun 21, 2016 at 15:47
\$\endgroup\$
0
\$\begingroup\$

APL, 13 bytes

{(×ばつ⍴⍵)↑⍵≡↓↑⍵}

Explanation:

  • ↓↑⍵: turn the list of arrays into a matrix, and then turn the matrix back into a list of arrays. Because a matrix has to be rectangular, short arrays will be padded with zeroes to match the longest.
  • ⍵≡: see if the result is equal to the input. This is only the case if no zeroes have been added, which means all the sublists were the same length.
  • ×ばつ⍴⍵: take the sign of the length of , which is 0 if is empty and 1 if not.
  • : take the first 0 or 1 items from the result depending on whether the array was empty or not.
answered Jun 21, 2016 at 16:35
\$\endgroup\$
3
  • \$\begingroup\$ Turn it into a train to save 4 bytes: ×∘⍴↑⊢≡↓∘↑. Btw, will I see you in Glasgow? \$\endgroup\$ Commented Sep 6, 2016 at 9:29
  • \$\begingroup\$ @Adám: hopefully, if nothing goes wrong, I will indeed come to Glasgow. But when you have improvements to my posts, it is better to suggest them as edits officially, that way you will get part of the reputation for subsequent upvotes. I don't want to just copy your improvements into my answers without you getting any benefit from it, it feels like cheating. \$\endgroup\$ Commented Sep 6, 2016 at 23:48
  • \$\begingroup\$ @marinus Suggesting golfing edits to an answer is against site policy. All such edits should be rejected as "causes harm" or "conflicts with author's intent". \$\endgroup\$ Commented Oct 24, 2016 at 18:27
0
\$\begingroup\$

Clojure, 40 bytes

#(if(not-empty %)(apply =(map count %)))

Yay for suitable language features :)

answered Dec 25, 2016 at 23:02
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.