tags:

views:

105

answers:

3

I'm trying to bind the following grid to a symbol

(def grid [08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
           49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
           81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
           52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
           22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
           24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
           32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
           67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
           24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
           21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
           78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
           16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
           86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
           19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
           04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
           88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
           04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
           20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
           20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
           01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48])

This yields Exception in thread "main" java.lang.NumberFormatException: Invalid number: 08 (11.clj:1). Why can't I do this in Clojure? Are there any workarounds?


Clarification

All I want to do is paste this grid somewhere and have it act as if there were no leading zeros, even if it takes a little coercion. I don't want to have to drop all of the zeros in my editor, I'd just like to paste it in there and have each number behave as if there were no leading zeros.


One other strange detail

The REPL seems to allow zero-padded numbers, but executing a .clj file with java -cp clojure.jar -i some_file.clj will throw the error.

+5  A: 

Leading zeros imply an octal number, so 08 is not valid. Many programming languages use this convention, starting with C.

Ned Batchelder
I hate this convention, sadly no matter how much I hate it it won't go away...
Carson Myers
Yes, it seems completely archaic. Perhaps left-pad with spaces?
Ned Batchelder
+1  A: 

numbers with a leading 0 are read as if they where in base 8 so any charcter not between 0-7 will not work. to fix this you can append 10r08 to explicity specify the base.

user> 10r08
8
user> 08
; Evaluation aborted.

This messes up your nice formatting though :( sorry about that. you could write a little macro to change this for a block if you want to preserve your nicely formatted code.

Arthur Ulfeldt
A macro cannot do anything about read-time exceptions, since macros are expanded after the reader is done with its job. E.g. after `(defmacro foo [x] nil)`, `(foo 123)` evaluates to `nil`, but `(foo 08)` throws an exception (a funny "two-level" exception, in fact, nicely illustrating the recursive workings of the reader).
Michał Marczyk
+1  A: 

SPOILER ALERT:

Since you're solving a Project Euler problem, you might not want to read this, even though it's only about the "how to read in the data?" part of it...


The reason this happens is as explained in the other answers. The correct solution would be to embed the input in your code as a string -- with linebreaks! -- and use something like the following:

(->> the-string
     (.split #"\n")
     (map #(.split #"\s+" %))
     (map (partial drop-while empty?))
     ;; this just doesn't care about the leading 0
     (mapcat (partial map #(Integer/parseInt %)))
     vec)

This should produce a vector of your numbers. For a two-dimentional vector, you could replace the mapcat with a regular map and put in an extra (map vec) before the final vec.

If you prefer to put the input in a separate file and have Clojure read it from there, replace the-string and (.split #"\n") with a call to line-seq on a reader on your file.x

Michał Marczyk
I'm having some problems using the `->>` method: `Exception in thread "main" java.lang.Exception: Unable to resolve symbol: ->> in this context (11.clj:25)`
Blaine LaFreniere
I don't think the ->> existed until Clojure 1.1. You might be using an ancient version of Clojure.
Rayne
Yeah, I'm using Clojure 1.0.0 via the Ubuntu repositories
Blaine LaFreniere
does the `(partial drop-while empty?)` strip whitespace? I can't figure out what it's supposed to do.
Blaine LaFreniere
Nevermind, I understand it now
Blaine LaFreniere