🎉 Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io 🎉
Avatar of n0mn0m

n0mn0m's solution

to Robot Name in the Racket Track

Published at Oct 29 2020 · 0 comments
Instructions
Test suite
Solution

Manage robot factory settings.

When robots come off the factory floor, they have no name.

The first time you boot them up, a random name is generated in the format of two uppercase letters followed by three digits, such as RX837 or BC811.

Every once in a while we need to reset a robot to its factory settings, which means that their name gets wiped. The next time you ask, it will respond with a new random name.

The names must be random: they should not follow a predictable sequence. Random names means a risk of collisions. Your solution must ensure that every existing robot has a unique name.


For installation and learning resources, refer to the exercism Racket page.

You can run the provided tests through DrRacket, or via the command line.

To run the test through DrRacket, simply open the test file and click the 'Run' button in the upper right.

To run the test from the command line, run the test from the exercise directory with the following command:

raco test robot-name-test.rkt

which will display the following:

raco test: (submod "robot-name-test.rkt" test)
2 success(es) 0 failure(s) 0 error(s) 2 test(s) run
0
2 tests passed

Source

A debugging session with Paul Blackwell at gSchool. http://gschool.it

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

robot-name-test.rkt

#lang racket/base

; There were no cannonical tests to perform.
(require "robot-name.rkt")

(module+ test
  (require rackunit
           rackunit/text-ui)

  (define max-names (* 26 26 10 10 10))

  (define proper-robot-name #px"\\p{Lu}{2}\\p{Nd}{3}")

  (define (check-proper-robot-name r)
    (check-regexp-match proper-robot-name (name r)))

  (define robot-name-suite
    (test-suite
     "Check proper operation of 'robots'"

     (test-case
      "Check that robot names conforms to the expected standard."
      (check-proper-robot-name (make-robot)))

     (test-case
      "Check that resetting a robot name also gives a proper name."
      (let* ([robby (make-robot)]
             [name1 (name robby)]
             [_ (reset! robby)]
             [name2 (name robby)])
        (and
         (and (check-regexp-match proper-robot-name name1)
              (check-regexp-match proper-robot-name name2))
         (not (string=? name1 name2)))))

     ;; reset cache in order to generate all the names
     (test-case
      "Check that robots are created with unique names."
      (begin
        (reset-name-cache!)
        (= max-names
           (let ([names (make-hash)])
             (for ((_ (in-range (/ max-names 4))))
               (hash-set! names (name (make-robot)) #t))
             (hash-count names)))))))

    (run-tests robot-name-suite))
#lang racket

(provide make-robot
         name
         reset!
         reset-name-cache!)

(define robot-set (mutable-set))

(define (make-robot)
  (let ([name (random-name)])
    (if (set-member? robot-set name) (make-robot) (begin (set-add! robot-set name) name))))

(define (name robot) robot)

(define (reset! robot) (set-remove! robot-set robot) (make-robot))

(define (reset-name-cache!) (set-clear! robot-set))

; functions to help generate a robot name
(define (random-char ascii-start ascii-end) (integer->char (random ascii-start ascii-end)))
; asciitable.com
(define (random-letter) (random-char 65 91))
(define (random-number) (random-char 48 58))
(define (random-name) (string (random-letter) (random-letter) (random-number) (random-number) (random-number)))

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?