编写一个函数,该函数接受(x,y)并将x返回y的幂,而没有循环[关闭]


14

这是一个非常简洁的挑战。

编写一个带有两个参数的函数或过程,x并使用循环或内置的幂函数y返回WITHOUT 的结果。xy

获胜者是最具创造力的解决方案,将在3天后根据最高投票数选出。


1
这是什么挑战?
VisioN 2014年

22
怎么exp(log(x)*y)
r3mainer 2014年

2
是否只接受整数的答案?由于这些是第一批答复。
mmumboss 2014年

4
到目前为止,看来答案还是使用递归或重复的'x'列表。我努力尝试思考另一种方式(特别是允许使用非整数y的方式)。
BenM 2014年

1
不幸的是,对循环的禁止排除了有趣的数学解决方案,例如泰勒展开式。
shadowtalker 2014年

Answers:


27

杀伤人员地雷(7)

{×/⍵/⍺}

左参数为基,右参数为指数,例如:

     5 {×/⍵/⍺} 6
15625

说明:

  • ⍵/⍺复制 时间,例如5 {⍵/⍺} 6->5 5 5 5 5 5
  • ×/拿产品,例如×/5 5 5 5 5 5-> 5×5×5×5×5×5->15625

2
嗯。这完全可以用J中的5个字符编写。*/@$~
seequ 2014年

@Sieg 4甚至,如果允许左边的指数,也要基于右边的指数。
ɐɔıʇǝɥʇuʎs

我有副词副词,因为我认为这是不允许的。
seequ

@Seeq 4 Dyalog APL×/⍴⍨
亚当

27

C#:浮点指数

好的,此解决方案非常脆弱。您可以通过向其抛出可笑的巨大数字(例如6)来轻松打破它。但是它对于诸如DoublePower(1.5, 3.4),并且不使用递归!

    static double IntPower(double x, int y)
    {
        return Enumerable.Repeat(x, y).Aggregate((product, next) => product * next);
    }

    static double Factorial(int x)
    {
        return Enumerable.Range(1, x).Aggregate<int, double>(1.0, (factorial, next) => factorial * next);
    }

    static double Exp(double x)
    {
        return Enumerable.Range(1, 100).
            Aggregate<int, double>(1.0, (sum, next) => sum + IntPower(x, next) / Factorial(next));
    }

    static double Log(double x)
    {
        if (x > -1.0 && x < 1.0)
        {
            return Enumerable.Range(1, 100).
                Aggregate<int, double>(0.0, (sum, next) =>
                    sum + ((next % 2 == 0 ? -1.0 : 1.0) / next * IntPower(x - 1.0, next)));
        }
        else
        {
            return Enumerable.Range(1, 100).
                Aggregate<int, double>(0.0, (sum, next) =>
                    sum + 1.0 / next * IntPower((x - 1) / x, next));
        }
    } 

    static double DoublePower(double x, double y)
    {
        return Exp(y * Log(x));
    } 

43
我非常喜欢“像6这样可笑的数字”。
DavidC 2014年

当然,可枚举函数的使用依赖于问题中禁止的循环,还是可以的,因为循环在框架方法内部?
克里斯

16

C ++

模板元编程怎么样?它弯弯曲曲了一些小规则,但是值得一试:

#include <iostream>


template <int pow>
class tmp_pow {
public:
    constexpr tmp_pow(float base) :
        value(base * tmp_pow<pow-1>(base).value)
    {
    }
    const float value;
};

template <>
class tmp_pow<0> {
public:
    constexpr tmp_pow(float base) :
        value(1)
    {
    }
    const float value;
};

int main(void)
{
    tmp_pow<5> power_thirst(2.0f);
    std::cout << power_thirst.value << std::endl;
    return 0;
}

1
但这不是一个函数,而是一个编译时值,不是吗?:O
PaperBirdMaster 2014年

好吧,构造函数是一个函数,而模板参数几乎就像函数参数一样...对吗?=)
erlc 2014年

@PaperBirdMaster是的...这就是为什么我承认有些弯腰的原因。我以为我要提交除尾递归以外的内容,但是我只是提交了编译时尾递归,哈哈。不过足够接近吧?
astephens4 2014年

@ astephens4足够接近,我喜欢它:3
PaperBirdMaster 2014年


10

Haskell-25个字符

f _ 0=1
f x y=x*f x (y-1)

遵循Marinus的APL版本:

f x y = product $ take y $ repeat x

移除mniip的注释和空格后,共有27个字符:

f x y=product$replicate y x

使用replicate y x代替take y $ repeat x
mniip

4
我坚信可以通过无点编写第二个函数来保存字符。事实证明f=(product.).flip replicate,字符数完全相同。
卡亚2014年

@mniip没关系,这不是代码高尔夫球。
nyuszika7h 2014年

10

蟒蛇

