Welcome to the CHICKEN Scheme pasting service

Parsing YouTube timestamps pasted by wasamasa on Tue Dec 1 22:20:07 2015

(use (only srfi-14 char-set:digit)
     comparse)

(define digit
  (in char-set:digit))

(define (as-number parser)
  (bind (as-string parser)
        (lambda (s)
          (result (string->number s)))))

(define digits
  (as-number (one-or-more digit)))

(define timestamp-hours
  (followed-by digits (is #\h)))

(define timestamp-minutes
  (followed-by digits (is #\m)))

(define timestamp-seconds
  (followed-by digits (is #\s)))

(define (maybe* parser)
  (any-of parser item))

(define timestamp
  (sequence* ((hours (maybe timestamp-hours))
              (minutes (maybe timestamp-minutes))
              (seconds timestamp-seconds))
    (result (list (or hours 0) (or minutes 0) seconds))))

;; expected: (0 0 1)
;; actual: (0 0 1)
(parse timestamp "1s")

;; expected: (0 1 2)
;; actual: #f
(parse timestamp "1m2s")

;; expected: (1 2 3)
;; actual: #f
(parse timestamp "1h2m3s")

Fixed version pasted by wasamasa on Tue Dec 1 23:03:59 2015

(use (only srfi-14 char-set:digit)
     comparse)

(define digit
  (in char-set:digit))

(define (as-number parser)
  (bind (as-string parser)
        (lambda (s)
          (result (string->number s)))))

(define digits
  (as-number (one-or-more digit)))

(define timestamp-hours
  (sequence* ((hours digits)
              (_ (is #\h)))
    (result hours)))

(define timestamp-minutes
  (sequence* ((minutes digits)
              (_ (is #\m)))
    (result minutes)))

(define timestamp-seconds
  (sequence* ((seconds digits)
              (_ (is #\s)))
    (result seconds)))

(define timestamp
  (sequence* ((hours (maybe timestamp-hours))
              (minutes (maybe timestamp-minutes))
              (seconds timestamp-seconds))
    (result (list (or hours 0) (or minutes 0) seconds))))

(define (parse-timestamp input)
  (parse (followed-by timestamp end-of-input) input))

(parse-timestamp "1s") ;=> (0 0 1)
(parse-timestamp "1m2s") ;=> (0 1 2)
(parse-timestamp "1h2m3s") ;=> (1 2 3)

Cleaned up version pasted by wasamasa on Tue Dec 1 23:16:21 2015

(define digit
  (in char-set:digit))

(define (as-number parser)
  (bind (as-string parser)
        (lambda (s)
          (result (string->number s)))))

(define digits
  (as-number (one-or-more digit)))

(define (number-unit suffix)
  (sequence* ((number digits)
              (_ (is suffix)))
    (result number)))

(define timestamp-hours
  (number-unit #\h))

(define timestamp-minutes
  (number-unit #\m))

(define timestamp-seconds
  (number-unit #\s))

(define timestamp
  (sequence* ((hours (maybe timestamp-hours 0))
              (minutes (maybe timestamp-minutes 0))
              (seconds timestamp-seconds))
    (result (list hours minutes seconds))))

(define (parse-timestamp input)
  (parse (followed-by timestamp end-of-input) input))

(parse-timestamp "1s") ;=> (0 0 1)
(parse-timestamp "1m2s") ;=> (0 1 2)
(parse-timestamp "1h2m3s") ;=> (1 2 3)

(define (timestamp-to-seconds timestamp)
  (if timestamp
      (+ (* (car timestamp) 60 60)
         (* (cadr timestamp) 60)
         (list-ref timestamp 2))
      0))

(timestamp-to-seconds (parse-timestamp "1y")) ;=> 0
(timestamp-to-seconds (parse-timestamp "1s")) ;=> 1
(timestamp-to-seconds (parse-timestamp "1m2s")) ;=> 62
(timestamp-to-seconds (parse-timestamp "1h2m3s")) ;=> 3723

wasamasa: functional timestamp->seconds :-) pasted by DerGuteMoritz on Wed Dec 2 11:12:50 2015

(define (timestamp->seconds timestamp)
  (fold + 0 (map * (or timestamp '()) '(3600 60 1))))

if you really like it functional ;-) pasted by florz on Wed Dec 2 12:15:07 2015

(define (parse-timestamp input)
  (parse
    (bind
      (followed-by
        (sequence
          (map
            (lambda (suffix p)
              (maybe
                (sequence* ((number (as-string (one-or-more (in char-set:digit))))
                            (_ (char-seq (symbol->string suffix))))
                           (result (* (string->number number) (expt 60 p))))
                0))
            '(h m s)
            (reverse (iota 3))))
        end-of-input)
      (o result (cut fold + 0 <>)))
    input))

or maybe slightly cleaner pasted by florz on Wed Dec 2 12:19:18 2015

(define (parse-timestamp input)
  (let ((units '(h m s)))
    (parse
      (bind
        (followed-by
          (sequence
            (map
              (lambda (suffix p)
                (maybe
                  (sequence* ((number (as-string (one-or-more (in char-set:digit))))
                              (_ (char-seq (symbol->string suffix))))
                             (result (* (string->number number) (expt 60 p))))
                  0))
              units
              (reverse (iota (length units)))))
          end-of-input)
        (o result (cut fold + 0 <>)))
      input)))

Just match it pasted by wasamasa on Wed Dec 2 12:23:50 2015

(define timestamp->seconds
  (match-lambda*
   ((#f) 0)
   (((hours minutes seconds))
     (+ (* hours 3600)
        (* minutes 60)
        seconds))))

use type checking (at runtime) pasted by C-Keen on Wed Dec 2 12:41:25 2015

(define timestamp->seconds
  (match-lambda*
   ((#f) 0)
   (((and (hours minutes seconds)
          (? (lambda (l) (every number? l)))))
     (+ (* hours 3600)
        (* minutes 60)
        seconds))))

using match-lambda and another way to do runtime type checks in a pattern added by DerGuteMoritz on Wed Dec 2 12:57:45 2015

(define timestamp->seconds
        (match-lambda
          (#f 0)
          (((? number? hours) (? number? minutes) (? number? seconds))
           (+ (* hours 3600)
              (* minutes 60)
              seconds))))

Your annotation:

Enter a new annotation:

Your nick:
The title of your paste:
Your paste (mandatory) :
Which R5RS procedure returns `'(2 3)' when given `'(1 2 3)' as input?
Visually impaired? Let me spell it for you (wav file) download WAV