Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Das Programmier-Spiel: nette Übungsaufgaben für zwischendurch
zommi
myCSharp.de - Member

Avatar #avatar-2617.png


Dabei seit:
Beiträge: 1380
Herkunft: Berlin

beantworten | zitieren | melden

Hi fielding,

ich kommentier auch nochmal kurz meinen Code:


// Methode geht alle Zahlen von [0 .. maximumSum] durch und prüft,
// ob sich diese als Summe von Zahlen aus values darstellen lässt.
// Die Größte Zahl, die nicht als Summe darstellbar ist, wird zurückgegeben.
public static int  MaxNonReachableSum(int[] values, int maximumSum)
{
	// Array in dem wir nach und nach eintragen, ob eine Summe erreichbar ist
    bool[] reachable = new bool[maximumSum+1];
	// Die 0 ist stets erreichbar (indem wir keine Zahl nehmen)
    reachable[0] = true;

	// nun jede Zahl durchgehen und gucken, ob wir mit dieser neue Summen erreichen können
    foreach(int value in values)
	{
		// hier könnte man ALLE möglichen Summen durchgehen, 
		// spart sich aber etwas, wenn man nur die prüft, 
		// die größer als die aktuelle Zahl <value> sind,
		// denn nur bei denen kann <value> in der Summe enthalten sein!
        for(int subSum = maximumSum; subSum ≥ value; subSum--)
		{
			// Wenn eine Summe <subSum> bisher nicht erreichbar war, gucken, 
			// ob wir sie vielleicht jetzt bilden können
			if(!reachable[subSum])
			{
				// subSum ist dann erreichbar, wenn <subSum-Value> bisher erreichbar war
				// (da ich dann ja "(subSum-value) + value = subSum" bilden kann)
				reachable[subSum] = reachable[subSum - value];
			}
		}
	}

	// Nun die letzte Summe wählen, die nicht erreicht worden ist.
    return Array.LastIndexOf(reachable, false);
}

Nachtrag zur inneren For-Schleife:
Es ist etwas riskant die neu erreichbaren Summen im alten Array direkt zu markieren. Dies ist nämlich höchst sensitiv gegenüber der Zählrichtung. Wenn wir vorwärts (subSum++) laufen würden, könnte eine Zahl mehrfach zur Summe beitragen, die sie auch zu Summen dazuaddiert wird, die erst durch sie selbst darstellbar wären.
(Angenommen ich fange mit dem Ausgangsarray an und wähle die 2 als erste Zahl, dann wäre beim Vorwärtslaufen danach jede gerade Zahln erreichbar)

Beim Rückwärtslaufen hingegen erreicht man die andere Semantik, dass jede Zahl nur genau einmal verwendet werden darf.
(Angenommen ich fange mit dem Ausgangsarray an und wähle die 2 als erste Zahl, dann wäre beim Rückwärtslaufen runter von 10 Mio. danach nur noch die 2 erreichbar)

beste Grüße
zommi
private Nachricht | Beiträge des Benutzers
fielding
myCSharp.de - Member



Dabei seit:
Beiträge: 62

beantworten | zitieren | melden

Vielen Dank euch beiden, das macht das ganze einfach viel verständlicher (nicht nur für mich, sondern für jeden besucher dieses threads) und man muss nicht erst umständlich mit dem debugger durch den code gehen, um zu begreifen was passiert. Das ist meiner Meinung nach das bisschen Mehraufwand wert ;)
private Nachricht | Beiträge des Benutzers
Floste
myCSharp.de - Member

Avatar #avatar-2376.jpg


Dabei seit:
Beiträge: 1158
Herkunft: Norddeutschland

beantworten | zitieren | melden

Nächste aufgabe:

Ein programm erstellen, in das man c#code eingibt, welcher dann ein bild generiert.
Der code den man eingibt soll eine klasse sein, die von folgendem interface ableitet:


