Schreiben Sie eine Funktion, die (x, y) nimmt und x zur Potenz von y zurückgibt. WITHOUT Loops [closed]

14

Dies ist eine wirklich nette kurze Herausforderung.

Schreibe eine Funktion oder eine Prozedur , die zwei Parameter nimmt, xund yund gibt das Ergebnis aus , ohne Schleifen oder in Potenzfunktionen aufgebaut.xy

Der Gewinner ist die kreativste Lösung und wird nach 3 Tagen anhand der höchsten Stimmenzahl ausgewählt.

CodyBugstein
quelle
1
Was ist das für eine Herausforderung?
VisioN
22
Wie wäre es exp(log(x)*y)?
Squeamish Ossifrage
2
Ist eine Antwort nur für ganze Zahlen akzeptabel? Da dies die ersten Antworten sind.
mmumboss
4
In den bisherigen Antworten werden entweder Rekursionen oder Listen mit wiederholten 'x' verwendet. Ich zerbreche mir den Kopf und versuche, mir einen anderen Gedanken zu machen (insbesondere etwas, das ein nicht ganzzahliges y erlaubt).
BenM
1
Leider schließt das Verbot von Schleifen spaßige mathematische Lösungen wie die Taylor-Erweiterung aus.
Shadowtalker

Antworten:

27

APL (7)

{×/⍵/⍺}

Linkes Argument ist Basis, rechtes Argument ist Exponent, zB:

     5 {×/⍵/⍺} 6
15625

Erläuterung:

  • ⍵/⍺repliziert mal, zB 5 {⍵/⍺} 6->5 5 5 5 5 5
  • ×/nimmt das Produkt, zB ×/5 5 5 5 5 5-> 5×5×5×5×5×5->15625
Marinus
quelle
2
Hm .. Dies kann in 5 Zeichen in J geschrieben werden, genau die gleiche Methode. */@$~
Siehe auch
@Sieg 4 sogar, wenn Sie Exponent links zulassen, Basis rechts.
Donnerstag,
Ich hatte das Flip-Adverb, weil ich dachte, dass es nicht erlaubt ist.
Siehe auch
@Seeq 4 in Dyalog APL :×/⍴⍨
Adám
27

C #: Gleitkommaexponenten

OK, diese Lösung ist ziemlich zerbrechlich. Sie können es leicht brechen, indem Sie lächerlich große Zahlen wie 6 darauf werfen. Aber es funktioniert wunderbar für Dinge wie DoublePower(1.5, 3.4)und verwendet keine Rekursion!

    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
quelle
43
"lächerlich große zahlen wie 6" das hat mir gefallen.
DavidC
Sicherlich basiert die Verwendung von Enumerable-Funktionen auf Schleifen, die in der Frage verboten waren, oder ist dies in Ordnung, weil sich die Schleife innerhalb von Framework-Methoden befindet?
Chris
16

C ++

Wie wäre es mit einer Template-Meta-Programmierung? Es verbiegt die kleinen Regeln, die es gab, aber es ist einen Versuch wert:

#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
quelle
1
Aber das ist keine Funktion, sondern ein Wert zur Kompilierungszeit, oder? : O
PaperBirdMaster
Nun, ein Konstruktor ist eine Funktion, und Template-Parameter sind fast wie Funktionsargumente ... richtig? =)
Erlc
@PaperBirdMaster Ja ... deshalb gab ich zu, dass ich Regeln biege. Ich dachte, ich würde etwas anderes als die Schwanzrekursion einreichen, aber ich habe nur die Schwanzrekursion zur Kompilierungszeit eingereicht, haha. Nah genug, richtig?
Astephens4
@ Astephens4 nah genug, ich liebe es: 3
PaperBirdMaster
15

Python

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

Funktioniert nicht für nicht ganzzahlige Potenzen.

Hovercouch
quelle
Ich mag dieses.
CodyBugstein
1
Warum fügen Sie ein Trennzeichen hinzu, ohne es zu verwenden join? eval('*'.join([str(x)] * y)).
Bakuriu
1
War das Code-Trolling?
Gerrit
Möchten Sie auch beachten, dass Python den **Operator hat, so dass Sie eval () d haben könnten.
Riking
3
@Riking: das wäre aber eine eingebaute.
Hovercouch
10

Haskell - 25 Zeichen

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

Folgende Marinus APL-Version:

f x y = product $ take y $ repeat x

Wenn der Kommentar von mniip und das Leerzeichen entfernt sind, werden 27 Zeichen angezeigt:

f x y=product$replicate y x
intx13
quelle
Verwenden Sie replicate y xanstelle vontake y $ repeat x
mniip
4
Ich war überzeugt, dass Sie Zeichen sparen können, indem Sie Ihre zweite Funktion ohne Punkte schreiben. Wie sich herausstellt, f=(product.).flip replicateist genau die gleiche Anzahl von Zeichen.
Kaya
@mniip Es ist egal, das ist kein Code Golf.
nyuszika7h
10

