Count number of preceding repeating items in an array - clickhouse

I have the following query that goes through each item in an array and looks back to see how many repeating f's including itself came before.
It works however it will be slow across a large number of rows - is there a cleaner way to work with sequences within arrays?
SELECT
['p','p','f','f','f','f','p','f', 'f', 'f'] AS sequence,
arrayMap( (x,y) -> (x,
if (x='f', (arrayFirstIndex( k -> k=0,
arrayCumSumNonNegative((n, index) -> n = 'f' ? 1 : -index,
arrayReverse(arraySlice(sequence,1,y)) as arr,
arrayEnumerate(arr)))
)-1, 0)), sequence, arrayEnumerate(sequence))
result:
[('p',0),('p',0),('f',1),('f',2),('f',3),('f',4),('p',0),('f',1),('f',2),('f',3)]
Thanks in advance

Try this query:
WITH 'f' AS ch
SELECT 
arraySplit((x, i) -> x = ch and sequence[i - 1] != ch or x != ch and sequence[i - 1] = ch, sequence, arrayEnumerate(sequence)) parts,
arrayMap(part -> arrayMap((x, index) -> (x, x = ch ? index : 0), part, arrayEnumerate(part)), parts) parts_and_number,
arrayFlatten(parts_and_number) result
FROM (
SELECT arrayJoin([
['p','p','f','f','f','f','p','f', 'f', 'f'],
['p','w','f','f','f','f','p','f', 'f', 'f'],
['f','f','f','f','p','f', 'f', 'f'],
['p','w'],
['f', 'f'],
['f']
]) as sequence)
/*
Row 1:
──────
parts: [['p','p'],['f','f','f','f'],['p'],['f','f','f']]
parts_and_number: [[('p',0),('p',0)],[('f',1),('f',2),('f',3),('f',4)],[('p',0)],[('f',1),('f',2),('f',3)]]
result: [('p',0),('p',0),('f',1),('f',2),('f',3),('f',4),('p',0),('f',1),('f',2),('f',3)]
Row 2:
──────
parts: [['p','w'],['f','f','f','f'],['p'],['f','f','f']]
parts_and_number: [[('p',0),('w',0)],[('f',1),('f',2),('f',3),('f',4)],[('p',0)],[('f',1),('f',2),('f',3)]]
result: [('p',0),('w',0),('f',1),('f',2),('f',3),('f',4),('p',0),('f',1),('f',2),('f',3)]
Row 3:
──────
parts: [['f','f','f','f'],['p'],['f','f','f']]
parts_and_number: [[('f',1),('f',2),('f',3),('f',4)],[('p',0)],[('f',1),('f',2),('f',3)]]
result: [('f',1),('f',2),('f',3),('f',4),('p',0),('f',1),('f',2),('f',3)]
Row 4:
──────
parts: [['p','w']]
parts_and_number: [[('p',0),('w',0)]]
result: [('p',0),('w',0)]
Row 5:
──────
parts: [['f','f']]
parts_and_number: [[('f',1),('f',2)]]
result: [('f',1),('f',2)]
Row 6:
──────
parts: [['f']]
parts_and_number: [[('f',1)]]
result: [('f',1)]
*/

Related

Algorithm for drawing profiles using long thin rectangles