interface ISharpPixelShader
{
    void Start(int width,height);
    int GetPixelColor(int x,int y,int width,height);//x und y sind die position des pixels. width und height sind die abmessungen des bildes.
    void End();
}
Das programm soll den code compilieren. Fehler sollten ausgegeben werden. Wenn das compilieren geklappt hat, eine instanz der compilieren klasse erstellen und mit dieser instanz soll ein bitmap (entweder fix 500x500 oder wählbare größe) befüllt werden. Das bitmap soll erst gespeichert und dann in einem fenster angezeigt werden.

Codeeingabe entweder als dateiname in einem argument der main oder über ein gui. (es reicht, wenn eine der beiden möglichkeiten implementiert wird.)

Tipp: man muss dem compiler mitteilen, dass auf typeof(ISharpPixelShader).Assembly verwiesen wird.

[ERG:]Bitte nicht getpixel, sondern lockbits verwenden!
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Floste am .
Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Hast du mal so eine Eingabeklasse?

Ansonsten hier mal meine Quick'n'Dirty-Lösung:


using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using Microsoft.CSharp;

public class PictureGenerator
{
	public static void Main(string[] args)
	{
		try
		{
			string path = args[0];
			string source = File.ReadAllText(path);

			CSharpCodeProvider cSharpCodeProvider = new CSharpCodeProvider(new Dictionary<string,string>() { { "CompilerVersion","v3.5" } });
			CompilerParameters compilerParameters = new CompilerParameters { GenerateInMemory = true,GenerateExecutable = false };

			Action<string> addAssembly = (assemblyLocation) =>
			{
				if (!compilerParameters.ReferencedAssemblies.Contains(assemblyLocation))
					compilerParameters.ReferencedAssemblies.Add(assemblyLocation);
			};
			addAssembly(Assembly.GetExecutingAssembly().Location);
			foreach (AssemblyName referencedAssemblyName in Assembly.GetExecutingAssembly().GetReferencedAssemblies())
				try { addAssembly(Assembly.ReflectionOnlyLoad (referencedAssemblyName.FullName).Location); }
				catch (FileNotFoundException) { }

			CompilerResults compilerResults = cSharpCodeProvider.CompileAssemblyFromSource(compilerParameters,source);

			if (compilerResults.Errors.Count>0)
				throw new ArgumentException(String.Join("\r\n",compilerResults.Errors.Cast<CompilerError>().Select(ce => ce.ErrorText).ToArray()));
			else
			{
				Type generatedType = compilerResults.CompiledAssembly.GetTypes().First(t => t.GetInterface("ISharpPixelShader")!=null);
				ISharpPixelShader sharpPixelShader = (ISharpPixelShader)Activator.CreateInstance(generatedType);

				Bitmap bitmap = new Bitmap(500,500);
				sharpPixelShader.Start(bitmap.Width,bitmap.Height);
				for (int x=0;x<bitmap.Width;x++)
					for (int y=0;y<bitmap.Height;y++)
						bitmap.SetPixel(x, y ,sharpPixelShader.GetPixelColor (x, y, bitmap.Width, bitmap.Height));
				sharpPixelShader.End();

				bitmap.Save(path+".png",ImageFormat.Png);

				Form form = new Form();
				PictureBox pictureBox = new PictureBox { Dock = DockStyle.Fill,Image = bitmap };
				form.Controls.Add(pictureBox);
				Application.Run(form);
			}
		}
		catch (Exception exception)
		{
			MessageBox.Show(exception.Message);
		}
	}
	
	public interface ISharpPixelShader
	{
		void Start(int width,int height);
		Color GetPixelColor(int x,int y,int width,int height);
		void End();
	}
}

Ich war mal so frei und habe dein Interface etwas angepasst. Erstens so, dass es auch kompiliert, zweitens gibt GetPixelColor auch eine Farbe zurück.

Gruß,
dN!3L
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dN!3L am .
private Nachricht | Beiträge des Benutzers
Floste
myCSharp.de - Member

Avatar #avatar-2376.jpg


Dabei seit:
Beiträge: 1158
Herkunft: Norddeutschland

beantworten | zitieren | melden

