Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

PROGRAMMING CONTEST #1

Name: Anonymous 2009-12-22 23:22

Write a program that outputs the distance of a unix timestamp from the current time in English (e.g., "5 minutes", "1 day", or "8 years").

Judging will be based on:
1. Efficiency
2. Style
3. Whim
4. Smugness

Please provide a sample of what your program does for the lazy.

Name: Anonymous 2009-12-22 23:29

DYOH

Name: Anonymous 2009-12-22 23:53

#!/usr/bin/perl

$ufn = (3600 * 24 * 14) / 1000000;
$now = time();
$target = $ARGV[0];
$delta = abs($target - $now)/$ufn;

printf("%.0f microfortnights %s\n", $delta, $target>$now?"from now":"ago");

Name: Anonymous 2009-12-22 23:54

>>1
Is using libraries meant for this sort of thing allowed? Some languages even include such functions in the standard lib, making this problem solvable with a one liner, but that would be pointless for a challenge.

Name: Anonymous 2009-12-22 23:58

>>3
I lol'd.

Name: Anonymous 2009-12-23 0:02

Name: Anonymous 2009-12-23 4:03

ENTERPRISE Lisp solution:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (asdf:oos 'asdf:load-op '#:local-time))

(defun seconds-elapsed-from-unix-timestamp (unix-timestamp &optional (from-timestamp (local-time:timestamp-to-unix (local-time:now))))
  "Calculates the difference in seconds, between 2 unix timestamps. If the FROM-TIMESTAMP parameter is not supplied, the current time is used."
  (let* ((elapsed (- from-timestamp unix-timestamp))
         (from-future (< elapsed 0)))
    (values (abs elapsed) from-future)))

(defun decode-seconds (seconds)
  "Decodes a seconds interval into seconds, minutes, hours, days, years."
  (multiple-value-bind (minutes seconds) (truncate seconds 60)
    (multiple-value-bind (hours minutes) (truncate minutes 60)
      (multiple-value-bind (days hours) (truncate hours 24)
        (multiple-value-bind (years days) (truncate days 365)
          (values seconds minutes hours days years))))))

(defmacro aif (test then &optional else)
  "Anaphoric IF macro. Binds the result of evaluating TEST to the local variable IT."
  `(let ((it ,test))
     (declare (ignorable it))
     (if it ,then ,else)))

(defun make-seconds-interval-string (seconds &optional (use-numerals t))
  "Makes an english readable description of the SECONDS parameter.
   USE-NUMERALS specifies wether the numerals should be written using decimals, or english words."
  (labels ((make-time-unit-string (value string)
             (let ((format-string (format nil"~~[~~:;~~:*~~~A ~A~~:p~~]" (if use-numerals "d" "r") string)))
               (format nil format-string value))))
    (aif (remove "" (mapcar #'(lambda (value string)
                                (make-time-unit-string value string))
                            (nreverse (multiple-value-list (decode-seconds seconds)))
                            '("year" "day" "hour" "minute" "second"))
                 :test #'equal)   
         (format nil "~{~#[~;~a~;~a and ~a~:;~@{~a~#[~;, and ~:;, ~]~}~]~}" it))))

(defun format-seconds-elapsed-from-unix-timestamp-in-english (unix-timestamp &key (stream t) use-numerals reference-timestamp)
  "Print an english readable description of the time that has passed since the given UNIX-TIMESTAMP to the stream STREAM (default *standard-output*).
   USE-NUMERALS specifies wether the numerals should be written using decimals, or english words.
   REFERENCE-TIMESTAMP specifies the timestamp from which time has supposedly passed or will pass. Ddefault is current time."
  (multiple-value-bind (elapsed-seconds from-future)
      (apply #'seconds-elapsed-from-unix-timestamp `(,unix-timestamp ,@(when reference-timestamp `(,reference-timestamp))))
    (format stream "~@(~A~) ~A that timestamp."
            (aif (make-seconds-interval-string elapsed-seconds use-numerals) it "no time has")
            (if from-future "will pass to reach" "passed since"))))

;;; Sample usage
#|
CL-USER> (make-seconds-interval-string 1)
"1 second"
CL-USER> (make-seconds-interval-string 100)
"1 minute and 40 seconds"
CL-USER> (make-seconds-interval-string 1000)
"16 minutes and 40 seconds"
CL-USER> (make-seconds-interval-string 9999999)
"115 days, 17 hours, 46 minutes, and 39 seconds"
CL-USER> (make-seconds-interval-string 9999959)
"115 days, 17 hours, 45 minutes, and 59 seconds"
CL-USER> (make-seconds-interval-string 9999960)
"115 days, 17 hours, and 46 minutes"
CL-USER> (make-seconds-interval-string 9999960999)
"317 years, 35 days, 6 hours, 56 minutes, and 39 seconds"
CL-USER> (make-seconds-interval-string (+ (* 60 60 2)))
"2 hours"
CL-USER> (make-seconds-interval-string (+ (* 60 60 2) (* 60 60 24 9)))
"9 days and 2 hours"
CL-USER> (make-seconds-interval-string (+ (* 60 60 2) (* 60 60 24 1)))
"1 day and 2 hours"
CL-USER> (make-seconds-interval-string 9999960999 nil)
"three hundred seventeen years, thirty-five days, six hours, fifty-six minutes, and thirty-nine seconds"
CL-USER> (make-seconds-interval-string (+ (* 60 60 2)) nil)
"two hours"
CL-USER> (make-seconds-interval-string (+ (* 60 60 10)) nil)
"ten hours"
CL-USER> (make-seconds-interval-string (+ (* 60 60 1000)) nil)
"forty-one days and sixteen hours"
CL-USER> (make-seconds-interval-string 0 nil)
NIL
CL-USER> (make-seconds-interval-string 0)
NIL

CL-USER> (format-seconds-elapsed-from-unix-timestamp-in-english 123 :reference-timestamp 123)
No time has passed since that timestamp.
NIL
CL-USER> (format-seconds-elapsed-from-unix-timestamp-in-english 123 :reference-timestamp 124)
One second passed since that timestamp.
NIL
CL-USER> (format-seconds-elapsed-from-unix-timestamp-in-english 9999 :reference-timestamp 124)
Two hours, forty-four minutes, and thirty-five seconds will pass to reach that timestamp.
NIL
CL-USER> (format-seconds-elapsed-from-unix-timestamp-in-english 9999 :reference-timestamp 124 :use-numerals t)
2 hours, 44 minutes, and 35 seconds will pass to reach that timestamp.
NIL
CL-USER> (format-seconds-elapsed-from-unix-timestamp-in-english 9999 :reference-timestamp 124 :use-numerals t)
2 hours, 44 minutes, and 35 seconds will pass to reach that timestamp.
NIL
CL-USER> (+ (* 60 60 2) (* 60 60 24 9))
#xBF9A0
CL-USER> (format-seconds-elapsed-from-unix-timestamp-in-english #xBF9A0 :reference-timestamp 0 :use-numerals t)
9 days and 2 hours will pass to reach that timestamp.
NIL
CL-USER> (format-seconds-elapsed-from-unix-timestamp-in-english 0 :reference-timestamp #xBF9A0)
Nine days and two hours passed since that timestamp.
NIL
CL-USER> (format-seconds-elapsed-from-unix-timestamp-in-english 0)
Forty years, one day, sixteen hours, forty-eight minutes, and twenty-four seconds passed since that timestamp.
NIL
|#

Name: Anonymous 2009-12-23 5:06

HAX MY LISP

Name: Anonymous 2009-12-23 5:07

>>7
Oh, jeez, I've never seen "macro-fu" and "enterprise" together.
My life is complete.

Name: Anonymous 2009-12-23 5:12

>9
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))


this is all i understand

Name: 7 2009-12-23 7:35

Refactored my previous code a little:

The DECODE-SECONDS function seemed a bit repetitive, so I've abstracted the functionality into a macro:

(defmacro with-measurement-units (source unit-bindings &body body)
  (destructuring-bind (first second . rest) unit-bindings
    (let ((units (list (car first) (car second))))
          `(multiple-value-bind ,(reverse units) (truncate ,source ,(second first))
             ,@(if rest
                   `((with-measurement-units ,(second units) ,(cons second rest) ,@body))
                   body)))))

(defun decode-seconds (seconds)
  (with-measurement-units seconds ((seconds 60) (minutes 60) (hours 24) (days 365) (years))
    (values seconds minutes hours days years)))

Removed a local function that was only used once:

(defun make-seconds-interval-string (seconds &optional (use-numerals t))
  "Makes an english readable description of the SECONDS parameter.
   USE-NUMERALS specifies wether the numerals should be written using decimals, or english words." 
  (aif (remove "" (mapcar #'(lambda (value string)                               
                              (format nil (format nil "~~[~~:;~~:*~~~A ~A~~:p~~]" (if use-numerals "d" "r") string) value))
                          (nreverse (multiple-value-list (decode-seconds seconds)))
                          '("year" "day" "hour" "minute" "second"))
               :test #'equal)   
       (format nil "~{~#[~;~a~;~a and ~a~:;~@{~a~#[~;, and ~:;, ~]~}~]~}" it)))

Name: Anonymous 2009-12-23 8:35

>>10
Maybe you should hang at reddit, then.

Name: Anonymous 2009-12-23 9:00

>>14 is a nigger

Name: Anonymous 2009-12-23 9:34

>>13
Back to /b/, please.

Name: Anonymous 2010-12-28 13:18

Name: Anonymous 2013-08-31 20:28


If theres ever a fire, the first thing you want to do is not get ran over by a crowed, pick up a char or desk or anything heavy and throw threw the window, this will give you a faster exit point and help remove smoke so people can breath.

Name: Anonymous 2013-08-31 21:59


ワロタwwww

Don't change these.
Name: Email:
Entire Thread Thread List