Python

If yist eine positive ganze Zahl

def P(x,y):
    return reduce(lambda a,b:a*b,[x]*y)
Julien Ch.
quelle
7

JavaScript (ES6), 31

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

Verwendung:

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

Erläuterung:

Die obige Funktion erstellt einen Ausdruck, der multipliziert x yund dann ausgewertet wird.

Florent
quelle
6

Ich bin überrascht zu sehen, dass noch niemand eine Lösung mit dem Y Combinator geschrieben hat ... also:

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

Keine Schleifen, keine Vektor- / Listenoperationen und keine (explizite) Rekursion!

>>> pow((2,0))
1
>>> pow((2,3))
8
>>> pow((3,3))
27
berdario
quelle
Äh, ich habe gerade KChaloux's Haskell-Lösung gesehen, die benutzt fix, um ihn zu stimmen ...
berdario
5

C #: 45

Funktioniert nur für ganze Zahlen:

int P(int x,int y){return y==1?x:x*P(x,y-1);}
Rik
quelle
Schlagen Sie mich :-) Ich denke, Sie könnten ein paar Bytes sparen, indem Sie return --y?x:x*P(x,y);stattdessen schreiben
zimperliches Ossifrage
1
Aber das ist kein Code-Golf ...
Oberon
1
@oberon Gewinnkriterien war nicht klar, als dies veröffentlicht wurde. Die Dinge sind weitergegangen.
Level River St
@steveverrill Entschuldigung.
Oberon
Auch in C # --y wäre ein Int, was nicht dasselbe ist wie ein Bool wie in anderen Sprachen.
Chris
5

bash & sed

Keine Zahlen, keine Schleifen, nur ein peinlich gefährlicher Glob-Missbrauch. Führen Sie es aus Sicherheitsgründen vorzugsweise in einem leeren Verzeichnis aus. Shell-Skript:

#!/bin/bash
rm -f xxxxx*
eval touch $(printf xxxxx%$2s | sed "s/ /{1..$1}/g")
ls xxxxx* | wc -l
rm -f xxxxx*
orion
quelle
Msgstr "Führen Sie das Programm aus Sicherheitsgründen vorzugsweise in einem leeren Verzeichnis aus." : D
Almo
5

Javascript

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

Verwendet reguläre Ausdrücke, um ein Array der Größe y + 1 zu erstellen, dessen erstes Element 1 ist. Reduzieren Sie dann das Array mit Multiplikation, um die Leistung zu berechnen. Wenn y = 0 ist, ist das Ergebnis das erste Element des Arrays, nämlich 1.

Zugegeben, mein Ziel war es, i) keine Rekursion zu verwenden, ii) sie dunkel zu machen.

Topkara
quelle
5

Mathematica

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

Wahrscheinlich zu betrügen, um die Tatsache zu nutzen, dass x ^ (1 / y) = y√x

Rob Farr
quelle
Nicht betrügen. Clever.
Michael Stern
Das ist brilliant. Ich wünschte, ich hätte für meinen R-Post daran gedacht.
Shadowtalker
4

JavaScript

function f(x,y){return y--?x*f(x,y):1;}
Stephen Melvin
quelle
4

Golfscript, 8 Zeichen (einschließlich E / A)

~])*{*}*

Erläuterung:

TLDR: ein weiteres "Produkt von wiederholten Array" -Lösung.

Die erwartete Eingabe besteht aus zwei Zahlen, z 2 5. Der Stapel beginnt mit einem Element, der Zeichenfolge "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
quelle
Golfscript ist immer der richtige Weg.
Nit
3

Rubin

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

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

Beispielgebrauch:

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

Dies ist letztendlich dasselbe wie bei mehreren vorherigen Antworten: Erstellt ein Array mit y-Länge, von dem jedes Element x ist, und übernimmt dann das Produkt. Es ist nur unbegründet, damit es so aussieht, als würde es den verbotenen **Operator verwenden.

Histokrat
quelle
3

C: Potenzierung durch Quadrieren

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

Golf Version in 46 Bytes (danke ugoren!)

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

sollte schneller sein als alle anderen rekursiven Antworten bisher oO

etwas langsamere Version in 45 Bytes

p(a,b){return b<2?b?a:1:p(a*a,b/2)*p(a,b&1);}
Izabera
quelle
1
Für ungerade b, ~-b/2 == b/2.
Ugoren
@ugoren oh sicher, du hast recht
Izabera
Dies ist eine beliebte Interviewfrage :) "Wie kannst du pow(n, x)besser schreiben als 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

