C# :: Aufgabe #276 :: Lösung #1

2 Lösungen Lösungen öffentlich
#276

Ägyptische Bruchrechnung

Fortgeschrittener - C# von hollst - 22.12.2019 um 22:50 Uhr
Gegeben seien zwei positive Ganzzahlen Z (wie Zaehler) und N (wie Nenner) mit N > Z
und Z sei kein Teiler von N.

Der Bruch Z/N ist immer als Summe der Kehrwerte positiver Ganzzahlen (Stammbrüche) darstellbar,
wobei es meist mehrer Möglichkeiten der Darstellung gibt.

Beispiele:

5/6 = 1/2 + 1/3 = 1/2 + 1/4 + 1/12 = 1/2 + 1/4 + 1/13 + 1/156 = ...

17/39 = 1/3 + 1/10 + 1/390 = ...

Man schreibe ein Programm, das Z und N entgegennimmt und die Zahlen der Stammbrüchesumme mit den wenigsten Summanden ausgibt.

Also obere Beispiele:

Input 5 und 6, Output 2 und 3,
Input 17 und 39, Output 3, 10 und 390.

Viel Spaß.
#1
vote_ok
von Heady20006 (100 Punkte) - 23.12.2019 um 23:52 Uhr
Hallo,
da ich ganz frisch auf der Seite bin hoffe ich, dass ich alles richtig einreiche :)

MainWindow.xaml
Quellcode ausblenden C#-Code
<Window x:Class="Egypt.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Egypt"
        mc:Ignorable="d"
        Title="Ägyptisches Bruchrechnen" Height="500" Width="400" WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
    <Window.Background>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#FF505050" Offset="0.013"/>
            <GradientStop Color="#FF434242" Offset="1"/>
        </LinearGradientBrush>
    </Window.Background>
    <Grid>
        <Label Content="Zähler:" HorizontalAlignment="Left" Margin="27,16,0,0" VerticalAlignment="Top" Foreground="White" FontSize="15"/>
        <Label Content="Nenner:" HorizontalAlignment="Left" Margin="27,51,0,0" VerticalAlignment="Top" Foreground="White" FontSize="15"/>
        <TextBox x:Name="TxbInputZ" HorizontalContentAlignment="Right" HorizontalAlignment="Left" Height="23" Margin="103,23,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="60" TextChanged="InputChanged"/>
        <TextBox x:Name="TxbInputN" HorizontalContentAlignment="Right" HorizontalAlignment="Left" Height="23" Margin="103,53,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="60"/>
        <Button x:Name="BtnStart" Content="berechnen" HorizontalAlignment="Left" Margin="30,98,0,0" VerticalAlignment="Top" Width="133" Height="25" Click="Start"/>
        <TextBlock x:Name="TbSolution" HorizontalAlignment="Left" Margin="10,158,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="299" Width="376" Foreground="White">
            <TextBlock.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF606060" Offset="0"/>
                    <GradientStop Color="#FF454545" Offset="1"/>
                </LinearGradientBrush>
            </TextBlock.Background>
        </TextBlock>
        <Label Content="Ergebniss:" HorizontalAlignment="Left" Margin="10,127,0,0" VerticalAlignment="Top" Foreground="White"/>

    </Grid>
</Window>


MainWindow.xaml.cs
Quellcode ausblenden C#-Code
using System;
using System.Windows;
using System.Windows.Controls;

namespace Egypt
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Start(object sender, RoutedEventArgs e)
        {
            var originalZaehler = Convert.ToDouble(TxbInputZ.Text);
            var originalNenner = Convert.ToDouble(TxbInputN.Text);

            // Rechnung ist: Neuer Bruch + (Alten Bruch - Neuen Bruch)
            if (originalZaehler < originalNenner)
            {
                TbSolution.Text += Environment.NewLine + originalZaehler + "/" + originalNenner + " =";

                double kuerzerZaehler = originalNenner;
                while (kuerzerZaehler > 0)
                {
                    // Wir bilden uns den neuen Bruch
                    double ersterBruchZaehler = NeuerBruch(originalZaehler, originalNenner).Item1;
                    double ersterBruchNenner = NeuerBruch(originalZaehler, originalNenner).Item2;

                    // Wir bilden den Stammbruch
                    double stammbruchZaehler = originalZaehler / originalZaehler; ;
                    double stammbruchNenner = Math.Ceiling((double)originalNenner / originalZaehler);
                    TbSolution.Text += " " + stammbruchZaehler + "/" + stammbruchNenner;

                    // Wir berechnen den größten gemeinsamen Teiler
                    double gemeinsamerTeiler = GemeinersamerTeiler(ersterBruchNenner, originalNenner);

                    // Wir berechnen das kleinste gemeinsame Vielfache
                    double klGemeinsameVielfache = KleinsteVielfache(ersterBruchNenner, originalNenner, gemeinsamerTeiler);

                    // Wir berechnen die Differenzen zwischen dem alten Bruch und dem neuen Bruch
                    double differenzZaehler = originalZaehler * (ersterBruchNenner / gemeinsamerTeiler) - ersterBruchZaehler * (originalNenner / gemeinsamerTeiler);

                    // Wir versuchen den Bruch noch zu kürzen
                    kuerzerZaehler = Kuerzen(differenzZaehler, klGemeinsameVielfache).Item1;
                    double kuerzerNenner = Kuerzen(differenzZaehler, klGemeinsameVielfache).Item2;
                    originalZaehler = kuerzerZaehler;
                    originalNenner = kuerzerNenner;
                    if (kuerzerZaehler > 0)
                        TbSolution.Text += " + ";
                };
            }
            else
                TbSolution.Text += Environment.NewLine + "N ist nicht größer als Z";
        }

        private (double, double) NeuerBruch(double z, double n)
        {
            double zaehler = z;
            double nenner = n;

            while (nenner % zaehler != 0)
            {
                nenner += 1;
            };
            return (zaehler, nenner);
        }

        private double GemeinersamerTeiler(double n1, double n2)
        {
            double rest = 1;
            while (rest > 0)
            {
                rest = n1 % n2;
                n1 = n2;
                if (rest != 0)
                {
                    n2 = rest;
                }
            };
            return n2;
        }

        private double KleinsteVielfache(double n1, double n2, double grTeiler)
        {
            double klVielfache = n1 * n2 / grTeiler;
            return klVielfache;
        }

        private (double, double) Kuerzen(double z, double n)
        {
            for (double a = 2; a < n; a++)
            {
                if (n % a == 0 && z % a == 0)
                {
                    return (z / a, n / a);
                }
            }
            return (z, n);
        }

        private void InputChanged(object sender, TextChangedEventArgs e)
        {
            try
            {
                double inputs = Convert.ToDouble(((TextBox)sender).Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Bitte keinen text eingeben und nur Zahlen-");
                ((TextBox)sender).Text = "0";
                return;
            }
        }
    }
}

Kommentare:

Für diese Lösung gibt es noch keinen Kommentar

Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben