1
\$\begingroup\$

The goal of this challenge is to show how many characters are in the name of a given integer. This is code golf, so the smallest code wins.

RULES

  • The input will be between 0 and 100 (inclusive). If it is not the program won't return anything.
  • The result has to be printed as input : answer
  • Result for 100 is hundred

For example, if the input is 23 you have to count the numbers of letters twenty-three : here the answer is 12, and you should print 23 : 12

\$\endgroup\$
  • 8
    \$\begingroup\$ I'm afraid this is too similar to Converting integers to English words to have any success. \$\endgroup\$ – manatwork Jun 26 '15 at 11:20
  • \$\begingroup\$ @manatwork: I was looking for that question- thank you for finding it for me. \$\endgroup\$ – SuperJedi224 Jun 26 '15 at 11:21
  • \$\begingroup\$ @manatwork meh, you found what i was searching this morning. Let's try to get some responses anyway.. \$\endgroup\$ – The random guy Jun 26 '15 at 11:26
  • 1
    \$\begingroup\$ Also what should we output for 100? "a hundred" and "one hundred" are both correct but are not the same number of letters. Some people in answers return the number of letters in "hundred" only. \$\endgroup\$ – Fatalize Jun 26 '15 at 13:48
  • 1
    \$\begingroup\$ @ThomasKwa yup, let's do some non-standard things :D \$\endgroup\$ – The random guy Jun 26 '15 at 14:03
3
\$\begingroup\$

Common Lisp - 72 bytes

(lambda(x)(if(<= 0 x 100)(format t"~A : ~A~%"x(length(format()"~R"x)))))

Output from 0 to 20

0 : 4
1 : 3
2 : 3
3 : 5
4 : 4
5 : 4
6 : 3
7 : 5
8 : 5
9 : 4
10 : 3
11 : 6
12 : 6
13 : 8
14 : 8
15 : 7
16 : 7
17 : 9
18 : 8
19 : 8
20 : 6
\$\endgroup\$
4
\$\begingroup\$

C : 117 bytes

(From kind suggestion of @edc65 and @ColeCameron)

f(a){char *d="0446554665366887798803665557667";printf("%d : %d",a,(a?a<20?d[a]-(a<10):d[a%10]+d[20+a/10]-48:52)-48);}

Live example

C++ : 159 bytes 178 bytes

int f(int a){char *d[3]={"0446554665","0366555766","3668877988"};printf("%d : %d",a,(a?a<20?a>9?d[2][a-10]:d[0][a]-1:a>99?55:d[0][a%10]+d[1][a/10]-48:52)-48);}

Live example

Explanation

Explanation from previous code, with all suggestions from comments incorporated.

