7
\$\begingroup\$

This Perl code is supposed to calculate the Leibniz formula. The original problem is here.

The input format is:

T
<T test cases, each on their own line>

Each test case is a number < 10^7. The output format should be the same, minus the first line.

For example, an input:

2 
10 
20

And for output:

0.760459904732351
0.77290595166696

My first solutions, at 62 and 61 characters respectively.

for(1..<>){$s=0;map{$s+=($_&1||-1)/(2*$_-1)}1..<>;print"$s\n"}

for(1..<>){$s=0;$s+=($_&1||-1)/(2*$_-1)for 1..<>;print"$s\n"}

Edit: The best solution so far is 53 characters, by @teebee:

<>;print${\map$a-=(-1)**$_/(2*$_-1),1..$_},$a=$/for<>
\$\endgroup\$
  • \$\begingroup\$ possible duplicate of Calculate pi to 5 decimals \$\endgroup\$ – Peter Taylor Feb 5 '13 at 7:49
  • \$\begingroup\$ Why post the same question on two sites? I feel like it's either help or a puzzle, but not both. And as a puzzle it needs a puzzle-type (code-golf, coding-challenge) and objective winning criteria. \$\endgroup\$ – luser droog Feb 5 '13 at 8:06
  • 2
    \$\begingroup\$ I was recommended that this question belongs here more then stackoverflow so posted here. \$\endgroup\$ – Techmonk Feb 5 '13 at 8:16
3
\$\begingroup\$

Perl 55 bytes

<>;map($s-=(-1)**$_/(2*$_-1),1..$_),$s=!print$s,$/for<>

Without using any Perl non-standard features (such as say). 3 bytes are wasted removing the first value from the input.

Sample usage:

in.dat

2
10
20

$ perl leibniz.pl < in.dat
0.760459904732351
0.77290595166696

Alternative, also 55 bytes

map{$s-=(-1)**$_/($_*2-1)for 1..<>;$s=!print$s,$/}1..<>

The alternative may be run interactively, without requiring an input file. Which, as I understand, is what you meant by running indefinitely.

\$\endgroup\$
  • 1
    \$\begingroup\$ That goes in an infinite loop, but using this notation for for can save 2 more bytes map($s-=(-1)**$_/(2*$_-1),1..<>),$s=!print$s.$/for 1..<> \$\endgroup\$ – Techmonk Feb 5 '13 at 8:58
  • \$\begingroup\$ It will only cause an 'infinite' loop if the input given contains an infinite amount of lines. The for<> construction will iterate over every line in input passed to STDIN exactly once, without needing to 'know' beforehand how many there are. \$\endgroup\$ – primo Feb 5 '13 at 9:07
5
\$\begingroup\$

Perl 53 bytes

You can save two more strokes:

<>;print${\map$a-=(-1)**$_/(2*$_-1),1..$_},$a=$/for<>
\$\endgroup\$
  • \$\begingroup\$ Very clever. One would expect \map... to return a single array reference, and not a list of scalar references. \$\endgroup\$ – primo Jun 10 '13 at 9:28

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.