Ein paar kleinigkeiten:
1. locken statt setpixel
2. zeilennummern in den fehlermeldungen?
3. out of range exception ist nicht sehr aufschlussreich, wenn man keine datei angibt.
(4. den typ der fehlermeldung im titel anzeigen)

ansonsten ok.
Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Pff... Dann halt einmal in schöner:


using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.CSharp;

public static class PictureGenerator
{
	public interface ISharpPixelShader
	{
		void Start(int width,int height);
		Color GetPixelColor(int x,int y,int width,int height);
		void End();
	}

	public static void Main(string[] args)
	{
		try
		{
			if (args.Length==0)
				throw new ArgumentException("Kein Pfad zur Quelldatei angegeben");
			string path = args[0];

			File.ReadAllText(path)
				.CompileToAssembly()
				.GetPixelShader()
				.CreateBitmap()
				.SaveBitmapFor(path)
				.ShowBitmap();
		}
		catch (Exception exception)
		{
			MessageBox.Show (exception.Message,exception.GetType ().Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
		}
	}

	private static Assembly CompileToAssembly(this string source)
	{
		CSharpCodeProvider cSharpCodeProvider = new CSharpCodeProvider(new Dictionary<string,string>() { { "CompilerVersion","v3.5" } });
		CompilerParameters compilerParameters = new CompilerParameters { GenerateInMemory = true,GenerateExecutable = false };
		compilerParameters.AddReferencedAssemblies();
		CompilerResults compilerResults = cSharpCodeProvider.CompileAssemblyFromSource(compilerParameters,source);
		if (compilerResults.Errors.Count>0)
			throw new ArgumentException (String.Join("\r\n", compilerResults.Errors.Cast<CompilerError>().Select(ce => ce.Line+": "+ce.ErrorText).ToArray()));
		else
			return compilerResults.CompiledAssembly;
	}

	private static void AddReferencedAssemblies(this CompilerParameters compilerParameters)
	{
		compilerParameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
		foreach (AssemblyName referencedAssemblyName in Assembly.GetExecutingAssembly().GetReferencedAssemblies())
			try
			{
				string assemblyLocation = Assembly.ReflectionOnlyLoad (referencedAssemblyName.FullName).Location;
				if (!compilerParameters.ReferencedAssemblies.Contains (assemblyLocation))
					compilerParameters.ReferencedAssemblies.Add (assemblyLocation);
			}
			catch (FileNotFoundException) { }
	}

	private static ISharpPixelShader GetPixelShader(this Assembly assembly)
	{
		Type generatedType = assembly.GetTypes().FirstOrDefault(t => t.GetInterface("ISharpPixelShader")!=null);
		if (generatedType==null)
			throw new ArgumentException("Assembly enthält keinen Typen, der die Schnittstelle 'ISharpPixelShader' implementiert.");
		else
			return (ISharpPixelShader)Activator.CreateInstance(generatedType);
	}

	private static Bitmap CreateBitmap(this ISharpPixelShader sharpPixelShader)
	{
		Bitmap bitmap = new Bitmap(500,500);
		sharpPixelShader.Start(bitmap.Width,bitmap.Height);
		BitmapData bitmapData = bitmap.LockBits(new Rectangle(0,0,bitmap.Width,bitmap.Height),ImageLockMode.ReadWrite,PixelFormat.Format32bppRgb);
		byte[] rgbValues = new byte[bitmapData.Stride*bitmap.Height];
		Marshal.Copy(bitmapData.Scan0,rgbValues,0,rgbValues.Length);
		for (int x=0;x<bitmap.Width;x++)
			for (int y=0;y<bitmap.Height;y++)
			{
				int i = x*4+y*bitmapData.Stride;
				Color color = sharpPixelShader.GetPixelColor(x,y,bitmap.Width,bitmap.Height);

				rgbValues[i+0] = color.B;
				rgbValues[i+1] = color.G;
				rgbValues[i+2] = color.R;
				rgbValues[i+3] = color.A;
			}
		Marshal.Copy(rgbValues,0,bitmapData.Scan0,rgbValues.Length);
		bitmap.UnlockBits(bitmapData);
		sharpPixelShader.End();
		return bitmap;
	}

	private static Bitmap SaveBitmapFor(this Bitmap bitmap,string sourcePath)
	{
		bitmap.Save(sourcePath+".png",ImageFormat.Png);
		return bitmap;
	}

	private static void ShowBitmap(this Bitmap bitmap)
	{
		Form form = new Form();
		PictureBox pictureBox = new PictureBox { Dock = DockStyle.Fill,Image = bitmap };
		form.Controls.Add(pictureBox);
		Application.Run(form);
	}
}
private Nachricht | Beiträge des Benutzers
Floste
myCSharp.de - Member

Avatar #avatar-2376.jpg


Dabei seit:
Beiträge: 1158
Herkunft: Norddeutschland

beantworten | zitieren | melden

^.^ is ja gut, du bist dran.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Floste am .
Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Neue Aufgabe.

Erstmal etwas Vorgeplänkel: Gegeben sein beispielsweise folgende Auflistung


public class Container
{
	public DateTime Date { get; set; }
	public string Value { get; set; }
	public override string ToString() { return this.Value; }
}
//...
Container[] dataSource = new[]
{
    new Container { Date = new DateTime(2009,1,1),Value = "Januar '09" },
    new Container { Date = new DateTime(2009,2,1),Value = "Februar '09" },
    new Container { Date = new DateTime(2010,1,1),Value = "Januar '10" },
    new Container { Date = new DateTime(2010,2,1),Value = "Feburar '10" },
    new Container { Date = new DateTime(2010,3,1),Value = "März '10" },
};
Mit einem Left Outer Join kann man nun jedes Element der Auflistung mit dem Element des Montats des Vorjahres (falls vorhanden) zusammenführen:


var query = 
	from left in dataSource join right in dataSource 
	on left.Date equals right.Date.AddYears(1) into rightGroup
	from right in rightGroup.DefaultIfEmpty()
	select new { LeftValue = left.Value,RightValue = (right!=null) ? right.Value : null };
... ergibt dann für obiges Beispiel...

{ LeftValue = "Januar '09", RightValue = null }
{ LeftValue = "Februar '09", RightValue = null }
{ LeftValue = "Januar '10", RightValue = "Januar '09" }
{ LeftValue = "Feburar '10", RightValue = "Februar '09" }
{ LeftValue = "März '10", RightValue = null }
Es soll eine (Erweiterungs-)Methode erstellt werden, die genau das tut, allerdings mit folgenden Bedingungen:
[list]
[*]Die Eingabeauflistung (IEnumerable<T>) kann unendlich groß sein.
[*]Die Eingabeauflistung ist flüchtig, d.h. zwei Enumeratoren dieser Auflistung liefern [i]nicht[/i] die gleichen Elemente.
[*]Die Eingabeauflistung wird mit sich selbst zusammengeführt (vgl. Join mit sich selbst)
[/list]
Es kann vorrausgesetzt werden, dass die Eingabeauflistung bezüglich des Vergleichswertes geordnet vorliegt (d.h für das obige Beispiel, dass der Datumswert eines Elements immer größer[/gleich] seinen Vorgängern ist).

Und noch ein Beispiel für eine flüchtige unendliche Quellauflistung:


public IEnumerable<Container> GetValues()
{
	while (true)
	{
		yield return new Container { Date = dateTime,Value = dateTime.ToString("MMM yy") };
		dateTime = dateTime.AddMonths(1);
	}
}
private static DateTime dateTime = new DateTime(2001,5,1);

Gutes Gelingen,
dN!3L
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7548
Herkunft: Waidring

beantworten | zitieren | melden

Hallo,

den Punkt
Zitat
Die Eingabeauflistung wird mit sich selbst zusammengeführt (vgl. Join mit sich selbst)
habe ich nicht verstanden. Aber eine Lösung für die Aufgabe habe ich hoffentlich doch ;-)


