myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
   » Plugin für Firefox
   » Plugin für IE7
   » Gadget für Vista
» Regeln
» Wie poste ich richtig?
» Datenschutzerklärung
» wbb-FAQ

Mitglieder
» Liste / Suche
» Stadt / Anleitung dazu
» Wer ist wo online?

Angebote
» ASP.NET Webspace
» Bücher
» Zeitschriften
   » dot.net magazin
» Accessoires

Ressourcen
» .NET-Glossar
» guide to C#
» openbook: Visual C#
» openbook: OO
» .NET BlogBook
» MSDN Webcasts
» dotnetjob.de
» Search.Net

Team
» Kontakt
» Übersicht
» Wir über uns
» Bankverbindung
» Impressum

» Unsere MiniCity
MiniCity
» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Gemeinschaft » Smalltalk » Das Programmier-Spiel: nette Übungsaufgaben für zwischendurch
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen

Seiten (17): « erste ... « vorherige 5 6 7 8 [9] 10 11 12 13 nächste » ... letzte » Antwort erstellen
Zum Ende der Seite springen  

Das Programmier-Spiel: nette Übungsaufgaben für zwischendurch

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
talla talla ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-3214.jpg


Dabei seit: 20.07.2003
Beiträge: 6.863
Entwicklungsumgebung: VS 2010
Herkunft: Esslingen


talla ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

ist das nicht eher nen mathematisches bzw. logisches Problem? Ich seh da nicht die Herausforderung irgendwas programmtechnisch entwickeln zu müssen, da der Code nur die Implementierung der Formeln wäre. Oder seh ich das falsch?
15.10.2010 13:24 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 5.358
Entwicklungsumgebung: VS 2010 sup{Editionen}
Herkunft: Waidring / Tirol


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo talla,

es ist ein mathematisches Problem das sich aber nur mit Hilfe von Programmierung lösen lässt. Formeln zur Lösung gibt es nicht wirklich (zumindest keine geschlossene Formel). Die Lösung hängt viel mehr von den verwendeten Datenstrukturen die für das Programm verwendet werden ab.

mfG Gü
15.10.2010 13:32 Beiträge des Benutzers | zu Buddylist hinzufügen
Spontifixus Spontifixus ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3052.gif


Dabei seit: 06.09.2005
Beiträge: 360
Entwicklungsumgebung: VisualStudio 2008/2010
Herkunft: Hannover


Spontifixus ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hier ist sie nun die Lösung - auch wenn der Gehirnschmalz dahinter nicht von mir kommt, die Implementierung ist von mir. Augenzwinkern

Damit wir im weiteren Verlauf einfach und übersichtlich arbeiten können brauchen wir zwei kleine Extras. Zum einen eine Extension-Method die aus einer IEnumerable von IGroupings wieder eine flache Liste macht:

C#-Code:
public static class Extensions {

    public static List<TOut> ToFlatList<TOut>(this IEnumerable<IGrouping<int, TOut>> grouping) {

        var newList = new List<TOut>();
        foreach (var group in grouping)
            newList.AddRange(group);
        return newList;

    }

}

Als nächstes brauchen wir noch eine Datenstruktur die Zahlenpaare sowie deren Produkte, Summen und Differenzen halten kann:

C#-Code:
private struct CalculationInfo {

    public int X;
    public int Y;

    public int Product;
    public int Sum;
    public int Difference;

    public override string ToString() {
        return string.Format("CalculationInfo: X={0}, Y={1}, Product={2}, Sum={3}, Difference={4}", X, Y, Product, Sum, Difference);
    }

}

Bis hierhin war's einfach. großes Grinsen

Für die Lösung des Rätsels brauchen wir eine Liste mit den Faktoren und Summanden. Sowohl Multiplikation als auch Addition sind Kommutativ (Das Zahlenpaar (X,Y) ist für die Lösung der Aufgabe identisch zum Paar (Y,X)). Zwar ist die Subtraktion nicht kommutativ, trotzdem kann man aufgrund der Aufgabenstellung davon ausgehen, dass der Betrag der Differenz interessant ist, denn Daniela erwähnt nichts von einer positiven oder negativen Zahl. Von daher können wir um unnötigen Rechenaufwand zu vermeiden für die Lösung auf Zahlenpaare zurückgreifen, bei denen die zweite Zahl größer oder gleich der ersten ist.

C#-Code:
var workingList = new List<CalculationInfo>();
for (var x = 1; x <= 1000; x++)
    for (var y = x; y <= 1000; y++)
            workingList.Add(new CalculationInfo {
                X = x,
                Y = y,
                Product = x * y,
                Sum = x + y,
                Difference = Math.Abs(x - y)
            });

Berta sagt zu den anderen: "Ich kann die Lösung nicht nennen".
Was verannlasst Berta zu dieser Aussage? Antonia hat Berta das Produkt zweier Zahlen genannt. Wäre das Produkt kleiner als Tausend und eine Primzahl, dann würde Berta die Lösung kennen, denn dann kämen nur zwei Zahlen in Betracht: Die eins und das Produkt selber.
Berta würde die Lösung ebenfalls kennen, wenn die genannte Zahl größer als 1000 und das Produkt zweier Primzahlen wäre - denn dann würde die Lösung mit der eins nicht mehr greifen.
Die Zahl 5055 zum Beispiel ist in der Primfaktorenzerlegung 3 x 5 x 337. Soll das Produkt durch zwei Zahlen im Bereich von 1 bis 1000 dargestellt werden geht das nur als 15 x 337, denn sowohl bei 3 x 1685 als auch bei 5 x 1011 ist der zweite Faktor größer als 1000.
Wirklich aussagekräftig ist die Aussage von Berta also nicht, denn wir haben ja schon festgestellt, dass wir mit Primzahlen nicht weiterkommen.
Was wir aber wissen, ist, dass das Produkt, das Antonia Berta zugeflüstert hat mehrfach vorkommen muss, denn ansonsten wüsste Berta ja bereits was die Lösung wäre.
Diese Erkenntnis könnten wir jetzt ausnutzen um die Menge der verfügbaren Zahlenpaare einzugrenzen - tun wir aber nicht.

Christina antwortet: "Das wusste ich großes Grinsen "
Da scheint sich Christina ja ganz schön sicher zu sein. Dieser Hinweis ist - nunja - herausfordernd platziert. Den Christina wusste eigentlich schon von Anfang an, dass Berta die Lösung nicht kennen kann.
Was heißt das genau? Christina sieht eine Zahl, die man nur so aus zwei Summanden zusammensetzen kann, dass für alle Paare der Summanden gilt was zuvor bereits gesagt wurde. Kennt Christina zum Beispiel die Zahl 18, könnte die Lösung 1 + 17 sein. 17 ist allerdings eine Primzahl und deswegen könnte Berta die Lösung kennen. Also könnte im Falle der 18 Christina nicht schon vorher wissen das Berta die Lösung nicht kennt. Damit scheidet die 18 aus, und mit ihr alle Paare von Zahlen die addiert 18 ergeben.
Was lernen wir? Die Information das Christina weiß, dass Berta die Lösung nicht kennt ist viel Wertvoller als das Geständnis von Berta keine Ahnung zu haben.
Wir können jetzt aus unserer Arbeitsliste alle die Datensätze streichen bei denen eine oder mehrere Kombinationen von Summanden existieren mit denen man bei Kenntnis des Produktes auf die Lösung kommen würde.
Im Klartext heißt das: Wir suchen alle eindeutigen Produkte aus der Arbeitsliste, holen uns die dazugehörigen Summen und entfernen anschließend alle Werte mit diesen Summen aus der Arbeitsliste. Im Code sieht das dann so aus:

C#-Code:
var sumsByUniqueProducts = workingList.GroupBy(value => value.Product)
                                      .Where(item => item.Count() == 1)
                                      .ToFlatList()
                                      .GroupBy(value => value.Sum)
                                      .Select(value => value.Key)
                                      .ToArray();
workingList = workingList.Where(workingItem => !sumsByUniqueProducts.Contains(workingItem.Sum)).ToList();

