6
\$\begingroup\$

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
asked Mar 14, 2012 at 21:15
\$\endgroup\$
5
  • \$\begingroup\$ 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. :) \$\endgroup\$ Commented Mar 15, 2012 at 1:42
  • \$\begingroup\$ @IlmariKaronen we need to use the zeros. I will clarify that (updating) \$\endgroup\$ Commented Mar 15, 2012 at 4:23
  • \$\begingroup\$ Integers only or will it have to support floats too? \$\endgroup\$ Commented Mar 15, 2012 at 15:06
  • \$\begingroup\$ @elssar you can use floats as long as they don't add the commas for you automatically or something like that \$\endgroup\$ Commented Mar 15, 2012 at 15:26
  • \$\begingroup\$ @ajax333221 : commas, by definition, involve a string op, since integers don't come with commas. you want to add commas without string ops ???? cuz even after doing all the division and modulo by 1000 still involves prepending or appending a 1-byte string "," to them. \$\endgroup\$ Commented May 9, 2023 at 2:36

13 Answers 13

6
\$\begingroup\$

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]
answered Mar 15, 2012 at 1:01
\$\endgroup\$
2
  • \$\begingroup\$ I don't understand Haskell, but is that array-free? \$\endgroup\$ Commented Mar 15, 2012 at 19:15
  • \$\begingroup\$ 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... \$\endgroup\$ Commented Mar 15, 2012 at 19:59
5
\$\begingroup\$

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%
answered Mar 15, 2012 at 1:38
\$\endgroup\$
2
  • \$\begingroup\$ you used an array. Using strings, character position, indexes or arrays is not allowed \$\endgroup\$ Commented Mar 15, 2012 at 4:27
  • \$\begingroup\$ 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! \$\endgroup\$ Commented Apr 29, 2012 at 15:55
2
\$\begingroup\$

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
answered Mar 15, 2012 at 16:35
\$\endgroup\$
2
\$\begingroup\$

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
answered Mar 16, 2012 at 16:37
\$\endgroup\$
2
\$\begingroup\$

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);}
answered Apr 28, 2012 at 21:34
\$\endgroup\$
2
  • 2
    \$\begingroup\$ I'm curious, why do you say ;n^0; instead of just ;n;? \$\endgroup\$ Commented Oct 1, 2014 at 3:56
  • \$\begingroup\$ In C, the ^ operator means xor, so it should evaluate to 0. In this case, with that context, the for loop should never run. Is this a typo? \$\endgroup\$ Commented Oct 9, 2014 at 23:49
2
\$\begingroup\$

awk, 47 chars

awk '{for(_=NF-2;1<_;_-=3)$_=","$_}NR' FS= OFS=
10,100
120,406
999,999,999
answered Dec 19, 2022 at 3:49
\$\endgroup\$
1
  • \$\begingroup\$ This is splitting the string into characters (FS=), and looping over character positions to insert ,. The rules for this question say no string manipulation. \$\endgroup\$ Commented Nov 7, 2023 at 18:01
1
\$\begingroup\$

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.

answered Mar 15, 2012 at 21:11
\$\endgroup\$
1
\$\begingroup\$

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.

answered Mar 24, 2012 at 6:17
\$\endgroup\$
1
\$\begingroup\$

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})
answered Apr 29, 2012 at 1:03
\$\endgroup\$
0
\$\begingroup\$

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

answered Mar 15, 2012 at 8:54
\$\endgroup\$
3
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Mar 16, 2012 at 19:04
  • \$\begingroup\$ @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 \$\endgroup\$ Commented Mar 16, 2012 at 20:48
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Mar 16, 2012 at 21:33
0
\$\begingroup\$

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 (削除ここまで)

answered Mar 16, 2012 at 7:37
\$\endgroup\$
2
  • \$\begingroup\$ does not preserve zeros. eg: 976235004 = 976,235,4 \$\endgroup\$ Commented Mar 16, 2012 at 17:44
  • \$\begingroup\$ gah! back to the drawing board. \$\endgroup\$ Commented Mar 17, 2012 at 4:52
0
\$\begingroup\$

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));
}
answered Apr 29, 2012 at 6:32
\$\endgroup\$
2
  • \$\begingroup\$ You can shave off a few characters if you declare something like v=1000 and use x=n%v; and n/=v. \$\endgroup\$ Commented Apr 30, 2012 at 16:15
  • \$\begingroup\$ @GigaWatt ,v=1000 costs 7 chars, saves 6. ,v=1e3 comes out even. \$\endgroup\$ Commented Apr 30, 2012 at 17:22
0
\$\begingroup\$

JavaScript (削除) 104 (削除ここまで), (削除) 99 (削除ここまで), (削除) 90 (削除ここまで), 81

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=~~((n%i-r)/i*m),s=r+(i-m?",":"")+s;alert(s)

Note: change the value of n for different inputs

answered Mar 15, 2012 at 5:53
\$\endgroup\$
3
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Mar 15, 2012 at 15:44
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Mar 15, 2012 at 18:40
  • \$\begingroup\$ @Blazer maybe you are right, I will update that. Sorry, this is my second code-golf :) \$\endgroup\$ Commented Mar 15, 2012 at 19:12

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.