Hackerboard WikiHaboBlog

[HaBo]

 
Programmieraufgaben Hier wird regelmäßig eine neue Programmieraufgabe gestellt, die dann gelöst werden soll und in Zusammenarbeit mit den Moderatoren auch besprochen werden kann.

Treppensteigen

Diskussion: Treppensteigen im Forum Programmieraufgaben, in der Kategorie Code Kitchen; Hi, ich hab wieder mal eine Programmieraufgabe für euch (angelehnt an ein 'Hackit'): Und zwar sollt ihr ein Programm schreiben ...

Antwort
Alt 18.11.06, 18:56   #1 (permalink)
 
Registriert seit: 23.05.05
Xalon Leistung: Facit NTK
Xalon eine Nachricht über ICQ schicken
Likes: 0
Standard Treppensteigen


Hi,
ich hab wieder mal eine Programmieraufgabe für euch (angelehnt an ein 'Hackit'):

Und zwar sollt ihr ein Programm schreiben das ausrechnet wie viele Möglichkeiten es gibt
eine x Stufen lange Treppe zu ersteigen wenn man zwischen 2 und 1 Stufen pro 'Tritt'
wählen kann.

Die Anzahl der Stufen soll vom User kommen,das Programm soll die Möglichkeiten und
deren Anzahl ausgeben.

Mögliches Output:

Treppenstufen: 4
...
Möglichkeiten: 5
1 1 1 1 - 1 1 2 - 1 2 1 - 2 1 1 - 2 2


Happy Coding,
Xalon

Xalon ist offline   Mit Zitat antworten
Alt 22.11.06, 14:10   #2 (permalink)
 
Registriert seit: 03.12.04
Boar Leistung: Facit NTK
Likes: 0
Standard RE: Treppensteigen

Java-Lösung   

Die Klasse Treppensteigen:
Code:
package treppen;

import java.util.Vector;

public class Treppensteigen {
	private int stufen;
	private Vector<String> moeglichkeit = new Vector<String>();
	private boolean add;
	
	public Treppensteigen(int stufen) {
		this.stufen = stufen;		
		String buffer = "";
		for(int i=0; i<stufen; i++) {
			buffer+= "1";
		}
		moeglichkeit.addElement(buffer);
		suche(buffer,-1,0);
	}

	private void suche(String buffer,int a, int b) {
		if(a!=-1) {
			// Lösche die 1en an den Stellen a und b
			// und ersetze sie durch eine 2
			if(b!=buffer.length()-1) {
				buffer = buffer.substring(0, a)+"2"+buffer.substring(b+1);
			} else {
				buffer = buffer.substring(0, a)+"2";
			}	
			
			//Vermeiden von doppelten Lösungen
			add = true;
			for(int i=0; i<moeglichkeit.size(); i++) {
				if(buffer.equals(moeglichkeit.elementAt(i))) {
					add = false;
				}
			}
			if(add) {
				moeglichkeit.addElement(buffer);
			}			
		}		
		
		// Suche nach zwei 1ern nebeneinander
		if((stufen % 2 == 0 && buffer.length()>(stufen/2))
				|| (stufen % 2 !=0 && buffer.length()>(stufen/2+1))){
			for(int i=0; i<buffer.length()-1; i++) {
				if(buffer.charAt(i)== '1' && buffer.charAt(i+1)=='1') {
					suche(buffer,i,i+1);
				}
			}
		}	
	}
	
	public void ausgabe() {
		System.out.println("Treppenstufen: "+stufen);
		System.out.println("Möglichkeiten: "+moeglichkeit.size());
		for(int i=0; i<moeglichkeit.size(); i++) {		
			System.out.print(moeglichkeit.elementAt(i));
			if(i!= moeglichkeit.size()-1) {
				System.out.print(" - ");
			}
		}
		System.out.println("\n");
	}
}
Die Klasse TreppenTest:
Code:
package treppen;

public class TreppenTest {
	public static void main(String[] args) {
		Treppensteigen vier = new Treppensteigen(4);
		vier.ausgabe();
		
		Treppensteigen fuenf = new Treppensteigen(5);
		fuenf.ausgabe();
	}
}

