Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

This challenge consist in adding commas to numbers every 3 spaces like:

123456789 => 123,456,789

Specifications:

  • The possible inputs will be 1,000 <= input <= 100,000,000
  • You can ONLY use Mathematical Operators
  • (*) You can NOT do string, array, index or character manipulation
  • You can NOT use any kind of built-in functions that add these commas
  • The zeros should remain, ex 10000 => 10,000
  • You need to print/alert/log the output (so "the output is at x var" is not allowed)

(*) the only exception is when forming/printing the output (but not in a manner that suggest cheating)

Examples

10100 => 10,100
120406 => 120,406
999999999 => 999,999,999

A basic idea on how to get numbers legally:

n = 123456;
m = roundDown(n / 10);//even if ends with .9
d = n - m;//we get the last number
share|improve this question
    
Just to clarify, is 123,45,6 acceptable output for the input 123045006, or do we need to include the leading zeros? I'd assume we do, but if not, I have a very nice 13-char GolfScript solution. :) –  Ilmari Karonen Mar 15 '12 at 1:42
    
@IlmariKaronen we need to use the zeros. I will clarify that (updating) –  ajax333221 Mar 15 '12 at 4:23
    
Integers only or will it have to support floats too? –  elssar Mar 15 '12 at 15:06
    
@elssar you can use floats as long as they don't add the commas for you automatically or something like that –  ajax333221 Mar 15 '12 at 15:26

12 Answers 12

up vote 3 down vote accepted

GolfScript, 13 37 chars

