Interpret numbers very literally

37

2

To interpret a positive integer very literally, write it in English words (without "and"), replace hyphens with spaces, replace each resulting word with its number value, and concatenate the results into a single number.

To write a positive integer more than 99 but less than 1000 in English words, prefix its last two digits written in English with [first digit in English]hundred with a trailing space.

To write a positive integer more than 999 but less than 1 million in English words, use the following syntax: [part before the last 3 digits in English]thousand[last 3 digits in English], all separated by spaces.

The task is to input a positive integer (less than 1 million) and output it, interpreted very literally.

Examples

1 -> 1                       (one)
10 -> 10                     (ten)
16 -> 16                     (sixteen)
23 -> 203                    (twenty three)
111 -> 110011                (one hundred eleven)
123 -> 1100203               (one hundred twenty three)
1234 -> 110002100304         (one thousand two hundred thirty four)
12345 -> 1210003100405       (twelve thousand three hundred forty five)
123456 -> 110020310004100506 (one hundred twenty three thousand four hundred fifty six)
1056 -> 11000506             (one thousand fifty six)
101101 -> 11001100011001     (one hundred one thousand one hundred one)
110110 -> 1100101000110010   (one hundred ten thousand one hundred ten)

Feel free to add more test cases if necessary.

This is tagged , so the shortest code wins.

my pronoun is monicareinstate

Posted 2019-11-01T13:48:59.830

Reputation: 3 111

Link to deleted sandbox post – my pronoun is monicareinstate – 2019-11-01T13:49:57.013

May I suggest a couple test cases where there are 0s in the middle of the number? e.g. 1056 -> 11000506 – Business Cat – 2019-11-01T15:47:00.960

Also, what output should be given for 100? I would assume it should be 1100 (one hundred)? – Business Cat – 2019-11-01T16:01:34.900

@BusinessCat That's correct. I will add some more test cases later. – my pronoun is monicareinstate – 2019-11-01T16:13:19.413

Answers

2

05AB1E, 26 23 21 bytes

₄вεтвεSÐP@θ1Ký0Û]тý₄ý

Port of @Neil's Charcoal answer, so make sure to upvote him as well.
-5 bytes thanks to @Grimy.

Try it online or verify all test cases.

Explanation:

₄в                # Convert the (implicit) input-integer to base-1000 as list
                  #  i.e. 119100 → [119,100]
                  #  i.e. 23 → [23]
  ε               # Map each value to:
   тв             #  Convert the value to base-100 as list
                  #   i.e. [119,100] → [[1,19],[1,0]]
                  #   i.e. [23] → [[23]]
     ε            #  Map each value `y` to:
      S           #   Convert the current value to a list of digits
                  #    i.e. [[1,19],[1,0]] → [[[1],[1,9]],[[1],[0]]]
                  #    i.e. [[23]] → [[[2,3]]]
       Ð          #   Triplicate this list
        P         #   Take the product of each inner list of digits
                  #    i.e. [[[1],[1,9]],[[1],[0]]] → [[[1],[9]],[[1],[0]]
                  #    i.e. [[[2,3]]] → [[6]]
         @        #   Check if it's larger than or equal to each digit
                  #    i.e. [[[1],[1,9]],[[1],[0]]] and [[[1],[9]],[[1],[0]]
                  #     → [[[1],[1,1]],[[1],[1]]]
                  #    i.e. [[[2,3]]] and [[6]] → [[[0,0]]]
          θ       #   Keep only the last check of each
                  #    i.e. [[[1],[1,1]],[[1],[1]]] → [[[1],[1]],[[1],[1]]]
                  #    i.e. [[[0]]]
           1K     #   Remove all 1s from each 'string'
                  #    i.e. [[[1],[1]],[[1],[1]]] → [[[""],[""]],[[""],[""]]]
                  #    i.e. [[["0"]]]
             ý    #   Join the list of digits by this string
                  #    i.e. [[[1],[1,9]],[[1],[0]]] and [["",""],["",""]]→ [[1,19],[1,0]]
                  #    i.e. [[[2,3]]] and [["0"]] → [[203]]
      0Û          #   Remove any trailing 0s
                  #    i.e. [[1,19],[1,0]] → [[1,19],[1,""]]
                  #    i.e. [[203]] → [[203]]
  ]               # Close both maps
   тý             # Join the inner lists by "100"
                  #  i.e. [[1,19],[1,""]] → [110019,1100]
                  #  i.e. [[203]] → [203]
     ₄ý           # And then those strings by "1000"
                  #  i.e. [110019,1100] → 11001910001100
                  #  i.e. [203] → 203
                  # (after which the result is output implicitly)

Kevin Cruijssen

Posted 2019-11-01T13:48:59.830

Reputation: 67 575