I want to draw profiles similar to the ones at https://steeldoor.org like:
programmatically. (Probably in FreeSCAD, but possibly Python).
I want to define a global thickness and then specify the profiles with a vector of directions and another one of lengths (specifically the lengths of the outer edges). The vectors for the second drawing in the example might be ['N', 'E', 'S', 'W', 'S', 'W', 'N'] and [10,100,80,20,70,80,10].
Given a primitive for drawing a rectangle starting at (x,y) with length l and width (corresponding to line thickness) t, say, rect(x,y,l,t), which would draw a horizontal rectangle to the right with l and t positive, is there a generic algorithm that would take the two vectors as input and draw the profile using the primitive? I can solve for a specific profile, but not for the general case.
Perhaps you need something like this approach.
I assume that Y axis is up, and base line (current coordinate x,y) goes through middle of thick lines (E-F-K at the picture), rectangle is defined by left-down corner (points A and H), width and height.
dirs = ['N', 'E', 'S', 'W', 'S', 'W', 'N']
lens = [10,100,80,20,70,80,10]
half_thickness = 3
x = 0
y = 0
for i in range(dirs):
if dirs == 'N':
rect(x-half_thickness, y, 2*half_thickness, lens[i])
y += lens[i]
elif dirs == 'S':
rect(x-half_thickness, y - lens[i], 2*half_thickness, lens[i])
y -= lens[i]
elif dirs == 'E':
rect(x, y-half_thickness, lens[i], 2*half_thickness)
x += lens[i]
else:
rect(x - lens[i], y-half_thickness, lens[i], 2*half_thickness)
x -= lens[i]
I ended up using the answer above (fixing a mistake in the else clause). The Python code below generates the OpenSCAD file that in turn produces the desired profile.
def rect(x,y,w,h,hh):
print("translate([", x,",",y,"])")
print("\tlinear_extrude(height=",hh,")")
print("\t\tsquare([", w,",",h,"]);")
dirs = ['W', 'S', 'E', 'S', 'E', 'N', 'E', 'N', 'E', 'N', 'W']
lens = [14,68,14,6,90,13,35,7,13,68,14]
thickness = 4
height=20
ht = thickness/2;
x = 0
y = 0
li=0;
for dir in dirs:
len = lens[li]
li += 1
if dir == 'N':
rect(x-ht, y, 2*ht, len, height)
y += len
elif dir == 'S':
rect(x-ht, y - len, 2*ht, len, height)
y -= len
elif dir == 'E':
rect(x, y-ht, len, 2*ht, height)
x += len
else:
rect(x - len, y-ht, len, 2*ht, height)
x -= len

Scala extract neighbours in a List who differ by 1 (Ints)