public static class ProgrammierSpiel
{
	public static IEnumerable<Result> Daniel(this IEnumerable<Container> dataSource)
	{
		Dictionary<DateTime, Container> memo = new Dictionary<DateTime, Container>();

		foreach (Container left in dataSource)
		{
			Container right = null;
			DateTime rightDate = left.Date.AddYears(-1);
			if (memo.ContainsKey(rightDate))
			{
				right = memo[rightDate];
				memo.Remove(rightDate);		// damit memo nicht sinnlos wächst
			}

			yield return new Result
			{
				LeftValue = left.Value,
				RightValue = (right != null) ? right.Value : null
			};

			memo[left.Date] = left;
		}
	}
}

public class Result
{
	public string LeftValue { get; set; }
	public string RightValue { get; set; }
}

Liefert das korrekte Ergebnis für das Referenzbeispiel und läuft solange bis AddMonth in der GetValues-Methode einen Fehler wirft.


mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Zitat von gfoidl
den Punkt "Die Eingabeauflistung wird mit sich selbst zusammengeführt (vgl. Join mit sich selbst)" habe ich nicht verstanden.
Zu einem Join (den ich ja als Beispiel gebracht hatte) gehören ja zwei Auflistungen (an die Elemente aus A werden Elemente aus B "rangejoint"/zusammengeführt). Ich wollte nur noch einmal verdeutlichen, dass bei der Aufgabe eine Auflistung mit sich selbst gejoined wird.