1yĀ× to , y20›yθĀ* to ySPyθ›. TIO. – Grimmy – 2019-11-04T17:47:59.153

1@Grimmy Thanks. That ySPyθ› is smart! :D Too bad the duplicated yS cannot be golfed. I saw a few alternatives, but all the same byte-count. Unless you know an alternative for the 0#× for "0" if truthy; "" if falsey? – Kevin Cruijssen – 2019-11-04T18:24:34.140

1

Actually the duplicated yS can be golfed: 22. EDIT: 21.

– Grimmy – 2019-11-04T22:54:46.783

1@Grimmy Ah, that 21 is smart. First doing the >= check, and only then getting the last value. And also that 1K for "0" or "". Nice one! – Kevin Cruijssen – 2019-11-05T08:12:38.190

2@Grimmy I like that replacement of ">20 and >0 (mod 10)" with "digitial product exceeds last digit" - it saved me two bytes on my Charcoal answer too, thanks! – Neil – 2019-11-06T21:37:00.920

12

Python 2, 76 bytes

f=lambda n,k=1000:n>19and(f(n/k,k/10)+`k-k%4*5`)*(n>=k)+f(n%k,k/10)or`n`[:n]

Try it online!

Test suite from Chas Brown.

A fully recursive solution that splits on place values k=1000, k=100, and k=10. The separator for the place values is computed as k-k%4*5, which maps

1000 -> 1000
100  -> 100
10   -> 0

By stopping when n<=19, we avoid one-word numbers in the teens being split up.

xnor

Posted 2019-11-01T13:48:59.830

Reputation: 115 687

4

Gaia, 44 43 bytes

