Как бы я создать отрицательную двоичную функцию в ракетке - PullRequest
0 голосов
/ 26 февраля 2020

Я не совсем понимаю, как подойти к этой функции

Функция negate-binary использует список натуральных чисел, alist, и создает список, содержащий те, которые дополняют числа в списке, которые являются действительными двоичными числами. числа (то есть числа, которые содержат только 0 и 1).

Номера дополнений в создаваемом списке должны быть в том же порядке, что и исходные двоичные числа в alist.

Предположим, что ни одно из чисел не имеет ведущих нулей; другими словами, alist не будет содержать никаких чисел, таких как 0001

  • число-> строка и строка-> число может быть полезным *
(negate-binary (list 1000 101010 123 111)) ⇒ (list 111 10101 0)
(negate-binary (list 95 137 401)) ⇒ empty


1 Ответ

0 голосов
/ 26 февраля 2020
#lang racket

; 1String is a String of length 1.

; [List-of Number] -> [List-of Number]
(define (negate-binary lon)
  (map ones-complement (filter is-binary? lon)))

; Number -> Boolean
; is `num` a binary number?
(define (is-binary? num)  
  (andmap is-binary-1string? (num->1string-list num)))

; Number -> [List-of 1String]
; number to a list of 1strings
(define (num->1string-list num)
  (explode (number->string num)))

; String -> [List-of 1String]
; convert a string to a list of 1strings
(define (explode str)
  (map string (string->list str)))

; 1String -> Boolean
; is 1string a binary 1string?
(define (is-binary-1string? 1string)
  (or (string=? 1string "0") (string=? 1string "1")))

; Number -> Number
; one's complement of a number
(define (ones-complement num)
  (str-list->number (flip-bits (num->1string-list num))))

; [List-of 1String] -> [List-of 1String]
; "0" to "1" and "1" to "0" in list of 1strings
(define (flip-bits lo1s)
  (map flip-bit lo1s))

; 1String -> 1String
; convert "0" to "1" and "1" to "0"
(define (flip-bit 1string)
  (if (string=? 1string "0") "1" "0"))

; [List-of 1String] -> Number
; convert the list of 1strings to a number
(define (str-list->number lo1s)
  (string->number (apply string-append lo1s)))


(module+ test
  (require rackunit)
  (check-equal? (negate-binary (list 1000 101010 123 111)) (list 111 10101 0))
  (check-equal? (negate-binary (list 95 137 401)) empty))

Редактировать : удалены все абстракции списка высшего порядка, такие как map, andmap, filter и apply.

#lang racket

; 1String is a String of length 1.

; [List-of Number] -> [List-of Number]
(define (negate-binary lon)
  (ones-complement* (binary-only lon)))

; [List-of Number] -> [List-of Number]
; only keep the binary numbers
(define (binary-only lon)
  (cond
    [(empty? lon) '()]
    [else (if (is-binary? (first lon))
              (cons (first lon) (binary-only (rest lon)))
              (binary-only (rest lon)))]))

; [List-of Number] -> [List-of Number]
; one's complement for all numbers in lon
(define (ones-complement* lon)
  (cond
    [(empty? lon) '()]
    [else (cons (ones-complement (first lon))
                (ones-complement* (rest lon)))]))

; Number -> Boolean
; is `num` a binary number?
(define (is-binary? num)  
  (all-binary-1strings? (num->1string-list num)))

; [List-of 1String] -> Boolean
; are all 1strings in lo1s binary?
(define (all-binary-1strings? lo1s)
  (cond
    [(empty? lo1s) #true]
    [else (and (is-binary-1string? (first lo1s))
               (all-binary-1strings? (rest lo1s)))]))

; Number -> [List-of 1String]
; number to a list of 1strings
(define (num->1string-list num)
  (explode (number->string num)))

; String -> [List-of 1String]
; convert a string to a list of 1strings
(define (explode str)
  (charlist->string-list (string->list str)))

; [List-of Char] -> [List-of 1String]
; convert a list of characters to a list of 1strings
(define (charlist->string-list charlist)
  (cond
    [(empty? charlist) '()]
    [else (cons (string (first charlist))
                (charlist->string-list (rest charlist)))]))

; 1String -> Boolean
; is 1string a binary 1string?
(define (is-binary-1string? 1string)
  (or (string=? 1string "0") (string=? 1string "1")))

; Number -> Number
; one's complement of a number
(define (ones-complement num)
  (str-list->number (flip-bits (num->1string-list num))))

; [List-of 1String] -> [List-of 1String]
; "0" to "1" and "1" to "0" in list of 1strings
(define (flip-bits lo1s)
  (flip-all-bits lo1s))

; [List-of 1String] -> [List-of 1String]
; flip bits of all 1strings in lo1s
(define (flip-all-bits lo1s)
  (cond
    [(empty? lo1s) '()]
    [else (cons (flip-bit (first lo1s))
                (flip-all-bits (rest lo1s)))]))

; 1String -> 1String
; convert "0" to "1" and "1" to "0"
(define (flip-bit 1string)
  (if (string=? 1string "0") "1" "0"))

; [List-of 1String] -> Number
; convert the list of 1strings to a number
(define (str-list->number lo1s)
  (string->number (join-all lo1s)))

; [List-of 1String] -> String
; join all 1strings in lo1s into a single string
(define (join-all lo1s)
  (cond
    [(empty? lo1s) ""]
    [else (string-append (first lo1s)
                         (join-all (rest lo1s)))]))


(module+ test
  (require rackunit)
  (check-equal? (negate-binary (list 1000 101010 123 111)) (list 111 10101 0))
  (check-equal? (negate-binary (list 95 137 401)) empty))
...