• re: matrix operations

    From B. Pym@21:1/5 to Barry Margolin on Wed Jul 3 01:32:54 2024
    Barry Margolin wrote:

    Zachary Turner <ztur...@bindview.com> wrote:
    I've got a 3x3 matrix, stored as ((r1c1 r1c2 r1c3) (r2c1 r2c2 r2c3) (r3c1 >r3c2 r3c3)). I want to check if any of the columns have the same three >elements. It's easy for rows, I can just use
    (or
    (every #'equal (car matrix))
    (every #'equal (cadr matrix))
    (every #'equal (caddr matrix)))

    Actually, that doesn't work. EVERY passes a single element to the test function, but EQUAL requires two arguments. What you need is:

    (or (every #'(lambda (x) (equal x (caar matrix)))
    (cdar matrix))
    (every #'(lambda (x) (equal x (caadr matrix)))
    (cdadr matrix))
    (every #'(lambda (x) (equal x (caaddr matrix)))
    (cdaddr matrix)))

    That's hideous.


    My questions are:
    a) Can I do this more elegantly using a mapxxx function?

    (defun (all-elements-equal (list)
    (destructuring-bind (head . tail) list
    (every #'(lambda (x) (equal x head))
    tail))))

    "#'(lambda" shows that he doesn't understand
    the lambda macro.


    Scheme (Gauche or Racket)

    ;; Racket needs this:
    (require srfi/1) ;; every

    (define (all-elements-equal lst)
    (or (null? lst)
    (every equal? lst (cdr lst))))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to B. Pym on Wed Jul 3 02:41:20 2024
    On 2024-07-03, B. Pym <No_spamming@noWhere_7073.org> wrote:
    Barry Margolin wrote:

    Zachary Turner <ztur...@bindview.com> wrote:
    I've got a 3x3 matrix, stored as ((r1c1 r1c2 r1c3) (r2c1 r2c2 r2c3) (r3c1 >> >r3c2 r3c3)). I want to check if any of the columns have the same three
    elements. It's easy for rows, I can just use
    (or
    (every #'equal (car matrix))
    (every #'equal (cadr matrix))
    (every #'equal (caddr matrix)))


    If it didn't have to scale to larger matrices, I'd probaby just do:

    (defun has-column-3x3 (matrix)
    (if-match @(or ((@x . @nil)
    (@x . @nil)
    (@x . @nil))
    ((@nil @x . @nil)
    (@nil @x . @nil)
    (@nil @x . @nil))
    ((@nil @nil @x)
    (@nil @nil @x)
    (@nil @nil @x)))
    matrix
    t))

    (defun has-column-3x3 (matrix)
    (if-match @(or ((@x @x @xl) . @nil)
    (@nil (@x @x @x) . @nil)
    (@nil @nil (@x @x @x)))
    matrix
    t))

    (defun has-diagonal-3x3 (matrix)
    (if-match @(or ((@x . @nil)
    (@nil @x . @nil)
    (@nil @nil @x))
    ((@nil @nil @x)
    (@nil @x . @nil)
    (@x . @nil)))
    matrix
    t))

    If we want to test for a specific value of x (e.g. #\X or #\O
    in Tic Tac Toe), we just add that as a parameter

    (defun has-diagonal-3x3 (matrix x)
    (if-match @(or ((@x . @nil)
    (@nil @x . @nil)
    (@nil @nil @x))
    ((@nil @nil @x)
    (@nil @x . @nil)
    (@x . @nil)))
    matrix
    t))

    The pattern matcher will substitute the value of the existing
    lexical x for the pattern variable @x.

    (has-diagonal-3x3 '((x o o)
    (o x _)
    (_ _ x)) 'x)
    t
    (has-diagonal-3x3 '((x o o)
    (o _ _)
    (_ _ x)) 'x)
    nil
    (has-diagonal-3x3 '((x o o)
    (o o x)
    (o x x)) 'x)
    nil
    (has-diagonal-3x3 '((x o o)
    (o o x)
    (o x x)) 'o)
    t

    Backquote notation can be used.

    (defun has-diagonal-3x3 (matrix x)
    (if-match @(or ^((,x . ,nil)
    (,nil ,x . ,nil)
    (,nil ,nil ,x))
    ^((,nil ,nil ,x)
    (,nil ,x . ,nil)
    (,x . ,nil)))
    matrix
    t))

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)