Zitat von gfoidl
Liefert das korrekte Ergebnis für das Referenzbeispiel und läuft solange bis AddMonth in der GetValues-Methode einen Fehler wirft.
Gut, ganz so unendlich ist die Auflistung auch nicht. Aber im Prinzip... :)
Ich guck mir deine Lösung morgen mal genauer an.

Zum Zeitvertreib kann ich ja noch wie Floste nachträglich die Bedingungen verschärfen ;)
  • Generisch, nicht nur auf Container beschränkt
  • Nicht nur auf Date und nicht nur auf AddYear(1) beschränkt
  • Nicht auf Result beschränkt
Hinweis: Signatur von Enumerable.Join

Nee, musst nicht. Bisherige Lösung reicht aus. Es sein denn, es will noch jemand eine Lösung mit einer Queue anbieten...

Bis morgennachher,
dN!3L
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dN!3L am .
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Hallo Gü,

Sodenn. Eine Kleinigkeit ist noch: Für die Eingabedaten...


var dataSource = new[]
{
	new Container { Date = new DateTime(2009,1,1),Value = "Januar '09" },
	new Container { Date = new DateTime(2010,1,1),Value = "Januar '10" },
	new Container { Date = new DateTime(2010,1,1),Value = "Januar '10" }
};
... ergibt dein Code:

LeftValue = "Januar '09" RightValue = null
LeftValue = "Januar '10" RightValue = "Januar '09"
LeftValue = "Januar '10" RightValue = null
Der zweite Jan10 hat kein Jan09. Das ein Eingabelement gleich dem Vorgängerelement sein kann, steht zwar in der Aufgabenstellung nur in Klammern, aber vll. bekommst du das noch schnell geändert.

Ansonsten: Sehr schön. Ist eine gültige Lösung. Du bist dran.

Besten Gruß,
dN!3L
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7548
Herkunft: Waidring

beantworten | zitieren | melden

Hallo Daniel,
Zitat
Eine Kleinigkeit ist noch: Für die Eingabedaten...
Lässt sich durch entfernen von memo.Remove(...) lösen, allerdings wächst dann das Dictionary bei der unendlichen Eingabe ;-)

Für die neue Aufgabe muss ich erstmal prüfen ob die noch im Verlaufe des Spiels gestellt worden ist - habe den Thread noch nicht lange verfolgt.


mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7548
Herkunft: Waidring

beantworten | zitieren | melden

Hallo zusammen,

die nächste Aufgabe ;-)
Gegeben sei folgender Code:
[CSHARP]
public class Aufgabe
{
	public IEnumerable<Ergebnis> Ermittle()
	{
		throw new NotImplentedException();
	}
}

public struct Ergebnis
{
	public int A;
	public int B;
	public int C;
}

