count pairs of matching integers in a collection in Common Lisp This defines count-pairs which

takes a collection of integers
returns the number of pairs of integers that are equal to each other.

If the input collection has these integers ...
1 2 0 2 1 3 2

... then count-pairs returns 2 because

one pair can be made with the 1's
a second pair can be made with the 2's
The leftover unpaired integers do not affect the answer.

(defun make-pair (table i)
  (setf
   ;; increment pair count:
   (gethash 'pairs table) (1+ (gethash 'pairs table 0))
   ;; make first half of the new pair unavailable:
   (gethash i table) nil)
  table)

(defun keep-first-half-of-pair (table i)
  (setf (gethash i table) t)
  table)

(defun first-half-available-p (table i)
  (gethash i table))

(defun consider-one (table i)
  (if (first-half-available-p table i)
      (make-pair table i)
      (keep-first-half-of-pair table i)))

(defun count-pairs (integers)
  (let ((table (reduce #'consider-one
                       integers
                       :initial-value
                       (make-hash-table))))
    (gethash 'pairs table 0)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; boilerplate for running as a hacker rank submission
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(read-line) ;; we don't need n

(defvar integers
  (read-from-string
   (concatenate 'string
                &quot;(&quot; (read-line) &quot;)&quot;)))

(format t &quot;~a~%&quot; (count-pairs integers))


Some questions I have:

What changes would make this more idiomatic?
Is there an alternative for setf that returns the modified container instead of the multiple values returned by the storing form for the last altered place? (See how I really want the container as the result of make-pair and keep-first-half-available-p ...)
Should I stick with the -p naming convention for predicates? It seems ending with a ? is possible and looks more readable to me.
I guess Emacs knows if is a macro and is indenting it that way?
If there is an entirely different and better way to solve in Common Lisp, please do let me know.

Thanks in advance!
Stylistic consideration: a global variable is usually written with double &quot;*&quot; (earmuffs), so the global variable integers should be written as *integers*.
Now, for your questions.

I think your code is not particularly unidiomatic, just a little bit complex to read. What I find more unusual is your use of reduce to iterate over a list. In fact reduce is normally called with a binary function that takes pairs of elements of the same type, while you use it as a kind of iterator. In your case I would use a more classical iterator, like mapc, or, even better for me, loop. Another thing that I don't like is the use of the table to store also the global counter that will be used as result.

Summing all these considerations, I will rewrite your solution using
local helper functions, to reduce the complexity and simplify the
use of the parameters, and substitute the iterator while reducing by
one the number of auxiliary functions.
 (defun count-pairs (integers)
  (let ((pairs 0)
        (table (make-hash-table)))
    (flet ((make-pair (i)
             (incf pairs)
             (setf (gethash i table) nil))
           (keep-first-half-of-pair (i)
             (setf (gethash i table) t))
           (first-half-available-p (i)
             (gethash i table)))
      (loop for i in integers
        if (first-half-available-p i)
          do (make-pair i)
        else
          do (keep-first-half-of-pair i)))
    pairs))


If you need to return the table there is no other possibility. In the above solution this is not necessary, since table is not returned by the functions.

It's just a convention that you can follow or not. If you want to stick to Common Lisp common style, it is better to use the -p convention.

Yes.


Finally, for the fifth point, I would prefer a more concise solution, that counts all the elements, and only at the end counts all the pairs, in this way:
(defun count-pairs (integers)
  &quot;returns the numbers the pairs of the list integers&quot;
  (let ((table (make-hash-table)))
    (loop for i in integers
          do (incf (gethash i table 0)))
    (loop for v being the hash-value of table
          sum (truncate v 2))))