:(!>
ℍZ:₸Z¤1>∧'0פṙ$×:dẏ×,↑ℍṙ×
@3eZ,↑¦↓3eṙ×

Longer than my original answer, but it works now.

fixed my code again but now it's twice as sad

Try it online!

@3eZ,↑¦↓3eṙ×  Main function.
@3eZ          Input divmod 1000, pushes input div 1000 then input mod 1000
    ,         Pair those two value into a list
     ↑¦       Run the upper function on both
       ↓      Call the function below (loops to top function)
        3eṙ   The string "1000"
           ×  Join the list with "1000"

ℍZ:₸Z¤1>∧'0פṙ$×:dẏ×,↑ℍṙ×  Helper function. Called with 1 argument.
ℍZ                          Divmod with 100
  :₸Z                       Copy the mod part and divmod with 10
                            Stack is: [100s digit, arg mod 100, 10s digit, 1s digit]
     ¤1>                    Bring 10s digit to the top and check if it's greater than 1
        ∧                   Logical AND with 1s digit. (results in 0 or 1)
         '0×                Multiply the character 0 by that result
            ¤               Bring 'arg mod 100' to the top
             ṙ$             Get its string representation and split it into characters
                            (simply doing digit list doesn't work in the case it's 0)
               ×            Join this with the multiplied '0' string
                :d          Copy and parse as a number
                  ẏ         Is it positive? (0 or 1)
                   ×        Multiply the string of the number by that result.
                    ,       Pair: gives the list [100s digit, string from above]
                     ↑      Call the function above
                      >     Remove the first ^ elements from the pair
                       ℍṙ×  Join the resulting list with the string "100"

:(!>  Helper function 2. In this program it is only called with a list.
:(    Copy and get the first element.
  !   Boolean negate (0 or 1)
   >  Remove that many characters from the start of the list

Business Cat

Posted 2019-11-01T13:48:59.830

Reputation: 8 927

3

PHP, 137 136 143 bytes

function f($n){return$n>99?$n>999?f(substr($n,0,-3)).(1e3).f(substr($n,-3)):$n[0].'100'.f($n[1].$n[2]):($n>20&&$n%10?(0^$n/10).'0'.$n[1]:+$n);}

Try it online!

Night2

Posted 2019-11-01T13:48:59.830

Reputation: 5 484

2Also doesn't work for the 1056 case – JBernardo – 2019-11-01T16:49:02.710

1@JBernardo thanks, fixed. – Night2 – 2019-11-01T19:49:35.113

3

Python 3+inflect, 193 bytes

import inflect,re
exec("for i in re.sub('(and)|\W',' ',%sinput())).split():\n for j in range(0,6**8):\n  if i in %sj):\n   print(j,end='')\n   break"%(('inflect.engine().number_to_words(',)*2))

Try it online!

Very naive solution which uses Python's inflect library. Here is the unfurled code:

import inflect,re
for i in re.sub('(and)|\W+',' ',inflect.engine().number_to_words(input())).split():
 for j in range(0,6**8):
  if i in inflect.engine().number_to_words(j):
   print(j,end='')
   break

79037662

Posted 2019-11-01T13:48:59.830

Reputation: 1 739

Replace 6**8 with 9**9 and this should work in theory for all inputs under a billion, but would take ages. – 79037662 – 2019-11-01T17:56:38.763

So you're using a 3rd party library that is exactly to convert numbers to words... So why don't you create a library that completes the exercise and just use that. I bet you can do it in less than 10 bytes – JBernardo – 2019-11-01T20:15:21.123

1

@JBernardo For the same reason you can't just write a language that solves the question in 0 bytes, but my mistake was not putting the library in the header. https://codegolf.meta.stackexchange.com/questions/7243/can-i-write-a-golfing-library

– 79037662 – 2019-11-01T20:34:32.963

Or am I wrong about that? – 79037662 – 2019-11-01T20:37:43.120

3

Charcoal, 34 32 31 29 bytes

⪫E↨Nφ⪫E↨ι¹⁰⁰⪫↨λχ…0›Πλ﹪λχ100Iφ

Try it online! Link is to verbose version of code. Edit: Saved 2 bytes thanks to @Grimmy. Saved a further byte by finding a better way to choose between 0 or the empty string from a boolean. Saved a further 2 bytes because Base(l, 10) conveniently returns an empty array when l is zero. Explanation:

   N                            Input number
  ↨ φ                           Convert to base 1000 as an array
 E                              Map over elements
        ι                       Current element
       ↨ ¹⁰⁰                    Convert to base 100 as an array
      E                         Map over elements
              λ                 Current element
             ↨ χ                Convert to base 10 as an array
            ⪫                   Join with
                 0              Literal `0`
                …               Truncated to length
                    λ           Current element
                   Π            Digital product
                  ›             Is greater than
                      λ         Current element
                     ﹪          Modulo
                       χ        Predefined variable 10
     ⪫                          Join with
                        100     Literal string `100`
⪫                               Join with
                            φ   Predefined variable 1000
                           I    Cast to string

Example: 67890[67, 890][[67], [8, 90]][[607], [8, 90]][607, 810090]6071000810090.

Neil

Posted 2019-11-01T13:48:59.830

Reputation: 95 035

3

JavaScript, 69 bytes

Recursively splits and joins based on place values stored in k. Inspired by xnor's Python answer.

f=(n,k=1e3)=>n<20?+n||'':(n<k?'':f(n/k|0,k/10)+[k-10&&k])+f(n%k,k/10)

Try it online!

darrylyeo

Posted 2019-11-01T13:48:59.830

Reputation: 6 214

2

JavaScript, 95 93 92 bytes

f=n=>n>999?f(n/1e3|0)+[1e3]+f(n%1e3):n>99?(n/100|0)+'100'+f(n%100):n>20&&(x=n%10)?n-x+''+x:n

Try it online!


  • -2 bytes (@Shaggy): store n%10 in a variable

  • -1 byte (@Arnauld): replace '1000' with [1e3]

darrylyeo

Posted 2019-11-01T13:48:59.830

Reputation: 6 214

193 bytes – Shaggy – 2019-11-02T10:21:02.100

2'1000' can be turned into [1e3]. – Arnauld – 2019-11-02T17:20:26.483

1

Python 3, 110 115 bytes

def F(n,o=""):
 for i in 1000,100:
  if n>=i:o+=F(n//i)+str(i);n%=i
 return o+'0'[:0<n%10<=n>19].join(str(n))*(n>0)

Try it online!

Pretty simple. Hundreds and thousands are handled recursively.

+5 bytes but fixed a bug with F(100) thanks to @ChasBrown.

randomdude999

Posted 2019-11-01T13:48:59.830

Reputation: 789

2F(100) gives wrong result. – JBernardo – 2019-11-01T16:46:26.377

107 bytes, also fixes the F(100) issue. – Chas Brown – 2019-11-01T22:49:37.300

Which python is it? QtPython 3.6.6 on Android gives me just the digit representation not words. F(55) -> '505' – Gnudiff – 2019-11-01T23:09:15.117

@ChasBrown Unfortunately that fails on F(20). – 79037662 – 2019-11-01T23:50:08.787

@79037662 : Quite right! 115 bytes . Also was a bug in my answer as well.

– Chas Brown – 2019-11-02T01:16:43.923

1

Python 2, 106 105 100 107 bytes

f=lambda n:n/T and f(n/T)+`T`+f(n%T)or(n>=H)*`n/H*T+H`+'0'[:n%10>0<n%H>19].join(`n%H`)*(n%H>0)
H=100;T=1000

Try it online!

Saved 5 bytes adapting the .join approach of randomdude999's answer; lost 7 bytes fixing a bug :).

Chas Brown

Posted 2019-11-01T13:48:59.830

Reputation: 8 959