如果y为正整数

def P(x,y):
    return reduce(lambda a,b:a*b,[x]*y)

7

JavaScript (ES6), 31

// Testable in Firefox 28
f=(x,y)=>eval('x*'.repeat(y)+1)

Usage:

> f(2, 0)
1
> f(2, 16)
65536

Explanation:

The above function builds an expression which multiply x y times then evaluates it.


6

I'm surprised to see that nobody wrote a solution with the Y Combinator, yet... thus:

Python2

Y = lambda f: (lambda x: x(x))(lambda y: f(lambda v: y(y)(v)))
pow = Y(lambda r: lambda (n,c): 1 if not c else n*r((n, c-1)))

No loops, No vector/list operations and No (explicit) recursion!

>>> pow((2,0))
1
>>> pow((2,3))
8
>>> pow((3,3))
27

Uh, I've just seen right now KChaloux's Haskell solution that uses fix, upvoting him...
berdario

5

C# : 45

Works for integers only:

int P(int x,int y){return y==1?x:x*P(x,y-1);}

Beat me to it :-) I think you could save a few bytes by writing return --y?x:x*P(x,y); instead
r3mainer

1
But this isn't code-golf...
Oberon

1
@oberon winning criteria was not clear when this was posted. Things have moved on.
Level River St

@steveverrill Sorry.
Oberon

Also in C# --y would be an int which is not the same as a bool like in other languages.
Chris

5

bash & sed

No numbers, no loops, just an embarrasingly dangerous glob abuse. Preferably run in an empty directory to be safe. Shell script:

#!/bin/bash
rm -f xxxxx*
eval touch $(printf xxxxx%$2s | sed "s/ /{1..$1}/g")
ls xxxxx* | wc -l
rm -f xxxxx*

"Preferably run in an empty directory to be safe." :D
Almo

5

Javascript

function f(x,y){return ("1"+Array(y+1)).match(/[\,1]/g).reduce(function(l,c){return l*x;});}

Uses regular expressions to create an array of size y+1 whose first element is 1. Then, reduce the array with multiplication to compute power. When y=0, the result is the first element of the array, which is 1.

Admittedly, my goal was i) not use recursion, ii) make it obscure.


5

Mathematica

f[x_, y_] := Root[x, 1/y]

Probably cheating to use the fact that x^(1/y) = y√x


Not cheating. Smart.
Michael Stern

This is brilliant. Wish I'd thought of it for my R post.
shadowtalker


4

Golfscript, 8 characters (including I/O)

~])*{*}*

Explanation:

TLDR: another "product of repeated array" solution.

The expected input is two numbers, e.g. 2 5. The stack starts with one item, the string "2 5".

Code     - Explanation                                             - stack
                                                                   - "2 5"
~        - pop "2 5" and eval into the integers 2 5                - 2 5        
]        - put all elements on stack into an array                 - [2 5]
)        - uncons from the right                                   - [2] 5
*        - repeat array                                            - [2 2 2 2 2]
{*}      - create a block that multiplies two elements             - [2 2 2 2 2] {*}
*        - fold the array using the block                          - 32

Golfscript is always the way to go.
Nit

3

Ruby

class Symbol
  define_method(:**) {|x| eval x }
end

p(:****[$*[0]].*(:****$*[1]).*('*'))

Sample use:

$ ruby exp.rb 5 3
125
$ ruby exp.rb 0.5 3
0.125

This ultimately is the same as several previous answers: creates a y-length array every element of which is x, then takes the product. It's just gratuitously obfuscated to make it look like it's using the forbidden ** operator.


3

C, exponentiation by squaring

int power(int a, int b){
    if (b==0) return 1;
    if (b==1) return a;
    if (b%2==0) return power (a*a,b/2);
    return a*power(a*a,(b-1)/2);
}

golfed version in 46 bytes (thanks ugoren!)

p(a,b){return b<2?b?a:1:p(a*a,b/2)*(b&1?a:1);}

should be faster than all the other recursive answers so far o.O

slightly slower version in 45 bytes

p(a,b){return b<2?b?a:1:p(a*a,b/2)*p(a,b&1);}

1
For odd b, ~-b/2 == b/2.
ugoren

@ugoren oh sure, you're right
izabera

This is a popular interview question :) "How can you write pow(n, x) better than O(n)?"
Jordan Scales

3

Haskell - 55

pow x y=fix(\r a i->if i>=y then a else r(a*x)(i+1))1 0

There's already a shorter Haskell entry, but I thought it would be interesting to write one that takes advantage of the fix function, as defined in Data.Function. Used as follows (in the Repl for the sake of ease):

ghci> let pow x y=fix(\r a i->if i>=y then a else r(a*x)(i+1))1 0
ghci> pow 5 3
125

2

Q

9 chars. Generates array with y instances of x and takes the product.