int f(int a) {  // Return int to save a byte, a is the argument

    int d[3][10]={
             {0,4,4,6,5,5,4,6,6,5},  // Length of "", "-one", "-two", "-three" etc.
             {0,3,6,6,5,5,5,7,6,6},  // Length of "", "ten", "twenty", etc.
             {3,6,6,8,8,7,7,9,8,8}   // Length of "ten", "eleven", etc.
           };
    printf ("%d : %d", a,
               a 
                 // If a is not zero
                 ? a < 20
                     // If a is less than 20
                     ? a > 9
                         // a is in range 10-19
                         ? d[2][a-10]
                         // a is in range 0-9
                         : d[0][a]-1  // Subtract one as '-' is not required
                     // If a is >= 20
                     : a > 99
                         // If a is 100
                         ? 7  // Length of hundred
                         // a is between 20-99
                         : d[0][a%10] + d[1][a/10]  // unit digit length + tens digit length
                 // If a is zero
                 : 4
            );
}
\$\endgroup\$
  • \$\begingroup\$ I really like the explanation on this one.. If you save the length oh 0 in your tab of int, i think you can save on or two bytes : int d[3][10]={{5,4,4,6,5,5,4,6,6,5},...} for -zero, you delete the first test and it might be ok with the d[0][a]-1 (when a is in range 0-9). Not tested. \$\endgroup\$ – The random guy Jun 26 '15 at 12:49
  • \$\begingroup\$ @Therandomguy I will try your suggestion and let the code run through my tester. Thanks. \$\endgroup\$ – Mohit Jain Jun 26 '15 at 12:57
  • \$\begingroup\$ 138: ideone.com/B4xSXr f(a){int d[]={0,4,4,6,5,5,4,6,6,5,3,6,6,8,8,7,7,9,8,8,0,3,6,6,5,5,5,7,6,6,7};printf("%d : %d",a,a?a<20?d[a]-(a<10):d[a%10]+d[20+a/10]:4);} \$\endgroup\$ – edc65 Jun 26 '15 at 13:24
  • \$\begingroup\$ I'm a noob with ideone, so i can't tell how many bytes i save on your code. But as i said you can do without excluding the 0 : f(a){int d[]={5,4,4,6,5,5,4,6,6,5,3,6,6,8,8,7,7,9,8,8,0,3,6,6,5,5,5,7,6,6,7};printf("%d : %d",a,a<20?d[a]-(a<10):d[a%10]+d[20+a/10]);} (This solution save 4 characters) \$\endgroup\$ – The random guy Jun 26 '15 at 13:29
  • 2
    \$\begingroup\$ f(a){char d[]="0446554665366887798803665557667";printf("%d : %d",a,a?a<20?d[a]-48-(a<10):d[a%10]-48+d[20+a/10]-48:4);} \$\endgroup\$ – Cole Cameron Jun 26 '15 at 13:49
0
\$\begingroup\$

PHP 613 Characters

As a bonus, I don't use a dictionary of integer character lengths.

<?php $i=10;$b[0]='zero';$b[1]='one';$b[2]='two';$b[3]='three';$b[4]='four';$b[5]='five';$b[6]='six';$b[7]='seven';$b[8]='eight';$b[9]='nine';$t='teen';$c[0]='ten';$c[1]='eleven';$c[2]='tweleve';$c[3]='thir'.$t;$c[4]=$b[4].$t;$c[5]='fif'.$t;$c[6]=$b[6].$t;$c[7]=$b[7].$t;$c[8]=$b[8].$t;$c[9]=$b[9].$t;$d[2]='twenty';$d[3]='thirty';$d[4]='fourty';$d[5]='fifty';$d[6]='sixty';$d[7]='seventy';$d[8]='eighty';$d[9]='ninety';$z='onehundred';$j=str_split($i);if(strlen($i)===1){$a=$b[$i];}elseif(strlen($i===3)){$a=$z;}elseif(substr($i,0,1)==='1'){$a=$c[$j[1]];}else{$a=$d[$j[0]].' '.$b[$j[1]];}echo$i.' : '.strlen($a);

Long hand

<?php
// Input
$i=10;
// 0-9
$b[0]='zero';
$b[1]='one';
$b[2]='two';
$b[3]='three';
$b[4]='four';
$b[5]='five';
$b[6]='six';
$b[7]='seven';
$b[8]='eight';
$b[9]='nine';
// 10-19 (Very tricky)
$t='teen';
$c[0]='ten';
$c[1]='eleven';
$c[2]='tweleve';
$c[3]='thir'.$t;
$c[4]=$b[4].$t;
$c[5]='fif'.$t;
$c[6]=$b[6].$t;
$c[7]=$b[7].$t;
$c[8]=$b[8].$t;
$c[9]=$b[9].$t;
// Left digit of 20-99
$d[2]='twenty';
$d[3]='thirty';
$d[4]='fourty';
$d[5]='fifty';
$d[6]='sixty';
$d[7]='seventy';
$d[8]='eighty';
$d[9]='ninety';
// 100
$z='one hundred';
// Split input
$j=str_split($i);
// 1 digit inputs
if (strlen($i)===1){$a=$b[$i];}
// 3 digit input
else if (strlen($i===3)){$a=$z;}
// 10-19
else if (substr($i, 0, 1)==='1'){$a=$c[$j[1]];}
// 20-99
else{$a=$d[$j[0]].' '.$b[$j[1]];}
// result
echo $i.' : '.strlen($a);
\$\endgroup\$
  • \$\begingroup\$ You can save a huge amount of bytes if you give the length of the number in your tabs instead of writing it and counting the amount of characters. For example instead of $c[1]='eleven'; you can write $c[1]=6; \$\endgroup\$ – The random guy Jun 26 '15 at 13:11
  • \$\begingroup\$ As I said in the post, I wanted to accomplish it without a dictionary. \$\endgroup\$ – Goose Jun 26 '15 at 13:12
  • \$\begingroup\$ Oh ok, my bad. I need to sleep. \$\endgroup\$ – The random guy Jun 26 '15 at 13:16
