Reputation: 45
i would like to ask you for help with my task i am trying to solve. Function should work like this. Input is sublist ((1 10 250) (1 10 250) (250 10 250) (1 10 255)))
and output should be ((1 . 3) (10 . 4) (250 . 4) (255 . 1))
so it output is actually histogram in text format.
I am using this code with implementation of flatten
function which is making from sublists one list. But it is counting number of sublists and not every element in sublist.
(define (run-length-encode lst )
(define (rle val-lst cur-val cur-cnt acc)
(if (pair? val-lst)
(let ((new-val (car val-lst)))
(if (eq? new-val cur-val)
(rle (cdr val-lst) cur-val (+ cur-cnt 1) acc)
(rle (cdr val-lst) new-val 1 (cons (cons cur-cnt cur-val) acc))))
(cons (cons cur-cnt cur-val) acc)))
(if (pair? lst)
(reverse (rle (cdr lst) (car lst) 1 '()))
'()))
Flatten function:
(define (flatten lst)
(if (not (list? lst))
(list lst)
(apply append (map flatten lst))))
Output:
> (run-length-encode '((1 10 250) (1 10 250) (250 10 250) (1 10 255)))
(250 10 1 1 250 10 1 1 250 10 250 1 255 10 1 1)
Thanks for help on this. Jan
Upvotes: 1
Views: 242
Reputation: 235994
In Racket there's a built-in flatten
procedure, there's no need to rewrite it. Coupled with good old bagify
, we can solve the problem using simple procedure composition - you should avoid trying to do everything in a single procedure, it'll be confusing:
#lang racket
(define (bagify lst)
(foldl (lambda (key ht)
(hash-update ht key add1 0))
#hash() lst))
(define (run-length-encode lst)
(hash->list
(bagify (flatten lst))))
It works as expected:
(run-length-encode '((1 10 250) (1 10 250) (250 10 250) (1 10 255)))
=> '((1 . 3) (250 . 4) (10 . 4) (255 . 1))
Upvotes: 1