You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: integer-to-english/README.org
+102-3
Original file line number
Diff line number
Diff line change
@@ -23,6 +23,8 @@ Input: num = 1234567
23
23
Output: "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
24
24
25
25
* Brainstorming
26
+
What's the max here? That detemrmines how many decimal place value names I have to hard code src_emacs-lisp[]{(expt 2 31)} {{{results(=2147483648=)}}}. Ok, so that's just "billions", easy.
27
+
26
28
Let's see if we can just say the rules in english and I'll try to avoid saying that the right answer is just to throw it at ChatGPT.
27
29
28
30
I'm thinking about examining the number form the back forward
@@ -103,7 +105,7 @@ Clearly I'm going to need to do pattern matching, lets see how it looks in ruby
@@ -236,4 +244,95 @@ now this can be simplified to the following. Here we alias our new ~three_digits
236
244
- for a 9 digit number its ~(dte d123) million (6dte d456789)~ - we'll alias this to 9dte
237
245
- for a 10 digit number its ~(dte d1) billion (9dte d234567890)~
238
246
239
-
So now, we just know the breaks and teh word associated to each of the breaks and then we do something like ~(dte head..break) word rest~
247
+
So now, we just know the breaks and the word associated to each of the breaks and then we do something like ~(dte head..break) word rest~
248
+
249
+
Ok so lets do that. There's the question of what the structure for those breaks/word associations should look like. While we could do an array or a hash, because we're always processing it from highest break to lowest I think the best approach is more like a linked list as it can be unrolled more easily. Quick google tells me Ruby has one-line structs that can be used for this. Note that we have special handling for "hundreds and below" already so no need to go lower
250
+
251
+
#+name: dynamic-place-name
252
+
#+begin_src ruby :results silent :session
253
+
PlaceName = Struct.new(:place, :name, :next)
254
+
ALL_PLACE_NAMES = PlaceName.new(10, "billion",
255
+
PlaceName.new(7, "million",
256
+
PlaceName.new(4, "thousand")))
257
+
#+end_src
258
+
259
+
Note the capitalization here is interesting. I got stuck on it for a bit. In ruby - unlike other languages - all caps matters for making your variable visible down the scope chain
260
+
261
+
We're almost there, we can now unroll this across all our digits
262
+
263
+
There's one gocha here, in that if the next set of digits are all 0, then we don't want to say anything. This will allow us to handle situations like =10000= recursively without saying the "hundred" that you *would* say if you've got a number like =100= or =10100=
264
+
265
+
#+name: many-digits-to-english
266
+
#+begin_src ruby :results silent :session
267
+
def many_digits_to_english(digits, place_name)
268
+
if digits.all? { |d| d == "0" } # the hundreds in 1000
269
+
""
270
+
elsif not place_name # terminal condition and when 3 digit or lower
271
+
three_digits_to_english digits
272
+
elsif digits.length < place_name.place # when not in the billions and need to get down to the place name that matters
273
+
many_digits_to_english(digits, place_name.next)
274
+
else
275
+
split_at = digits.length - place_name.place
276
+
place_digits = digits[0..split_at]
277
+
rest_digits = digits[(split_at + 1)..-1]
278
+
if place_digits.all? { |d| d == "0" } # situations like 1000001
0 commit comments