0
\$\begingroup\$

Prolog, 261 211 bytes

u(X,Y):-nth0(X,[4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8],Y).
a(X):-X>=0,X<101,(X=100,Y=7;X<20,u(X,Y);A is X//10-2,nth0(A,[6,6,5,5,5,7,6,6],B),C is X-X//10*10,(C=0,D=0;u(C,D)),Y is B+D+1),writef('%t : %t',[X,Y]).
\$\endgroup\$
0
\$\begingroup\$

Python 2, 158 Bytes

Just a little bit of hex :)

n=input()
print(`n`+' : '+`int('433544355436688779886aacbbaccb6aacbbaccb599baa9bba599baa9bba599baa9bba7bbdccbddc6aacbbaccb6aacbbaccb7'[n%101],16)`)*(-1<n<101)
\$\endgroup\$
  • \$\begingroup\$ @Sp3000 That would be correct, I believe I've fixed it now. \$\endgroup\$ – Kade Jun 26 '15 at 14:03
  • \$\begingroup\$ simple question : i just saw this 0<n<101 ... when n=0, what this code do ? (normally it should show 0 : 4) \$\endgroup\$ – The random guy Jun 26 '15 at 14:36
  • \$\begingroup\$ @Therandomguy good catch, I updated it :) \$\endgroup\$ – Kade Jun 26 '15 at 14:40
  • \$\begingroup\$ @Therandomguy I'm not sure if it's possible, but you should un-accept my answer, coredump's is shorter. And in the future, most people prefer when you allow undefined behavior when something is not within the range of inputs. \$\endgroup\$ – Kade Jun 26 '15 at 14:45
  • \$\begingroup\$ .. Yup, you're right. Time for me to sleep. \$\endgroup\$ – The random guy Jun 26 '15 at 14:48
0
\$\begingroup\$

Python, 172 bytes

l='33544355436688779980'
a='776668778'
n=int(raw_input())
if n==0:
 print n,':',4
elif n<20:
 print n,':',l[n-1]
elif n<100:
 print n,':',int(a[n/10-2])+int(l[n-n/10*10-1])

Stores all the units number name lengths in a string, from 1 to 19. Combines them with 10s number name lengths if the number >=20.

0 is an exception. 100 is taken to be hundred.

\$\endgroup\$
  • \$\begingroup\$ May n==0 be n<1? In any case, you could save characters by using a ternary or array indexing instead of the if:elif:elif. \$\endgroup\$ – lirtosiast Jun 26 '15 at 13:23
  • \$\begingroup\$ @ThomasKwa will look into the second suggestion. if it is a negative number it would return something without the ==1 \$\endgroup\$ – Tim Jun 26 '15 at 13:33
  • \$\begingroup\$ @ThomasKwa I thought that, but then he said If it is not the program won't return anything. \$\endgroup\$ – Tim Jun 26 '15 at 13:55
  • \$\begingroup\$ This doesn't follow the spec at all.. All of them need to be the same format (i.e. 0 should print 0 : 4, not just 4, and 17 should print 17 : 9, not just 9). It's shorter to just put ':' instead of chr(58), n-int(n/10)*10-1 can be shortened to n%10-1, and since this is Python 2, you can do n/10-2 instead of int(n/10)-2. \$\endgroup\$ – Kade Jun 26 '15 at 14:53

Not the answer you're looking for? Browse other questions tagged or ask your own question.