Müsste einwandfrei Funktionieren. Ein Beispiel für die Ausgabe bei 6 Treppenstufen:

Code:
Treppenstufen: 6
Möglichkeiten: 13
111111 - 21111 - 2211 - 222 - 2121 - 2112 - 12111 - 1221 - 1212 - 11211 - 1122 - 11121 - 11112
Gruß, Boar
Boar ist offline   Mit Zitat antworten
   
HaBOT
 

Werbung ist gerade online    
Alt 22.11.06, 16:22   #3 (permalink)
 
Registriert seit: 21.07.05
Cube Leistung: Facit NTK
Likes: 0
Standard

es kommt die Reihe der fibonaccizahlen raus...nur falls jumd ma überprüfen will, ob sein prog auch für größere treppen läuft...
Cube ist offline   Mit Zitat antworten
Alt 22.11.06, 18:53   #4 (permalink)
 
Registriert seit: 03.12.04
Boar Leistung: Facit NTK
Likes: 0
Standard

Zitat:
Original von Cube
es kommt die Reihe der fibonaccizahlen raus...nur falls jumd ma überprüfen will, ob sein prog auch für größere treppen läuft...
Cool, hat ein bisschen gedauert bis ich verstanden hab was du meinst.

Habs jetzt auch mit 10 Stufen (89 Möglichkeiten) und 15 Stufen (987 Möglichkeiten) getestet. Bei 15 Stufen rechnet er aber schon ne ganze weile.
Boar ist offline   Mit Zitat antworten
Alt 13.01.07, 15:40   #5 (permalink)
 
Registriert seit: 01.11.03
lagalopex Leistung: Facit NTK
Likes: 0
Standard

Meine Lösung in C++
37 Zeilen C++   
Code:
#include <iostream>

using namespace std;

int main()
{
	int i = 0, co = 0, num, l = 0;
	cout << "Treppenstufen: " << flush;
	cin >> num;

	char *c = new char [num];
	c[0] = 0;
	i = 0;
	for (;;) {
		if (c[i] <= 1 && co < num) {
			++c[i];
			++co;
			++i;
			c[i] = 0;
			if (co == num) {
				if (l != 0)
					cout << " - ";
				for (int j = 0; j < i; ++j)
					cout << (unsigned int) c[j];
				++l;
			}
		} else {
			co -= c[i];
			--i;
			if (i < 0)
				break;
		}
	}
	delete [] c;
	cout << "\nMoeglichkeiten: " << l << endl;
	return 0;
}

Also bei 15 Stufen geht es noch fast ohne Verzögerung (~50ms). Bei 30 Stufen sinds dann aber gut 5 Sekunden.
lagalopex ist offline   Mit Zitat antworten
Alt 16.06.07, 03:22   #6 (permalink)
 
Registriert seit: 29.04.07
pi() Leistung: Facit NTK
Likes: 0
Standard

OMG.Ich glaub ich hab die schnellste Lösung .Ist ja mal echt nicht schwer gewesen!

Lösung   

# include <stdio.h>

int main () {
int treppen;
printf("Geben Sie bitte die Anzahl der Treppen ein\n");
scanf("%d",&treppen);


int n;
long double a=1,b=0,c;
for (n=0;n<treppen;n++) {
c=a+b;
b=a;
a=c;
}
printf("bei %d Treppen gibt es %Lf Möglichkeiten",treppen,c);
}


edit: Diese Aufgabe wäre sehr gut in Java zu Lösen (BigInteger), weil man da auch sehr große Treppen eingeben kann.Dafür gehts etwas langsamer, denn BigInteger ist ne saulahme Klasse.....

weiteres edit:Hoppla, mit dieser Möglichkeit gibt man ja die Möglichkeiten nicht aus.... Sry.
__________________
Seht euch das bitte einmal an.Hab mir echt Mühe gegeben:
Hier: www.gutinmathe.at
pi() ist offline   Mit Zitat antworten
Alt 04.07.07, 02:48   #7 (permalink)
ba2
Guest
 
Likes:
Standard

Ich habe das ganze in Python Programmiert (Mein erstes sinnvolles Python Programm)

Code   
Code:
def stufen(stufen):
	a=0
	b=1
	i=0
	
	while i < stufen:
		c=a+b
		a=b
		b=c
		i=i+1
	return b
	
print 'Ergebnis: ', stufen(input('Anzal der Stufen? '))


Richtig testen ob es die korrekten werte liefert konnte ich es nicht.

Ich hab mich jetzt einfach mal an der Aussage von Boar orrientiert das 10 Stufen 89 Möglichkeiten und 15 stufen 987 Möglichkeiten sind.

Das ganze arbeitet recht flott 50000 Stufen unter einer Sekunde, nur die Zahl ist Gigantisch ^^


mfg ba2
  Mit Zitat antworten
Alt 04.07.07, 23:01   #8 (permalink)
 
Benutzerbild von metax.
 
Registriert seit: 22.01.07
metax. Leistung: 8086
metax. eine Nachricht über ICQ schicken
Likes: 10
Standard

Hier noch eine Lösung in Perl nach dem bewährten Divide-And-Conquer Verfahren ;-)

code   

Code:
#!/usr/bin/perl -w

use strict;
use warnings;

my $gesamt;

sub stufen {
  my $l = shift;
  my $c = shift;

  if($l < 1) {
    return;
  } else {
    if ($l == 1) {
      print $c . '1' . "\n";
      $gesamt++;
    } else {
      if ($l == 2) {
        stufen ($l - 1, $c . '1-');
        print $c . '2' . "\n";
        $gesamt++;
      } else {
        stufen ($l - 1, $c . '1-');
        stufen ($l - 2, $c . '2-');
      }
    }
  }
}

print "Bitte ganze Zahl fuer Anzhal Schritte eingeben:\n";
chomp(my $a = <STDIN>);
print "--------\n\n";

stufen($a, '');
print "\nGesamt:$gesamt\n";

mfg, metax.
__________________
Wenn keiner zuschaut, teile ich heimlich durch Null!
Meine Homepage: Planet Metax | meine Bilder: DeviantArt | Twitter
metax. ist offline   Mit Zitat antworten
Alt 14.07.07, 20:41   #9 (permalink)
 
Registriert seit: 14.07.07
MattA Leistung: Facit NTK
Likes: 0
Standard

Habs auch nochmal mit Backtracking unter C gemacht, leider nur so dass es zeigt wie viele Möglichkeiten, aber nicht welche:

Code:
#include <stdio.h>

void treppe(int stufen, int aktuell, int * moeg){
        if(stufen==aktuell) {
                (*moeg)++;
                return;
        }
        if(aktuell+2<=stufen){
                treppe(stufen,aktuell+2, moeg);
        }
        treppe(stufen,aktuell+1, moeg);
}

int main() {
        int moeg=0;
        int stufen=6;
        treppe(stufen,0,&moeg);
        printf("Moeglichkeiten bei %d Stufen: %d\n",stufen,moeg);
        return 0;
}
MattA ist offline   Mit Zitat antworten
Alt 21.02.08, 15:53   #10 (permalink)
 
Registriert seit: 14.11.07
Cyber_Puma Leistung: Facit NTK
Likes: 0
Standard

Lest euch mal bitte die Aufgabenstellung durch...

Es kann garnicht sein das bei 10 Stufen es 89 Möglichkeiten gibt jedenfalls nicht nach diese Aufgabenstellung ......

Die möglichkeit 112 und 211 ist doch die gleiche also dürfte es doch nur 1 Möglichkeit sein, oder seh ich etwas falsch.
Hier mein Lösungsansatz ich denk mal die Aufgabe war so gemeint.
Angehängte Dateien
Dateityp: txt Treppensteigen.txt (1,0 KB, 33x aufgerufen)
Cyber_Puma ist offline   Mit Zitat antworten
Alt 21.02.08, 18:29   #11 (permalink)
Senior Member
 
Registriert seit: 26.03.06
Serow Leistung: 8086
Likes: 12
Standard

