|
| » myCSharp.de Diskussionsforum |
|
|
|
|
Autor
 |
|
Floste
myCSharp.de-Mitglied
Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008 Herkunft: Norddeutschland
|
|
Schade, dass es hier nicht weitergeht, aber ich habe ehrlichgesagt auch keine lust obige aufgabe zu lösen.
Vielleicht fällt ja jemandem eine bessere ein.
|
|
06.09.2010 16:20
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
JAck30lena
myCSharp.de-Team (Admin)
Dabei seit: 01.10.2006
Beiträge: 11.393
Entwicklungsumgebung: Visual Studio 05/08/10 Prof.
|
|
Ich finde du hast recht. Hiermit erkläre ich die obige Aufgabe für nicht mehr gültig, weil obsolet. Jemand darf nun eine neue Aufgabe stellen. Der Erste der postet hat gewonnen.
|
|
06.09.2010 17:04
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
herbivore
myCSharp.de-Team (Admin)
Dabei seit: 11.01.2005
Beiträge: 47.477
Entwicklungsumgebung: csc/nmake (nothing is faster) Herkunft: Berlin
|
|
Hallo zusammen,
ich würde einen Schritt weiter gehen und sagen, dass der Thread grundsätzlich wieder frei für eine neue Aufgabe ist, wenn eine Woche seit dem letzten Beitrag vergangen ist (egal ob dieser letzte Beitrag nun eine Aufgabe, eine Nachfrage oder eine Lösung ist und egal ob die Lösung richtig oder falsch war, also einfach: eine Woche Inaktivität = neue Aufgabe erlaubt).
herbivore
|
|
06.09.2010 18:11
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Corpsegrinder
myCSharp.de-Mitglied
Dabei seit: 30.01.2007
Beiträge: 401
Entwicklungsumgebung: VS 2008 , .Net 3.5
|
|
Also ich habe jetzt keine programmierte Lösung parat, aber es wäre relativ einfach gewesen. Alle Transaktionen kommen in eine Queue und werden nacheinander abgearbeitet, so ist kein Lock und keine Synchronisation nötig ;-).
edit: lesen des aktuellen Kontostandes geschieht natürlich direkt...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Corpsegrinder am 07.09.2010 11:07.
|
|
07.09.2010 11:04
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Corpsegrinder
myCSharp.de-Mitglied
Dabei seit: 30.01.2007
Beiträge: 401
Entwicklungsumgebung: VS 2008 , .Net 3.5
|
|
| Zitat von Arithmetika: |
| sorry aber eine Queue ist nicht Threadsafe und daher ist Synchronisation und Locking notwendig. |
Wenn du meine Aufgabe gelesen hättest, dann wüsstest du, dass ich erlaubt habe Strukturen zu benutzen, die schon Threadsafe sind. Also auch eine Threadsafe Queue.
Hier aber nochmal eine Lösung, die ich eben erstellt habe:
Code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
|
import scala.actors.Actor
import scala.collection.immutable.HashMap
object Main {
/**
* @param args the command line arguments
*/
def main(args: Array[String]) = {
TransactionSystem ! ('create, "foo", 4000.)
TransactionSystem ! ('create, "bar", 0.)
TransactionSystem ! ('transfer, "foo", "bar", 2000.)
println(TransactionSystem !? Tuple2('balance, "foo"))
println(TransactionSystem !? Tuple2('balance, "bar"))
TransactionSystem ! 'exit
}
object TransactionSystem extends Actor {
start
case class Account(val amount: Double)
def act {
act(HashMap[String, Account]())
}
def act(accs: HashMap[String, Account]): Unit = {
react {
case ('transfer, from: String, to: String, amount: Double)
if(accs.contains(from) && accs.contains(to) &&
accs(from).amount >= amount) => {
act(accs.filter((acc) => acc != from && acc != to) ++
HashMap(from -> Account(accs(from).amount - amount),
to -> Account(accs(to).amount + amount)))
}
case ('create, name: String, amount: Double) if(!accs.contains(name)) => act(accs ++ HashMap(name -> Account(amount)))
case ('balance, name: String) if(accs.contains(name)) => reply(Some(accs(name).amount)); act(accs)
case 'exit => exit
case _ => println("Operation could not be completed."); act(accs)
}
}
}
} |
|
|
|
07.09.2010 11:39
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Floste
myCSharp.de-Mitglied
Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008 Herkunft: Norddeutschland
|
|
So, da immernoch keine neue aufgabe da ist, habe ich mal versucht eine zu machen (besonders kreativ is sie nicht, aber lösbar):
Aufgabe:
Schreibe ein programm, das das gemeinsame kgv (= kleinste gemeinsame vielfache) aller Zahlen in der liste im anhang in unter 10 sekunden findet. Das programm soll also genau eine zahl ausgeben.
Optional / Wünschenswert ist:
-lösen aufgabe in unter 1 sec
-möglichst simpler code
-eine gute nächste aufgabe in petto haben
| Dateianhang: |
numbers.txt (11 KB, 131 mal heruntergeladen) |
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Floste am 07.09.2010 16:34.
|
|
07.09.2010 16:30
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
zommi
myCSharp.de-Poweruser/ Experte
Dabei seit: 14.11.2007
Beiträge: 1.229
Entwicklungsumgebung: VS 2005+2010 Herkunft: Berlin
|
|
Mit .NET 4.0 würd ichs wie folgt machen:
C#-Code: |
using System;
using System.Numerics;
using System.IO;
using System.Linq;
public class LeastCommonMultiple
{
public static void Main()
{
Console.Write(
File
.ReadAllLines("numbers.txt")
.Select(s => BigInteger.Parse(s))
.Aggregate((oldLCM, nextNumber) =>
(oldLCM * nextNumber) / BigInteger.GreatestCommonDivisor(oldLCM, nextNumber)
)
);
}
}
|
ergibt:
beste Grüße
zommi
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von zommi am 07.09.2010 17:14.
|
|
07.09.2010 17:14
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
gfoidl
myCSharp.de-Team (Moderation)
Dabei seit: 07.06.2009
Beiträge: 5.349
Entwicklungsumgebung: VS 2010 sup{Editionen} Herkunft: Waidring / Tirol
|
|
Hallo zommi,
wenn statt ReadAllLines ReadLines verwendet wird sollte es noch ein wenig schneller gehen da nicht zuerst die ganze Datei gelesen werden muss bevor mit Select fortgefahren werden kann. ReadLines enumeriert die Zeilen während ReadAllLines ein Array von Zeilen zurückgibt.
Sonst: Super Ansatz!
mfG Gü
|
|
07.09.2010 17:20
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Floste
myCSharp.de-Mitglied
Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008 Herkunft: Norddeutschland
|
|
o.O, so war das nicht geplant, die funktion gibts in .net 3.5, das ich noch verwende ned.
Das ergebnis sieht aber richtig aus.
|
|
07.09.2010 17:29
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
zommi
myCSharp.de-Poweruser/ Experte
Dabei seit: 14.11.2007
Beiträge: 1.229
Entwicklungsumgebung: VS 2005+2010 Herkunft: Berlin
|
|
Mhh.. aus Flostes Antwort konnte ich jetzt nicht herauslesen, wie zufrieden er mit der Lösung ist. Aber ich sehs mal als gelöst an :D
Also meine neue Aufgabe:
| Zitat von dem neuem Aufgabensteller: |
Es wird Hacky:
Ihr sollt ein bischen Code schreiben, der aus einem gegebenen int[]-Array ein kleines Teilstück als neues int[]-Array extrahiert. Quasi ein SubArray. Aber so, dass Veränderungen am SubArray real im Ausgangsarray zu bemerken sind. Das SubArray muss also noch immer, speichermäßig, irgendwie, im großen Array "drin" liegen.
Ich gebe folgende Programmrahmen vor:
C#-Code: |
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
class Program
{
static void Main(string[] args)
{
int[] numberArray = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
GCHandle gch = GCHandle.Alloc(numberArray, GCHandleType.Pinned);
int[] subArray = SubArrayMaker.GetSubArray(numberArray);
if (numberArray[5] != 5 || numberArray[6] != 6)
return;
lock(subArray)
Array.Clear(subArray, 0, subArray.Length);
if (numberArray[5] == 0 && numberArray[6] == 6)
Console.WriteLine("SUCCESS");
}
}
public class SubArrayMaker
{
}
|
Ihr sollt der Klasse SubArrayMaker Leben einhauchen, sodass "SUCCESS" ausgegeben wird.
Man erkennt schon, dass das SubArray von seiner Länge her bis zum 6. Element des Ausgangsarrays gehen muss.
Kern der Aufgabe ist zu experimentieren, wie man ein managed .NET Objekt "konstruieren" kann, ohne jemals "new" aufgerufen zu haben und das dann auch noch in eine echte Objekt-Referenz zu pressen.
Das ganze ist tricky und erfordert wahrscheinlich unsafe-Pointer-Arithmetik. Man muss schon etwas über die CLR-Internas nachlesen und in ihren Eingeweiden rumfummeln ;)
Aber alles wichtige ist im Abschnitt "Object Instances" unter Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects zu finden.
PS: Ich empfehle ein 32-Bit System. Da ich selbst kein 64-Bit System verwende, kann ich nich garantieren, dass es dort auch eine Lösung gibt / machbar ist. |
Ich wünsche viel Vergnügen und spannende Einsichten ;-)
Und bei Fragen, einfach fragen.
beste Grüße
zommi
Dieser Beitrag wurde 6 mal editiert, zum letzten Mal von zommi am 08.09.2010 11:33.
|
|
07.09.2010 20:39
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Floste
myCSharp.de-Mitglied
Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008 Herkunft: Norddeutschland
|
|
C#-Code: |
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Modus: "+(IntPtr.Size*8)+"bit");
int[] numberArray = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
GCHandle gch = GCHandle.Alloc(numberArray, GCHandleType.Pinned);
int[] subArray = SubArrayMaker.GetSubArray(numberArray);
if (numberArray[5] != 5 || numberArray[6] != 6)
return;
lock (subArray)
Array.Clear(subArray, 0, subArray.Length);
if (numberArray[5] == 0 && numberArray[6] == 6)
Console.WriteLine("SUCCESS");
Console.ReadLine();
}
}
public class SubArrayMaker
{
delegate IntPtr pRefToPtr(ref object reference);
static pRefToPtr RefToPtr=MakeRefToPtr();
private static pRefToPtr MakeRefToPtr()
{
DynamicMethod meth = new DynamicMethod("GetAddr", typeof(IntPtr), new Type[1] { typeof(object).MakeByRefType() },typeof(SubArrayMaker),true);
ILGenerator gen= meth.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Conv_I);
gen.Emit(OpCodes.Ret);
return (pRefToPtr)meth.CreateDelegate(typeof(pRefToPtr));
}
struct ArrayHeader
{
public IntPtr Syncblock1;
public IntPtr TypeId;
public IntPtr Length;
}
public static unsafe int[] GetSubArray(int[] numberArray)
{
ArrayHeader* oldArray = &(((ArrayHeader*)Marshal.UnsafeAddrOfPinnedArrayElement(numberArray, 0))[-1]);
ArrayHeader* newArray=&(((ArrayHeader*)Marshal.UnsafeAddrOfPinnedArrayElement(numberArray, 5))[-1]);
*newArray = *oldArray;
newArray->Length = (IntPtr)1;
object array = null;
IntPtr* pArrayVar = ((IntPtr*)RefToPtr(ref array));
*pArrayVar = (IntPtr)(&(newArray->TypeId));
return (int[])array;
}
}
|
Geht unter 32 und 64 bit!
( aber auch nur, weil .net von m$ die letzten 4 bytes der arraylänge ignoriert, weil arrays mit 32 bit ints indiziert werden.)
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Floste am 08.09.2010 17:24.
|
|
08.09.2010 17:20
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
zommi
myCSharp.de-Poweruser/ Experte
Dabei seit: 14.11.2007
Beiträge: 1.229
Entwicklungsumgebung: VS 2005+2010 Herkunft: Berlin
|
|
Sehr schön
Meine Implementierung (für 32Bit) war:
C#-Code: |
public class SubArrayMaker
{
public unsafe static int[] GetSubArray(int[] array)
{
fixed (int* ptr = array)
{
ptr[0] = 0;
ptr[1] = ptr[-2];
ptr[2] = 3;
return ConvertPointerToIntArrayReference(ptr + 1);
}
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct IntArrayHolder
{
public int[] array;
public int* ptr;
}
unsafe static int[] ConvertPointerToIntArrayReference(int* ptr)
{
IntArrayHolder ah = new IntArrayHolder();
(&ah.ptr)[-1] = ptr;
return ah.array;
}
}
|
Dann ist der Ball jetzt wohl wieder bei Floste
|
|
08.09.2010 19:04
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Floste
myCSharp.de-Mitglied
Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008 Herkunft: Norddeutschland
|
|
Etwas skurril, aber ich stells mal trotzdem:
Schreibe ein programm, das folgendes tut:
wenn das programm ohne adminrechte läuft soll es nach diesen fragen. (runas)
danach soll es cmd.exe auf dem interactive service desktop starten.
Wichtig ist:
-das zu keinem zeitpunkt ein autostart installiert wird (darunter verstehe ich eine komponente/service/programm das beim systemstart automatisch geladen wird)
-der pc nicht neugestartet wird und weiterhin funktioniert
-am ende keinerlei listen- oder serviceeinträge übrigbleiben (wenn erstellt, müssen diese hinterher wieder entfernt werden.)
-keine dateien außerhalb des programmordners geschrieben werden. (am besten garkeine)
Außerdem soll das ganze am besten sofort und nicht erst nach einer minute passieren.
Es dürfen sämtliche .net und windows boardmittel benutzt werden, inklusive sämtlicher kommandozeilenprogramme.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Floste am 08.09.2010 21:03.
|
|
08.09.2010 21:02
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
| Zwischen diesen beiden Beiträgen liegt mehr als ein Monat. |
herbivore
myCSharp.de-Team (Admin)
Dabei seit: 11.01.2005
Beiträge: 47.477
Entwicklungsumgebung: csc/nmake (nothing is faster) Herkunft: Berlin
|
|
Hallo zusammen,
nachdem (mehr als) eine Woche ohne Antwort vergangen ist, ist entsprechende der Regeln die letzte Aufgabe (leider) obsolet und der Ball ja wieder frei. Ich nutze diesen Umstand für eine neue, hoffentlich populärere Aufgabe.
Es geht darum eine Methode zu schreiben, die ein Array von fünf Integers bekommt, das das Ergebnis von fünf Spielwürfelwürfen repräsentiert und als Ergebnis ein Array aller bei diesem Wurf möglichen Punkte nach den Kniffelregeln liefert.
Vorgegeben ist folgender Enum
C#-Code: |
public enum Scores
{
Ones,
Twos,
Threes,
Fours,
Fives,
Sixes,
ThreeOfAKind,
FourOfAKind,
FullHouse,
SmallStraight,
LargeStraight,
Yahtzee,
Chance
}
|
der die Indexwerte für das zurückgelieferte Array definiert. Das zurückgelieferte Array hat also eine Länge von Enum.GetValues (typeof (Scores)).Length und enthält als Werte die Punkte, die durch den übergebenen Wurf in jeder der Kategorien erzielt werden können.
Die Signatur der Methode ist ebenfalls vorgegeben:
C#-Code: |
public static int [] GetPoints (int [] dice)
|
Getestet werden kann mit der folgenden Methode, die indirekt auch alle Zweifelsfälle bei der Interpretation von Ein- und Ausgabe der GetPoints-Methode klären sollte, insbesondere, dass die Werte der Würfelwürfe nicht als 1..6 sondern zerobased als 0..5 repräsentiert werden.
C#-Code: |
public static void Main (string [] astrArg)
{
Random rand = new Random ();
int [] dice = new int [5];
for (int i = 0; i < dice.Length; ++i) {
dice [i] = rand.Next (6);
}
int [] points = GetPoints (dice);
foreach (Scores score in Enum.GetValues (typeof (Scores))) {
Console.WriteLine ("{0,15} {1}", score, points [(int)score]);
}
}
|
Jetzt noch ein Beispiel. Das Eingabe-Array { 0, 4, 4, 0, 4 }, sprich zwei Einer und drei Fünfer (sic!), würde folgende Ausgabe produzieren:
Ones 2
Twos 0
Threes 0
Fours 0
Fives 15
Sixes 0
ThreeOfAKind 17
FourOfAKind 0
FullHouse 25
SmallStraight 0
LargeStraight 0
Yahtzee 0
Chance 17
Es werden also alle Punkte angezeigt, die bei diesem Wurf möglich sind.
Es soll kein komplettes Kniffelspiel implementiert werden, sondern nur die eine wichtige Hilfsmethode GetPoints. Der Code meiner Implementierung dieser Methode ist knapp über 50 (normal formatierte) Zeilen lang. Die Aufgabe sollte also keine besondere Hürde darstellen, aber trotzdem Spaß machen!
herbivore
|
|
08.10.2010 22:50
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
herbivore
myCSharp.de-Team (Admin)
Dabei seit: 11.01.2005
Beiträge: 47.477
Entwicklungsumgebung: csc/nmake (nothing is faster) Herkunft: Berlin
|
|
Hallo TheBrainiac,
deine Lösung ist korrekt [EDIT=bis auf, dass Yahtzee auch als Fullhouse zählt (siehe Anmerkung von N1ls)[/EDIT]. Du bist mit der nächsten Aufgabe dran.
Hier zum Vergleich noch, wie ich mir das vorgestellt hatte [EDIT=korrigiert, dass Yahtzee auch als Fullhouse zählt[/EDIT]. Basierend auf dem Vorschlag in Kniffelspiel: Ermitteln, was geworfen wurde (z.B. Full House), ohne alle Kombinationen abzufragen habe ich zunächst ein Array aufgebaut, in dem für jede Augenzahl steht, wie oft die jeweilige Augenzahl gewürfelt wurde, um die anschließenden Berechnungen zu vereinfachen:
C#-Code: |
public static int [] GetPoints (int [] dice)
{
int [] diceCounts = new int [6];
int [] points = new int [Enum.GetValues (typeof (Scores)).Length];
int sumOfAllDice = 0;
int straight = 0;
int maxStraight = 0;
bool full = false;
bool house = false;
for (int i = 0; i < dice.Length; ++i) {
++diceCounts [dice [i]];
sumOfAllDice += dice [i] + 1;
}
for (int i = 0; i < diceCounts.Length; ++i) {
points [i] = diceCounts [i] * (i + 1);
if (diceCounts [i] > 0) { ++straight; }
else { if (straight > maxStraight) { maxStraight = straight; } straight = 0; }
if (diceCounts [i] == 2) { full = true; }
if (diceCounts [i] >= 3) { points [(int)Scores.ThreeOfAKind] = sumOfAllDice; house = true; }
if (diceCounts [i] >= 4) { points [(int)Scores.FourOfAKind] = sumOfAllDice; }
if (diceCounts [i] >= 5) { points [(int)Scores.Yahtzee] = 50; points [(int)Scores.FullHouse] = 25; }
}
if (full && house) { points [(int)Scores.FullHouse] = 25; }
if (straight > maxStraight) { maxStraight = straight; }
if (maxStraight >= 4) { points [(int)Scores.SmallStraight] = 30; }
if (maxStraight >= 5) { points [(int)Scores.LargeStraight] = 40; }
points [(int)Scores.Chance] = sumOfAllDice;
return points;
}
|
herbivore
|
|
09.10.2010 09:49
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
TheBrainiac
myCSharp.de-Mitglied
Dabei seit: 17.12.2006
Beiträge: 767
Entwicklungsumgebung: VS 2010 Prof. Herkunft: /dev/null
|
|
Die neue Aufgabe:
Entwickle einen simplen Kompressions-Algorithmus!
Vorgegeben ist folgendes Snippet (Vollständige Vorlage siehe Anhang):
C#-Code: |
using System;
using System.Text;
public class Compression
{
public static void Main() {
string input = "";
byte[] uncompressed = Encoding.ASCII.GetBytes(input);
byte[] compressed = Compress(uncompressed);
byte[] decompressed = Decompress(compressed);
string output = Encoding.ASCII.GetString(decompressed);
double ratio = (1d - (double)compressed.Length / (double)uncompressed.Length) * 100;
bool equal = input == output;
bool success = ratio > 10d && equal;
Console.WriteLine("Uncompressed Length: {0}", uncompressed.Length);
Console.WriteLine("Compressed Length: {0}", compressed.Length);
Console.WriteLine("Decompressed Length: {0}", decompressed.Length);
Console.WriteLine("Compression Ratio: {0:0.0000}%", ratio);
Console.WriteLine("Input equals output: {0}", equal);
Console.WriteLine("Successful: {0}", success);
Console.ReadKey(true);
}
public static byte[] Compress(byte[] input) {
}
public static byte[] Decompress(byte[] input) {
}
}
|
Bedingungen: - Frameworks- / 3rd-Party-Klassen, die selbst Komprimierungsalgorithmen in irgend einer Form bereitstellen, sind verboten!
- Die Kompressionsrate muss zum Erfolgreichen bestehen mindestens 10% betragen!
- Die Kompression muss verlustfrei sein! (D.h. der Output von der Dekompressions-Methode muss gleich dem Input der Kompressions-Methode sein!)
Tipps: - Am Anfang war das Wort!
- Ein Wörterbuch kann auch nicht schaden!
Gruß & Viel Spaß, Christian.
Dieser Beitrag wurde 5 mal editiert, zum letzten Mal von TheBrainiac am 09.10.2010 14:47.
|
|
09.10.2010 14:42
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
herbivore
myCSharp.de-Team (Admin)
Dabei seit: 11.01.2005
Beiträge: 47.477
Entwicklungsumgebung: csc/nmake (nothing is faster) Herkunft: Berlin
|
|
Hallo TheBrainiac,
da du nur moderate 10% Kompression gefordert hast, hat sich mir sofort die Idee aufgedrängt, dass bei normalem Text das erste Bit meistens Null ist und daher eingespart werden kann, wenn man einfach immer nur die restlichen 7bit dicht an dich packt. So bekommt man je 8 Bytes in je 7 Bytes komprimiert, d.h. wenn es genau aufgeht eine Kompression von 12,5%. Da du Encoding.ASCII verwendest, ist das erste Bit sogar immer Null. Trotzdem habe ich den Fall implementiert, dass erste Bit manchmal auch Eins sein kann. In diesem Fall wird mit 0x7f eine Escapesequenz eingeleitet. Damit es keine Konflikte gibt, muss man auch 0x7f escapen, wenn es als normales Zeichen im Text auftaucht. Das alles macht der folgende Code:
C#-Code: |
public static byte[] Compress(byte[] input) {
List <byte> result = new List <byte> ();
int bitsLeft = 0;
foreach (byte b in input) {
if ((b & 0x80) == 0x80) {
AddPacked (result, 0x7f, ref bitsLeft);
AddPacked (result, (byte)(b & 0x7f), ref bitsLeft);
} else if (b == 0x7f) {
AddPacked (result, 0x7e, ref bitsLeft);
AddPacked (result, 0x01, ref bitsLeft);
} else if (b == 0x7e) {
AddPacked (result, 0x7e, ref bitsLeft);
AddPacked (result, 0x00, ref bitsLeft);
} else {
AddPacked (result, b, ref bitsLeft);
}
}
if (bitsLeft == 7) {
result [result.Count - 1] |= 0x7f;
}
return result.ToArray ();
}
private static void AddPacked (List <byte> list, byte b, ref int bitsLeft)
{
try {
if (bitsLeft == 0) {
list.Add ((byte)(b << 1));
return;
}
if (bitsLeft == 7) {
list [list.Count - 1] |= b;
return;
}
list [list.Count - 1] |= (byte)(b >> (7 - bitsLeft));
list.Add ((byte)(b << (bitsLeft + 1)));
}
finally {
bitsLeft = (bitsLeft + 1) % 8;
}
}
public static byte[] Decompress(byte[] input) {
List <byte> result = new List <byte> ();
byte currByte;
for (int bitOffset = 0; bitOffset <= input.Length * 8 - 7;) {
currByte = GetPacked (input, ref bitOffset);
if (currByte == 0x7f) {
if (bitOffset <= input.Length * 8 - 7) {
result.Add ((byte)(GetPacked (input, ref bitOffset) | 0x80));
}
continue;
}
if (currByte == 0x7e) {
if (GetPacked (input, ref bitOffset) == 0x00) {
result.Add (0x7e);
continue;
}
result.Add (0x7f);
continue;
}
result.Add (currByte);
}
return result.ToArray ();
}
private static byte GetPacked (byte [] list, ref int bitOffset)
{
try {
int byteOffset = bitOffset / 8;
if (bitOffset % 8 == 0) {
return (byte)(list [byteOffset] >> 1);
}
if (bitOffset % 8 == 1) {
return (byte)(list [byteOffset] & 0x7f);
}
return (byte)(((list [byteOffset] << ((bitOffset % 8) - 1)) & 0x7f)
| (list [byteOffset + 1] >> (9 - (bitOffset % 8))));
}
finally {
bitOffset += 7;
}
}
|
Ausgabe für den vorgegebenen Teststring:
Uncompressed Length: 3941
Compressed Length: 3449
Decompressed Length: 3941
Compression Ratio: 12,4841%
Input equals output: True
Successful: True |
Wenn du meine Lösung als richtig akzeptierst, dann trete ich schon jetzt das Recht, die nächste Aufgabe zu stellen, an gfoidl ab. Der hat nämlich schon was parat.
herbivore
|
|
09.10.2010 20:43
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
N1ls
myCSharp.de-Mitglied
Dabei seit: 27.12.2007
Beiträge: 46
Entwicklungsumgebung: Visual Studio 2008
|
|
Hallo Herbivore,
| Zitat von herbivore: |
Hallo TheBrainiac,
deine Lösung ist korrekt.
...
Hier zum Vergleich noch, wie ich mir das vorgestellt hatte.
... |
Ich halte beide Lösungen für relativ schwer lesbar. Wirklich korrekt sind sie auch nicht. Ein Kniffel ist immer auch ein FullHouse, das berücksichtigen beide Varianten nicht. Das lässt sich natürlich einfach korrigieren, steigert aber die Verständlichkeit des Codes nicht wirklich.
MfG,
N1ls
|
|
09.10.2010 23:48
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
TheBrainiac
myCSharp.de-Mitglied
Dabei seit: 17.12.2006
Beiträge: 767
Entwicklungsumgebung: VS 2010 Prof. Herkunft: /dev/null
|
|
Hi, Herbivore.
Da deine Lösung richtig ist 
, Bist du dran, aber da du diesen Part gfoidl überlassen hast --> gfoidl, du bist dran
Gruß, Christian.
|
|
10.10.2010 02:37
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
gfoidl
myCSharp.de-Team (Moderation)
Dabei seit: 07.06.2009
Beiträge: 5.349
Entwicklungsumgebung: VS 2010 sup{Editionen} Herkunft: Waidring / Tirol
|
|
Hallo,
erstmal bedanke ich mich bei herbivore dafür dass er mir die nächste Aufgabe schenkt ;-)
Die Aufgabe:
Prüfe ob ein beliebiger Polygonzug offen ist, d.h. keine geschlossene Kurve (~eine "Schleife") enthält. Siehe angehängtes Bild für einfache Beispiele.
Für die Eingaben der Punkte der Polygonzuges gilt zusätzlich die Einschränkung dass 3 aufeinander folgende Punkte nicht auf einer Geraden liegen dürfen. Eine Prüfung dessen ist nicht erforderlich, sondern die Einschränkung behandelt lediglich eine Grenzfall der Aufgabenstellung.
Gegeben sei folgender Code-Rumpf:
C#-Code: |
using System;
using System.Collections.Generic;
namespace Polygonzug
{
public struct Punkt
{
public double X;
public double Y;
public Punkt(double x, double y)
{
X = x;
Y = y;
}
}
public class PolygonzugAufgabe
{
public bool IstOffen(IEnumerable<Punkt> punkte)
{
throw new NotImplementedException();
}
}
}
|
Ein einfacher Test um das Ergebnis validieren zu können:
C#-Code: |
using System.Collections.Generic;
using NUnit.Framework;
namespace Polygonzug
{
[TestFixture]
public class PolygonzugAufgabeTest
{
[Test]
public void IstOffen_OffenerPolygonzug_ReturnsTrue()
{
PolygonzugAufgabe sut = new PolygonzugAufgabe();
bool istOffen = sut.IstOffen(this.GeneriereOffenenPolygonzug());
Assert.IsTrue(istOffen);
}
[Test]
public void IstOffen_GeschlossenerPolygonzug_ReturnsFalse()
{
PolygonzugAufgabe sut = new PolygonzugAufgabe();
bool istOffen = sut.IstOffen(this.GeneriereGeschlossenenPolygonzug());
Assert.IsFalse(istOffen);
}
private IEnumerable<Punkt> GeneriereOffenenPolygonzug()
{
yield return new Punkt(0.0, -0.6);
yield return new Punkt(2.2, 2.4);
yield return new Punkt(5.4, 0.4);
yield return new Punkt(1.6, -0.2);
yield return new Punkt(3.0, -2.2);
yield return new Punkt(1.0, -0.6);
yield return new Punkt(0.2, -2.0);
yield return new Punkt(1.2, -2.4);
}
private IEnumerable<Punkt> GeneriereGeschlossenenPolygonzug()
{
yield return new Punkt(0.6, -1.7);
yield return new Punkt(0.0, 0.5);
yield return new Punkt(3.0, 0.9);
yield return new Punkt(3.8, -0.9);
yield return new Punkt(4.8, 0.7);
yield return new Punkt(6.2, -0.3);
yield return new Punkt(2.4, -2.1);
yield return new Punkt(2.6, 2.1);
}
}
}
|
Die Polygonzüge der Tests entsprechen nicht jenen des angehängtesn Bildes.
Es gelten die "üblichen" Bedingungen: Frameworks- / 3rd-Party-Klassen sind verboten! |
Viel Spass bei der Aufgabe!
mfG Gü
gfoidl hat dieses Bild angehängt:

|
|
10.10.2010 20:12
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Spontifixus
myCSharp.de-Mitglied
Dabei seit: 06.09.2005
Beiträge: 360
Entwicklungsumgebung: VisualStudio 2008/2010 Herkunft: Hannover
|
|
Moin,
zur Lösung der Aufgabe von gfoidl brauche ich folgendes:
Eine Extension-Method die berechnet ob sich ein double-Wert in einem bestimmten Bereich findet:
C#-Code: |
public static class Extenstions
{
public static bool IsBetween(this double value, double border1, double border2) {
if (border1 < border2) return (value >= border1 && value <= border2);
if (border1 > border2) return (value >= border2 && value <= border1);
return value == border1;
}
}
|
Dann einen Struct der einen Punkt darstellt:
C#-Code: |
public struct Punkt {
public double X;
public double Y;
public Punkt(double x, double y) {
X = x;
Y = y;
}
public override bool Equals(object obj) {
if (!(obj is Punkt)) return false;
var andererPunkt = (Punkt)obj;
return (X.Equals(andererPunkt.X) && Y.Equals(andererPunkt.Y));
}
}
|
Einen Struct der eine Strecke abbildet und der Methoden enthält mit denen festgestellt werden kann ob eine Strecke eine andere schneidet oder ein direkter Nachbar einer anderen Strecke ist:
C#-Code: |
public struct Strecke {
public Punkt P1;
public Punkt P2;
public double M;
public double C;
public Strecke(Punkt p1, Punkt p2) {
P1 = p1;
P2 = p2;
M = (P2.Y - P1.Y) / (P2.X - P1.X);
C = P1.Y - (M * P1.X);
}
public bool Schneidet(Strecke andereStrecke) {
var schnittpunkt = (andereStrecke.C - C) / (M - andereStrecke.M);
if (double.IsInfinity(schnittpunkt) || double.IsNaN(schnittpunkt)) return false;
return schnittpunkt.IsBetween(P1.X, P2.X) &&
schnittpunkt.IsBetween(andereStrecke.P1.X, andereStrecke.P2.X);
}
public bool IstNachbar(Strecke andereStrecke) {
return (P1.Equals(andereStrecke.P1) || P1.Equals(andereStrecke.P2)) ||
(P2.Equals(andereStrecke.P1) || P2.Equals(andereStrecke.P2));
}
public override bool Equals(object obj) {
if (!(obj is Strecke)) return false;
var andereLinie = (Strecke)obj;
return (P1.Equals(andereLinie.P1) && P2.Equals(andereLinie.P2));
}
}
|
Und last but not least die von gfoidl vorgegebene Klasse die die Logik zur Überprüfung der einzelnen Polygonzüge enthält:
C#-Code: |
public class PolygonzugAufgabe {
private readonly List<Strecke> _linien = new List<Strecke>();
public bool IstOffen(IEnumerable<Punkt> punkte) {
var punkteArray = punkte.ToArray();
for (var i = 0; i < punkte.Count() - 1; i++)
_linien.Add(new Strecke(punkteArray[i], punkteArray[i + 1]));
return _linien.All(linie1 => !_linien.Any(linie2 => !linie1.IstNachbar(linie2) &&
!linie1.Equals(linie2) &&
linie1.Schneidet(linie2)));
}
}
|
Das ganze in einen Kochtopf, kompilieren, testen, fertig. Ist vielleicht nicht immer unbedingt die eleganteste Lösung - aber sie funktioniert. :)
|
|
12.10.2010 16:29
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
gfoidl
myCSharp.de-Team (Moderation)
Dabei seit: 07.06.2009
Beiträge: 5.349
Entwicklungsumgebung: VS 2010 sup{Editionen} Herkunft: Waidring / Tirol
|
|
Hallo Spontifixus,
die beiden Tests - die der Aufgabenstellung angehängt sind - wurden bestanden. Der Test für ein einfaches Quadrat wird aber nicht bestanden. Insofern ist die Aufgabe noch nicht gelöst, da ein beliebiger Polygonzug verlangt wurde ;-)
Dennoch ein interessanter Ansatz.
C#-Code: |
[Test]
public void IstOffen_EinfacherGeschlossenerPolygonzug_ReturnsFalse()
{
PolygonzugAufgabe sut = new PolygonzugAufgabe();
bool istOffen = sut.IstOffen(this.GeneriereEinfachenGeschlossenenPolygonzug());
Assert.IsFalse(istOffen);
}
private IEnumerable<Punkt> GeneriereEinfachenGeschlossenenPolygonzug()
{
yield return new Punkt(0, 0);
yield return new Punkt(1, 0);
yield return new Punkt(1, 1);
yield return new Punkt(0, 1);
yield return new Punkt(0, 0);
}
|
mfG Gü
|
|
12.10.2010 16:42
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Spontifixus
myCSharp.de-Mitglied
Dabei seit: 06.09.2005
Beiträge: 360
Entwicklungsumgebung: VisualStudio 2008/2010 Herkunft: Hannover
|
|
Mir ist gerade aufgefallen, dass laut Steigung eine parallele zur y-Achse nicht als Funktionsgraph gilt, die Steigung aber als Unendlich angesehen werden kann. Dann funktioniert natürlich meine Rechnung nicht mehr.
Ich hatte gehofft meine Lösung noch aufbohren zu können aber für Strecken parallel zur y-Achse taugt die wohl nichts...
Das hier beschriebene Steigungsproblem lässt aber den Hinweis von gfoidl unberührt - selbst wenn ich das Quadrat auf die Spitze stelle wird es nicht als geschlossen erkannt.
Lange Rede kurzer Sinn: Der hier vorgestellte Ansatz ist hervorragend als Exponat für das Museum der krankhaften Ideen auf Maximegalon geeignet, aber nicht als Lösungsansatz, der die von gfoidl gestellten Kriterien erfüllt.
Ich bin gespannt auf die Lösung!
|
|
12.10.2010 18:22
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
gfoidl
myCSharp.de-Team (Moderation)
Dabei seit: 07.06.2009
Beiträge: 5.349
Entwicklungsumgebung: VS 2010 sup{Editionen} Herkunft: Waidring / Tirol
|
|
Hallo,
in meiner Lösung verwende ich auch die Steigung. Die Parallele zur Ordinate handhabe ich da gesondert mit double.IsInfinity und wenn beide Strecken den selben (unendlichen) Wert für die Steigung haben so sind diese parallel.
Vllt. hilft dir das noch für deine Lösung - ich denke dass sich das noch leicht einbauen lässt.
| Zitat: |
| Ich bin gespannt auf die Lösung! |
Meine Lsg. hänge ich dann an ;-)
mfG Gü
|
|
12.10.2010 18:28
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Spontifixus
myCSharp.de-Mitglied
Dabei seit: 06.09.2005
Beiträge: 360
Entwicklungsumgebung: VisualStudio 2008/2010 Herkunft: Hannover
|
|
Hallo gfoidl,
da ich gerade ein bisschen auf der Leitung stehe habe ich mal recherchiert.
In diesem Dokument (Seite 9) steht eine geringfügig abweichende Definition von "geschlossen" und "offen".
Wäre dem so - würde folgende Implementierung der Klasse PolygonzugAufgabe Ausreichen:
C#-Code: |
public class PolygonzugAufgabe {
public bool IstOffen(IEnumerable<Punkt> punkte)
{
return !punkte.Last().Equals(punkte.First());
}
}
|
Die Klassen für die Strecke, sowie die Extension-Methode wären dann nicht mehr nötig.
In deiner Aufgabenstellung geht es aber darum, das von den Strecken des Polygonzuges mindestens eine Fläche komplett umschlossen wird - auch wenn das Polygon selber (gemäß der o.g. Definition) als offen zu bezeichnen ist?
Viele Grüße,
Markus :)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Spontifixus am 12.10.2010 19:32.
|
|
12.10.2010 19:12
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
gfoidl
myCSharp.de-Team (Moderation)
Dabei seit: 07.06.2009
Beiträge: 5.349
Entwicklungsumgebung: VS 2010 sup{Editionen} Herkunft: Waidring / Tirol
|
|
Hallo,
| Zitat: |
| In deiner Aufgabenstellung geht es aber darum, das von den Strecken des Polygonzuges mindestens eine Fläche komplett umschlossen wird |
Genau.
Bzgl. Definition hab ich auch nochmal geschaut. Bei meiner Aufgabe gehts demnach ob das Polygon überschlagen ist oder nicht. Ich finde aber dennoch dass die Aufgabenstellung klar ist ;-)
mfG Gü
|
|
12.10.2010 19:42
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Floste
myCSharp.de-Mitglied
Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008 Herkunft: Norddeutschland
|
|
Diese lösung dürfte auch für quadrate und dreiecke gehen.
C#-Code: |
public class PolygonzugAufgabe
{
public static bool IstOffen(IEnumerable<Punkt> punkte)
{
List<Punkt> liste = punkte.ToList();
for (int ia = 1; ia < liste.Count; ia++)
{
double sax = liste[ia - 1].X;
double say = liste[ia - 1].Y;
double dax = liste[ia].X - sax;
double day = liste[ia].Y - say;
for (int ib = 1; ib < liste.Count; ib++)
if (Math.Abs(ia-ib)>1)
{
double sbx = liste[ib - 1].X;
double sby = liste[ib - 1].Y;
double dbx = liste[ib].X - sbx;
double dby = liste[ib].Y - sby;
double b = -(-say * dax + day * sax - day * sbx + sby * dax) / (-dbx * day + dby * dax);
if (b <= 1 && b >= 0)
{
double a = (-sax + sbx + b * dbx) / dax;
if (a <= 1 && a >= 0)
return false;
}
}
}
return true;
}
}
|
|
|
12.10.2010 20:27
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Floste
myCSharp.de-Mitglied
Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008 Herkunft: Norddeutschland
|
|
Ok: nächste aufgabe:
Schreibe ein programm, das alle zahlen findet, die die ziffern von 1 bis 9 jeweils exakt einmal enthalten. Es sind also alle kombinationen aus {1,2,3,4,5,6,7,8,9} gesucht. Jede dieser zahlen soll exakt einmal gefunden werden (keine doppelten):
123456789
123456798
123456879
123456897
123456978
123456987
123457689
...
987654321 |
Von diesen zahlen soll die 111.111te ausgegeben werden. (Dazu müssen die zahlen nach größe sortiert sein.)
Am besten soll es unter einer sekunde dauern, ich aktzeptiere aber auch langsamere lösungen. Meine zeit ist bei 0,013sec
Damit mir auch keiner die zahl direkt hinter der gesuchten liefert: Zaunpfahlproblem
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Floste am 13.10.2010 15:37.
|
|
13.10.2010 15:32
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
gfoidl
myCSharp.de-Team (Moderation)
Dabei seit: 07.06.2009
Beiträge: 5.349
Entwicklungsumgebung: VS 2010 sup{Editionen} Herkunft: Waidring / Tirol
|
|
Hallo Floste,
stimmt 381496527?
Zeit nicht messbar. ~2000 Ticks der Stopwatch ;-)
mfG Gü
|
|
13.10.2010 18:17
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Floste
myCSharp.de-Mitglied
Dabei seit: 13.06.2007
Beiträge: 1.131
Entwicklungsumgebung: VS 2008 Herkunft: Norddeutschland
|
|
Stimmt genau, und bei der zeit kann man nicht meckern. Poste bitte mal deinen code.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Floste am 13.10.2010 19:17.
|
|
13.10.2010 19:13
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
talla
myCSharp.de-Team (Moderation)
Dabei seit: 20.07.2003
Beiträge: 6.863
Entwicklungsumgebung: VS 2010 Herkunft: Esslingen
|
|
Hallo,
sollte stimmen, hab ich auch ;) Aber ich verzichte auf posten der Lösung (gefragt war ja das Programm, oder nur die Lösung?) weil mir grad keine neue Aufgabe einfällt *gg*
Aber poste mal deine Frequency der Stopwatch - ohne die ist die Tickangabe wenig hilfreich weil die ja abhängig vom Hardwaretimer ist.
Aber selbst mit diesen Angaben ist die Ausführungszeit ja von der Hardware abhängig. Deshalb könnte man höchsten auf ner Referenzmaschine vergleichen.
Meine Lösung liegt auch im unteren Millisekundenbereich auf nem 2 Jahre alten Notebook.
|
|
13.10.2010 19:13
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
gfoidl
myCSharp.de-Team (Moderation)
Dabei seit: 07.06.2009
Beiträge: 5.349
Entwicklungsumgebung: VS 2010 sup{Editionen} Herkunft: Waidring / Tirol
|
|
Hallo,
die Frequency der Stopwatch ist auf meinem 2 Jahre alten Laptop 3.579.545
Die Lösung ist eigentlich relativ einfach wenn die richtige Datenstruktur verwendet wird. Andernfalls lässt sich mMn kein vernüftiger Algorithmus entwickeln.
Hier hab ich die möglichen Permutationen der Ziffern als Baum dargestellt. Die Wurzel des Baums hat alle Ziffern der gegebenen Menge. Jedes Kind davon hat dann alle anderen Ziffern außer diejenigen welche im Pfad schon berücksichtigt sind. Es gibt also soviele Ebenen im Baum bis am Ende nur Blätter mit einer Ziffer übrigbleiben.
Auf diese Idee ein wenig Mathe angewandt so kann das "Bucket" berechnet werden indem der rekursive Abbau des Baums fortgesetzt wird.
Als Code schaut dann so aus:
C#-Code: |
static void Main(string[] args)
{
int targetIndex = 111111 - 1;
List<int> digits = Enumerable.Range(1, 9).ToList();
List<int> solution = new List<int>();
Permutation(digits, targetIndex, solution);
solution.ForEach(i => Console.Write(i));
Console.ReadKey();
}
private static void Permutation(List<int> digits, int index, List<int> solution)
{
int n = digits.Count;
if (n == 1)
{
solution.Add(digits[0]);
return;
}
int treeBucketSize = Factorial(n - 1);
int splitIndex = index / treeBucketSize;
int splitDigit = digits[splitIndex];
digits.RemoveAt(splitIndex);
solution.Add(splitDigit);
Permutation(digits, index - treeBucketSize * splitIndex, solution);
}
private static int Factorial(int n)
{
if (n <= 1) return 1;
if (n == 2) return 2;
return Factorial(n - 1) * n;
}
|
Für die nächste Aufgabe fällt mir auch nichts ein -> ich gebe somit das Spiel frei. D.h. der schnellste Aufgabensteller ist dran ;-)
mfG Gü
|
|
13.10.2010 20:55
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
gfoidl
myCSharp.de-Team (Moderation)
Dabei seit: 07.06.2009
Beiträge: 5.349
Entwicklungsumgebung: VS 2010 sup{Editionen} Herkunft: Waidring / Tirol
|
|
Hallo,
ich hab doch eine Aufgabe ;-)
Dazu eine kurze Geschichte:
Antonia denkt sich 2 ganze Zahlen aus dem Intervall [1; 1000].
Sie nennt Berta das Produkt ihrer beiden Zahlen, Christina nennt sie die Summe und Daniela die Differenz.
Berta sagt zu den anderen: "Ich kann die Lösung nicht nennen".
Christina antwortet: "Das wusste ich
"
Darauf Berta: "Dann weiß ich jetzt die Lösung."
Christina entgegnet: "Dann weiß ich sie jetzt auch."
Daniela sagt: "Ich nicht, aber ich habe eine Vermutung, was eine der beiden Zahlen wahrscheinlich ist."
Berta sagt: "Ich weiß, was du vermutest, aber das ist falsch."
Daniela: "Dann kenne ich jetzt auch die Lösung." |
Wie lauten Antonias Zahlen?
mfG Gü
|
|
14.10.2010 12:29
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
Spontifixus
myCSharp.de-Mitglied
Dabei seit: 06.09.2005
Beiträge: 360
Entwicklungsumgebung: VisualStudio 2008/2010 Herkunft: Hannover
|
|
Moin,
ich hab lange nachgedacht und bin zu keinem Ergebnis gekommen und hab schließlich gegoogelt. Das Ding ist tatsächlich mit einigem Hirnschmalz und ein paar Zeilen Code zu lösen. Faszinierend... :)
Viele Grüße,
Markus :)
|
|
15.10.2010 08:36
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
|