[TestFixture]
public class AufgabeTest
{
	[Test]
	public void Ermittle_OK()
	{
		Aufgabe sut = new Aufgabe();

		List<Ergebnis> ergebnis = sut.Ermittle().ToList();
		Assert.AreEqual(1, ergebnis.Count);

		int a = ergebnis[0].A;
		int b = ergebnis[0].B;
		int c = ergebnis[0].C;

		Assert.IsTrue(a < b && b < c);
		Assert.AreEqual(c * c, a * a + b * b);
		Assert.AreEqual(1000, a + b + c);
	}
}
[/CSHARP]
Der Code für die Methode [tt]Ermittle[/tt] soll nun so vervollständigt werden dass der Test erfolgreich bestanden wird. Dabei soll zur Lösung jedoch kein brachialer Brute-Force verwendet werden (also möglichst wenig Iterationen ;-). Bei der Lösung auch [tt]Ergebnis[/tt] angeben.

Viel Spass!


mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Hallo Gü,

interessante Aufgabe. Kann man sogar ohne Programmieren lösen, indem man mal Wolfram fragt...
Hast du mal einen Richtwert für "möglichst wenig Iterationen"? Im Moment liege ich bei 83.167.
Wobei man den Test ja auch ohne eine einzige Iteration bestehen kann. Ergebnis ist ja konstant. ;)

Gruß,
dN!3L
private Nachricht | Beiträge des Benutzers
Lennart
myCSharp.de - Member



Dabei seit:
Beiträge: 429
Herkunft: Bawü

beantworten | zitieren | melden

Hallo,

ich hänge schon bei
Zitat
Ergebnis: a: 200 b: 375 c: 425 Durchläufe: 25810025

private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7548
Herkunft: Waidring

beantworten | zitieren | melden

Hallo Daniel,
Zitat
Hast du mal einen Richtwert für "möglichst wenig Iterationen"?
Ich benötige < 5 Iterationen ;-)
Zitat
Wobei man den Test ja auch ohne eine einzige Iteration bestehen kann. Ergebnis ist ja konstant. ;)
Der Test ist nur dazu gedacht damit die Aufgabe erst daraus ermittelt werden muss - sonst empfand ich es als zu einfach ;-)


Hallo Lennart,

das Ergebnis stimmt schon mal - aber zu viele Iterationen.



mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
Lennart
myCSharp.de - Member



Dabei seit:
Beiträge: 429
Herkunft: Bawü

beantworten | zitieren | melden

Hallo Gü,
Zitat von gfoidl
Ich benötige < 5 Iterationen ;-)
auch für andere Werte als 1000?

gruß
private Nachricht | Beiträge des Benutzers
der-schlingel
myCSharp.de - Member

Avatar #avatar-3239.jpg


Dabei seit:
Beiträge: 820
Herkunft: Österreich/Wien

beantworten | zitieren | melden

Darf das Verfahren schon nach dem ersten Fund aufhören oder sollen alle Tripel für a + b + c = 1000 gefunden werden? Oder gibt es gar nur eine Lösung?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von der-schlingel am .
As a man thinketh in his heart, so he is.
- Jun Fan
Es gibt nichts Gutes, außer man tut es.
- Erich Kästner
Krawutzi-Kaputzi
- Kasperl
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7548
Herkunft: Waidring

beantworten | zitieren | melden

Hallo Lennart,

wenns >> 1000 dann ein paar mehr, aber nicht wesentlich mehr.


Hallo der-schlingel,

nachdem der Test nur 1 Lösung erlaubt kann abgebrochen werden ;-)
Für a + b + c = 1000 gibts eh nur 1 Lösung.



mfG Gü
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von gfoidl am .
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
zommi
myCSharp.de - Member

Avatar #avatar-2617.png


Dabei seit:
Beiträge: 1380
Herkunft: Berlin

beantworten | zitieren | melden

Hi,
Zitat von dN!3L
Kann man sogar ohne Programmieren lösen, indem man mal Wolfram fragt...
Das schließt sich doch nicht gegenseitig aus!
Daher - auch wenn nur so aus Spaß