0:|;~{.10%|):|3%''','if@10/.9>}do]-1%

Look, Ma, no arrays!

Well, almost. The pieces of the output are collected on the stack in right-to-left order, so the final ]-1% is needed to reverse them. But I assume that's OK, as it counts as "forming/printing the output".

Here's an ungolfed version with comments:

0 :| ;         # initialize the variable | to the value 0
~              # eval the input, turning it from a string into a number

{              # start of loop
  .            # duplicate the number on top of the stack; we'll need it later
  10 %         # take the remainder modulo 10 and leave it on the stack

  | ) :| 3 %   # increment | by one and take the remainder modulo 3 of the result
  '' ',' if    # if the remainder is 0, push a comma onto the stack, else an empty string

  @            # pull the value we saved at the start of the loop to top of the stack
  10 /         # divide it by ten, rounding down
  . 9 >        # check if the result is greater than 9...
} do           # ...and repeat the loop if so

]              # finally, collect the digits and commas off the stack into an array...
-1 %           # ...and reverse it for output

If it weren't for a few pesky details, the following 13-char solution would be pretty hard to beat:

~1000base','*

However, it fails on two counts: it doesn't correctly preserve leading zeros in digit groups, and the built-in base conversion operator base might be considered "array manipulation", since it takes a number and returns an array of digits.


Ps. Here's an older 49-char arrayless solution:

~{.999>}{:^1000%:&9&>99&>+{0}*','^1000/}while]-1%
share|improve this answer
    
you used an array. Using strings, character position, indexes or arrays is not allowed –  ajax333221 Mar 15 '12 at 4:27
    
the only exception is when forming/printing the output, the "collect digits and commas" is a formatting operation; no cheating to me. I'm developing a C interpreter of a language derived from GolfScript, which is able to interpret this solution; if you remove the array-related ]-1% part,my lang will output the correct result since it by default "dumps" the stack from top to bottom (it seems to me more natural for a stack oriented lang);the point is that the result is ready, you need just formatting, and this must be allowed or very few solutions would be possible! –  ShinTakezou Apr 29 '12 at 15:55

You weren't very specific on the output format...

Haskell, 56

reverse.takeWhile(>0).map(`mod`1000).iterate(`div`1000)

example:

GHCi> reverse.takeWhile(>0).map(`mod`1000).iterate(`div`1000)$93842390862398
[93,842,390,862,398]
share|improve this answer
    
I don't understand Haskell, but is that array-free? –  ajax333221 Mar 15 '12 at 19:15
    
As array-free as it gets. Only lazy lists, i.e. pointers to functions and to integers. – It also has the leading-zero-problem, though, that requirement came in after my post; I can't fix that without String objects. Or can I? Wait... –  leftaroundabout Mar 15 '12 at 19:59

Python 2, 86 chars

I figured this warranted a different enough answer. The first answer is for 3.0 only because of the print statement with end=, and this answer because division automatically floors instead of converts to float, and the use of backticks

b=input()
k=0
x=''
while b>0:
 x=`b%10`+x;b/=10;k+=1
 if k%3==0and b>0:x=','+x
print x

Only string manipulation is building the output

edit: by adding 5 characters int(), this program can accept any integer, even above 1 billion. The previous program inserts Ls (python longs) if the number is too large, but is still within the constraints of the challenge. Here is the program that works with any integer:

b=input()
k=0
x=''
while b>0:
 x=`int(b%10)`+x;b/=10;k+=1
 if k%3==0and b>0:x=','+x
print x

-

879612587634598623589762354009
879,612,587,634,598,623,589,762,354,009
share|improve this answer

Python, 82 chars

n=input()
x=''
while n>999:x=','+`n/100%10`+`n/10%10`+`n%10`+x;n/=1000
print `n`+x

I can get it shorter (67 chars) with

while n>999:x=',%03d'%(n%1000)+x;n/=1000

Not sure if that's legal.

share|improve this answer

AWK, no strings, 84 chars:

{for(p=$0;.1<p/=10;++i);for(;i-->0;printf i&&i%3==0?"%d,":"%d",$0/10**i%10);print""}

Test runs:

% awk -f commas.awk <<< 1230
1,230
% awk -f commas.awk <<< 123012
123,012
% awk -f commas.awk <<< 12301 
12,301
% awk -f commas.awk <<< 12301000
12,301,000
share|improve this answer

befunge, 62

&# <v%3-\3%3y+8a$j*d`0:/a\%a:
1`j@>:3%\3/!3*j',,\'0+,1+a8+y

well this code is array free, since befunge itself is array free.

  • the first line simply reads a number and push every digit into stack.
  • the second line reads those digits and prints then once at a time. and put commas if needed.

note that if you are trying to run it using rcfunge, you need run using "-Y" option.

share|improve this answer

C, 136

i,j,k;main(m,n){scanf("%d",&n);for(m=n;n^0;i++,n/=10);k=i%3;while(j++<i)printf("%d%c",(int)(m/pow(10,i-j))%10,j%3==k?',':0);putchar(8);}
share|improve this answer

Scala 65:

def f(n:Int){if(n<1000)print(n)else{f(n/1000)
print("."+n%1000)}}

Testcode:

val l=List(1,12,123,1234,12345,123456,1234567)
l.foreach(x=>{f(x);println})
share|improve this answer

Python 3, 165 chars

from math import*
b=int(input())
j=10**8
k=l=0
while j>0:
 z=int(floor(b/j));b-=z*j;k+=1;j=floor(j/10)
 if not l:l=z!=0
 if l:print(z,end=','if k%3==0and j>0 else'')

No strings except for '' and ',', no arrays/lists/tuples/dicts, or indexing

edit: nixxed some characters

share|improve this answer
    
Not sure how python works, but surely int(floor(x)) is the same as int(x) or floor(x)? And if python is anything like the languages I use, you should be able to change ','if k%3==0and j>0 else'' to ''if k%3&j>0 else',' Also, I think while j>0 can be changed to while j –  Griffin Mar 16 '12 at 19:04
    
@Griffin thought int() rounded to the nearest. I guess I'm still learning some small details about Python xD. python's & operator is bitwise, not logical, so it can't be used the same way all the time. the while thing was just me being a noob –  Blazer Mar 16 '12 at 20:48
    
floor is essentially truncating after the decimal point, depending on the language int will round or truncate. Either way doing int(floor()) is no different from floor(). In javascript, because of the loose typing ORing by zero will truncate decimals: AAA.BBB | 0 == AAA - this might work for phython... My bad about the bitwise and, at least switch the if statement around so you don't need the ==0 –  Griffin Mar 16 '12 at 21:33

JavaScript 104, 99, 90

Edit: I just noticed I also have this missing zeros bug when any group of contains 000 ,00X or 0X0. If you see this message, the code below isn't fixed yet

Code:

for(n=0,s="",i=m=1e3,r=0;i<n*m;i*=m)r=Math.floor((n%i-r)/i*m),s=r+(i==m?"":",")+s;alert(s)

Note: change the value of n for different inputs

share|improve this answer
    
ah, I just noticed I also have this missing zeros bug when any group of contains like 000 ,001 or 010... I will try to fix this later –  ajax333221 Mar 15 '12 at 15:44
    
I think the input should always count towards the final character count. at least the minimum: n=0; = 4 characters. I could reduce at least 6 characters in both my codes if input lines were free –  Blazer Mar 15 '12 at 18:40
    
@Blazer maybe you are right, I will update that. Sorry, this is my second code-golf :) –  ajax333221 Mar 15 '12 at 19:12

Python 2.6.5, 65 94 chars

n=input()
s=''
while n:
    s=','+str(x)+s if x else','+'000'+s
    n/=1000
print s[1:]

Just used the string to store the output.

*Now preserves zeros

share|improve this answer
    
does not preserve zeros. eg: 976235004 = 976,235,4 –  Blazer Mar 16 '12 at 17:44
    
gah! back to the drawing board. –  elssar Mar 17 '12 at 4:52

C, 80 chars

Using recursion within printf to reverse the printing order (recursion handles the least significant digits first, but printing is done when returning, so they're printed last).

n;
p(x) {
    x=n%1000;
    n/=1000;
    printf(n?p(),",%03d":"%d",x);
}
main(){
    p(scanf("%d",&n));
}
share|improve this answer
    
You can shave off a few characters if you declare something like v=1000 and use x=n%v; and n/=v. –  GigaWatt Apr 30 '12 at 16:15
    
@GigaWatt ,v=1000 costs 7 chars, saves 6. ,v=1e3 comes out even. –  ugoren Apr 30 '12 at 17:22

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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