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.


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

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

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

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.


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

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)

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.


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

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

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*

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.


5

Mathematica

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

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


Nicht betrügen. Clever.
Michael Stern

Das ist brilliant. Ich wünschte, ich hätte für meinen R-Post daran gedacht.
Shadowtalker


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

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.


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

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

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}

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


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.


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!


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


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
** 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}

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

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

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


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.


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

"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.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.