public IEnumerable<Ergebnis> Ermittle()
        {            
            string url = "http://api.wolframalpha.com/v1/query?appid=beta824g5&input=solve+a^2%2Bb^2%3Dc^2+and+a%2Bb%2Bc%3D1000+and+a%3Cb%3Cc+over+the+integers";
            var reg = new System.Text.RegularExpressions.Regex(@"a = (?<a>.*) and b = (?<b>.*) and c = (?<c>.*)");

            // Query an Wolfram Alpha absetzen
            // solve a^2+b^2=c^2 and a+b+c=1000 and a<b<c over the integers
            var xd = System.Xml.Linq.XDocument.Load(url);

            // ErgebnisTag finden
            var resultPod =
                (from item in xd.Descendants("queryresult").First().Descendants("pod")
                where (string)item.Attribute("id")=="Result"
                select item).First();
                        
            // Einzelne Ergebnisse als strings raussuchen "a=... and b=... and c=..."
            var solutions =
                from item in resultPod.Descendants("subpod")
                select item.Descendants("plaintext").First().Value;

            // Integer-Werte extrahieren
            return solutions.Select(s => 
                {
                    var g = reg.Match(s).Groups;
                    return new Ergebnis {
                        A = Int32.Parse(g["a"].Value), 
                        B = Int32.Parse(g["b"].Value),
                        C = Int32.Parse(g["c"].Value)
                    };
                });
                // Oder vor dem Semikolon noch ein 
                // .Where(e => e.A>0 && e.B>0 && e.C>0)
                // wenn man nur positive Lösungen sehen will
        }

beste Grüße
zommi
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von zommi am .
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7548
Herkunft: Waidring

beantworten | zitieren | melden

Hallo zommi,

interessant, aber die Ergebnisse stimmen nicht. Alleine schon deshalb da ich nicht das Ergebnis schreibe ;-)


mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
zommi
myCSharp.de - Member

Avatar #avatar-2617.png


Dabei seit:
Beiträge: 1380
Herkunft: Berlin

beantworten | zitieren | melden

Jaaa, jetzt beschwer dich mal nich,
du hast ja nie geschrieben, dass du nur Lösungen mit a,b,c > 0 haben willst ;-P
Das Assert mit Count=1 deutet zwar darauf hin, aber explizit geht anders :-)

Negative Lösungen gibt er halt auch noch aus.
Aber dann pack eben noch noch ein


.Where(e => e.A>0 && e.B>0 && e.C>0)
an das return-Statement :-)

beste Grüße
zommi
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von zommi am .
private Nachricht | Beiträge des Benutzers
Gelöschter Benutzer

beantworten | zitieren | melden

wozu das where? schick einfach an wolfram alpha die bedingungen mit....
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7548
Herkunft: Waidring

beantworten | zitieren | melden

Hallo zommi,
Zitat
du hast ja nie geschrieben, dass du nur Lösungen mit a,b,c > 0 haben willst
Das stimmt, aber es wurde nach 1 Lösung verlangt.

Assert.AreEqual(1, ergebnis.Count);
Aber egal...


Eigentlich hast du das Problem (mit der Where-Bedinung) gelöst und auch C#-Code gezeigt, aber es ist nicht so wie ich mir vorgestellt habe...

Wollt ihr noch weiter grübeln oder ist zommi dran?


mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
zommi
myCSharp.de - Member

Avatar #avatar-2617.png


Dabei seit:
Beiträge: 1380
Herkunft: Berlin

beantworten | zitieren | melden

Zitat
aber es ist nicht so wie ich mir vorgestellt habe...
Wollt ihr noch weiter grübeln oder ist zommi dran?
Ja bitte eine ordentlich Lösung !
Also weitergrübeln!
Das war nur als Spaß, weil ich dN!3Ls Wolfram-Idee so gut fand =)

beste Grüße
zommi

Zitat
wozu das where? schick einfach an wolfram alpha die bedingungen mit....