Damit enthält die Worklist jetzt statt 500500 nur noch 27596 Einträge.

Darauf Berta: "Dann weiß ich jetzt die Lösung."
Dieser Hinweis ist deutlich einfacher auszuwerten als die vorhergehenden. Wir wissen jetzt, dass das Produkt der gesuchten Zahlen nur noch einmal in der Arbeitsliste vorkommt. Das wiederum erlaubt es uns alle einträge aus der Arbeitsliste zu entfernen, deren Produkt mehr als einmal in der Liste auftaucht.

C#-Code:
workingList = workingList.GroupBy(value => value.Product)
                         .Where(item => item.Count() == 1)
                         .ToFlatList();

Die Arbeitsliste enthält jetzt noch 6984 Einträge.

Christina entgegnet: "Dann weiß ich sie jetzt auch."
Dieser Hinweis enthält eine ähnliche Annahme wie der vorangegangene von Berta. Nur das sich die Annahme hier auf die Summen und nicht auf die Produkte bezieht. Wir können also damit Fortfahren alle Einträge aus der Liste zu entfernen deren Summe mehr als einmal in der Liste auftaucht.

C#-Code:
workingList = workingList.GroupBy(value => value.Sum)
                         .Where(item => item.Count() == 1)
                         .ToFlatList();

Jetzt bleiben noch niedliche 27 EInträge übrig.

Daniela sagt: "Ich nicht, aber ich habe eine Vermutung, was eine der beiden Zahlen wahrscheinlich ist."
Aus diesem Hinweis kann man zwei Schlussfolgerungen ziehen. Einerseits weist er darauf hin, dass in der Menge der Zahlenpaare aus denen man Danielas Differenz bilden könnte ein Wert häufiger vorhanden ist als andere.
Es gibt allerdings noch eine weitere Schlussfolgerung: Danielas Differenz ist in der Arbeitstabelle mehr als einmal vorhanden, denn sonst wüsste Sie das Ergebnis ja jetzt auch.
Genau genommen müssen für die infragekommende Differenz mehr als zwei Einträge vorhanden sein, denn sonst kann nicht einer der Werte häufiger vorhanden sein als alle anderen.

C#-Code:
workingList = workingList.GroupBy(value => value.Difference)
                         .Where(item => item.Count() > 2)
                         .ToFlatList();

Unsere Arbeitsliste enthält jetzt noch genau 6 Einträge.

Berta sagt: "Ich weiß, was du vermutest, aber das ist falsch."
Von so einer Aussage lässt sich Daniela allerdings nicht unterkriegen. Wir wissen jetzt dass einer der Werte bei zwei Datensätzen der Arbeitsliste auftauchen muss. Das Ergebnis dieser Datensätze ist also die Differenz. Dazu zählen wir die Datensätze bei denen der doppelte Wert vorkommt und entfernen anschließend alle Datensätze die die dort berechnete Differenz nicht enthalten aus der Arbeitsliste.

C#-Code:
var occurrences = new Dictionary<int, int>();
foreach (var difference in workingList) {
    if (!occurrences.ContainsKey(difference.X))
        occurrences.Add(difference.X, 0);
    occurrences[difference.X]++;
    if (!occurrences.ContainsKey(difference.Y))
        occurrences.Add(difference.Y, 0);
    occurrences[difference.Y]++;
}
var wrongNumber = occurrences.Where(item => item.Value == occurrences.Values.Max())
                             .First()
                             .Key;
workingList = workingList.Where(item => item.X != wrongNumber &&
                                        item.Y != wrongNumber)
                         .ToList();

Wir erhalten eine Liste mit drei Werten. Jetzt ist auch Daniela stolz wie Oskar:

Daniela: "Dann kenne ich jetzt auch die Lösung."
Jetzt weiß auch Daniela dass ihre Differenz in der Arbeitsliste nur noch ein einziges Mal enthalten ist und kann so die überflüssigen Datensätze ausschließen:

C#-Code:
workingList = workingList.GroupBy(value => value.Difference)
                         .Where(item => item.Count() == 1)
                         .ToFlatList();

Und endlich, endlich kennen auch wir den gesuchten Datensatz:

Code:
1:
CalculationInfo: X=64, Y=73, Product=4672, Sum=137, Difference=9

Den Code habe ich nochmal als kompilierbare Datei an diesen Beitrag angehängt. Vielen Dank an  fairymail.de für die Denkarbeit hinter der Lösung Augenzwinkern


Dateianhang:
unknown Program.cs (3,49 KB, 100 mal heruntergeladen)

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Spontifixus am 01.11.2010 22:58.

15.10.2010 14:07 Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 5.358
Entwicklungsumgebung: VS 2010 sup{Editionen}
Herkunft: Waidring / Tirol


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Spontifixus,

somit bist du mit der nächsten Aufgabe dran.

Hätte ich damals bei der Mathe-Prüfung auch schon das WWW verwenden dürfen... großes Grinsen

mfG Gü
15.10.2010 14:23 Beiträge des Benutzers | zu Buddylist hinzufügen
Spontifixus Spontifixus ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3052.gif


Dabei seit: 06.09.2005
Beiträge: 360
Entwicklungsumgebung: VisualStudio 2008/2010
Herkunft: Hannover


Spontifixus ist offline

XAML-Texteditor

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Die nächste Aufgabe braucht keine Logik - und zwar im wahrsten Sinne des Wortes:
Erstelle einen kleinen Texteditor ausschließlich in XAML. Für den Editor sind folgende Anforderungen definiert:
  1. Der Editor besteht aus genau einem Fenster
  2. Der Editor hat direkt unter dem Fenstertitel eine Menüleiste mit einem Menü beschriftet mit "Editor". Darin Menüpunkte Rückgängig, Wiederherstellen, Kopieren, Ausschneiden und Einfügen, die jeweils auch über die Windows-üblichen Tastenkürzel ansprechbar sein müssen und in der jeweils eingestellten Sprache des Betriebssystems beschriftet sein sollen. Zusätzlich sollen die Tastenkürzel im Menü angezeigt werden. Die Menüpunkte dürfen nur aktiviert werden, wenn die entsprechende Aktion verfügbar ist.
  3. Der Editor verfügt über einen Eingabebereich für den Text, der den gesamten Rest des Fensters einnimmt.
Der Code zur Lösung ist nicht als Dateianhang, sondern inline im Beitrag zu posten. Es gilt je kürzer desto besser - Trotzdem sollte das XAML natürlich wie üblich formatiert sein.

EDIT: Natürlich darf das C#-Projekt weitere notwendige Dateien wie z.B. die App.xaml enthalten.

Viel Spaß :)

Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Spontifixus am 15.10.2010 16:23.

15.10.2010 14:51 Beiträge des Benutzers | zu Buddylist hinzufügen
talla talla ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-3214.jpg


Dabei seit: 20.07.2003
Beiträge: 6.863
Entwicklungsumgebung: VS 2010
Herkunft: Esslingen


talla ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

die Aufgabe find ich nett smile Hab sie auch gelöst, aber lass gerne Anderen den Vortritt. Ich find an der Aufgabe gut das sie auch für Einsteiger gut lösbar ist wenn man sich bissle in WPF eingelesen hat und nen recht mächtiges Feature von WPF verdeutlicht. Daumen hoch
15.10.2010 18:06 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Spontifixus Spontifixus ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3052.gif


Dabei seit: 06.09.2005
Beiträge: 360
Entwicklungsumgebung: VisualStudio 2008/2010
Herkunft: Hannover


Spontifixus ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Moin moin,

wenn die bisherige Aufgabe nicht gelöst wurde, kann nach bisherigen Regeln dieses Threads jeder eine neue Aufgabe stellen.

Die Lösung für meine Aufgabe wäre ein 14 Zeilen langer XAML-Schnipsel gewesen:

XML-Code:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="Editor">
                <MenuItem Command="Undo" />
                <MenuItem Command="Redo" />
                <MenuItem Command="Cut" />
                <MenuItem Command="Copy" />
                <MenuItem Command="Paste" />
            </MenuItem>
        </Menu>
        <RichTextBox />
    </DockPanel>
</Window>

Wenn talla eine Aufgabe hat - darf er aber gerne weitermachen ;)

Viele Grüße,
Markus :)
22.10.2010 10:48 Beiträge des Benutzers | zu Buddylist hinzufügen
JunkyXL JunkyXL ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-3234.gif


Dabei seit: 02.05.2006
Beiträge: 1.663
Entwicklungsumgebung: Visual Studio 2010 Ultimate
Herkunft: Ein paar Bytes südlich von string


JunkyXL ist offline Füge JunkyXL Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top



Zitat von talla:
...und nen recht mächtiges Feature von WPF verdeutlicht.

Nur der Vollständigkeit halber: Welches Feature davon meinst du? Die beliebige Control-Verschachtelung, das Menu, die integrierte Interaktion der Menüpunkte mit dem Editor, der Editor an sich?
25.10.2010 16:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
m0rius
myCSharp.de-Mitglied

images/avatars/avatar-3125.png


Dabei seit: 28.08.2007
Beiträge: 994
Entwicklungsumgebung: Visual Studio 2010 Professional


m0rius ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo JunkyXL,

ich lege meine Hand dafür ins Feuer, dass talla von  Commands gesprochen hat :).

m0rius
25.10.2010 16:42 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
talla talla ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-3214.jpg


Dabei seit: 20.07.2003
Beiträge: 6.863
Entwicklungsumgebung: VS 2010
Herkunft: Esslingen


talla ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Genau :) Ohne die ist die die Aufgabe in der Kürze nicht lösbar. Vor allem die Komfortfunktionen wie De/aktivieren der Menüpunkte, richtige Lokalisierung, KeyBindings usw. sind recht länglich auszuprogrammieren wenn man das von Hand macht. ( Okay, hinter den Commands bzw. CommandTargets mit der Logik, liegt natürlich ne Menge Code, aber der ist in dem Beispiel ja nicht sichtbar und das ergibt dann ein kurzes Stück XAML was nen halber Editor ist.)
Die Schachtelungsmöglichkeiten der Controls in WPF wird hier gar nicht so arg deutlich find ich, da es in Windows Forms ähnlich aussehen könnte mit einem LayoutContainer und verschiedenen Children. Auch das MenuItems in ein Menu gesteckt werden scheint nicht besonders. Wenn man weiß das man auch beliebig anderes Zeug ins Menu packen kann, oder nen Menu als Child von nem Button packen kann *gG*, dann wird der Unterschied zu Windows Forms deutlich.


Hab das Angebot eine Aufgabe stellen zu dürfen gar nicht gesehen gehabt, aber ich überleg mir was bis morgen. Falls ich bis Morgen Mittag (26.10.2010 - 12.00 Uhr) nichts geschrieben habe darf gerne jemand anderes eine Aufgabe stellen.
25.10.2010 17:24 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 5.358
Entwicklungsumgebung: VS 2010 sup{Editionen}
Herkunft: Waidring / Tirol


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,



Zitat:
Falls ich bis Morgen Mittag (26.10.2010 - 12.00 Uhr) nichts geschrieben habe darf gerne jemand anderes eine Aufgabe stellen.

Ich bin mal so frei ;-)


Folgende Aufgabe:

Erstelle einen Cache zudem Objekte hinzugefügt werden können. Die Objekte sollen per Schlüssel abgerufen werden können (also so wie ein Dictionary<TKey, TValue>).

Für jedes Objekt im Cache soll ein Ablaufdatum angeben werden können, so dass beim Zugriff niemals ein abgelaufenes Objekt zurückgegeben wird. Dabei soll es zwei Arten des Ablaufsdatum geben:
  1. absoluter Ablauf, d.h. sobald das Objekt dem Cache zugeführt wurde beginnt der Ablaufzähler -> AbsoluteExpiration
  2. Zugriff-Ablauf, d.h. wenn seit dem Hinzufügen zum Cache nicht binnen des Intervalls auf das Objekt (über den Key) zugegriffen wird läuft es ab -> AccessExpiration
Es gelten die "üblichen" Bedingungen: Frameworks- / 3rd-Party-Klassen sind verboten! Auch die in .net enthaltenen Caches sind nicht erlaubt - selbst machen ist angesagt ;-)

Viel Spass bei der Aufgabe!

mfG Gü
08.11.2010 15:37 Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 5.358
Entwicklungsumgebung: VS 2010 sup{Editionen}
Herkunft: Waidring / Tirol


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

da die Aufgabe nicht gelöst wurde stell ich meine Lösung rein und gegebe das Spiel somit explizit frei.

C#-Code (CacheItem):
using System;

namespace SimpleCache
{
    public sealed class CacheItem
    {
        public object Item      { get; private set; }
        public DateTime TimeOut { get; private set; }
        //---------------------------------------------------------------------
        public CacheItem(object item, TimeSpan timeSpanForTimeOut)
        {
            this.Item    = item;
            this.TimeOut = DateTime.Now + timeSpanForTimeOut;
        }
    }
}

C#-Code (Cache):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace SimpleCache
{
    public sealed class Cache : IDisposable
    {
        private const int scavengerIntervall = 10 * 60 * 1000;
        private readonly Dictionary<string, CacheItem> _cachedItems;
        private readonly Timer  _timer;
        private readonly object _syncRoot = new object();
        //---------------------------------------------------------------------
        public Cache()
        {
            _cachedItems = new Dictionary<string, CacheItem>();

            _timer = new Timer(
                this.Scavenge,
                null,
                scavengerIntervall,
                scavengerIntervall);
        }
        //---------------------------------------------------------------------
        public void Add(string key, object item, TimeSpan timeSpanForTimeOut)
        {
            CacheItem cacheItem = new CacheItem(item, timeSpanForTimeOut);

            lock (_syncRoot)
                _cachedItems[key] = cacheItem;
        }
        //---------------------------------------------------------------------
        public object GetItem(string key)
        {
            CacheItem cacheItem = null;
            lock (_syncRoot)
            {
                if (!_cachedItems.ContainsKey(key)) return null;
                cacheItem = _cachedItems[key];
            }

            if (cacheItem.TimeOut > DateTime.Now)
            {
                lock (_syncRoot)
                    _cachedItems.Remove(key);

                return null;
            }

            return cacheItem.Item;
        }
        //---------------------------------------------------------------------
        private void Scavenge(object state)
        {
            DateTime now = DateTime.Now;

            lock (_syncRoot)
            {
                var outdatedKeys = _cachedItems
                    .Where(kvp   => kvp.Value.TimeOut > now)
                    .Select(kvp  => kvp.Key);

                foreach (string key in outdatedKeys)
                    _cachedItems.Remove(key);
            }
        }
        //---------------------------------------------------------------------
        #region IDisposable Members
        private bool _isDisposed = false;
        //---------------------------------------------------------------------
        private void Dispose(bool disposing)
        {
            if (!_isDisposed)
            {
                if (disposing)
                    if (_timer != null)
                        _timer.Dispose();

                _isDisposed = true;
            }
        }
        //---------------------------------------------------------------------
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion
    }
}

Ab .net 4.0 wäre statt dem Dictionary ein ConcurrentDictionary zu verwenden da dadurch der explizite Lock entfallen kann.


mfG Gü
22.11.2010 11:48 Beiträge des Benutzers | zu Buddylist hinzufügen
Floste
myCSharp.de-Mitglied

images/avatars/avatar-2376.jpg


Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008
Herkunft: Norddeutschland


Floste ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich hab mir mal ne aufgabe ausgedacht. Wenn man die vorgegebenen zeilen nicht mitzählt, kann man sie in 15 zeilen lösen.

Es ist ohne das wörtchen unsafe und ohne die klasse Marshal lösbar. Wer es nicht ohne hinbekommt, kann es aber trotzdem benutzen.

Aufgabe: Füge dort, wo die fragezeichen stehen code ein, der bewirkt, dass das programm folgendes ausgibt:

Code (Console):
1:
2:
method:A, Class:ClassA, filedA:1337
method:B, Class:ClassA, filedB:1337

C#-Code:
     class Aufgabe
    {

        class ClassA
        {
            public int fieldA;
            public void Test()
            {
                Console.WriteLine("method:A, Class:" + this.GetType().Name + ", fieldA:" + this.fieldA);
            }
        }

        class ClassB
        {
            public int fieldB;
            public void Test()
            {
                Console.WriteLine("method:B, Class:" + this.GetType().Name + ", fieldB:" + this.fieldB);
            }
        }


        static void Main()
        {
            ClassA a = new ClassA();
            ClassB b = Magic(a);
            a.fieldA = 1337;
            a.Test();
            b.Test();
            Console.ReadLine();
        }

        private static ClassB Magic(ClassA a)
        {

        ??????


    }

Dieser Beitrag wurde 4 mal editiert, zum letzten Mal von Floste am 29.11.2010 19:45.

29.11.2010 19:34 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Floste
myCSharp.de-Mitglied

images/avatars/avatar-2376.jpg


Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008
Herkunft: Norddeutschland


Floste ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Da mich jemand per pm gefragt hat:
Ich habe die schließende klammer hinter "Magic" bewusst weggelassen, um zu zeigen, das man auch hinter die Methode noch etwas schreiben kann.

Noch ein Tipp zum Googeln: LayoutKind.Explicit

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Floste am 01.12.2010 15:16.

01.12.2010 15:15 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
zommi zommi ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2617.png


Dabei seit: 14.11.2007
Beiträge: 1.229
Entwicklungsumgebung: VS 2005+2010
Herkunft: Berlin


zommi ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hey,

ich ergänze folgenden Code: (nutzt .NET 4.0 Featur für named parameters)

C#-Code:
    return (new BrutalCastContainer{BRef=null, ObjectRef=a}).BRef;
}

[StructLayout(LayoutKind.Explicit)]
struct BrutalCastContainer
{
    [FieldOffset(0)]
    public object ObjectRef;
    [FieldOffset(0)]
    public ClassB BRef;
}

Insgesamt also:

C#-Code:
using System;
using System.Runtime.InteropServices;

class Aufgabe
    {

        class ClassA
        {
            public int fieldA;
            public void Test()
            {
                Console.WriteLine("method:A, Class:" + this.GetType().Name + ", fieldA:" + this.fieldA);
            }
        }

        class ClassB
        {
            public int fieldB = 0;
            public void Test()
            {
                Console.WriteLine("method:B, Class:" + this.GetType().Name + ", fieldB:" + this.fieldB);
            }
        }


        static void Main()
        {
            ClassA a = new ClassA();
            ClassB b = Magic(a);
            a.fieldA = 1337;
            a.Test();
            b.Test();
            Console.ReadLine();
        }

        // Start Magic-Code
        private static ClassB Magic(ClassA a)
        {
            return (new BrutalCastContainer{BRef=null, ObjectRef=a}).BRef;
        }

        [StructLayout(LayoutKind.Explicit)]
        struct BrutalCastContainer
        {
            [FieldOffset(0)]
            public object ObjectRef;
            [FieldOffset(0)]
            public ClassB BRef;
        }
        // End Magic-Code
    }

beste Grüße
zommi

Ich grübel schonmal über ne neue Aufgabe...
01.12.2010 16:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Floste
myCSharp.de-Mitglied

images/avatars/avatar-2376.jpg


Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008
Herkunft: Norddeutschland


Floste ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Passt, du bist dran.

Zitat:
ich ergänze folgenden Code: (nutzt .NET 4.0 Featur für named parameters)

dein code geht mit .net 3

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Floste am 01.12.2010 16:19.

01.12.2010 16:18 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
zommi zommi ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2617.png


Dabei seit: 14.11.2007
Beiträge: 1.229
Entwicklungsumgebung: VS 2005+2010
Herkunft: Berlin


zommi ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

So,

dann mal ne kleine Geschichte:

Die drei globalisierten Bankräuber Alice, Bob und Carl sind seit ihrem letzten Streifzug ziemlich zerstritten. Da alle drei in unterschiedlichen Ländern wohnen, läuft ihre Kommunikations komplett über das Internet.

Als es um die Planung der Beute-Aufteilung zwischen Alice und Bob für den nächsten Deal geht, traut keiner dem anderen. Da macht Carl den Vorschlag, dass sie doch beide einen verbindlichen Vertrag eingehen, der die Aufteilung regelt. [Damit man seinen Teil der gestohlenen Beute auch gerichtlich einklagen kann ;)]

Carl bietet sich als Vermittler an, fertigt die Verträge aus und schickt sie Alice und Bob. Doch Carl will Alice und Bob noch ein wenig ärgern, und so möchte er den beiden jeweils unterschiedliche Verträge zusenden:

Zitat von Vertragstext für Alice:
Hiermit beschliessen Alice und Bob die Aufteilung der Beute. Alice bekommt 80 Prozent und Bob den Rest.

Zitat von Vertragstext für Bob:
Hiermit beschliessen Alice und Bob die Aufteilung der Beute. Bob bekommt 80 Prozent und Alice den Rest.

Doch Alice und Bob vertrauen prinzipiell auch Carl nicht und vermuten bereits, dass er ihnen einen Streich spielen will. Deshalb einigen sie sich darauf, dass sie zuvor ihre Vertragstexte abgleichen. Da sie mal etwas von Digitalen Signaturen gehört haben, wollen sie diese nutzen und so meinen sie, dass es genügen sollte, die Hash-Werte der Vertragstexte zu vergleichen.

Da sie nur 4 Bytes für ihre Hashfunktion verschwenden möchten, überlegen sie sich ein cleveres Verfahren: Alice schlug vor, zunächst das MD5-Verfahren zu nutzen und einfach die ersten 4 Bytes zu nehmen. Bob wendet ein, dass damit ja die restlichen 12 Bytes des MD5-Wertes völlig unberücktsichtigt bleiben. Da kommt Alice wiederum die Idee einfach auf den MD5-Hash nochmal MD5 anzuwenden, um alle Bytes zu verwenden und von diesem neuen Hash die ersten 4 Bytes zu nehmen. Bob findet diesen Einfall brillant und so einigen sie sich auf:

SpecialHash(message) = First4Bytes(MD5(MD5(message))

(Message ist ASCII-kodiert)

Carl hat das mitbekommen, und so muss er zwei neue Vertragstexte anfertigen, die immernoch den beiden obigen ähneln, aber den selben Hash-Wert besitzen:

SpecialHash(SpecialTextForAlice) = SpecialHash(SpecialTextForBob)

Dabei bedeutet "ähneln", dass in den obigen Texten an beliebig vielen Stellen die Leerzeichen durch doppelte Leerzeichen ersetzt werden dürfen.

Damit wären also folgende Sätze ähnlich:

Das ist ein Satz.
Das  ist  ein  Satz.
Das ist ein  Satz.
Das  ist ein Satz.
...

Hilf Carl mit einem C#-Programm dabei, zwei zu den obigen Vertragstexten ähnliche zu finden, die den selben Hash-Wert besitzen!

Viel Spaß beim Lesen und Implementieren ! :)

beste Grüße
zommi

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von zommi am 02.12.2010 01:44.

02.12.2010 00:22 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
zommi zommi ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2617.png


Dabei seit: 14.11.2007
Beiträge: 1.229
Entwicklungsumgebung: VS 2005+2010
Herkunft: Berlin


zommi ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi nochma,

als typischer Stakeholder hab ich natürlich vergessen, die nichtfunktionalen Anforderungen zu spezifizieren Augenzwinkern

Das Programm soll solch eine Kollision innerhalb weniger Sekunden finden! (vielleicht eine, oder auch zwei)

beste Grüße
zommi
02.12.2010 10:52 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Xander Xander ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3215.jpg


Dabei seit: 02.11.2010
Beiträge: 54
Entwicklungsumgebung: VS C#2010Exp., SharpDevelop
Herkunft: Sonneberg


Xander ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi,

ich habs mal versucht aber als C# Neuling schaff ich Sekundenzeiten allerdings nicht. Ich bin mir nichtmal sicher ob es stimmt. Ich brauch ca. 2,5min für den Vergleich aller 4.294.967.296 Möglichkeiten und finden ca. nach 1,5min das erste und einzige Ergebnis.

Achja ich hab das nur versucht schnell hinzubekommen und nicht wirklich auf Form und speziell Zeilenlänge geachtet. Sorry.

C#-Code:
    class BeuteTeilen
    {
        public BeuteTeilen()
        {
            Stopwatch stopWatch = new Stopwatch();
            string vertragAlice = "Hiermit beschliessen Alice und Bob die Aufteilung der Beute." +
                                  " Alice bekommt 80 Prozent und Bob den Rest.";
            string vertragBob = "Hiermit beschliessen Alice und Bob die Aufteilung der Beute." +
                                " Bob bekommt 80 Prozent und Alice den Rest.";
            string[] splittedAlice = vertragAlice.Split(' ');
            string[] splittedBob = vertragBob.Split(' ');
            int variations = Convert.ToInt32(Math.Pow(2,splittedAlice.Length - 1));
            byte[] SpecialHashAlice = new byte[variations];
            byte[][] SpecialHashBob = new byte[variations][];

            for (int i = 0; i < variations; ++i)
                SpecialHashBob[i] = SpecialHash(SpecialText(splittedBob, i));

            stopWatch.Start();
            for (int i = 0; i < variations; ++i)
            {
                SpecialHashAlice = SpecialHash(SpecialText(splittedAlice, i));
                for (int j = 0; j < variations; ++j)
                {
                    if (VergleicheInhalte(SpecialHashAlice,SpecialHashBob[j]))
                    {
                        Console.WriteLine("__________________________________________________");
                        Console.WriteLine("Result nach: " + stopWatch.Elapsed.ToString());
                        Console.WriteLine("Alice: " + SpecialText(splittedAlice, i));
                        Console.WriteLine("Hash: " + System.BitConverter.ToString(SpecialHashAlice));
                        Console.WriteLine("---------------------------------------");
                        Console.WriteLine("Bob: " + SpecialText(splittedBob, j));
                        Console.WriteLine("Hash: " + System.BitConverter.ToString(SpecialHashBob[j]));
                    }
                }
            }
            Console.WriteLine("__________________________________________________");
            Console.WriteLine("Alles durchprobiert nach: " + stopWatch.Elapsed.ToString());
            stopWatch.Stop();
            Console.ReadLine();
        }
        //---------------------------------------------------------------------
        bool VergleicheInhalte(byte[] val1, byte[] val2)
        {
            if (val1[0] != val2[0] || val1[1] != val2[1] || val1[2] != val2[2] || val1[3] != val2[3])
            {
                return false;
            }
            else
                return true;
        }
        //---------------------------------------------------------------------
        string SpecialText(string[] splittedOrginal, int variation)
        {
            StringBuilder sbHelper = new StringBuilder();
            string asBinary = Convert.ToString(variation, 2).PadLeft(16, '0');

            for (int i = 0; i < splittedOrginal.Length - 1; ++i)
            {
                sbHelper.Append(splittedOrginal[i]);
                if (asBinary[i] == '1')
                    sbHelper.Append("  ");
                else
                    sbHelper.Append(" ");
            }
            sbHelper.Append(splittedOrginal[splittedOrginal.Length - 1]);
            return sbHelper.ToString();
        }
        //---------------------------------------------------------------------
        static byte[] SpecialHash(string message)
        {
            byte[] result = GetMD5Hash(GetMD5Hash(Encoding.Default.GetBytes(message)));
            return new byte[] { result[0], result[1], result[2], result[3] };
        }
        //---------------------------------------------------------------------
        static byte[] GetMD5Hash(byte[] BytesToHash)
        {
            return new MD5CryptoServiceProvider().ComputeHash(BytesToHash);
        }
    }

Meine Lösung war dann:

Code:
1:
2:
3:
4:
5:
6:
Result nach: 00:01:38.462238
Alice: Hiermit  beschliessen Alice und  Bob die  Aufteilung  der  Beute. Alice bekommt 80  Prozent  und Bob den  Rest.
Hash:A3-D5-6C-0A
------------------------------------------------
Bob: Hiermit beschliessen  Alice  und  Bob die Aufteilung der Beute.  Bob bekommt 80  Prozent  und Alice den  Rest.
Hash:A3-D5-6C-0A
02.12.2010 13:41 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
zommi zommi ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2617.png


Dabei seit: 14.11.2007
Beiträge: 1.229
Entwicklungsumgebung: VS 2005+2010
Herkunft: Berlin


zommi ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Schaut aber gut aus! Daumen hoch

Carl dankt dir ! Augenzwinkern

Wegen Performance:
  • Konvertiere die 4-Byte langen Byte[]-Arrays in einen Int32 (mit dem BitConverter)
  • Verwende zwei Dictionaries, oder zwei HashSets anstatt den einfachen Arrays. So kannst du auf Kollisionen dank der schnellen Contains-Methode in insgesamt O(n+m) suchen anstatt wie bei dir (wegen der verschachtelten Schleife) in O(n*m)
  • ...
Diese beiden Punkte sollten schon reichen um nen ausreichenden Speedup zu gewährleisten.

Mein Referenzprogramm sah so aus:

C#-Code:
static void Main(string[] args)
{
    string originTextForAlice = "Hiermit beschliessen Alice und Bob die Aufteilung der Beute. Alice bekommt 80 Prozent und Bob den Rest.";
    string originTextForBob = "Hiermit beschliessen Alice und Bob die Aufteilung der Beute. Bob bekommt 80 Prozent und Alice den Rest.";

    string finalTextForAlice = "", finalTextForBob = "";

    HashSet<uint> hashesAlice = new HashSet<uint>();
    HashSet<uint> hashesBob = new HashSet<uint>();

    IEnumerator<string> textsAlice = AllModifiedTexts(originTextForAlice).GetEnumerator();
    IEnumerator<string> textsBob = AllModifiedTexts(originTextForBob).GetEnumerator();

    while (textsAlice.MoveNext() && textsBob.MoveNext())
    {
        string textForAlice = textsAlice.Current;
        string textForBob = textsBob.Current;

        uint hashAlice = SpecialHash(textForAlice);
        uint hashBob = SpecialHash(textForBob);

        if (hashesAlice.Contains(hashBob))
        {
            finalTextForBob = textForBob;
            finalTextForAlice = AllModifiedTexts(originTextForAlice).First(s => SpecialHash(s) == hashBob);
            break;
        }

        if (hashesBob.Contains(hashAlice))
        {
            finalTextForAlice = textForAlice;
            finalTextForBob = AllModifiedTexts(originTextForBob).First(s => SpecialHash(s) == hashAlice);
            break;
        }

        hashesAlice.Add(hashAlice);
        hashesBob.Add(hashBob);
    }

    Console.WriteLine("{0}: {1}", SpecialHash(finalTextForAlice), finalTextForAlice);
    Console.WriteLine("{0}: {1}", SpecialHash(finalTextForBob), finalTextForBob);
}

static MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();

//---------------------------------------------------------------------
static uint SpecialHash(string s)
{
    return BitConverter.ToUInt32(MD5(MD5(ASCIIEncoding.ASCII.GetBytes(s))), 0);
}

//---------------------------------------------------------------------
static byte[] MD5(byte[] message)
{
    return md5Hasher.ComputeHash(message);
}

//---------------------------------------------------------------------
static IEnumerable<string> AllModifiedTexts(string s)
{
    return JoinWithOneOrTwoSpaces(s.Split(' '));
}

//---------------------------------------------------------------------
static IEnumerable<string> JoinWithOneOrTwoSpaces(IEnumerable<string> words)
{
    if (words.Count() == 1)
        yield return words.Single();
    else
        foreach (string suffix in JoinWithOneOrTwoSpaces(words.Skip(1)))
        {
            yield return words.First() + " " + suffix;
            yield return words.First() + "  " + suffix;
        }
}

Aber wie dem auch sei, deine Lösung tuts, damit du bist nun dran ! smile
02.12.2010 15:24 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Xander Xander ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3215.jpg


Dabei seit: 02.11.2010
Beiträge: 54
Entwicklungsumgebung: VS C#2010Exp., SharpDevelop
Herkunft: Sonneberg


Xander ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Juhu. Und danke für die Hinweise.
Aber ich würde die Aufgabenstellung gerne erstmal abgeben. Ich werd zwar mal überlegen ob mir was einfällt, was nicht zu einfach für euch alle ist aber ich will das hier nicht allzulang blockieren. Grade weil ichs auch zum Üben gut find :D
02.12.2010 15:33 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
der-schlingel der-schlingel ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3239.jpg


Dabei seit: 13.10.2007
Beiträge: 754
Entwicklungsumgebung: VS 2005/ 2008 Pro
Herkunft: Österreich/Wien


der-schlingel ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Na gut, dann bringe ich einmal eine kleine mathematische Aufgabe. (Die ich diese Woche in Haskell lösen musste.)

Gegeben sei ein ungerichteter Graph als Adjazenzliste dessen Knoten vier verschiedene Farben annehmen können. (blau, gelb, rot und grün).

Ziel ist es einen gegebenen Graphen falls möglich so einzufärben dass jeder Knoten eine andere Farbe hat als seine Nachbarn wobei Nachbar als mit einer Kante verbundener Nachbar definiert ist.

C#-Code:
enum NodeColor
{
  blue,
  yellow,
  red,
  green
}

class Node
{
  public int NodenID { get; set; }

  public NodeColor Color { get; set; }

  public ICollection<int> Neighbours { get; set; } // die IDs
}

wobei eure Methode der Form sein soll:

C#-Code:
ICollection<Node> getColoredGraph(ICollection<Node> preColoredGraph);

Falls der Graph nicht einfärbar ist, soll Null zurückgegeben werden ansonsten der eingefärbte Graph.

Edit: Wäre natürlich schön, wenn ihr keinen naiven Ansatz verwendet.

Dieser Beitrag wurde 4 mal editiert, zum letzten Mal von der-schlingel am 02.12.2010 16:25.

02.12.2010 16:22 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Stipo Stipo ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-2966.gif


Dabei seit: 09.04.2007
Beiträge: 699
Entwicklungsumgebung: VS 2010 Pro, Blend 4
Herkunft: Lörrach


Stipo ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

So da ja 1 Woche vergangen ist, und laut den Regeln dann jeder eine neue Aufgabe bringen darf, möchte ich mal etwas dazu beitragen Augenzwinkern

Es soll eine Klasse entworfen werden, die den Wochentag eines Datum berechnen kann. Das Datum darf nicht als ein DateTime übergeben werden. Als Hilfe kann der Artikel  Wochentagsberechnung verwendet werden.

Die Aufgabe richtet sich an die Anfänger hier im Forum. Mit ein bisschen lesen und nachdenken, ist diese Aufgabe gut lösbar.

Folgenden Beispiel Code stelle ich zur verfügung:

C#-Code (Programm.cs):
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Bitte geben Sie ein Datum ein (dd.mm.YYYY): ");
            string inputDatum = Console.ReadLine();
            string[] splittedDatum = inputDatum.Split(new Char[] { '.' });

            Wochentag wochentag = new Wochentag();
            Int32 tag = wochentag.GetWochentag(Int32.Parse(splittedDatum[0]), Int32.Parse(splittedDatum[1]), Int32.Parse(splittedDatum[2]));

            Wochentage wt = (Wochentage)tag;
            Console.WriteLine("Der Wochentag lautet: {0}", wt);

            Console.ReadLine();
        }
    }

Das passende Enum dazu:

C#-Code:
    enum Wochentage
    {
        Sonntag = 0,
        Montag = 1,
        Dienstag = 2,
        Mittwoch = 3,
        Donnerstag = 4,
        Freitag = 5,
        Samstag = 6
    }

Und noch der Methoden Rumpf:

C#-Code:
    class Wochentag
    {
        public Int32 GetWochentag(Int32 tag, Int32 monat, Int32 jahr)
        {
            return ...
        }
    }

Wünsche allen viel freude beim lösen.

Grüße Stephan
09.12.2010 01:04 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
inflames2k inflames2k ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3407.gif


Dabei seit: 03.01.2010
Beiträge: 1.523
Entwicklungsumgebung: Visual Studio 2005 Standard
Herkunft: Riesa


inflames2k ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich war mal so frei die Aufgabe zu lösen, wenn auch eventuell nicht perfekt.

Meine Klasse Wochentag sieht wie folgt aus:

C#-Code:
class Wochentag
{
    Int32[] monthNumbers = new Int32[] { 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 };

        public Int32 GetWochentag(Int32 tag, Int32 monat, Int32 jahr)
        {
            Int32 day = tag % 7;
            Int32 yearHundred = 0;
            if (jahr > 99)
            {
                String year = jahr.ToString();
                jahr = Convert.ToInt32(year.Substring(2));
                // here we must decide...
                if(year.Length == 4)
                    yearHundred = Convert.ToInt32(year.Substring(0, 2));
                else
                    yearHundred = Convert.ToInt32(year.Substring(0, 1));
            }
            bool bSchaltJahr = IsSchaltJahr(jahr);
            jahr = (jahr + (jahr / 4)) % 7;
            yearHundred = (3 - (yearHundred % 4)) * 2;

            Int32 correct = 0;
            if(bSchaltJahr)
                correct = 6;

            tag = (day + yearHundred + jahr + correct + monthNumbers[monat-1]) % 7;

            return tag;
        }

        private bool IsSchaltJahr(Int32 year)
        {
            bool isIt = false;

            Int32 tempForeYear = year - 1;
            year = (year + (year / 4)) % 7;
            tempForeYear = (tempForeYear + (tempForeYear / 4)) %7;
            if (year - tempForeYear == 2)
                isIt = true;
            return isIt;
        }
}

Eine Aufgabe habe ich momentan nicht. - Sollte jemandem eine einfallen, kann er diese gern stellen. :)

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von inflames2k am 15.12.2010 10:46.

15.12.2010 10:36 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
pdelvo pdelvo ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3354.png


Dabei seit: 02.11.2008
Beiträge: 1.265
Entwicklungsumgebung: Visual Studio 2012 Prof.


pdelvo ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hey,

ja ich bin auchmal wieder da^^

dann mach ich einfach mal das nächste Rätsel und hoffe mal, dass es noch nicht gestellt wurde. Die Aufgabe ist es eine Klasse zu schreiben, die eine Liste von, sagen wir mal strings, darstellt. Implementieren sollt ihr die Methoden: Add, RemoveAt, Insert und Clear. Natürlich sind jegliche Collections verboten, sonst ist das ja keine Aufgabe. ist auch relativ einfach zu Lösen und es gibt nicht nur "die" Lösung. Wie ihr das macht ist wurscht.

lg pdelvo
15.12.2010 16:46 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
myCSharp.de
Moderationshinweis von talla (15.12.2010 17:27):

Beachtet bitte das der Aufgabensteller die Lösung auch absegnet und für richtig befindet! Nicht einfach ne neue Aufgabe Stellen nur weil jemand gepostet hat das er eine Lösung hat ohne das deren Korrektheit überprüft wurde.
 
winSharp93 winSharp93 ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-2918.png


Dabei seit: 19.01.2007
Beiträge: 5.711
Entwicklungsumgebung: VS 2010 Professional
Herkunft: Freiburg / Stuttgart


winSharp93 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top


mycsharp.de  Moderationshinweis von winSharp93 (12.02.2011 11:18):

Auf Hinweis von herbivore nochmals zur Klarstellung: Die Lösung mag zwar einfach sein, ist aber aufgrund von Einschränkungen (Verwendung von Rekursion, O(N) Aufwand für Einfügeoperationen, ...) nicht für produktiven Einsatz geeignet. Da gibt es bessere Listen u.a. in der FCL.
 

C#-Code:
public sealed class LinkedList<T>
{
    private Node<T> _first;

    public int Count
    {
        get
        {
            return this._first.CountFollowing();
        }
    }
    public T this[int index]
    {
        get
        {
            Node<T> node = this._first.GetNodeAt(index + 1);

            return node.Item;
        }
    }

    public LinkedList()
    {
        this._first = new Node<T>();
    }

    public void Add(T item)
    {
        this._first.AppendAtEnd(item);
    }
    public void Insert(T item, int index)
    {
        Node<T> node = this._first.GetNodeAt(index);

        node.Append(item);
    }
    public void RemoveAt(int index)
    {
        Node<T> previousNode = this._first.GetNodeAt(index);
        previousNode.DropFollowing();
    }
    public void Clear()
    {
        this._first = new Node<T>();
    }
}

internal class Node<T>
{
    public T Item
    {
        get;
        private set;
    }
    public Node<T> Next
    {
        get;
        private set;
    }
    public bool IsLast
    {
        get
        {
            return this.Next == null;
        }
    }

    public Node()
    {
    }
    private Node(T item)
    {
        this.Item = item;
    }

    public void AppendAtEnd(T item)
    {
        if (this.IsLast)
            this.Next = new Node<T>(item);
        else
            this.Next.AppendAtEnd(item);
    }
    public void Append(T item)
    {
        Node<T> oldNext = this.Next;
        this.Next = new Node<T>(item);
        this.Next.Next = oldNext;
    }
    public int CountFollowing()
    {
        if (this.IsLast)
            return 0;

        return this.Next.CountFollowing() + 1;
    }
    public Node<T> GetNodeAt(int index)
    {
        if (index == 0)
            return this;

        if (this.IsLast)
            throw new ArgumentOutOfRangeException();

        return this.Next.GetNodeAt(index - 1);
    }
    public void DropFollowing()
    {
        if (this.IsLast)
            throw new InvalidOperationException();

        this.Next = this.Next.Next;
    }
}

Testcode:

C#-Code:
LinkedList<string> list = new LinkedList<string>();

Console.WriteLine("Count {0}", list.Count);

list.Add("Hallo");
Console.WriteLine("Count {0}; list[0]: {1}", list.Count, list[0]);

list.Add(" ");
Console.WriteLine("Count {0}", list.Count);

list.Add("Welt");
Console.WriteLine("Count {0}", list.Count);

for (int i = 0; i < list.Count; i++)
    Console.Write(list[i]);
Console.WriteLine();

list.RemoveAt(1);
Console.WriteLine("Count {0}", list.Count);

for (int i = 0; i < list.Count; i++)
    Console.Write(list[i]);
Console.WriteLine();

list.Insert("-", 1);
for (int i = 0; i < list.Count; i++)
    Console.Write(list[i]);
Console.WriteLine();

list.Clear();
Console.WriteLine("Count {0}", list.Count);

Console.ReadKey();
15.12.2010 17:10 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegt mehr als ein Monat.
winSharp93 winSharp93 ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-2918.png


Dabei seit: 19.01.2007
Beiträge: 5.711
Entwicklungsumgebung: VS 2010 Professional
Herkunft: Freiburg / Stuttgart


winSharp93 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Nachdem ja kein Einspruch gegen meine Lösung erfolgte und ich gebeten wurde, eine neue Aufgabe zu stellen - hier ist sie Augenzwinkern :
Ergänzt den obigen Code für die Liste um eine Reverse Methode.
12.02.2011 08:22 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MarsStein MarsStein ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-3191.gif


Dabei seit: 27.06.2006
Beiträge: 2.718
Entwicklungsumgebung: VS 2010, MonoDevelop, #Develop
Herkunft: Trier -> München


MarsStein ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

Hier eine einfache Reverse-Methode:

C#-Code:
    public void Reverse()
    {
      Node<T> node = _first.Next;
      Clear();
      while(node != null)
      {
        _first.Append(node.Item);
        node = node.Next;
      }
    }

Da der Zugriff auf Next schreibgeschützt ist, und keine Append/Remove-Methoden für Nodes vorhanden sind, erschien es mir als einfachste Variante, die Liste zu leeren und die Items in umgekehrter Reihenfolge neu anzufügen. Alles andere bedarf IMHO außer der zusätzlichen Methode noch weiterer Änderungen.

Gruß, MarsStein
12.02.2011 15:06 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
winSharp93 winSharp93 ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-2918.png


Dabei seit: 19.01.2007
Beiträge: 5.711
Entwicklungsumgebung: VS 2010 Professional
Herkunft: Freiburg / Stuttgart


winSharp93 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Gut, gut smile
Du bist dran!
12.02.2011 15:56 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MarsStein MarsStein ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-3191.gif


Dabei seit: 27.06.2006
Beiträge: 2.718
Entwicklungsumgebung: VS 2010, MonoDevelop, #Develop
Herkunft: Trier -> München


MarsStein ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

hier die neue Aufgabe, eher ein Appetithäppchen für zwischendurch, das sich in ein paar Zeilen lösen lässt smile

Zeigt anhand folgendem Beispiel, daß man mit .NET das Prinzip der Kapselung ziemlich einfach aushebeln kann.
Erstellt hierzu innerhalb der Methode CreateForbiddenObject ein Objekt der Klasse MyNested, welches beim Aufruf seiner ToString()-Methode den an CreateForbiddenObject übergebenen String ausgibt.
Es darf nur die Methode CreateForbiddenObject bearbeitet werden, MyClass und MyNested müssen unangetastet bleiben.

Die Ausgabe müsste also etwa so aussehen:

MyClass+MyNested: nichts ist unmöglich!

Gegeben ist dazu folgender Code:

C#-Code:
class MyClass
{
  private class MyNested
  {
    private string name = null;

    private MyNested() { }

    public override string ToString() { return name; }
  }
}

class Program
{
  public static void Main(string[] args)
  {
    object o = CreateForbiddenObject("nichts ist unmöglich!");
    Console.WriteLine("{0}: {1}", o.GetType().FullName, o);
    Console.Read();
  }

  static object CreateForbiddenObject(string name)
  {
    // hier den nötigen Code einfügen
  }
}

Viel Spaß, MarsStein
12.02.2011 21:06 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
zero_x zero_x ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-2567.gif


Dabei seit: 16.02.2008
Beiträge: 1.043
Herkunft: Koblenz


zero_x ist offline Füge zero_x Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo MarsStein,

meinst Lösung:

C#-Code:
return new MyClass().GetType().GetNestedTypes(BindingFlags.NonPublic).First();

Ich hoffe mal, dass ich die Aufgabenstellung richtig verstanden habe.

zero_x
12.02.2011 21:24 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MarsStein MarsStein ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-3191.gif


Dabei seit: 27.06.2006
Beiträge: 2.718
Entwicklungsumgebung: VS 2010, MonoDevelop, #Develop
Herkunft: Trier -> München


MarsStein ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo zero_x,

Zitat von zero_x:
Ich hoffe mal, dass ich die Aufgabenstellung richtig verstanden habe.

Leider nicht. Die Vorgabe ist ja, daß das Objekt vom Typ MyClass+MyNested sein muss und mit ToString() den an die Create-Methode übergebenen String - im Beispiel "nichts ist unmöglich" - ausgibt.

Bei Dir ist das Objekt aber vom Typ System.RuntimeType und gibt mit ToString() "MyClass+MyNested" aus Augenzwinkern

Gruß, MarsStein
12.02.2011 21:39 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Sebastian.Lange Sebastian.Lange ist männlich
myCSharp.de-Poweruser/ Experte

Dabei seit: 22.06.2007
Beiträge: 915
Entwicklungsumgebung: Visual Studio 2008, 2010
Herkunft: Berlin


Sebastian.Lange ist offline MSN-Passport-Profil von Sebastian.Lange anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Dir gehts darum die Kapselung auszuhebeln also zugriff auf
'private string name' zu nehmen wenn ich dich richtig verstanden habe.
Gut das geht auch mit Reflection: zero_x ich lass dir mal noch einen Versuch *g
13.02.2011 03:13 Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Team (Admin)

images/avatars/avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 47.492
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Sebastian.Lange,

nein, das hast du falsch verstanden.

Die Aufgabe ist es, ein Objekt der geschachtelten und privaten Klasse MyNested zu erzeugen.

Dabei soll der Name zwar als Parameter übergeben werden, aber der Zugriff auf die Name-Property bzw. das dahinterliegenden Feld wird von der privaten Klasse durchgeführt (im Konstruktor und im ToString). Das ist nicht die Aufgabe des Codes, den man schreiben soll, sondern der soll "nur" das Objekt erzeugen.

herbivore
13.02.2011 07:45 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Floste
myCSharp.de-Mitglied

images/avatars/avatar-2376.jpg


Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008
Herkunft: Norddeutschland


Floste ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
aber der Zugriff auf die Name-Property bzw. das dahinterliegenden Feld wird von der privaten Klasse durchgeführt (im Konstruktor

Wie soll das gehen, wenn der constructor so aussieht:

C#-Code:
    private MyNested() { }

Also sowohl constructor aufrufen, alsauch das feld name setzen^^
13.02.2011 11:04 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MarsStein MarsStein ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-3191.gif


Dabei seit: 27.06.2006
Beiträge: 2.718
Entwicklungsumgebung: VS 2010, MonoDevelop, #Develop
Herkunft: Trier -> München


MarsStein ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

Zitat von Floste:
Also sowohl constructor aufrufen, alsauch das feld name setzen^^

Das tifft den Nagel auf den Kopf Daumen hoch
13.02.2011 11:51 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Scavanger Scavanger ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3209.jpg


Dabei seit: 13.03.2008
Beiträge: 265
Entwicklungsumgebung: MS VS C# 2010 Prof.


Scavanger ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Meine Lösung:

C#-Code:
static object CreateForbiddenObject(string name)
        {
            Type myType = new MyClass().GetType().GetNestedType("MyNested", BindingFlags.NonPublic);
            object myObject = Activator.CreateInstance(myType, true);

            FieldInfo fi = myType.GetField("name", BindingFlags.NonPublic | BindingFlags.Instance);
            fi.SetValue(myObject, name);

            return myObject;

        }

Natürlich geht das ganze nur über Reflection:

Zuerst per Activator-Klasse eine Instanz von MyNested erstellen.
Dann kommt der eigentliche Gag: Per FieldInfo.SetValue bekommt man Zugriff auf das private Feld.

Zitat MSDN zu FieldInfo.SetValue

Zitat:
Hinweis

Voll vertrauenswürdiger Code verfügt über die Berechtigungen für den Zugriff auf private Konstruktoren, Methoden, Feldern und Eigenschaften mit Reflektion sowie für das Aufrufen dieser.

 FieldInfo.SetValue-Methode (Object, Object)

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Scavanger am 13.02.2011 15:13.

13.02.2011 15:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MarsStein MarsStein ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-3191.gif


Dabei seit: 27.06.2006
Beiträge: 2.718
Entwicklungsumgebung: VS 2010, MonoDevelop, #Develop
Herkunft: Trier -> München


MarsStein ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Scavanger,

Deine Lösung ist richtig, Du bist somit dran.

Meine eigene Lösung ist ähnlich, allerdings ohne FieldInfo zu benutzen, denn wenn man die Instanz hat kann kann man auch per Type.InvokeMember das private Feld setzen.
Btw.statt new MyClass().GetType() kann sich mit typeof(MyClass) das Erstellen einer Instanz von MyClass sparen.

Hier nochmal meine eigene Lösung:

C#-Code:
  static object CreateForbiddenObject(string name)
  {
    Type t = typeof(MyClass).GetNestedType("MyNested", BindingFlags.NonPublic);
    object obj = Activator.CreateInstance(t, true);
    t.InvokeMember("name", BindingFlags.NonPublic|BindingFlags.SetField|BindingFlags.Instance,
                   null, obj, new object[] { name });
    return obj;
  }

Gruß, MarsStein
13.02.2011 15:37 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Sebastian.Lange Sebastian.Lange ist männlich
myCSharp.de-Poweruser/ Experte

Dabei seit: 22.06.2007
Beiträge: 915
Entwicklungsumgebung: Visual Studio 2008, 2010
Herkunft: Berlin


Sebastian.Lange ist offline MSN-Passport-Profil von Sebastian.Lange anzeigen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

ja das vorherige erzeugen war für mich so selbstverständlich das ich's garnicht erwähnt hab. war schon spät...
ansonsten wie schon gesagt das private feld noch mittels reflection setzen
(damit ToString() das richtige ausgibt)
13.02.2011 19:47 Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegt mehr als ein Monat.
Spontifixus Spontifixus ist männlich
myCSharp.de-Mitglied

images/avatars/avatar-3052.gif


Dabei seit: 06.09.2005
Beiträge: 360
Entwicklungsumgebung: VisualStudio 2008/2010
Herkunft: Hannover


Spontifixus ist offline

Das Osterei für den Ex...

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo zusammen,

da der letzte Beitrag ja schon eine kleine Ewigkeit her ist, erlaube ich mir mal ein neues kleines Rätsel zu stellen. Ich formuliere die Frage mal so, wie sie bei einer Zertifizierungsprüfung gestellt würde. ;)

Sie arbeiten als Software-Enwickler bei der Firma Kleine Klitsche GBR und verwenden Visual Studio 2010 mit .NET 4 als Entwicklungsumgebung.

Trotz exzellenter Leistungen erhalten Sie die Kündigung. Sie haben durch Zufall erfahren, dass der Chef bei Kündigungen immer ein kleines Konsolenprogramm aufruft, um sämtliche Daten des Gekündigten aus dem System zu entfernen.

Bevor der Chef Sie jedoch aus dem Büro geleitet, bekommt er einen Anruf und lässt Sie für ein paar Minuten an Ihrem Platz allein. Schnell starten Sie Visual Studio und laden die Solution der kleinen Applikation. Damit ihre Änderung so unauffällig wie möglich bleibt, fügen Sie der Originaldatei nur ein einziges Wort hinzu. Allerdings verstecken Sie eine weitere Datei in den Tiefen der kleinen Applikation.

Gerade als Sie Ihre "Arbeit" abgeschlossen haben erscheint Ihr Gerade-Noch-Chef und geleitet Sie aus dem Büro. Kaum das er Sie vor die Tür gesetzt hat verschwindet der Jetzt-Ex-Chef in seinem Kämmerlein. Sie spitzen die Ohren und richtig: Keine zwei Minuten später hören Sie ein ersticktes Schluchzen aus eben diesem Kämmerlein und machen sich fröhlich pfeifend auf den Weg zum Arbeitsamt...

Was war geschehen? Jedes mal wenn der Zum-Glück-Nicht-Mehr-Chef der kleinen Applikation Ihren Namen übergibt erscheint derselbe Text auf dem Bildschirm:

C:\Windows\system32\cmd.exe
c:\>KollegenKicker.exe "Ihr Name"
Bitte geben Sie den Namen des Angestellten an, den Sie feuern möchten!
c:\>

So sah das Programm vor Ihrer Änderung aus:

C#-Code:
static class Program {

    [STAThread]
    static void Main(string[] args) {

        if (args.Length == 0 || args[0] == string.Empty) {
            Console.WriteLine("Bitte geben Sie den Namen des Angestellten an, den Sie feuern möchten!");
            return;
        }

        // Jede
        // Menge
        // Code
        // um
        // den
        // Angestellten
        // loszuwerden
        // ...

    }

}

Welches Wort fügen Sie in die Datei Program.cs ein, und welche Datei erstellen Sie noch um den gewünschten Effekt zu erreichen?

Es gewinnt die Antwort, die mit dem wenigsten Code auskommt!

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Spontifixus am 14.03.2011 20:36.

14.03.2011 19:46 Beiträge des Benutzers | zu Buddylist hinzufügen
Seiten (17): « erste ... « vorherige 5 6 7 8 [9] 10 11 12 13 nächste » ... letzte » Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 3 Jahre.
Der letzte Beitrag ist älter als ein Monat.
Antwort erstellen


© Copyright 2003-2013 myCSharp.de-Team. Alle Rechte vorbehalten. 23.05.2013 07:36