I'm currently trying to extract neighbours in a List who differ by 1. For example if I had my List like this:
List(1,2,3,7,8,10,13,14)
//By extracting I want to get:
List(
List(1,2,3),
List(7,8),
List(10),
List(13,14)
)
I've tried it myself by doing foldLeft, I felt like I was close but yet so far. Can anyone help me? Any suggestions? ^^
Thank you so much! :)
Here is a solution using foldRight:
val oldList = List(1, 2, 3, 7, 8, 10, 13, 14)
val newList = oldList.foldRight[List[List[Int]]](Nil)((a, b) => b match {
case (bh # bhh :: _) :: bt if (bhh - a == 1) => (a :: bh) :: bt
case _ => (a :: Nil) :: b
})
So we iterate the entries backwards and either prepend to the existing head list or add a new head list depending on whether the difference is one:
Nil
(14, ...) => (14 :: Nil) :: Nil
(13, ...) => (13 :: 14 :: Nil) :: Nil
(10, ...) => (10 :: Nil) :: (13 :: 14 :: Nil) :: Nil
...
I haven't used Scala for a while so this might not be the best solution, but I hope you get the idea.
Consecutive integers will increment in line with the list index, thus we can subtract the index and they'll form groups of the same number
val li = List(1, 2, 3, 7, 8, 10, 13, 14)
val groups = li.zipWithIndex.groupBy({case (e, i) => e - i}) // group numbers
groups.values.toList.map(_.map(_._1)) // drop indices and grouping keys
Note: these will lose the ordering of unordered initial list. For your case, you can reorder with .sortBy(_.head)
//First Part: Separates the list into ordered pairs with tail - head == 1
val ls = List(1,2,3,7,8,10,13,14)
val lb: ListBuffer[List[Int]] = new ListBuffer[List[Int]]()
for (List(left,right) <- ls.sorted.sliding(2)) {
if (right - left == 1) {
lb += List(left, right)
}else {
if(!lb.flatten.toList.contains(left)) lb += List(left)
}
}
println(lb.toList)
//Second Part: Merges ordered pairs (x1, y1) and (x2, y2) when y1 == y2
val finalLb: ListBuffer[List[Int]] = new ListBuffer[List[Int]]()
for (List(left,right) <- lb.toList.sliding(2)) {
if(left.tail.contains(right.head)) {
finalLb += (left ++ right).distinct
}else{
finalLb += right
}
}
println(finalLb.toList)
Outputs
First Part: List(List(1, 2), List(2, 3), List(7, 8), List(10), List(13, 14))
Second Part: List(List(1, 2, 3), List(7, 8), List(10), List(13, 14))

Algorithm for generating all possible boolean functions of n variables

For n variables, there exists 2^(2^n) distinct boolean functions. For example, if n=2, then there exists 16 possible boolean functions which can be written in sum of product form, or product of sum forms. The number of possible functions increases exponentially with n.
I am looking for an algorithm which can generate all these possible boolean rules for n variables. I have tried to search at various places, but have not found anything suitable till now. Most of the algorithms are related to simplifying or reducing boolean functions to standard forms.
I know even for the number of rules become too large even for n=8 or 9, but can somebody please help me out with the relevant algorithm if it exists?
A boolean function of n variables has 2^n possible inputs. These can be enumerated by printing out the binary representation of values in the range 0 <= x < 2^n.
For each one of the those possible inputs, a boolean function can output 0 or 1. To enumerate all the possibilities (i.e. every possible truth table). List the binary values in range 0 <= x < 2^(2^n).
Here's the algorithm in Python:
from __future__ import print_function
from itertools import product # forms cartesian products
n = 3 # number of variables
print('All possible truth tables for n =', n)
inputs = list(product([0, 1], repeat=n))
for output in product([0, 1], repeat=len(inputs)):
print()
print('Truth table')
print('-----------')
for row, result in zip(inputs, output):
print(row, '-->', result)
The output looks like this:
All possible truth tables for n = 3
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 0
(1, 1, 1) --> 0
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 0
(1, 1, 1) --> 1
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 1
(1, 1, 1) --> 0
Truth table
-----------
(0, 0, 0) --> 0
(0, 0, 1) --> 0
(0, 1, 0) --> 0
(0, 1, 1) --> 0
(1, 0, 0) --> 0
(1, 0, 1) --> 0
(1, 1, 0) --> 1
(1, 1, 1) --> 1
... and so on
If you want the output in algebraic form rather than truth tables, the algorithm is the same:
from __future__ import print_function
from itertools import product # forms cartesian products
n = 3 # number of variables
variables = 'abcdefghijklmnopqrstuvwxyz'[:n]
pairs = [('~'+var, var) for var in variables]
print('All possible algebraic expressions for n =', n)
inputs = list(product(*pairs))
for i, outputs in enumerate(product([0, 1], repeat=len(inputs))):
terms = [''.join(row) for row, output in zip(inputs, outputs) if output]
if not terms:
terms = ['False']
print('Function %d:' % i, ' or '.join(terms))
The output looks like this:
All possible algebraic expressions for n = 3
Function 0: False
Function 1: abc
Function 2: ab~c
Function 3: ab~c or abc
Function 4: a~bc
Function 5: a~bc or abc
Function 6: a~bc or ab~c
Function 7: a~bc or ab~c or abc
Function 8: a~b~c
Function 9: a~b~c or abc
Function 10: a~b~c or ab~c
Function 11: a~b~c or ab~c or abc
Function 12: a~b~c or a~bc
Function 13: a~b~c or a~bc or abc
Function 14: a~b~c or a~bc or ab~c
Function 15: a~b~c or a~bc or ab~c or abc
Function 16: ~abc
Function 17: ~abc or abc
Function 18: ~abc or ab~c
Function 19: ~abc or ab~c or abc
Function 20: ~abc or a~bc
Function 21: ~abc or a~bc or abc
Function 22: ~abc or a~bc or ab~c
Function 23: ~abc or a~bc or ab~c or abc
Function 24: ~abc or a~b~c
Function 25: ~abc or a~b~c or abc
Function 26: ~abc or a~b~c or ab~c
Function 27: ~abc or a~b~c or ab~c or abc
Function 28: ~abc or a~b~c or a~bc
Function 29: ~abc or a~b~c or a~bc or abc
Function 30: ~abc or a~b~c or a~bc or ab~c
Function 31: ~abc or a~b~c or a~bc or ab~c or abc
Function 32: ~ab~c
Function 33: ~ab~c or abc
... and so on
As mentioned in comments, there's a one-to-one relation between numbers and truth tables. For example, we can represent the truth table
0 0 0 | 1
0 0 1 | 1
0 1 0 | 0
0 1 1 | 0
1 0 0 | 1
1 0 1 | 0
1 1 0 | 1
1 1 1 | 0
by the binary number 01010011 (the topmost row is represented by the least-significant bit).
It is obviously just a matter of looping over numbers to generate these representations:
for f := 0 to 2^(2^n) - 1:
# do something with f
What can we do with f? We can evaluate it, for example. Say we want to know f(0,1,0). It's as simple as interpreting the argument as the binary number x = 010 and doing some bit-magic:
def evaluate(f, x):
return (f & (1<<x)) != 0
We can also find its disjunctive normal form by just checking which bits are 0:
def dnf(f):
for x := 0 to 2^n - 1:
if f & (1<<x) != 0:
print binary(x) + " OR "
Giving a result like 000 OR 001 OR 100 OR 110 (OR) for the function above.
I've changed the code posted by Raymond Hettinger.
Now you can:
generate all Boolean expressions up to n_ary,
pick a particular function,
perform evaluation, and
get answers in binary or True/False manner.
Code:
from itertools import product
def allBooleanFunctions(kk):
"""Finds all Boolean functions for indegree kk"""
inputs1 = list(product([0, 1], repeat=kk))
variables = 'abcdefghijklmnopqrstuvwxyz'[:kk]
pairs = [('( not '+var+' )', var) for var in variables]
inputs = list(product(*pairs))
bool_func=[]
for i, outputs in enumerate(product([0, 1], repeat=len(inputs))):
terms = [' and '.join(row) for row, output in zip(inputs, outputs) if output]
if not terms:
terms = ['False']
bool_func.append(('('+(') or ('.join(terms))+')'))
return bool_func
n_ary=2 # number of inputs; keep it n_ary<=5
boolean_function_analytical=allBooleanFunctions(n_ary)
print('All Boolean functions of indegree:'+str(n_ary)+'\n')
print(boolean_function_analytical)
print
print('A Boolean function:'+'\n')
print(boolean_function_analytical[2])
# Evaluate third boolean function:
a=1 # first input
b=0 # second input
c=0 # third input
d=0 # fourth input
print('a='+str(a)+'; b='+str(b)+'; c='+str(c)+'; d='+str(d)+'\n')
print('Evaluation in 0/1 manner:')
print(int(eval((boolean_function_analytical[2]))))
print('Evaluation in True/False manner:')
print(bool(eval((boolean_function_analytical[2]))))
Result:
All Boolean functions of indegree:2
['(False)', '(a and b)', '(a and ( not b ))', '(a and ( not b )) or (a and b)', '(( not a ) and b)', '(( not a ) and b) or (a and b)', '(( not a ) and b) or (a and ( not b ))', '(( not a ) and b) or (a and ( not b )) or (a and b)', '(( not a ) and ( not b ))', '(( not a ) and ( not b )) or (a and b)', '(( not a ) and ( not b )) or (a and ( not b ))', '(( not a ) and ( not b )) or (a and ( not b )) or (a and b)', '(( not a ) and ( not b )) or (( not a ) and b)', '(( not a ) and ( not b )) or (( not a ) and b) or (a and b)', '(( not a ) and ( not b )) or (( not a ) and b) or (a and ( not b ))', '(( not a ) and ( not b )) or (( not a ) and b) or (a and ( not b )) or (a and b)']
A Boolean function:
(a and ( not b ))
a=1; b=0; c=0; d=0
Evaluation in 0/1 manner:
1
Evaluation in True/False manner:
True
Have fun!!!

Cartesian/combination algorithm (while maintaining order)

Since I don't quite know the language of these types of algorithms (i.e. how to google this), I'll just demonstrate what I'm looking for:
I have a three arrays (source arrays are of not equal lengths):
$array1 = array('A', 'B', 'C', 'D');
$array2 = array('x', 'y', 'z');
$array3 = array('1', '2', '3');
I would like all possible combinations of these arrays where:
No more than one element from each source array is taken.
The order of array1, array2, array3 is never broken (ABC always comes before xyz always comes before 123).
So the result would be:
array(
array('A', 'x', '1'),
array('A', 'x', '2'),
array('A', 'x', '3'),
array('A', 'y', '1'),
// etc ...
// But I also need all the partial sets, as long as the rule about
// ordering isn't broken i.e.:
array('B'),
array('B', 'x'),
array('B', 'x', '1'),
array('x'),
array('x', '1'),
array('1'),
);
The order of the results doesn't matter to me.
Working in php, but similar language or pseudo code is fine of course. Or I'd just take a tip on what specific types of permutation/combination algorithms I should be looking at.
I'd say these are Cartesian products. Generating them is quite easy.
for fixed number of arrays (in Perl):
for my $a(#arrayA) {
for my $b(#arrayB) {
push #result, [$a, $b];
}
}
general procedure: Assume #partial is an array for Cartesian product of A1 x A2 x ... x An and we want A1 x ... x An x An+1
for my $a(#partial) {
for my $b(#An_plus_1) {
push #result, [#$a, $b];
}
}
This would obviously need to iterate over all the arrays.
Now, that you want also to omit some of the elements in the sets, you just twist it a little. In the first method, you can just add another element to each of the arrays (undef is obvious choice, but anything will do) and then filter out these elements in the result sets. In the second method, it is even easier: You just add #partial and map { [$_] } #An_plus_1 to the result (or, in English, all the sets resulting from the partial Cartesian product of A1 x ... x An plus the single element sets made form the elements of the new set).
With RBarryYoung's hint, this is the shortest way to produce them, bash (and sed, to remove D, w, and 4):
echo {A..D}{w..z}{1..4} | sed 's/[Dw4]//g'
A1 A2 A3 A Ax1 Ax2 Ax3 Ax Ay1 Ay2 Ay3 Ay Az1 Az2 Az3 Az
B1 B2 B3 B Bx1 Bx2 Bx3 Bx By1 By2 By3 By Bz1 Bz2 Bz3 Bz
C1 C2 C3 C Cx1 Cx2 Cx3 Cx Cy1 Cy2 Cy3 Cy Cz1 Cz2 Cz3 Cz
1 2 3 x1 x2 x3 x y1 y2 y3 y z1 z2 z3 z
Another, easy way, is SQL, which does it by default:
SELECT upper, lower, num
FROM uppers, lowers, numbers
WHERE upper in ('A', 'B', 'C', ' ')
AND lower in (' ', 'x', 'y', 'z')
AND (number in (1, 2, 3) OR number IS NULL);
If your tables only contain 'A,B,C, ,' and 'x,y,z, ,' and '1,2,3, ' it is much shorter:
SELECT upper, lower, num
FROM uppers, lowers, numbers;
Another word, beside cartesian product, for this combinations is cross product.
For an unknown number of unknown size of Lists/Sequences/other collections, I would recommend an Iterator - if PHP has such things. Here is an implementation in Scala:
class CartesianIterator (val ll: Seq[Seq[_]]) extends Iterator [Seq[_]] {
var current = 0
def size = ll.map (_.size).product
lazy val last: Int = len
def get (n: Int, lili: Seq[Seq[_]]): List[_] = lili.length match {
case 0 => List ()
case _ => {
val inner = lili.head
inner (n % inner.size) :: get (n / inner.size, lili.tail)
}
}
override def hasNext () : Boolean = current != last
override def next (): Seq[_] = {
current += 1
get (current - 1, ll)
}
}
val ci = new CartesianIterator (List(List ('A', 'B', 'C', 'D', ' '), List ('x', 'y', 'z', ' '), List (1, 2, 3, 0)))
for (c <- ci) println (c)
List(A, x, 1)
List(B, x, 1)
List(C, x, 1)
List(D, x, 1)
List( , x, 1)
List(A, y, 1)
List(B, y, 1)
...
List( , z, 0)
List(A, , 0)
List(B, , 0)
List(C, , 0)
List(D, , 0)
List( , , 0)
A wrapper could be used to remove the '0' and ' ' from the output.

Algorithm to evenly distribute items into 3 columns

I'm looking for an algorithm that will evenly distribute 1 to many items into three columns. No column can have more than one more item than any other column. I typed up an example of what I'm looking for below. Adding up Col1,Col2, and Col3 should equal ItemCount.
Edit: Also, the items are alpha-numeric and must be ordered within the column. The last item in the column has to be less than the first item in the next column.
Items Col1,Col2,Col3
A A
AB A,B
ABC A,B,C
ABCD AB,C,D
ABCDE AB,CD,E
ABCDEF AB,CD,EF
ABCDEFG ABC,DE,FG
ABCDEFGH ABC,DEF,GH
ABCDEFGHI ABC,DEF,GHI
ABCDEFHGIJ ABCD,EFG,HIJ
ABCDEFHGIJK ABCD,EFGH,IJK
Here you go, in Python:
NumCols = 3
DATA = "ABCDEFGHIJK"
for ItemCount in range(1, 12):
subdata = DATA[:ItemCount]
Col1Count = (ItemCount + NumCols - 1) / NumCols
Col2Count = (ItemCount + NumCols - 2) / NumCols
Col3Count = (ItemCount + NumCols - 3) / NumCols
Col1 = subdata[:Col1Count]
Col2 = subdata[Col1Count:Col1Count+Col2Count]
Col3 = subdata[Col1Count+Col2Count:]
print "%2d %5s %5s %5s" % (ItemCount, Col1, Col2, Col3)
# Prints:
# 1 A
# 2 A B
# 3 A B C
# 4 AB C D
# 5 AB CD E
# 6 AB CD EF
# 7 ABC DE FG
# 8 ABC DEF GH
# 9 ABC DEF GHI
# 10 ABCD EFG HIJ
# 11 ABCD EFGH IJK
This answer is now obsolete because the OP decided to simply change the question after I answered it. I’m just too lazy to delete it.
function getColumnItemCount(int items, int column) {
return (int) (items / 3) + (((items % 3) >= (column + 1)) ? 1 : 0);
}
This question was the closest thing to my own that I found, so I'll post the solution I came up with. In JavaScript:
var items = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']
var columns = [[], [], []]
for (var i=0; i<items.length; i++) {
columns[Math.floor(i * columns.length / items.length)].push(items[i])
}
console.log(columns)
just to give you a hint (it's pretty easy, so figure out yourself)
divide ItemCount by 3, rounding down. This is what is at least in every column.
Now you do ItemCount % 3 (modulo), which is either 1 or 2 (because else it would be dividable by 3, right) and you distribute that.
I needed a C# version so here's what I came up with (the algorithm is from Richie's answer):
// Start with 11 values
var data = "ABCDEFGHIJK";
// Split in 3 columns
var columnCount = 3;
// Find out how many values to display in each column
var columnCounts = new int[columnCount];
for (int i = 0; i < columnCount; i++)
columnCounts[i] = (data.Count() + columnCount - (i + 1)) / columnCount;
// Allocate each value to the appropriate column
int iData = 0;
for (int i = 0; i < columnCount; i++)
for (int j = 0; j < columnCounts[i]; j++)
Console.WriteLine("{0} -> Column {1}", data[iData++], i + 1);
// PRINTS:
// A -> Column 1
// B -> Column 1
// C -> Column 1
// D -> Column 1
// E -> Column 2
// F -> Column 2
// G -> Column 2
// H -> Column 2
// I -> Column 3
// J -> Column 3
// K -> Column 3
It's quite simple
If you have N elements indexed from 0 to N-1 and column indexed from 0to 2, the i-th element will go in column i mod 3 (where mod is the modulo operator, % in C,C++ and some other languages)
Do you just want the count of items in each column? If you have n items, then
the counts will be:
round(n/3), round(n/3), n-2*round(n/3)
where "round" round to the nearest integer (e.g. round(x)=(int)(x+0.5))
If you want to actually put the items there, try something like this Python-style pseudocode:
def columnize(items):
i=0
answer=[ [], [], [] ]
for it in items:
answer[i%3] += it
i += 1
return answer
Here's a PHP version I hacked together for all the PHP hacks out there like me (yup, guilt by association!)
function column_item_count($items, $column, $maxcolumns) {
return round($items / $maxcolumns) + (($items % $maxcolumns) >= $column ? 1 : 0);
}
And you can call it like this...
$cnt = sizeof($an_array_of_data);
$col1_cnt = column_item_count($cnt,1,3);
$col2_cnt = column_item_count($cnt,2,3);
$col3_cnt = column_item_count($cnt,3,3);
Credit for this should go to #Bombe who provided it in Java (?) above.
NB: This function expects you to pass in an ordinal column number, i.e. first col = 1, second col = 2, etc...

Resources