7
\$\begingroup\$

I'm starting with golf code. But im only do C# so I know wont be a breaking record, but I want give it a try. Leibniz

Challenge is here

The first line contains the number of test cases (N) which is less than 100. Each additional line is a test case for a positive integer value (T) less than 10^7.

I format the code to easy the reading, removing spaces I reduce it to 210 chars. The best code submit for this problem is 54 char, but For C# lenguaje the best is 172 chars.

My guess is should remove reading the N, but couldn't make it stop properly.

using System;
class S
{
    static void Main()
    {
        int n=Convert.ToInt32(Console.ReadLine()),i=0;
        for (;i++<n;)
        {
            double r=0,t=Convert.ToInt32(Console.ReadLine()),j=0;
            for(;j<t;)
                r+=(1-j%2*2)/(2*j+++1);
            Console.WriteLine(r);
        }
    }
}

NOTE

Mono C# compiler 3.2.8.0 .NET 4.0 CLR
So using C=System.Console doesn't work.

\$\endgroup\$
8
  • \$\begingroup\$ This isn't an appropriate question for this site. Questions here are challenges for people to compete on (and a few other things like language tips). If you need help, submit your code as an answer to the challenge, and ask for help in the comments of your answer. \$\endgroup\$
    – Sparr
    Commented Apr 22, 2015 at 17:24
  • 2
    \$\begingroup\$ @Sparr this is an old challenge, you can see this question was already here for Python. codegolf.stackexchange.com/questions/10716/… , and is +2 years old, same challenge I just ask for a diferent lenguaje. Im not trying to get any prize, just trying to learn. \$\endgroup\$ Commented Apr 22, 2015 at 17:30
  • 10
    \$\begingroup\$ @Sparr Asking for golfing advice is definitely on topic, and has been officially for almost a year. Also see the help centre. \$\endgroup\$ Commented Apr 22, 2015 at 17:47
  • 1
    \$\begingroup\$ It's not clear to me whether you want help golfing the code in the question or solving the Hacker Rank challenge. The code in the question doesn't meet the spec for the Hacker Rank challenge. Consider e.g. that the correct output for 100000 is 0.785395663397448. \$\endgroup\$ Commented Apr 22, 2015 at 18:33
  • \$\begingroup\$ @PeterTaylor My request is for help golfing the code, especially the first FOR and try reading the number of cases. But you are right for that case doesn't work. As I say in the description Im new with this and I considere my program correct because pass the test case. Didnt consider have to try all the cases by myself. Do you think this is because a wrong data type, or is something wrong with my code logic? \$\endgroup\$ Commented Apr 22, 2015 at 18:55

4 Answers 4

7
\$\begingroup\$

As I suggested in a comment on VisualMelon's answer, the second for loop is being underutilised. By changing some variable scopes it's possible to use the fors in such a way that we save one set of curly brackets and one variable, and perform the sum in the correct order, fixing the bug in the supplied code.

Golfed:

using C=System.Console;class S{static void Main(){for(double n=int.Parse(C.ReadLine()),r,t;n-->0;C.WriteLine(r))for(r=0,t=2*int.Parse(C.ReadLine());t>0;t--)r-=(1-t%4)/--t;}}

Online demo

Ungolfed:

