Напишите функцию, которая принимает (x, y) и возвращает x в степень y без циклов [закрыто]

14

Это действительно аккуратный короткий вызов.

Написать функцию или процедуру , которая принимает два параметра, xа yи возвращает результат без использования петель, или встроенную функций питания.xy

Победитель является наиболее креативным решением и будет выбран на основе наибольшего количества голосов через 3 дня.

CodyBugstein
источник
1
Что это за вызов?
VisioN
22
Как насчет exp(log(x)*y)?
r3mainer
2
Приемлем ли ответ только для целых чисел? Так как это первые ответы.
mmumboss
4
Похоже, что ответы пока либо используют рекурсию, либо списки повторяющихся х. Я ломаю мозги, пытаясь придумать другой способ (особенно то, что допускает нецелое число y).
BenM
1
К сожалению, запрет на петли исключает забавные математические решения, такие как расширение Тейлора.
бродяга

Ответы:

27

APL (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
Хм .. Это может быть написано в 5 символов в J, точно таким же способом. */@$~
Seequ
@ Sieg 4 даже, если вы позволите показателю степени слева, основание справа.
Febıʇǝɥʇuʎs
У меня было перевернутое наречие, потому что я думал, что это не разрешено.
Seequ
@ Seq 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));
    } 
BenM
источник
43
"смехотворно огромные числа, такие как 6", я наслаждался этим.
DavidC
Конечно, использование функций Enumerable полагается на циклы, которые были запрещены в вопросе, или это нормально, потому что цикл находится внутри методов каркаса?
Крис
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;
}
astephens4
источник
1
но это не функция, это значение времени компиляции, не так ли? : O
PaperBirdMaster
Ну, конструктор - это функция, а параметры шаблона почти как аргументы функции ... верно? =)
erlc
@PaperBirdMaster Да ... вот почему я признался в изгибе некоторых правил. Я думал, что собираюсь представить что-то кроме хвостовой рекурсии, но я просто представил хвостовую рекурсию времени компиляции, хаха. Хотя достаточно близко, правда?
astephens4
@ astephens4 достаточно близко, я люблю это: 3
PaperBirdMaster
15

питон

def power(x,y):
    return eval(((str(x)+"*")*y)[:-1])

Не работает для нецелых сил.

Hovercouch
источник
Мне нравится этот.
CodyBugstein
1
Почему вы добавляете разделитель без использования join? eval('*'.join([str(x)] * y)),
Бакуриу
1
Был ли этот код-троллинг?
gerrit
Также хотелось бы отметить, что в python есть **оператор, так что вы могли бы сделать это с помощью eval ().
Riking
3
@Riking: это было бы встроено, все же.
Hovercouch
10

Haskell - 25 символов

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

После версии APL Маринуса:

f x y = product $ take y $ repeat x

С комментарием mniip и удалением пробела, 27 символов:

f x y=product$replicate y x
intx13
источник
используйте replicate y xвместоtake y $ repeat x
mniip
4
Я был убежден, что вы можете сохранить символы, написав свою вторую функцию pointfree. Как оказалось, f=(product.).flip replicateточно такое же количество символов.
Кая
@mniip Это не имеет значения, это не код гольф.
nyuszika7h
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)

Использование:

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

Объяснение:

Вышеприведенная функция создает выражение, которое умножается на несколько x yраз, а затем оценивает его.

Флоран
источник
6

Я удивлен, увидев, что никто не написал решение с Y Combinator, но ... таким образом:

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)))

Нет циклов, нет векторных / списочных операций и нет (явной) рекурсии!

>>> pow((2,0))
1
>>> pow((2,3))
8
>>> pow((3,3))
27
berdario
источник
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);}
Rik
источник
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*
orion
источник
"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.

topkara
источник
5

Mathematica

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

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

Rob Farr
источник
Not cheating. Smart.
Michael Stern
This is brilliant. Wish I'd thought of it for my R post.
shadowtalker
4

JavaScript

function f(x,y){return y--?x*f(x,y):1;}
Stephen Melvin
источник
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
Claudiu
источник
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.

histocrat
источник
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);}
izabera
источник
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
KChaloux
источник
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}
skeevey
источник
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

dkasipovic
источник
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.

daniero
источник
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!

celtschk
источник
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

seequ
источник
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)
Oberon
источник
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}
Julien Ch.
источник
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'*' ) ))
Digital Trauma
источник
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;}
Fors
источник
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

DavidC
источник
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.

mackthehobbit
источник
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
skibrianski
источник
"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.

ali
источник
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