code: def cluster(
      array: Sequence[float],
      k: int,
      *,
      weights: Optional[Sequence[float]] = None,
  ) -> Clustered:
      """
      :param array: A sequence of floats
      :param k: Number of clusters (int)
      :param weights: Sequence of weights (if provided, must have same length as `array`)
      :return: A tuple with (clusters, centroids)
      """
      assert k > 0, f"Invalid k: {k}"
      n = len(array)
      assert n > 0, f"Invalid len(array): {n}"
      k = min(k, n)
  
      if weights is not None:
          assert (
              len(weights) == n
          ), f"len(weights)={len(weights)} != len(array)={n}"
  
      c_array = (ctypes.c_double * n)(*array)
      c_n = ctypes.c_ulong(n)
      c_k = ctypes.c_ulong(k)
      c_clusters = (ctypes.c_ulong * n)()
      c_centroids = (ctypes.c_double * k)()
  
      if weights is None:
          _DLL.cluster(c_array, c_n, c_k, c_clusters, c_centroids)
      else:
          c_weights = (ctypes.c_double * n)(*weights)
          _DLL.cluster_with_weights(
              c_array, c_weights, c_n, c_k, c_clusters, c_centroids
          )
  
      clusters = list(c_clusters)
      centroids = list(c_centroids)
  
      output = Clustered(clusters=clusters, centroids=centroids)
  
      return output
  
imports: from collections import namedtuple
  import ctypes
  from typing import Optional, Sequence
  from .None import _core
label_desc: Use image node_id 1 for calling a global function with example usage: cluster(array, k) and returns: output