Sorry for reviving an old thread. As someone who did a lot of programming
competition in the past, I can totally see why IO in Racket is difficult. As
mark.engelberg said, the goal is to solve as many problems as possible. After
the competition is over, it's over. No one is going to care about
maintainability or good coding practice if it makes coding slower. For this
reason, I wouldn't use parsack if possible. While elegant, there's too much to
write which is a waste of time.
Luckily, major programming competitions (say, Facebook Hacker Cup, Google Code
Jam, early IOI, ACM-ICPC, etc.) usually have simple input format. Data are
usually separated by spaces. Rarely spaces matter. rom gcb says that the input
is:
3
[04, foo, 03.5]
[05, bar, 04.6]
[06, fun, 05.7]
but in these competitions, the input is more likely to be:
3
04 foo 03.5
05 bar 04.6
06 fun 05.7
What really gets in the way is that strings in the input could be something
that Racket's (read) doesn't recognize. As an example, a string might be #asd.
This would cause (read) to error "read: bad syntax `#a'".
Indeed, using (read-line) along with regex would solve the problem. The
downside is that it requires a lot of writing and is heavily task-dependent.
What I want is a uniform way to extract data easily like scanf.
I write the following module for this purpose. It's a lot of code, so it would
be useless in closed competitions like ACM-ICPC. However, for online
competitions like FB Hacker Cup, I find it pretty useful.
#lang racket
(provide (all-defined-out))
(define read-next
(let ([buffer #f])
(lambda (#:to-eol [to-eol #f])
(define (more!) (set! buffer (read-line)) (read-next #:to-eol to-eol))
(match buffer
[(? string?)
(cond
[to-eol (let ([ret buffer]) (set! buffer #f) ret)]
[else
(set! buffer (string-trim buffer #:right? #f))
(match (regexp-match #px"\\S+" buffer)
[(list ret) (set! buffer (regexp-replace #px"^\\S+" buffer ""))
ret]
[#f (more!)])])]
[_ (more!)]))))
(define (%list n typ) (thunk (for/list ([_ n]) (typ))))
(define (%gets) (read-next #:to-eol #t))
(define (%num) (string->number (read-next)))
(define (%str) (read-next))
(define-syntax-rule (scan [v m] ...) (begin (define v (m)) ...))
(module+ test
(require rackunit)
(parameterize
([current-input-port
(open-input-string
(string-append " 2 3 \n"
"1 2 3\n"
" 4 5 6 \n"
" \n"
" \n"
" \n"
"\n"
" '\"has-quotes\"' blah blah "))])
(scan [n %num]
[m %num]
[matrix (%list n (%list m %num))]
[trailing-spaces %gets]
[str-with-quotes %str]
[line-with-space %gets])
(check-equal? n 2)
(check-equal? m 3)
(check-equal? matrix (list (list 1 2 3) (list 4 5 6)))
(check-equal? trailing-spaces " ")
(check-equal? str-with-quotes "'\"has-quotes\"'")
(check-equal? line-with-space " blah blah ")))
For example, https://code.google.com/codejam/contest/6254486/dashboard#s=p1 can
be solved as follows:
(scan [n %num])
(for ([i n])
(scan [s %str])
(define simp (regexp-replaces s '([#px"\\++" "+"] [#px"\\-+" "-"])))
(define len (string-length simp))
(printf "Case #~a: ~a\n"
(add1 i)
(match (list (string-ref simp 0) (even? len))
[(or (list #\+ #t) (list #\- #f)) len]
[(or (list #\+ #f) (list #\- #t)) (sub1 len)])))
--
You received this message because you are subscribed to the Google Groups
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.