Das mag er bei mir irgendwie nicht 8o
Zuviele Bedingungen sind ihm wohl zu viel. Bei noch nehr Bedingung mehr oder nem "0<a<b<c" meckert er immer - bzw. liefert was ganz anderes, weil er die Frage dann nicht versteht. Daher das nachträgliche Rausfiltertern.
Aber siehs einfach als Quick and extradirty an - in jeder Hinsicht
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von zommi am .
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 3138

beantworten | zitieren | melden

Zitat von zommi
Das mag er bei mir irgendwie nicht
Nicht mit and, sondern mit Komma die Bedingungen trennen:
solve a^2+b^2=c^2 , a+b+c=1000 , 0<a<b<c over the integers


Ich habe zwar eine Lösung mit (momentan) 82.668 Iterationen (ohne Abbruch nach dem ersten Ergebnis), aber ich will erstmal den anderen den Vortritt lassen :)
Los, Lennart und der-schlingel!
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von dN!3L am .
private Nachricht | Beiträge des Benutzers
Lennart
myCSharp.de - Member



Dabei seit:
Beiträge: 429
Herkunft: Bawü

beantworten | zitieren | melden

Hallo,

bin im Moment bei 176 Durchläufen. Weiter runter kom ich aber glaub nicht. Irgendwie fehlt mir die zündende Idee .

gruß
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7548
Herkunft: Waidring

beantworten | zitieren | melden

Hallo Lennart,
Zitat
Irgendwie fehlt mir die zündende Idee
Mathematik ;-)
Irgendwie die Aufgabe umformen und dann kommt eine Ungleichung heraus. Somit müssen nur noch die Zahlen gesucht werden die Ungleichung erfüllen.


mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
Lennart
myCSharp.de - Member



Dabei seit:
Beiträge: 429
Herkunft: Bawü

beantworten | zitieren | melden

Hallo,

ne ich geb auf bin mit 176 auch zufrieden ;).
Hier mal mein Ansatz (über pythagoreische Tripel):


int zahl = 12, a, b, c;
int durchläufe = 0;

for (int u = 1; u ≤ zahl / 50 + 2; u++)
{
    for (int v = 1; v < u; v++)
    {
        if (u * u + u * v == zahl / 2)
        {
            b = u * u - v * v;
            a = 2 * u * v;
            c = u * u + v * v;

            if (a > b)
            {
                int tmp = a;
                a = b;
                b = tmp;
            }

            if (a + b + c == zahl && c * c == a * a + b * b && a > 0 && b > a && c > b)
            {
                Console.Out.WriteLine("Ergebnis: a: " + a + " b: " + b + " c: " + c + " Durchläufe: " + durchläufe);
            }
        }
        durchläufe++;
    }
}
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7548
Herkunft: Waidring

beantworten | zitieren | melden

Hallo,

nachdem etwas Ruhe eingekehrt ist und Lennart die Aufgabe mit den wenigsten Iteration gemeister hat ist er für mich der Gewinner meines Spiels. Lennart darf also die nächste Aufgabe stellen.

Da ich geschrieben habe dass es mit 5 Iterationen möglich ist will ich euch die Lösung nicht vorenthalten.
Wie Lennart auch erkannte ist der Ansatz über Pythagoräische Tripel -> siehe angehängtes Bild.


public class Aufgabe
{
	public IEnumerable<Ergebnis> Ermittle()
	{
		Func<int, int, Ergebnis> erstelleErgebnis = (m, n) =>
			new Ergebnis
			{
				A = 2 * m * n,
				B = m * m - n * n,
				C = m * m + n * n
			};

		// 500 könnte noch angepasst werden...aber es wird eh abgebrochen ;-)
		for (int n = 1; n < 500; n++)	
		{
			// nur das positive Ergebnis ist interessant:
			double m1 = -n * 0.5 + Math.Sqrt(n * n * 0.25 + 500);
			if (m1 > n && ((int)m1 == m1))
			{
				int m = (int)m1;
				yield return erstelleErgebnis(m, n);
				Debug.WriteLine("Found at m1, n={0}, m={1}", n, m);
				yield break;
			}
		}
	}
}


mfG Gü
Attachments
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers