Um Exceptionhandling hab ich mich nun aber nicht gekümmert. War auch wenn ich mich nicht verlesen hab kein Teil der Aufgabe. :)
Hoffe das passt so.
class IMapClass : IMap<String, Object>
{
#region IMap<T,T> Member
List<String> _leftList = new List<String>();
List<Object> _rightList = new List<object>();
public void Add(String leftItem, Object rightItem)
{
if (!this._leftList.Contains(leftItem)
&& !this._rightList.Contains(rightItem))
{
this._leftList.Add(leftItem);
this._rightList.Add(rightItem);
}
else
{
throw new InvalidOperationException("Zuordnung nicht möglich, ein Objekt darf nur einmal vorkommen.");
}
}
public Object this[String item]
{
get
{
return this._rightList[_leftList.IndexOf(item)];
}
set
{
if(!_rightList.Contains(item))
this._rightList[_leftList.IndexOf(item)] = value;
else
throw new InvalidOperationException("Das Objekt existiert bereits bei einer anderen Zuordnung.");
}
}
public String this[Object item]
{
get
{
return this._leftList[_rightList.IndexOf(item)];
}
set
{
if(!_leftList.Contains(item)=
this._leftList[_rightList.IndexOf(item)] = value;
else
throw new InvalidOperationException("Das Objekt existiert bereits bei einer anderen Zuordnung.");
}
}
public bool Contains(String item)
{
return _leftList.Contains(item);
}
public bool Contains(Object item)
{
return _rightList.Contains(item);
}
public bool Remove(String item)
{
return this._rightList.Remove(_rightList[_leftList.IndexOf(item)]) && this._leftList.Remove(item);
}
public bool Remove(Object item)
{
return this._leftList.Remove(_leftList[_rightList.IndexOf(item)]) && this._rightList.Remove(item);
}
public void Clear()
{
this._leftList.Clear();
this._rightList.Clear();
}
public int Count
{
get { return this._leftList.Count; }
}
#endregion
}
Für Meinungen bin ich natürlich offen.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von inflames2k am .
Wissen ist nicht alles. Man muss es auch anwenden können.
Um Exceptionhandling hab ich mich nun aber nicht gekümmert. War auch wenn ich mich nicht verlesen hab kein Teil der Aufgabe. :)
nö, aber es war verlangt, dass Objekte nicht mehrfach vorkommen können. Das hast du zwar bei Add berücksichtigt, aber an anderen Stellen nicht.
Hallo edsplash,
wo ich eh gerade einen Beitrag schreibe:
Zitat
Man sollte dabei sofern möglich vermeiden auf .NET Klassen wie Dictionary<T>, HashSet<T> zurück zu greifen.
Da hast du ja was schönes erreicht. inflames2k hat List <T>genommen (und wenn auch das nicht erlaubt gewesen wäre, dann vermutlich Array, irgendworauf wird man ja sinnvollerweise aufbauen). Dadurch ist deine Bedingung formal erfüllt. Aber was hast du erreicht? Der Code ist auch nicht länger oder komplizierter als wenn man Dictionary<> verwendet hätte, aber um Größenordnungen weniger performant.
dein Code trifft es immer noch nicht. Du musst ja auf jeden Fall auch value prüfen. Außerdem muss es erlaubt sein, einem Objekt das bereits zugeordnete Objekt erneut zuzuordnen. Überlegt dir nochmal genau, welche Fälle alle auftreten können.
BTW: warum hast du die Klasse denn für konkrete Typen implementiert? Statt class IMapClass : IMap<String, Object> wäre Map<TLeft, TRight> : IMap<TLeft, TRight> deutlich sinnvoller gewesen (mal ganz abgesehen davon, dass Klassennamen keinen Präfix haben sollten, erst recht nicht den Präfix I).
value hatte ich im Visual Studio geprüft wohl aber hier in der Änderung vergessen dies zu ändern.
Das mit der neu Zuordnung des selben Objektes stimmt so natürlich auch wieder. - Den Fall hatte ich nicht bedacht.
Konkrete Typen habe ich genommen, nachdem mein Compiler begann mir vorwürfe zu machen.
Nun aber die Volle und nun denk ich richtigere Variante:
class Map<TLeft, TRight> : IMap<TLeft, TRight>
{
#region IMap<TLeft,TRight> Member
List<TLeft> _leftList = new List<TLeft>();
List<TRight> _rightList = new List<TRight>();
public void Add(TLeft leftItem, TRight rightItem)
{
if (!_leftList.Contains(leftItem) && !_rightList.Contains(rightItem))
{
_leftList.Add(leftItem);
_rightList.Add(rightItem);
}
else
throw new InvalidOperationException("Ein Objekt kann nicht mehrfach zugeordnet werden.");
}
public TRight this[TLeft item]
{
get
{
return _rightList[_leftList.IndexOf(item)];
}
set
{
if(!_rightList.Contains(value) || _rightList[_leftList.IndexOf(item)].Equals(value))
_rightList[_leftList.IndexOf(item)] = value;
else throw new InvalidOperationException("Objekt ist bereits in der Zuordnung vorhanden.");
}
}
public TLeft this[TRight item]
{
get
{
return _leftList[_rightList.IndexOf(item)];
}
set
{
if (!_leftList.Contains(value) || _leftList[_rightList.IndexOf(item)].Equals(value))
_leftList[_rightList.IndexOf(item)] = value;
else throw new InvalidOperationException("Objekt ist bereits in der Zuordnung vorhanden.");
}
}
public bool Contains(TLeft item)
{
return _leftList.Contains(item);
}
public bool Contains(TRight item)
{
return _rightList.Contains(item);
}
public bool Remove(TLeft item)
{
return _rightList.Remove(_rightList[_leftList.IndexOf(item)]) && _leftList.Remove(item);
}
public bool Remove(TRight item)
{
return _leftList.Remove(_leftList[_rightList.IndexOf(item)]) && _rightList.Remove(item);
}
public void Clear()
{
_leftList.Clear();
_rightList.Clear();
}
public int Count
{
get { return _leftList.Count; }
}
#endregion
}
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von inflames2k am .
Wissen ist nicht alles. Man muss es auch anwenden können.
Da hast du ja was schönes erreicht. inflames2k hat List <T>genommen (und wenn auch das nicht erlaubt gewesen wäre, dann vermutlich Array, irgendworauf wird man ja sinnvollerweise aufbauen). Dadurch ist deine Bedingung formal erfüllt. Aber was hast du erreicht? Der Code ist auch nicht länger oder komplizierter als wenn man Dictionary<> verwendet hätte, aber um Größenordnungen weniger performant.
[offtopic]
Hehe, ich hatte gedacht, jemand würde es ohne Dictionary ähnlich performant hinkriegen ;) Mit dem Dictionary wird der Code allerdings weniger komplex, vorallem wenn man zwei davon verwendet -> Dictionary<TLeft, TRight> und Dictionar<TRight, TLeft>.
[/offtopic]
Gefragt war aber auch, die Implementierung ohne die Generischen Listen / Dictionaries aus System.Collections.Generic.
Hier ist meine Lösung:
public class Map<TLeft, TRight> : IMap<TLeft, TRight>
{
private TLeft[] m_Left = null;
private TRight[] m_Right = null;
private Boolean[] m_Used = null;
private Int32 m_Count = 0;
public Map()
: this(100) { }
public Map(Int32 startCapacity) {
m_Left = new TLeft[startCapacity];
m_Right = new TRight[startCapacity];
m_Used = new Boolean[startCapacity];
}
/// <summary>
/// Fügt der Map eine Zuordnung hinzu
/// </summary>
public void Add(TLeft leftItem, TRight rightItem) {
if (Contains(leftItem)) {
throw new ArgumentException("Item already added!", "leftItem");
}
if (Contains(rightItem)) {
throw new ArgumentException("Item already added!", "rightItem");
}
Int32 index = GetNextFreeIndex();
m_Used[index] = true;
m_Left[index] = leftItem;
m_Right[index] = rightItem;
m_Count++;
}
/// <summary>
/// Liest ein Element auf der rechten Seite der Map aus oder setzt dieses
/// </summary>
/// <param name="item">Ein Element auf der linken Seite, welches als Schlüssel dient</param>
public TRight this[TLeft item] {
get {
Int32 idx = Find(item);
if (idx == -1) {
throw new KeyNotFoundException("Item not found!");
}
return m_Right[idx];
}
set {
if (Contains(value)) {
throw new ArgumentException("Item already added!", "value");
}
Int32 idx = Find(item);
if (idx == -1) {
Add(item, value);
} else {
m_Right[idx] = value;
}
}
}
/// <summary>
/// Liest ein Element auf der linken Seite der Map aus oder setzt dieses
/// </summary>
/// <param name="item">Ein Element auf der rechten Seite, welches als Schlüssel dient</param>
public TLeft this[TRight item] {
get {
Int32 idx = Find(item);
if (idx == -1) {
throw new KeyNotFoundException("Item not found!");
}
return m_Left[idx];
}
set {
if (Contains(value)) {
throw new ArgumentException("Item already added!", "value");
}
Int32 idx = Find(item);
if (idx == -1) {
Add(value, item);
} else {
m_Left[idx] = value;
}
}
}
/// <summary>
/// Gibt an, ob auf der linken Seite ein spezifisches Element vorhanden ist
/// </summary>
public Boolean Contains(TLeft item) {
return Find(item) != -1;
}
/// <summary>
/// Gibt an, ob auf der rechten Seite ein spezifisches Element vorhanden ist
/// </summary>
public Boolean Contains(TRight item) {
return Find(item) != -1;
}
/// <summary>
/// Löscht eine Zuordnung
/// </summary>
/// <param name="item">Ein Element auf der linken Seite, welches als Schlüssel dient</param>
public Boolean Remove(TLeft item) {
return Remove(Find(item));
}
/// <summary>
/// Löscht eine Zuordnung
/// </summary>
/// <param name="item">Ein Element auf der rechten Seite, welches als Schlüssel dient</param>
public Boolean Remove(TRight item) {
return Remove(Find(item));
}
/// <summary>
/// Löscht alle Zuordnungen
/// </summary>
public void Clear() {
m_Used = new Boolean[m_Used.Length];
m_Left = new TLeft[m_Left.Length];
m_Right = new TRight[m_Right.Length];
}
/// <summary>
/// Gibt die Anzahl der vorhandenen Zuordnungen zurück
/// </summary>
public Int32 Count {
get {
return m_Count;
}
}
private Boolean Remove(Int32 idx) {
if (idx < 0 || idx > m_Used.Length || !m_Used[idx]) {
return false;
}
m_Used[idx] = false;
m_Left[idx] = default(TLeft);
m_Right[idx] = default(TRight);
m_Count--;
return true;
}
private Int32 GetNextFreeIndex() {
for (Int32 i = 0; i < m_Used.Length; i++) {
if (!m_Used[i]) {
return i;
}
}
EnlargeArrays();
return GetNextFreeIndex();
}
private void EnlargeArrays() {
Boolean[] tmpUsed = m_Used;
TLeft[] tmpLeft = m_Left;
TRight[] tmpRight = m_Right;
m_Used = new Boolean[tmpUsed.Length * 2];
m_Left = new TLeft[tmpLeft.Length * 2];
m_Right = new TRight[tmpRight.Length * 2];
tmpUsed.CopyTo(m_Used, 0);
tmpLeft.CopyTo(m_Left, 0);
tmpRight.CopyTo(m_Right, 0);
}
private Int32 Find(TLeft item) {
for (Int32 i = 0; i < m_Used.Length; i++) {
if (m_Used[i] && m_Left[i].Equals(item)) {
return i;
}
}
return -1;
}
private Int32 Find(TRight item) {
for (Int32 i = 0; i < m_Used.Length; i++) {
if (m_Used[i] && m_Right[i].Equals(item)) {
return i;
}
}
return -1;
}
}
Gruß, Christian.
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von TheBrainiac am .
There are 10 types of people in the world:
Those, who think they understand the binary system
Those who don't even have heard about it
And those who understand "Every base is base 10"
Gut, eine Aufgabe gibt es sobald mir etwas eingefallen ist. - Hatte zwar gerade einen Gedanken aber den müsst ich erstmal selbst für mich zusammen fassen.
Esseidenn dir fällt eine gute Aufgabe ein Schamese. :-) - Dann darfst du sie auch gern stellen.
Vermieden werden sollten Dictionary und HashSet, nicht alle Generics, aufgrund der Funktionalitäten die vom Dictionary Beispielsweise schon gegeben sind.
Wobei das nun auch unrelevant wäre. - Wie herbivore sagte, performant ist das nicht.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von inflames2k am .
Wissen ist nicht alles. Man muss es auch anwenden können.
Nach Absprache mit inflames2k darf ich nun eine Aufgabe stellen.
Entwickle einen kleinen Parser & Interpreter für simple mathematische Formeln.
Er soll folgendes beherrschen:
Addieren, Subtrahieren, Multiplizieren und Dividieren von Integer-Literalen.
Terme sollen mit Klammern zusammengefasst werden können.
Der Interpreter soll das Ergebnis des eingegebenen Terms berechnen.
Variablen, Funktionen und symbolische Konstanten brauchen nicht eingebaut werden.
Natürlich soll man seinen eigenen Parser/Interpreter schreiben. Parser-Generatoren, Vorgefertigte Interpreter, Scripting-Engines, Regex etc. sind nicht erlaubt. Ebenso gilt der Parser für mathematische Formeln nicht und darf auch nicht als Vorlage benutzt werden.
Gruß & Viel Spaß,
Christian.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von TheBrainiac am .
There are 10 types of people in the world:
Those, who think they understand the binary system
Those who don't even have heard about it
And those who understand "Every base is base 10"
Ich habe auf den Rat von herbivore die Aufgabenstellung noch einmal angepasst.
Gruß, Christian.
There are 10 types of people in the world:
Those, who think they understand the binary system
Those who don't even have heard about it
And those who understand "Every base is base 10"
using System;
using System.Collections.Generic;
namespace TestApp
{
class Program
{
static double Calc(string input)
{
// die folgende Zeile wiede4r einkommentieren um das Verfahren zu sehen
// Console.WriteLine(input);
input = input.Trim();
if(input.Length > 0)
{
int open = input.LastIndexOf('(');
if(open ≥ 0)
{
int match = input.IndexOf(')',open);
if(match > open)
{
double partRes = Calc(input.Substring(open+1, match-open-1));
if(partRes != double.NaN)
{
return Calc(input.Remove(open, match-open+1).Insert(open, partRes.ToString()));
}
}
}
else
{
if(char.IsDigit(input[input.Length-1]))
{
int pos = input.IndexOf('+');
if(pos > 0)
{
return Calc(input.Substring(0,pos)) + Calc(input.Substring(pos+1));
}
pos = input.IndexOf('-');
if((pos > 0) && (Char.IsDigit(input[pos-1]))) // <<< hier das IsDigit eingebaut
{
return Calc(input.Substring(0,pos)) - Calc(input.Substring(pos+1));
}
pos = input.IndexOf('*');
if(pos > 0)
{
return Calc(input.Substring(0,pos)) * Calc(input.Substring(pos+1));
}
pos = input.IndexOf('/');
if(pos > 0)
{
return Calc(input.Substring(0,pos)) / Calc(input.Substring(pos+1));
}
double result;
if(double.TryParse(input, out result))
{
return result;
}
}
}
}
return double.NaN;
}
public static void Main(string[] args)
{
do
{
Console.WriteLine("Term eingeben:");
double result = Calc(Console.ReadLine());
Console.WriteLine("Ergebnis: " + result.ToString());
Console.WriteLine();
Console.WriteLine("Leertaste zum Beenden, andere Taste zum Fortfahren");
}while(Console.ReadKey().Key != ConsoleKey.Spacebar);
}
}
}
Edit: erlaubt sind nur die runden Klammern "()". Bei Fehleingaben müsste immer NaN zurückgegeben werden.
EDIT 2: Der Code hat nicht funktioniert, wenn innerhalb eines Klammerpaars eine negative Zahl herauskam. Ich habe die korrigierte Stelle oben markiert (Prüfung auf IsDigit vor einem '-')
Gruß, MarsStein
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von MarsStein am .
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
ist immer true. also kannst du es auch gleich weglassen, was dir dann immernoch das problem übriglässt, das partRes noch NaN sein könnte. aber fehleingaben sind ja keine bedingung. ich wollte es nur mal erwähnt wissen :-)
string nurUmOptimierungenZuVermeiden = Console.ReadLine();
double d = double.NaN;
if(d == double.NaN) Console.WriteLine("hier ist double ein NaN \n" + nurUmOptimierungenZuVermeiden);
Gib mal (12+1)*2 ein... --> Heraus kommen sollte 26, aber es kommt NaN raus...
Gruß, Christian.
//EDIT Irgendie kommt bei mir immer wenn eine Klammer drin ist n. def. raus...
Dieser Beitrag wurde 4 mal editiert, zum letzten Mal von TheBrainiac am .
There are 10 types of people in the world:
Those, who think they understand the binary system
Those who don't even have heard about it
And those who understand "Every base is base 10"
in der Tat ist es genau so wie Cat schrieb: Da ist mir 'ne Zeile vom Testen stehengeblieben. Ich editiere das gleich oben im Code und mache die Stelle dort auch kenntlich. Danach sollte aber alles laufen ;)
Die nächste Aufgabe gibt's dann heut abend.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Stimmt. Wenn ich die Zeile Raus nehme, funktioniert's einwandfrei.
Wie JAck30lena schon gesagt hat:
Zitat von JAck30lena
ich kann keine fehler mehr feststellen. wunderschöne lösung. respekt :-)
Damit bist du dran!
Gruß, Christian.
There are 10 types of people in the world:
Those, who think they understand the binary system
Those who don't even have heard about it
And those who understand "Every base is base 10"
danke dafür und für den Hinweis wegen NaN
Rekursion mal von hinten nach vorn und von innen nach außen
Dann mal die nächste Aufgabe:
erstellt ein Programm, das eine vom Benutzer wählbare Anzahl von Kugeln nach dem Prinzip des Galtonbretts auf einzelne Fächer verteilt. Die Anzahl der Stufen des Bretts soll ebenfalls vom Benutzer gewählt werden können (denkt daran, daß es ein Fach mehr als Stufen gibt).
Die dabei erzeugte Verteilung soll in einem Balkendiagramm (1 Balken je Fach) sinnvoll skaliert* ausgegeben werden. Die Balken sollen mit der entsprechenden Trefferzahl beschriftet werden.
Die Aufgabe ist mit der Ausgabe von waagerechten Balken auf der Konsole erfüllt.
Gruß, MarsStein
*Edit: Sinnvoll skaliert bezieht sich auf sinnvolle Eingabebereiche (die nicht geprüft werden müssen), bei denen die Anzahl der Kugeln viel größer als die Anzahl der Fächer ist, und die maximale Anzahl der Fächer im Bereich der Zeilenzahl der Konsole liegt.
Ich erwarte aber, daß die maximale Länge der Balken mit steigender Anzahl an Fächern mitwächst, die Kurve also halbwegs mitskaliert wird.
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von MarsStein am .
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
hier mal ne kurze Lösung von mir weil ich auch mal ne Aufgabe stellen möchte :)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace Galton {
class Program {
static void Main(string[] args) {
Console.Write("Geben Sie die Anzahl der Stufen an: ");
var stufen = Convert.ToInt32(Console.ReadLine());
Console.Write("Geben sie die Anzahl der Kugeln an: ");
var kugeln = Convert.ToInt32(Console.ReadLine());
Galton g = new Galton(stufen);
var bins = g.DropBalls(kugeln);
PrintResults(3, bins);
Console.ReadLine();
}
static void PrintResults(int startY, int[] bins) {
// Skalierungsfaktor anhand der größten Kugelmenge berechnen
var scale = 75.0 / bins.Max();
for (int i = 0; i < bins.Length - 1; i++) {
// Anzahl zu druckender Zeichen bestimmen
var end = (int)(bins[i] * scale);
for (int j = 0; j < end; j++) {
Console.SetCursorPosition(j, startY + i*2);
Console.Write("x");
}
// Noch die Anzahl der Kugeln an den Anfang schreiben
Console.SetCursorPosition(0, startY + i*2);
Console.Write(String.Format("{0} ",bins[i]));
}
}
}
public class Galton {
List<double> factors = new List<double>();
Random rand = new Random();
double sum;
public Galton(int level) {
Func<Decimal, Decimal> factorial = null;
Func<Decimal, Decimal, Decimal> binom = null;
// Fakultät
factorial = (n) => (n == 0) ? 1 : n * factorial(n - 1);
// Binomialkoeffizenten
binom = (n, k) => factorial(n) / (factorial(k) * factorial(n - k));
sum = Math.Pow(2.0, level);
foreach (var i in Enumerable.Range(0, level + 1)) {
factors.Add(Convert.ToDouble(binom(level, i)));
}
// Summen für jedes Fach aufaddieren, siehe DropBalls für warum
factors = factors.Aggregate(
new List<double>() { 0 },
(acc, item) => {
acc.Add(acc[acc.Count - 1] + item);
return acc;
}
, (acc) => acc).ToList();
}
public int[] DropBalls(int balls) {
// Fächer
int[] bins = new int[factors.Count];
// für jeden gezogenen Ball...
for (int i = 0; i < balls; i++) {
// Zufallszahl erzeugen
var num = rand.NextDouble()*sum;
// Fächersummen durchgehen wenn Zufallszahl kleiner als Summe, ist die Kugel ins vorherige Fach gefallen
for (int j = 0; j < factors.Count; j++) {
if (num < factors[j]) {
bins[j-1]++;
break;
}
}
};
return bins;
}
}
}
Zitat von MarsStein
*Edit: Sinnvoll skaliert bezieht sich auf sinnvolle Eingabebereiche (die nicht geprüft werden müssen), bei denen die Anzahl der Kugeln viel größer als die Anzahl der Fächer ist, und die maximale Anzahl der Fächer im Bereich der Zeilenzahl der Konsole liegt.
Ich erwarte aber, daß die maximale Länge der Balken mit steigender Anzahl an Fächern mitwächst, die Kurve also halbwegs mitskaliert wird.
Ich erfülle diese Erwartung mit Absicht nicht - ob du die Aufgabe als gelöst erklärst ist dir überlassen. Der Grund ist einfach der, dass ich darin keinen Sinn sehe. Die Zeichenzahl in der Konsole pro Zeile ist so gering das man eh schon kaum gescheit skalieren kann. Wenn man bei wenigen Fächern die Balken kürzer macht, erkennt man bei Angabe der Kugeln in den Fächern gar nichts mehr.
da die Skalierung ausdrücklich gefordert war, kann ich Deine Lösung leider so nicht durchgehen lassen
Diese eine Mutiplikation wirst Du schon noch einbauen müssen, wenn Du die nächste Aufgabe stellen möchtest...
Ich habe auch einen Grund dafür: Wenn die Balken an der Zeilenzahl skaliert werden, sind die Kurven von der Form her vergleichbarer, und die Gleichverteilung bei verschiedenen Eingaben läßt sich besser erkennen. Als Beispiel mal die Ausgabe meiner eigenen Lösung, ich denke das veranschaulicht das etwas:
static void PrintResults(int startY, int[] bins) {
var max = Convert.ToDouble(bins.Max());
var baseChars = 10.0;
// skalieren mit dem 10er Logarithmus des Maximums
var log = (int)Math.Log10(max);
for (int i = 0; i < log; i++) {
baseChars += 5.0;
}
// Skalierungsfaktor anhand der größten Kugelmenge berechnen
var scale = baseChars / bins.Max();
var offset = 10;
for (int i = 0; i < bins.Length - 1; i++) {
// Anzahl zu druckender Zeichen bestimmen
var end = (int)(bins[i] * scale);
for (int j = 0; j < end; j++) {
Console.SetCursorPosition(offset + j, startY + i*2);
Console.Write("x");
}
// Noch die Anzahl der Kugeln an den Anfang schreiben
Console.SetCursorPosition(0, startY + i*2);
Console.Write(bins[i]);
}
}
Wobei ich die Skalierung immer noch vollkommen irreführend finde. Gerade in deinem letzten Beispiel sieht man das gut. Sowohl das erste Fach mit 20, als auch das 4. mit 8443 Kugeln, werden mit jeweils nur einer Einheit dargestellt. Wenn man von ganz weit weg schaut, sieht man zwar die entstehende Binomialverteilung, aber die Kurve stimmt vorne und hinten nicht in der Darstellung (was natürlich an der Konsole liegt als Ausgabemedium).
Über den SInn und Unsinn der Skalierung kann man sicherlich streiten, vor allem hast Du recht mit Deinen Aussagen:
Zitat
Gerade in deinem letzten Beispiel sieht man das gut. Sowohl das erste Fach mit 20, als auch das 4. mit 8443 Kugeln, werden mit jeweils nur einer Einheit dargestellt.
und
Zitat
sieht man zwar die entstehende Binomialverteilung, aber die Kurve stimmt vorne und hinten nicht in der Darstellung
Und ich hnbe recht , wenn ich behaupte, daß die Kurven wenn sie skaliert sind vom optischen Eindruck her leichter untereinander zu vergleichen sind.
Die Aufgabe ist jedenfalls mit der erweiterten Ausgabefunktion gelöst und Du bist dran
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
ich hab ne kleine Implementierungsaufgabe bei der es mehr um Wissen geht, als irgend einen Standardalgorithmus zu implementieren.
Gegeben ist ein Stück Code names Add welcher eine Addition von 4 Werten übernehmen soll. Er soll dabei folgendermaßen aufgerufen werden können:
var erg = Add(1, 2, 3, 4);
var erg2 = Add.SomethingNice()(1)(2)(3)(4);
In beiden Variablen, erg und erg2 soll als Ergebnis die Summe der Argumente, also 10, stehen.
Nun die Frage: Wie müsste Add aussehen und wie SomethingNice? Wie nennt man das, was da passiert. Ist es vielleicht gar nicht möglich in C# sowas zu schreiben?
EDIT: Kleine Ergänzung (die im Prinzip auch ein, gar nicht mal so unbedeutender, Tipp ist):
Sowas soll auch möglich sein:
var tmp = Add.SomethingNice()(1)(3);
var erg3 = tmp(4)(2);
Ergebniss ist natürlich wieder die Summe der Argumente, also 10.
Ich gehe zwar davon aus, dass du eigentlich eine Lösung in F# haben wolltest, da es aber ja auch Scala für die .Net Plattform gibt hab ich es mal in Scala gemacht:
object Main {
/**
* @param args the command line arguments
*/
def main(args: Array[String]): Unit = {
println(Add(1,2,3,4))
val add5 = Add.somethingNice(2)(3) _
println(add5(2)(3))
}
}
object Add {
def apply(a: Int, b: Int, c: Int, d: Int) = somethingNice(a)(b)(c)(d)
def somethingNice(a: Int)(b: Int)(c: Int)(d: Int) = a + b + c + d
}
Ich gehe zwar davon aus, dass du eigentlich eine Lösung in F# haben wolltest
Dann hätte ich was gesagt. Ich dachte die Frage danach, ob es in C# geht, deutet darauf hin, dass ich natürlich eine Lösung in C# möchte :) Daher kann ich deine Lösung so nicht gelten lassen (ich kann praktisch kein Scala, aber soweit ich deinen Code verstehe macht er schon prinzipiell das wonach ich gefragt habe, halt auf die Scala Art)
EDIT: Durch die Antwort ist ja praktisch schon verraten das es natürlich in C# geht - ich hätte neben der Lösung aber auch noch den Namen der Technik ( aber bitte beides zusammen, nur die Nennung des Namens würde die Lösung dann durch suchen im Inet trivial machen)