Skip to content

Instantly share code, notes, and snippets.

@jacquesattack
Created July 17, 2019 16:40
Show Gist options
  • Save jacquesattack/97fbd9318cb7c07985a38278dcdca34c to your computer and use it in GitHub Desktop.
Save jacquesattack/97fbd9318cb7c07985a38278dcdca34c to your computer and use it in GitHub Desktop.
#lang racket
(define (values-in-row pz row)
(filter
identity
(map
(lambda (col)
(let ([key (list row col)])
(if (hash-has-key? pz key)
(hash-ref pz key)
#f)))
(range 9))))
(define (values-in-col pz col)
(filter
identity
(map
(lambda (row)
(let ([key (list row col)])
(if (hash-has-key? pz key)
(hash-ref pz key)
#f)))
(range 9))))
(define (get-squ-ind val)
(cond
[(>= val 6) '(6 7 8)]
[(>= val 3) '(3 4 5)]
[else '(0 1 2)]))
(define (values-in-squ pz row col)
(filter identity
(for*/list ([row-ind (get-squ-ind row)] [col-ind (get-squ-ind col)])
(if (hash-has-key? pz (list row-ind col-ind))
(hash-ref pz (list row-ind col-ind))
#f))))
; find free spot
(define (gen-inds)
(for*/list ([x (range 10)] [y (range 10)])
(list x y)))
(define (find-open-spots pz)
(filter (lambda (key) (not (hash-has-key? pz key))) (gen-inds)))
(define (spot-with-values pz)
(first (find-open-spots pz)))
(define (available-slots pz)
(filter identity (flatten (map spot-with-values pz))))
(define (is-member? mem myl)
(sequence-ormap (lambda (val) (= mem val)) myl))
(define (taken-values pz row col)
(remove-duplicates
(append (values-in-row pz row)
(values-in-col pz col)
(values-in-squ pz row col))))
(define (available-values pz spot)
; get values already taken in row, column, and square
(let ([tv (taken-values pz (first spot) (second spot))])
(filter (lambda (val) (not (is-member? val tv))) (range 10))))
; find next value
(define (find-next-value pz)
(let* ([spot (first (find-open-spots pz))]
[values (available-values pz spot)])
(if (empty? values)
#f
(hash 'key spot 'value (first values)))))
; main method
(define (solve pz)
(let ([next-value (find-next-value pz)])
(cond
[(or (false? next-value) (false? pz)) pz]
[(= 81 (hash-count pz)) pz]
[else
(solve (hash-set pz (hash-ref next-value 'key) (hash-ref next-value 'value)))])))
; test
(define ht (hash '(0 0) 1 '(0 1) 2))
;(values-in-row ht 0)
(define pz (hash '(0 0) 1))
(spot-with-values pz)
(is-member? 1 (range 10))
(values-in-col (hash '(0 1) 1 '(1 1) 2 '(0 0) 3) 1)
(get-squ-ind 3)
(values-in-squ pz 0 2)
(available-values pz '(2 2))
(solve pz)
(let ([next-value (find-next-value pz)])
(hash-set pz (hash-ref next-value 'key) (hash-ref next-value 'value)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment