0

How can I test whether an array mfselc is composed of zeroes or all zeroes except for a single value being 1.

Thus mfselc [0 0 1 0 0 0] is acceptable

Also mfselc [0 0 0 0 0 0] is acceptable

But mfselc [0 1 1 0 0 0] is not acceptable

dalanicolai
  • 6,108
  • 7
  • 23
Dilna
  • 1,173
  • 3
  • 10

2 Answers2

2
(defun acceptable-p (zeros-and-ones-array)
  "Test ZEROS-AND-ONES-ARRAY for comprising at most one 1.
All elements are either 0 or 1."
  (<= (reduce #'+ zeros-and-ones-array) 1))

reduce applies the same function cumulatively to each element of a sequence. It's a solution that should leap to mind whenever you see a problem where you want a single-thing output from a collection of some kind. So what we're doing here is summing the elements of the array (by cumulatively applying the function called +) and then testing that the resulting sum is no more than 1.

Phil Hudson
  • 1,651
  • 10
  • 13
  • 1
    Thanks for jumping in with this elegant solution! I saw reduce being heavily used in some Clojure book before, but I don't have much experience with it. And somehow I failed to conclude that the question 'implies' that the arrays are only composed of zeros and ones. Anyway, this certainly is an 'affirmative answer to the question 'Can a solution be made more readable?' I think it is generally recommended to prefix `reduce` with `seq-` (or `cl-`) b.t.w. – dalanicolai Nov 15 '22 at 21:27
1

You can get the number of occurrences of a certain element in a sequence using seq-count. You can check if all elements are the same using seq-every-p:

(let ((seqs '([0 0 0]
              [0 0 1]
              [0 1 1])))
  (mapcar (lambda (seq)
            (unless (> (seq-count (apply-partially #'= 1) seq) 1)
              (seq-every-p #'zerop (seq-remove (apply-partially #'= 1) seq))))
          seqs))
dalanicolai
  • 6,108
  • 7
  • 23
  • This is quite an esoteric solution. Can a solution be made more readable? – Dilna Nov 15 '22 at 16:22
  • Ah, I see now that I did not read the question correctly. – dalanicolai Nov 15 '22 at 16:49
  • Have looked at the documentation for `seq-count` and is not informative. – Dilna Nov 15 '22 at 17:01
  • The docstring of 'seq-count` is as clear as it can be. However, [you should look up](https://www.tutorialspoint.com/lisp/lisp_predicates.htm) what 'predicate' means in lisp. – dalanicolai Nov 15 '22 at 17:09
  • You have over-complicated even more. – Dilna Nov 15 '22 at 18:36
  • Haha, well, I misread your question, so my earlier answer was wrong. As you asked a 'complicated' question, you get a 'complicated' answer. Well, it should be simple enough for you to study how it works. It is really only two lines of code (the rest is just to show its effect on three different examples). You can also look at the earlier (and simpler) versions, to see why they were wrong... – dalanicolai Nov 15 '22 at 19:40
  • I could test seperately. First with `seq-count`, then with `seq-every-p`. No real need to call `apply-partially` as far as I can see. – Dilna Nov 15 '22 at 19:46