Search code examples
schemeracketblackjack

How can I rearrange the order of a list of pairs (that have chars or numbers) in Racket?


How can I move all cards with characters 'A 'K 'Q 'J to the front of my hand and all the numbers 1-10 to the end in Racket?

Ex: ((4 . ♠) (9 . ♣) (10 . ♠) (Q . ♦) (A . ♠))

becomes

((A . ♠) (Q . ♦) (10 . ♠) (9 . ♣) (4 . ♠))

My struggle here is dealing with the mixture of numbers and char. I can sort the numbers with the sort function but I get errors as soon as a char appears.


Solution

  • Basically sort has an optional less-than? function you can provide where you check if first argument is less than second. eg. Imagine I want to sort cards by their value 1-10 and that J,Q,K,A are 11-14:

    ;; produce a numeric value for all cards
    (define (card->value c)
      (let ((v (car c)))
        (case v
          ((J) 11)
          ((Q) 12)
          ((K) 13)
          ((A) 14)
          (else v))))
    
    (define cards '((4 . ♠) (9 . ♣) (10 . ♠) (Q . ♦) (A . ♠)))
    (map card->value cards) ; ==>  (4 9 10 12 14)
    
    (define (card-less? c1 c2)
       (< (card->value c1) (card->value c2)))
    
    (sort '((4 . ♠) (9 . ♣) (10 . ♠) (Q . ♦) (A . ♠)) card-less?)
    ; ==> ((4 . ♠) (9 . ♣) (10 . ♠) (Q . ♦) (A . ♠))
    

    Since you are after the opposite order you should pass a card-greater? instead that does the opposite of card-less? and sort will reverse the order.

    If you are using #lang racket you can make use of the two extra optional values and make it without card-less?:

    (sort cards < #:key card->value     #:cache-keys? #t)
    ; ==> ((4 . ♠) (9 . ♣) (10 . ♠) (Q . ♦) (A . ♠))