Nonoblock: Difference between revisions

Content added Content deleted
m (=={{header|Racket}}== stub added)
(→‎{{header|Racket}}: actual implementation added)
Line 350: Line 350:


=={{header|Racket}}==
=={{header|Racket}}==

This implementation does not "error" on the impossible case.

Knowing that there are no solutions (empty result list) is good enough.

Also, the blocks are not identified. I suppose they could be easily enough, but in the nonogram task, these patterns are converted to bit-fields shortly after the nonoblock generation, and bits have no names (sad, but true).

<lang racket>#lang racket
(require racket/trace)

(define add1-to-car (match-lambda [(cons (app add1 p1) t) (cons p1 t)]))

;; inputs:
;; cells -- available cells
;; blocks -- list of block widths
;; output:
;; gap-block+gaps
;; where gap-block+gaps is:
;; (list gap) -- a single gap
;; (list gap block-width gap-block+gaps) -- padding to left, a block, right hand side
(define (nonoblock cells blocks)
(match* ((- cells (apply + (length blocks) -1 blocks)) #| padding available on both sides |# blocks)
[(_ (list)) (list (list cells))] ; generates an empty list of padding
[((? negative?) _) null] ; impossible to satisfy
[((and avp
;; use add1 with in-range because we actually want from 0 to available-padding
;; without add1, in-range iterates from 0 to (available-padding - 1)
(app add1 avp+1))
(list block))
(for/list ((l-pad (in-range 0 avp+1)))
(define r-pad (- avp l-pad)) ; what remains goes to right
(list l-pad block r-pad))]
[((app add1 avp+1) (list block more-blocks ...))
(for*/list ((l-pad (in-range 0 avp+1))
(cells-- (in-value (- cells block l-pad 1)))
(r-blocks (in-value (nonoblock cells-- more-blocks)))
(r-block (in-list r-blocks)))
(list* l-pad block (add1-to-car r-block)))])) ; put a single space pad on left of r-block

(define (neat rslt)
(define dots (curryr make-string #\.))
(define Xes (curryr make-string #\X))
(define inr
(match-lambda
[(list 0 (app Xes b) t ...)
(string-append b (inr t))]
[(list (app dots p) (app Xes b) t ...)
(string-append p b (inr t))]
[(list (app dots p)) p]))
(define (neat-row r)
(string-append "|" (inr r) "|"))
(string-join (map neat-row rslt) "\n"))

(define (tst c b)
(define rslt (nonoblock c b))
(define rslt-l (length rslt))
(printf "~a cells, ~a blocks => ~a~%~a~%" c b
(match rslt-l
[0 "impossible"]
[1 "1 solution"]
[(app (curry format "~a solutions") r) r])
(neat rslt)))

(module+ test
(tst 5 '[2 1])
(tst 5 '[])
(tst 10 '[8])
(tst 15 '[2 3 2 3])
(tst 5 '[2 3]))</lang>

{{out}}
<pre>5 cells, (2 1) blocks => 3 solutions
|XX.X.|
|XX..X|
|.XX.X|
5 cells, () blocks => 1 solution
|.....|
10 cells, (8) blocks => 3 solutions
|XXXXXXXX..|
|.XXXXXXXX.|
|..XXXXXXXX|
15 cells, (2 3 2 3) blocks => 15 solutions
|XX.XXX.XX.XXX..|
|XX.XXX.XX..XXX.|
|XX.XXX.XX...XXX|
|XX.XXX..XX.XXX.|
|XX.XXX..XX..XXX|
|XX.XXX...XX.XXX|
|XX..XXX.XX.XXX.|
|XX..XXX.XX..XXX|
|XX..XXX..XX.XXX|
|XX...XXX.XX.XXX|
|.XX.XXX.XX.XXX.|
|.XX.XXX.XX..XXX|
|.XX.XXX..XX.XXX|
|.XX..XXX.XX.XXX|
|..XX.XXX.XX.XXX|
5 cells, (2 3) blocks => impossible
</pre>


=={{header|Ruby}}==
=={{header|Ruby}}==