{prd y#x}

Can explicitly cast to float for larger range given int/long x:

{prd y#9h$x}

1
Matching Golfscript in length is a feat to achieve.
Nit

2

Similar logic as many others, in PHP:

<?=array_product(array_fill(0,$argv[2],$argv[1]));

Run it with php file.php 5 3 to get 5^3


2

I'm not sure how many upvotes I can expect for this, but I found it somewhat peculiar that I actually had to write that very function today. And I'm pretty sure this is the first time any .SE site sees this language (website doesn't seem very helpful atm).

ABS

def Rat pow(Rat x, Int y) =
    if y < 0 then
        1 / pow(x, -y)
    else case y {
        0 => 1;
        _ => x * pow(x, y-1);
    };

Works for negative exponents and rational bases.

I highlighted it in Java syntax, because that's what I'm currently doing when I'm working with this language. Looks alright.


2

Pascal

The challenge did not specify the type or range of x and y, therefore I figure the following Pascal function follows all the given rules:

{ data type for a single bit: can only be 0 or 1 }
type
  bit = 0..1;

{ calculate the power of two bits, using the convention that 0^0 = 1 }
function bitpower(bit x, bit y): bit;
  begin
    if y = 0
      then bitpower := 1
      else bitpower := x
  end;

No loop, no built-in power or exponentiation function, not even recursion or arithmetics!


2

J - 5 or 4 bytes

Exactly the same as marinus' APL answer.

For x^y:

*/@$~

For y^x:

*/@$

For example:

   5 */@$~ 6
15625
   6 */@$ 5
15625

x $~ y creates a list of x repeated y times (same as y $ x

*/ x is the product function, */ 1 2 3 -> 1 * 2 * 3


1

Python

from math import sqrt

def pow(x, y):
    if y == 0:
        return 1
    elif y >= 1:
        return x * pow(x, y - 1)
    elif y > 0:
        y *= 2
        if y >= 1:
            return sqrt(x) * sqrt(pow(x, y % 1))
        else:
            return sqrt(pow(x, y % 1))
    else:
        return 1.0 / pow(x, -y)

1
** is built-in operator imo.
Silviu Burcea

@SilviuBurcea True, editing.
Oberon

@SilviuBurcea operator =/= function
VisioN

@VisioN true, but the idea was about built-ins. I don't think the OP knows about all these built-in operators ...
Silviu Burcea

1

Javascript

With tail recursion, works if y is a positive integer

function P(x,y,z){z=z||1;return y?P(x,y-1,x*z):z}

1

Bash

Everyone knows bash can do whizzy map-reduce type stuff ;-)

#!/bin/bash

x=$1
reduce () {
    ((a*=$x))
}
a=1
mapfile -n$2 -c1 -Creduce < <(yes)
echo $a

If thats too trolly for you then there's this:

#!/bin/bash

echo $(( $( yes $1 | head -n$2 | paste -s -d'*' ) ))

1

C

Yet another recursive exponentiation by squaring answer in C, but they do differ (this uses a shift instead of division, is slightly shorter and recurses one more time than the other):

e(x,y){return y?(y&1?x:1)*e(x*x,y>>1):1;}

1

Mathematica

This works for integers.

f[x_, y_] := Times@@Table[x, {y}]

Example

f[5,3]

125


How it works

Table makes a list of y x's. Times takes the product of all of them.`


Another way to achieve the same end:

#~Product~{i,1,#2}&

Example

#~Product~{i, 1, #2} & @@ {5, 3}

125


1

Windows Batch

Like most of the other answers here, it uses recursion.

@echo off
set y=%2
:p
if %y%==1 (
set z=%1
goto :eof
) else (
    set/a"y-=1"
    call :p %1
    set/a"z*=%1"
    goto :eof
)

x^y is stored in the environment variable z.


1

perl

Here's a tail recursive perl entry. Usage is echo $X,$Y | foo.pl:

($x,$y) = split/,/, <>;
sub a{$_*=$x;--$y?a():$_}
$_=1;
print a

Or for a more functional-type approach, how about:

($x,$y) = split/,/, <>;
$t=1; map { $t *= $x } (1..$y);
print $t

"a: stuff goto a if something" looks like a loop.
Glenn Randers-Pehrson

Yep, the goto version is a loop, but isn't tail recursion also essentially a loop?
skibrianski

1

Python

def getRootOfY(x,y):
   return x**y 

def printAnswer():
   print "answer is ",getRootOfY(5,3)
printAnswer()

answer =125

I am not sure if this is against the requirements, but if not here is my attempt.


Welcome to PPCG! When you do your language header you can leave out the "language=" since by custom everyone puts the language in the header so that's understood. You may indeed have run afoul of the rules here, but we'll let the voters decide. Glad to have a new member at the country club.
Jonathan Van Matre
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.