| Bytes | Lang | Time | Link |
|---|---|---|---|
| 006 | 05AB1E | 241030T110527Z | Kevin Cr |
| 163 | Python 2 | 170718T034410Z | Chas Bro |
| 141 | Mathematica | 170718T080105Z | ZaMoC |
| 088 | Haskell | 170718T134227Z | Zgarb |
| 134 | Python 3 | 170718T035745Z | Leaky Nu |
| 008 | Jelly | 170717T235741Z | Jonathan |
| 016 | Pyth | 170718T032447Z | Leaky Nu |
| 135 | Haskell | 170718T021739Z | Wheat Wi |
05AB1E, 6 bytes
.œÅ²PO
Try it online or verify all test cases.
Explanation:
.œ # Get all partitions of the (implicit) input
Ų # Vectorized check whether each inner-most value is a square
P # Product on each inner list, to see if all checks were truthy
O # Sum, to get the amount of truthy values
# (which is output implicitly as result)
PS: Outputting the valid partitions instead of the count would be 6 bytes as well, by removing the sum O, and adding a filter ʒ earlier on: .œʒŲP
Try it online or verify all test cases.
Python 2, 173 163 bytes
lambda s:len([l for l in[''.join(sum(zip(s,[','*(n>>i&1)for i in range(len(s))]+['']),())).split(',')for n in range(2**~-len(s))]if {int(x)**.5%1for x in l}=={0}])
Edit: Saved 10 bytes due to ArnoldPalmer
Mathematica, 141 bytes
Count[FreeQ[IntegerQ/@Sqrt[FromDigits/@#],1<0]&/@(FoldPairList[TakeDrop,s,#]&/@Flatten[Permutations/@IntegerPartitions[Length[s=#]],1]),1>0]&
input (a list of digits)
[{1,6,4}]
Haskell, 88 bytes
f x=sum[0.5|y<-mapM(\c->[[c],c:" "])x,all((`elem`map(^2)[0..read x]).read).words$id=<<y]
Defines a function f that takes a string and returns a float.
Very slow.
Try it online!
Explanation
I'm using my Haskell tip for computing all partitions of a string with mapM and words.
The snippet mapM(\c->[[c],c:" "])x replaces every character 'c' of a string x with either the one-element string "c" or the two-element string "c ", and returns the list of all possible combinations.
If I take one of the results, y, concatenate it and call words on the result, it will be split at the spaces inserted by mapM.
In this way I obtain all partitions of x into contiguous substrings.
Then I just count those results where each partition element is a perfect square (by finding it in the list [0,1,4,9,..,x^2]).
A caveat is that each partition is counted twice, with and without a trailing space, so I take the sum of 0.5s instead of 1s; this is why the result type is a float.
f x= -- Define f x as
sum[0.5| -- the sum of 0.5 for
y<- -- every y drawn from
mapM(\c->[[c],c:" "])x, -- this list (explained above)
-- (y is a list of one- and two-element strings)
all(...) -- such that every element of
id=<<y] -- concatenated y
.words$ -- split at spaces satisfies this:
-- (the element is a string)
(...).read -- if we convert it to integer
`elem` -- it is an element of
map(^2) -- the squares of
[0..read x] -- the numbers in this list.
Python 3, 148 139 135 134 bytes
10 bytes thanks to Arnold Palmer.
def f(a):
s=[a[:1]]
for i in a[1:]:s=sum([[x+[i],x[:-1]+[x[-1]*10+i]]for x in s],[])
return sum({n**.5%1for n in x}=={0}for x in s)
Jelly, 8 bytes
ŒṖḌƲẠ€S
A monadic link taking a list of digits and returning a non-negative integer.
Try it online! or see the test suite.
How?
ŒṖḌƲẠ€S - Link: list of digits e.g. [4,0,0,4]
ŒṖ - all partitions [[4,0,0,4],[4,0,[0,4]],[4,[0,0],4],[4,[0,0,4]],[[4,0],0,4],[[4,0],[0,4]],[[4,0,0],4],[4,0,0,4]]
Ḍ - convert from decimal list (vectorises) [[4,0,0,4],[4,0, 4 ],[4, 0,4],[4, 4],[ 40,0,4],[ 40, 4],[ 400,4], 4004]
Ʋ - is square? (vectorises) [[1,1,1,1],[1,1, 1 ],[1, 1,1],[1, 1],[ 0,1,1],[ 0, 1],[ 1,1], 0]
Ạ€ - all truthy? for €ach [ 1, 1, 1, 1 0, 0, 1, 0]
S - sum 5
Haskell, 135 bytes
s x=any((x==).(^2))[0..x]
c(a:b:x)=a*10+b:x
c x=x
h[x]=1>0
h x=(s.head)x
f x@(_:_:_)|y<-until h c x=f(tail y)+f(c y)
f x=sum[1|any s x]
Probably not well golfed yet but this is a surprisingly difficult problem