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\$
  • \$\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 Apr 22 '15 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\$ – Juan Carlos Oropeza Apr 22 '15 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\$ – Martin Ender Apr 22 '15 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\$ – Peter Taylor Apr 22 '15 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\$ – Juan Carlos Oropeza Apr 22 '15 at 18:55
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\$
  • \$\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\$ – VisualMelon Apr 22 '15 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\$ – Peter Taylor Apr 22 '15 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\$ – Juan Carlos Oropeza Apr 22 '15 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\$
  • \$\begingroup\$ Point 1 applies to the second for loop too. \$\endgroup\$ – Peter Taylor Apr 22 '15 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\$ – VisualMelon Apr 22 '15 at 19:04
  • \$\begingroup\$ Yes, That part I try putting the variable inside the loop and couldnt access outside. \$\endgroup\$ – Juan Carlos Oropeza Apr 22 '15 at 19:06
  • \$\begingroup\$ Looks like I cant use using C=System.Console; Say `System.Console' is a type not a namespace \$\endgroup\$ – Juan Carlos Oropeza Apr 22 '15 at 19:10
  • 1
    \$\begingroup\$ There's no reason why n can't be a double... See my answer. \$\endgroup\$ – Peter Taylor Apr 22 '15 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\$
  • \$\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\$ – Juan Carlos Oropeza Apr 22 '15 at 17:22
  • \$\begingroup\$ I went back to double, Need 15 decimals precision. :( \$\endgroup\$ – Juan Carlos Oropeza Apr 22 '15 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, privacy policy and cookie policy

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