@Boar:
Um doppelte zu vermeiden kannst du statt Vector<String> ein Set<String> benutzen.
Serow ist offline   Mit Zitat antworten
Alt 26.02.08, 21:09   #12 (permalink)
 
Registriert seit: 28.09.07
Kenniej91 Leistung: Facit NTK
Likes: 0
Standard

@CyberPuma:
Ne, ich glaube nicht, außerdem ist das doch gerade schwieriger.

Hier jedenfalls mein Programm, es gibt die Kombinationen zwar noch nicht richtig aus, aber das werde ich noch beheben. Zudem kann man die Maximale Schrittgröße bei mir eingeben. Das Ganze habe ich rekursiv gelöst, wobei ich glaube das man das ja nicht anders machen kann(wenn nicht, dann sagt es mir bitte).
Code:
#include<iostream>

using namespace std;

int GiveNumber(const int NumberHoles,int MaxStep);

int main(void)
{
	  cout<<"Geben sie die Anzahl der Stufen an\n";
	  int NumberHoles=0;
	  int MaxStep=0;
			cin>>NumberHoles;
			if(NumberHoles<1)return 1;
			cout<<"Wie gross darf ein Schritt sein?\n";
			cin>>MaxStep;
			if(MaxStep<1)return 1;
			int InfoSteps=GiveNumber(NumberHoles,MaxStep);
   cout<<"\n\n\nEs gibt "<<InfoSteps<<" Moeglichkeiten\n";
   cin>>NumberHoles;
	  
	  return 0;
}
int GiveNumber(const int NumberHoles,int MaxStep)
{
	  int PossibleSteps=0;
	  int CopyHoles=NumberHoles;
	  for(int i=1;i<=MaxStep;i++)
	  {
				  CopyHoles=NumberHoles;
				  CopyHoles-=i;
				  cout<<i;
				  if(CopyHoles==0)
						{
							  cout<<'\n';
									PossibleSteps++;
									return PossibleSteps;
						}
						PossibleSteps+=GiveNumber(CopyHoles,MaxStep);
			}
	  return PossibleSteps;
}
Kenniej91 ist offline   Mit Zitat antworten
Alt 22.03.08, 23:10   #13 (permalink)
 
Registriert seit: 22.03.08
MontyPerl Leistung: Facit NTK
Likes: 0
Standard

Treppenknecht v0.1   
Code:
#!/usr/bin/env perl
use warnings;
use strict;

our $STEPMAXIMUM = 2;

my $stufenCount;
if (@ARGV) {$stufenCount = $ARGV[0]}
else {chomp($stufenCount = <>)}

sub treppenKnecht {
    my ($cur, $sol, $pos, $max) = @_;
    if ($pos == $max) {push(@$sol, join('', @$cur)); return 1}
    if ($pos > $max) {return 0}
    for my $step (1..$STEPMAXIMUM) {
        if (treppenKnecht([@$cur, $step], $sol, $pos+$step, $max)) {return 0}
    }
}

my @solutions;
treppenKnecht([], \@solutions, 0, $stufenCount);

foreach (@solutions) {print "$_\n"}

Nimmt die Stufenanzahl entweder als erstes Argument oder von STDIN. Außerdem kann man einfach das "Schrittweitenmaximum" ändern beziehungsweise auch einfach irgendeine willkürliche Liste mit Schrittmöglichkeiten eintragen.

Die Anzahl der Möglichkeiten hätte ich extra mit angeben können, aber ich habe lieber eine Möglichkeit pro Zeile und pipe das dann in wc. Wäre ja auch kein Problem das eben mit ins Skript zu nehmen, but i prefer not to.
Code:
./treppenknecht.pl 23|wc -l
46368
MontyPerl ist offline   Mit Zitat antworten
Alt 03.06.08, 21:25   #14 (permalink)
CDW
Moderator
 
Benutzerbild von CDW
 
Registriert seit: 20.07.05
CDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: Opteron
Likes: 156
Standard

Wozu muss man sich irgendwelche Algorithmen überlegen? Der Computer ist doch zum Nachdenken da, man muss ihm nur das Problem beschreiben
Prolog gut kommentiert   

