Seite 1 von 1

Aufsummieren mal anders

Verfasst: Montag 26. Mai 2014, 17:20
von duodiscus
Hallo zusammen,
wenn ich eine Summe von Werten bilden wollte, habe ich dieses bisher immer mit einer Schleife gelöst:

Code: Alles auswählen

def summe(n):
    summe=0
    for i in range(n):

        summe = summe + i+1
        
    print(summe)
Wie könnte ich denn eine Aufsummierung der Zahlen rekursiv angehen? Also das sich die Funktion immer wieder selbst aufruft und die Werte bis n aufsummiert? Kann mir da jemand was zu sagen? Vielen Dank!

Re: Aufsummieren mal anders

Verfasst: Montag 26. Mai 2014, 17:25
von duodiscus
Habe es schon.

Code: Alles auswählen


return n + SummeRek(n-1)

Re: Aufsummieren mal anders

Verfasst: Montag 26. Mai 2014, 18:42
von snafu
Wohl eher so:

Code: Alles auswählen

def gib_summe(n):
    return n + gib_summe(n - 1) if n > 1 else n
Denn ohne eine Abbruchbedingung wird die rekursive Aufrufkette niemals beendet. Außer natürlich, wenn der Stack voll ist. Wobei die Abbruchbedingung keinesfalls nur ein notwendiges Übel ist, sondern vielmehr einen essentiellen Bestandteil für die dahinter stehende Logik darstellt.

Und falls man mal was ganz Verrücktes machen möchte:

Code: Alles auswählen

def gib_summe(n):
    return sum(range(n + 1))
Oder auch total crazy:

Code: Alles auswählen

def gib_summe(n):
    return (n**2 + n) / 2

Re: Aufsummieren mal anders

Verfasst: Montag 26. Mai 2014, 18:51
von BlackJack
Und wieder eine Hausaufgabenlösung für duodiscus. Hihihi. :-)

Re: Aufsummieren mal anders

Verfasst: Dienstag 27. Mai 2014, 11:09
von Hyperion
In Scala mit Endrekursion

Code: Alles auswählen

package Summen

import scala.annotation.tailrec

object Summe {

  def main(args: Array[String]) {
    println("Summe von 5 ist " + sum(5))
  }

  def sum(limit: Int) = {

    @tailrec
    def sumAcc(acc: Int, rest: Int): Int =
      if (rest == 0) acc
      else sumAcc(acc + rest, rest - 1)

    sumAcc(0, math.abs(limit))
  }

}

Re: Aufsummieren mal anders

Verfasst: Dienstag 27. Mai 2014, 13:19
von BlackJack
Vielleicht noch die *vernünftige* Lösung für diese Aufgabe, die weder iterativ noch rekursiv ist:

Code: Alles auswählen

def gib_summe(n):
    return n * (n + 1) / 2

Re: Aufsummieren mal anders

Verfasst: Dienstag 27. Mai 2014, 14:05
von Hyperion
BlackJack hat geschrieben:Vielleicht noch die *vernünftige* Lösung für diese Aufgabe, die weder iterativ noch rekursiv ist:
Ach komm... der kleine Gauß wäre doch auch nie darauf gekommen, wenn seine REPL nicht aus Schiefer gewesen wäre :twisted:

Re: Aufsummieren mal anders

Verfasst: Dienstag 27. Mai 2014, 18:30
von Hyperion
Hier noch mal der rekursive Ansatz in Clojure (Wieso gibt es da kein Syntax-Highlighting? Nicht mal irgend ein Lisp / Scheme finde ich da :-( )

Code: Alles auswählen

(defn sum [n]
  (loop [acc 0 rest n]
    (if (zero? rest)
      acc
      (recur (+ acc rest) (dec rest)))))
Dabei fiel mir ein, dass wir den über ``reduce`` "vergessen" haben, also auch den mal in Clojure:

Code: Alles auswählen

(defn sum [n]
  (reduce + (range 1 (+ n 1))))

Re: Aufsummieren mal anders

Verfasst: Dienstag 27. Mai 2014, 18:34
von BlackJack
@Hyperion: Lisp und Scheme kann man manuell angeben. Aber wie man sieht, sind die nicht besonders.

Re: Aufsummieren mal anders

Verfasst: Dienstag 27. Mai 2014, 18:39
von Hyperion
Danke für den Tipp... ja, bringt jetzt nicht so viel :-D

Verwendet das Board hier Geshi? Dafür gibts ne Implementierung: Link

Re: Aufsummieren mal anders

Verfasst: Dienstag 27. Mai 2014, 18:47
von BlackJack
@Hyperion: Jup, das Board verwendet Geshi.

Re: Aufsummieren mal anders

Verfasst: Dienstag 27. Mai 2014, 18:51
von snafu
Steht ja nur unter jedem Codeblock rechts unten... :roll: :twisted: :wink:

Re: Aufsummieren mal anders

Verfasst: Dienstag 27. Mai 2014, 19:11
von Hyperion
snafu hat geschrieben:Steht ja nur unter jedem Codeblock rechts unten... :roll: :twisted: :wink:
Ja hab ich die Zeit und Muße alles zu lesen... :oops:

Auf uu.de gibt's Clojure Highlighting bereits - Pygments sei dank :-)

Edit: Hier auch! s.o.
@BlackJack: Man kann auch "clojure" von Hand angeben - da geht vermutlich also so ziemlich alles von Geshi :-)

Re: Aufsummieren mal anders

Verfasst: Dienstag 27. Mai 2014, 20:03
von BlackJack
Dann will ich auch mal etwas Rekursives beisteuern. Langweiliges JavaScript:

Code: Alles auswählen

var sum = function (n) { return (n > 0) ? n + sum(n - 1) : 0; };

Re: Aufsummieren mal anders

Verfasst: Dienstag 27. Mai 2014, 21:03
von EyDu
Dann mache ich mal mit:

Code: Alles auswählen

sum = lambda n: (lambda f, x: f(f, x))(lambda f, x: x + f(f, x - 1) if x > 0 else 0, n)

Re: Aufsummieren mal anders

Verfasst: Mittwoch 28. Mai 2014, 00:29
von DasIch
Wirklich elegant lässt sich sowas doch nur in Opal implementieren:

Sum.sign

Code: Alles auswählen

SIGNATURE Sum

IMPORT Nat ONLY nat
       Seq ONLY seq


FUN sum : seq[nat] -> nat
Sum.impl

Code: Alles auswählen

IMPLEMENTATION Sum

IMPORT Nat COMPLETELY
       Seq COMPLETELY
       SeqReduce COMPLETELY


DEF sum(ns) == (+, 0) \ ns

Re: Aufsummieren mal anders

Verfasst: Mittwoch 28. Mai 2014, 10:27
von BlackJack
Iterativ in 6510-Assembler:

Code: Alles auswählen

!zone
; In:   A = n
; Out:  A/X = sum from 1 to n
;       Y = 0
; Uses: A, X, Y, r1
sum:
        ldx #0
        tay
        cpy #0
        beq .exit
        stx r1
-
        clc
        tya
        adc r1
        sta r1
        bcc +
        inx
+
        dey
        bne -

        lda r1
.exit:
        rts