using C = System.Console;
class S {
    static void Main() {
        for (double n=int.Parse(C.ReadLine()), r, t; n-- > 0; C.WriteLine(r))
            for (r=0, t=2*int.Parse(C.ReadLine()); t>0; t--)
                r -= (1-t%4) / --t;
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ I've heard that a double can perfectly represent an Int32, but I never quite believed it (too lazy to find a good source more than anything else), I was holding back on suggesting collapsing t/j as well, this is considerably better than my job. \$\endgroup\$ Commented Apr 22, 2015 at 19:22
  • \$\begingroup\$ A double can perfectly represent any integer up to 2^51 or 2^52 (can't quite remember offhand and don't feel like looking it up). \$\endgroup\$ Commented Apr 22, 2015 at 19:25
  • \$\begingroup\$ Setting all variables and printing result in the same for very cleaver. But you lose me on the second for. You move the 2* to t assignment and then you have t-- and --t. I think i will have to run it step by step to see what is doing. \$\endgroup\$ Commented Apr 22, 2015 at 19:49
3
\$\begingroup\$

Couple of simple things that apply in lots of places:

  1. You've got a free semi-colon in your first for loop which you can make use of

  2. You keep track of i against n, but you as you never use the value of n, you can use it as the counter itself.

  3. As someone else said, you can use int.Parse (or double.Parse) instead of the Convert namespace/class/whatever it is - this makes your using System directive less helpful, and you are better of using the classic using C=System.Console (unless C# 6 has come out, I can't say I'm sure, in which case you can using System.Console directly)

  4. There is an unneeded space after the first for (not sure if you'd accounted for this or not)

I haven't tested this code, but hopefully it will at least help:

using C=System.Console; // 3

class S
{
    static void Main()
    {
        for(int n=int.Parse(C.ReadLine()); // 1, 3, 4
            n-->0;) // 2
        {
            double r=0,t=int.Parse(C.ReadLine()),j=0; // 3
            for(;j<t;)
                r+=(1-j%2*2)/(2*j+++1);
            C.WriteLine(r); // 3
        }
    }
}

Is it possible that the shorter C# solution disregards the first line, and just assumes the input is clean? May well be cheaper to do that if it is allowed.

This is just a quick reply, I might have a better bash at this tomorrow when I have less going on.

\$\endgroup\$
7
  • \$\begingroup\$ Point 1 applies to the second for loop too. \$\endgroup\$ Commented Apr 22, 2015 at 19:03
  • \$\begingroup\$ @PeterTaylor unfortunately it doesn't seem to pay to move the doubles outside of the for loop, and you need access to r below (which you don't have if you define it in the for loop initial expression) \$\endgroup\$ Commented Apr 22, 2015 at 19:04
  • \$\begingroup\$ Yes, That part I try putting the variable inside the loop and couldnt access outside. \$\endgroup\$ Commented Apr 22, 2015 at 19:06
  • \$\begingroup\$ Looks like I cant use using C=System.Console; Say `System.Console' is a type not a namespace \$\endgroup\$ Commented Apr 22, 2015 at 19:10
  • 1
    \$\begingroup\$ There's no reason why n can't be a double... See my answer. \$\endgroup\$ Commented Apr 22, 2015 at 19:20
2
\$\begingroup\$
  • Instead of Convert.ToInt32, use int.Parse; it saves a few characters.
  • Unless you really need a double, use a float; it's one char shorter than double.
\$\endgroup\$
2
  • \$\begingroup\$ Thanks, I was using Math.power() that is why I need double, but i replace it for r+=(1-j%2*2), so no need it anymore. \$\endgroup\$ Commented Apr 22, 2015 at 17:22
  • \$\begingroup\$ I went back to double, Need 15 decimals precision. :( \$\endgroup\$ Commented Apr 22, 2015 at 17:27
1
\$\begingroup\$

172 Characters

The permanent version of the challenge can be found here. I have the shortest solution for C#, which is 172 characters.

Golfed

using R=System.Console;class C{static void Main(){R.ReadLine();for(double s,n,j;;){for(s=0,n=int.Parse(R.ReadLine()),j=0;j<n;){s+=(j%2<1?1:-1)/(2*j+++1);}R.WriteLine(s);}}}

Ungolfed

using R=System.Console;
class C
{
    static void Main()
    {
        R.ReadLine();
        for(double s,n,j;;)
        {
            for(s=0,n=int.Parse(R.ReadLine()),j=0;j<n;)
            {
                s+=(j%2<1?1:-1)/(2*j+++1);
            }
            R.WriteLine(s);
        }
    }
}

It does error out on the last loop, but it's after outputting all test cases.

Edit

Seeing it ungolfed like this, just realized I can inline the for loop.

170 characters

Golfed

using R=System.Console;class C{static void Main(){R.ReadLine();for(double s,n,j;;){for(s=0,n=int.Parse(R.ReadLine()),j=0;j<n;)s+=(j%2<1?1:-1)/(2*j+++1);R.WriteLine(s);}}}

Ungolfed

using R=System.Console;
class C
{
    static void Main()
    {
        R.ReadLine();
        for(double s,n,j;;)
        {
            for(s=0,n=int.Parse(R.ReadLine()),j=0;j<n;)
                s+=(j%2<1?1:-1)/(2*j+++1);
            R.WriteLine(s);
        }
    }
}

Edit 2

@PeterTaylor's answer has some fantastic logic. Cleaned it up a bit, and I'm still using exceptions for control flow.

155 characters

Golfed

using R=System.Console;class C{static void Main(){R.ReadLine();for(double s,n;;R.WriteLine(s))for(s=0,n=2*int.Parse(R.ReadLine());n>0;n--)s-=(1-n%4)/--n;}}

Ungolfed

using R = System.Console;
class C
{
    static void Main()
    {
        R.ReadLine();
        for(double s, n;; R.WriteLine(s))
            for(s = 0, n = 2 * int.Parse(R.ReadLine()); n > 0; n--)
                s -= (1 - n % 4) / --n;
    }
}

I really wish I could get rid of the extra ReadLine().

\$\endgroup\$

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.