Code:
schritt(1).  %es gibt zwei Arten von Schritten.
schritt(2).
%Problem des Treppensteigens ist gelöst
%sofern man alle Stufen überwunden hat (wer hätte es gedacht ;) )
loesung(Stufen_gesamt,Zurueckgelegt):-
	Stufen_gesamt =:= Zurueckgelegt.
%sonst:
loesung(Stufen_gesamt,Zurueckgelegt):-
	Stufen_gesamt>Zurueckgelegt,  %hat man noch nicht alle Stufen zurückgelegt,
	schritt(Schrittweite),  %gibt es einen Schritt, der uns vielleicht 
	loesung(Stufen_gesamt,Zurueckgelegt+Schrittweite), %in Lösungsnähe bringt	
	write(Schrittweite),write(' '). %wenn es so war, 
        %sollte man den Schritt ausgeben

%gehört nicht mehr zur Lösung, sondern dient eher bequemeren Ausgabe
loesungen(Stufen_gesamt, Anzahl):-
	findall(X,(loesung(Stufen_gesamt,0),nl),Ergebnis),
	length(Ergebnis,Anzahl).

oder Prolog, kommentarlos und kompakt   

Code:
schritt(1). 
schritt(2).

loesung(St,Zu):- St is Zu.

loesung(St,Zu):- St>Zu, 	
       schritt(Sw),loesung(St,Zu+Sw),write(Sw),write(' ').

loesungen(Stufen_gesamt, Anzahl):-
	findall(X,(loesung(Stufen_gesamt,0),nl),Ergebnis),
	length(Ergebnis,Anzahl).


wobei "findall" keine magische und geheime Handlung darstellt, sondern dazu dient alle Lösungen aufeinmal auszugeben (normalerweise liefert Prolog immer nur eine und man muss explizit bestätigen, wenn man eine weitere haben möchte).

Ausgabe   

Code:
?- loesungen(5,Anzahl).
1 1 1 1 1 
2 1 1 1 
1 2 1 1 
1 1 2 1 
2 2 1 
1 1 1 2 
2 1 2 
1 2 2 
Anzahl = 8.

?- loesungen(4,Anzahl).
1 1 1 1 
2 1 1 
1 2 1 
1 1 2 
2 2 
Anzahl = 5.

Wobei man sich auch eine Beschreibung als Permutation der Schritte vorstellen könnte (aber solange mache ich Prolog noch nicht).
__________________
Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf!
Selig, wer nichts zu sagen hat und trotzdem schweigt.
CDW ist offline   Mit Zitat antworten
Alt 16.06.08, 20:07   #15 (permalink)
 
Registriert seit: 12.01.07
Scorn07 Leistung: Facit NTK
Likes: 0
Standard

ObjectPascal Lösung   
Code:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var global_stufen : integer;
    global_string : string;
    Stufen : Integer;

procedure Stufe(iZähler : Integer; Str : String);
  begin
    if iZähler >=2 then
    begin
       Stufe(iZähler-1, Str+ '1');
       Stufe(iZähler-2, Str+ '2');
    end else
      if iZähler = 1 then
      Stufe(iZähler-1, Str+ '1')
      else begin
       inc(global_stufen);
       global_string := global_string + Str + ' | ';
      end;
  end;

begin
  global_stufen := 0;
  writeln('Bitte Anzahl der Stufen eingeben:');
  readln(Stufen);
  Stufe(Stufen, '');
   writeln(global_string);
   writeln('Anzahl der Moeglichkeiten:');
   writeln(global_stufen);
   readln;
end.
end.


Ich hab das Problem mit einer Rekursion gelöst.

Eine Beispielausgabe:
Code:
Bitte Anzahl der Stufen eingeben:
5
11111 | 1112 | 1121 | 1211 | 122 | 2111 | 212 | 221 |
Anzahl der Moeglichkeiten:
8
//Edit1: Quelltext berichtigt
Scorn07 ist offline   Mit Zitat antworten
Antwort
   

Werbung ist gerade online    

[HaBo] » Software Home » Code Kitchen » Programmieraufgaben » Treppensteigen
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61