Es gibt bereits einen kürzeren Haskell-Eintrag, aber ich dachte, es wäre interessant, einen zu schreiben, der die fixin definierte Funktion nutzt Data.Function. Wird wie folgt verwendet (im Repl der Einfachheit halber):

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
quelle
2

Q.

9 Zeichen. Erzeugt ein Array mit yInstanzen vonx und übernimmt das Produkt.

{prd y#x}

Kann bei int / long x explizit in float umgewandelt werden, um einen größeren Bereich zu erreichen:

{prd y#9h$x}
Skeevey
quelle
1
Passendes Golfscript in der Länge ist eine Meisterleistung.
Nit
2

Ähnliche Logik wie viele andere in PHP:

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

Führen Sie es mit aus php file.php 5 3, um 5 ^ 3 zu erhalten

dkasipovic
quelle
2

Ich bin mir nicht sicher, wie viele Upvotes ich dafür erwarten kann, aber ich fand es etwas merkwürdig, dass ich heute tatsächlich genau diese Funktion schreiben musste. Und ich bin mir ziemlich sicher, dass dies das erste Mal ist, dass eine .SE-Site diese Sprache sieht (die Website scheint nicht sehr hilfreich zu sein).

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

Funktioniert für negative Exponenten und rationale Basen.

Ich habe es in der Java-Syntax hervorgehoben, weil ich das gerade mache, wenn ich mit dieser Sprache arbeite. Sieht gut aus.

daniero
quelle
2

Pascal

In der Challenge wurde weder der Typ noch der Bereich von x und y angegeben. Daher befolge die folgende Pascal-Funktion alle angegebenen Regeln:

{ 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;

Keine Schleife, keine eingebaute Potenz- oder Potenzierungsfunktion, nicht einmal Rekursion oder Arithmetik!

Celtschk
quelle
2

J - 5 oder 4 Bytes

Genau das gleiche wie die APL-Antwort von Marinus .

Für x^y:

*/@$~

Für y^x:

*/@$

Beispielsweise:

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

x $~ yerstellt eine Liste mit xWiederholungen y(wiey $ x

*/ xist die Produktfunktion, */ 1 2 3->1 * 2 * 3

seequ
quelle
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
quelle
1
** ist eingebauter Operator imo.
Silviu Burcea
@SilviuBurcea Wahr, Bearbeitung.
Oberon
@ SilviuBurcea Operator- =/=Funktion
VisioN
@VisioN wahr, aber die Idee war über eingebaute. Ich glaube nicht, dass das OP über all diese eingebauten Operatoren Bescheid weiß ...
Silviu Burcea
1

Javascript

Funktioniert mit der Schwanzrekursion, wenn yes sich um eine positive Ganzzahl handelt

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

Bash

Jeder weiß, bashdass er verrückte Kartenreduzierungen machen kann ;-)

#!/bin/bash

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

Wenn das zu trolly für Sie ist, dann gibt es das:

#!/bin/bash

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

C

Noch eine rekursive Potenzierung durch Quadrieren der Antwort in C, aber sie unterscheiden sich (dies verwendet eine Verschiebung anstelle einer Division, ist etwas kürzer und rekursiv ein Mal mehr als das andere):

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

Mathematica

Dies funktioniert für ganze Zahlen.

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

Beispiel

f[5,3]

125


Wie es funktioniert

Tablemacht eine Liste von y x's. Timesnimmt das Produkt von allen.`


Ein anderer Weg, um das gleiche Ziel zu erreichen :

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

Beispiel

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

125

DavidC
quelle
1

Windows Batch

Wie die meisten anderen Antworten hier wird die Rekursion verwendet.

@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 ist in der Umgebungsvariablen gespeichert z.

mackthehobbit
quelle
1

perl

Hier ist ein rekursiver Perl-Eintrag. Die Verwendung ist echo $ X, $ Y | foo.pl:

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

Oder für einen eher funktionalen Ansatz:

($x,$y) = split/,/, <>;
$t=1; map { $t *= $x } (1..$y);
print $t
Skibrianski
quelle
"a: stuff goto a if something" sieht aus wie eine Schleife.
Glenn Randers-Pehrson
Ja, die goto-Version ist eine Schleife, aber ist die Schwanzrekursion nicht auch im Wesentlichen eine Schleife?
Skibrianski
1

Python

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

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

answer =125

Ich bin nicht sicher, ob dies gegen die Anforderungen verstößt, aber wenn nicht, ist hier mein Versuch.

ali
quelle
Willkommen bei PPCG! Wenn Sie Ihre Sprachüberschrift schreiben, können Sie das "language =" weglassen, da jeder die Sprache in die Überschrift einsetzt, damit sie verstanden wird. Möglicherweise haben Sie hier gegen die Regeln verstoßen, aber wir lassen die Wähler entscheiden. Froh, ein neues Mitglied im Country Club zu haben.
Jonathan Van Matre