22
\$\begingroup\$

I'm trying to read 4 ints in C in a golfing challenge and I'm bothered by the length of the code that I need to solve it:

scanf("%d%d%d%d",&w,&x,&y,&z)

that's 29 chars, which is huge considering that my total code size is 101 chars. I can rid of the first int since I don't really need it, so I get this code:

scanf("%*d%d%d%d",&x,&y,&z)

which is 27 chars, but it's still lengthy.

So my question is, is there any other way (tricks, functions, K&R stuff) to read ints that I don't know of that could help me reduce this bit of code?


Some users have reported that my question is similar to Tips for golfing in C

While this topic contain a lot of useful information to shorten C codes, it isn't relevant to my actual use case since it doesn't provide a better way to read inputs.

I don't know if there is actually a better way than scanf to read multiple integers (that's why I'm asking the question in the first place), but if there is, I think my question is relevant and is sufficiently different than global tips and tricks.

If there is no better way, my question can still be useful in the near future if someone find a better solution.

I'm looking for a full program (so no function trick) and all libraries possible. It needs to be C, not C++. Currently, my whole program looks like this:

main(w,x,y,z){scanf("%*d%d%d%d",&x,&y,&z)}

Any tricks are welcome, as long as they shorten the code (this is code golf) and work in C rather than C++.

\$\endgroup\$
8
  • 17
    \$\begingroup\$ 1) @BusyBeingDelicious, welcome to PPCG! :) 2) To the close voters, this is not a general programming question. This is a tips question which asks for help golfing code which is absolutely on topic. \$\endgroup\$ Commented May 15, 2016 at 11:49
  • \$\begingroup\$ I'm not sure it's possible to give a good answer without knowing anything about the problem domain at all. I suspect the real answer is to figure out a way to only read one int at a time and/or abuse pointers. \$\endgroup\$
    – Comintern
    Commented May 16, 2016 at 3:03
  • \$\begingroup\$ @BusyBeingDelicious what are the constraints you are imposed or you do impose on us ? range of integers ? libraries used ? declarations of variables which you forgot to precede your piece of golfed code by ? are you considering c++ ? \$\endgroup\$
    – Abr001am
    Commented May 17, 2016 at 9:03
  • \$\begingroup\$ @BusyBeingDelicious i m not sure what you are doing, the function you defined doesnt retain nothing because the variables stored are volatiles, look any function which does affect on addresses must encompasse pointers not simple integers. \$\endgroup\$
    – Abr001am
    Commented May 19, 2016 at 11:19
  • 1
    \$\begingroup\$ I don't really get what you're talking about @Agawa001, the portion I show is using K&R C syntax . If you're talking about the fact that I don't use the variables afterwards, it's because it's not the full full code, just a piece of it. And it's also because the rest of the code isn't relevant to the actual question. If there is an answer, it could solve multiple cases that look like this one. \$\endgroup\$ Commented May 20, 2016 at 13:41

3 Answers 3

9
\$\begingroup\$

Thanks to @DialFrost for drawing my attention to this question.

I believe for reading 4 numbers your solution is optimal. However, I found a solution that saves bytes when reading 5 or more numbers at a time.

It will also consume the entire input (i.e. it can't be used in a loop).

Depending on the context it might help you with only 4 variables too

If you define your variables in a sequence like this:

a,b,c,d,e;main(){

In this case, the variables will be layed out in successive memory addresses, we can abuse that.

for(;~scanf("%d",&a+e);e++);

Full program:

// new
a,b,c,d,e;main(){for(;~scanf("%d",&a+e);e++);}
// original
a,b,c,d;main(e){scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);}

This 29 byte segment will paste all the input in successive variables starting in a. We re-use e, (the last variable) as the index variable. This saves declaring one variable.

Size comparison

Number of inputs Original New Original (full program) new (full program)
1 14 28 24 38
2 19 28 31 40
3 24 28 38 42
4 29 28 45 44
5 34 28 52 46
6 39 28 59 48

Note that the new method gains a 1 byte disadvantage in full programs because you can't use function arguments, however, this doesn't matter if you can use another variable as the argument to main.

Note there is also a slot in the initialization portion of the for loop. If you can put another expression there this method can save 1 byte even with only 4 arguments.

Try it online!

@JDT ponted out you can save 1 byte at the cost of having 1 added to e at the end:

for(;0<scanf("%d",&a+e++););
\$\endgroup\$
2
  • 4
    \$\begingroup\$ This 27 bytes gives the correct value for e but need an additional integer i to be declared on the global scope. \$\endgroup\$
    – jdt
    Commented Oct 4, 2022 at 11:59
  • \$\begingroup\$ Nice find, including the declaration it's 1 extra byte but it could be useful if you have some other use for i afterwards \$\endgroup\$ Commented Oct 4, 2022 at 12:04
5
\$\begingroup\$

If you want to e.g. print all the inputs then we have this, being 64 bytes long:

main(x,y,z){scanf("%*d%d%d%d",&x,&y,&z);printf("%d%d%d",x,y,z);}

We can actually shorten this with a loop, bringing the total down to 47 bytes:

main(z){for(;scanf("%d",&z)>0;)printf("%d",z);}

So the reading part is only 23 bytes long:

for(;scanf("%d",&z)>0;)

Note that this only works when you don't want to assign a value to a specific variable and only want to read the values.

A method that is 29 bytes long:

for(;scanf("%d",&a+i)>0;i++);

Shout out to @mousetail for helping me out!

\$\endgroup\$
1
\$\begingroup\$

C (gcc), 44 43 bytes

main(i,a,b,c,d){for(;i+=scanf("%d",i+&i););

Try it online!

This frees up an extra integer i=0, while mousetail's solution make i=5(can't find a compiler that allow reusing e as index without adding extra 1)

Need -m32 maybe because on x64 values are passed via registers

C (tcc), 44 bytes

a,b,c,d,i;main(){for(;i+=scanf("%d",i+&a););

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ @mousetail How? I can only find one occurance of +=sc in this page \$\endgroup\$
    – l4m2
    Commented Jan 24, 2023 at 17:42

Your Answer

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

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