• Какая книга лучше?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Можно смело начинать учить по книге с C# 9
    Скорее всего, это все отличия (см. по ссылкам). В книге по 9 версии не будет информации о версиях 10 и 11
    Новые возможности C# 10
    Новые возможности C# 11
    Ответ написан
    Комментировать
  • Как можно подправить код для выполнения задачи?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    При помощи kstr[N] ты обращаешься к N-ному СИМВОЛУ в строке.
    Тебе нужно сопоставить символ с цифрой и реальное число.
    Проще всего это можно сделать, отняв '0'.
    Код получается примерно такой:
    using System;
    int ks = 0;
    for (int i = 0; i < 999999; i++)
    {
        char[] kstr = i.ToString("D6").ToCharArray();
        var leftPartSum = (kstr[0] - '0' + kstr[1] - '0' + kstr[2] - '0');
        var rightPartSum = (kstr[3] - '0' + kstr[4] - '0' + kstr[5] - '0');
        if (leftPartSum == rightPartSum)
        {
            ks++;
            Console.WriteLine($"{i:D6}|{leftPartSum}={rightPartSum}");
        }
    }
    Console.WriteLine($"Total: {ks}");

    Но код можно улучшить:
    Вместо форматирования числа в строку и обращения к символам по индексу - использовать целочисленное деление и взятие остатка.
    PS:
    Вот сравнение по производительности

    Код:
    using BenchmarkDotNet.Running;
    using BenchmarkDotNet.Attributes;
    
    var summary = BenchmarkRunner.Run<DetectLuckyTicket>();
    
    [MemoryDiagnoser]
    public class DetectLuckyTicket
    {
        private readonly int ticketNumber;
        public DetectLuckyTicket()
        {
            ticketNumber = Random.Shared.Next(1, 1000000);
        }
    
        [Benchmark]
        public bool IsLuckyFast()
        {
            var leftPart = ticketNumber / 1000;
            var leftPartSum = (leftPart / 100) + (leftPart / 10 % 10) + (leftPart % 100);
    
            var rightPart = ticketNumber % 1000;
            var rightPartSum = (rightPart / 100) + (rightPart / 10 % 10) + (rightPart % 100);
    
            return leftPartSum == rightPartSum;
        }
    
        [Benchmark]
        public bool IsLuckySlow()
        {
            var kstr = ticketNumber.ToString("D6").ToCharArray();
            var leftPartSum = (kstr[0] - '0' + kstr[1] - '0' + kstr[2] - '0');
            var rightPartSum = (kstr[3] - '0' + kstr[4] - '0' + kstr[5] - '0');
            return leftPartSum == rightPartSum;
        }
    }


    Результат:
    // * Detailed results *
    DetectLuckyTicket.IsLuckyFast: DefaultJob
    Runtime = .NET 7.0.0 (7.0.22.15202), X64 RyuJIT; GC = Concurrent Workstation
    Mean = 6.417 ns, StdErr = 0.039 ns (0.60%), N = 15, StdDev = 0.150 ns
    Min = 6.113 ns, Q1 = 6.318 ns, Median = 6.408 ns, Q3 = 6.505 ns, Max = 6.671 ns
    IQR = 0.188 ns, LowerFence = 6.036 ns, UpperFence = 6.787 ns
    ConfidenceInterval = [6.257 ns; 6.577 ns] (CI 99.9%), Margin = 0.160 ns (2.49% of Mean)
    Skewness = -0.06, Kurtosis = 2.24, MValue = 2
    -------------------- Histogram --------------------
    [6.034 ns ; 6.193 ns) | @
    [6.193 ns ; 6.427 ns) | @@@@@@@@
    [6.427 ns ; 6.606 ns) | @@@@
    [6.606 ns ; 6.751 ns) | @@
    ---------------------------------------------------
    
    DetectLuckyTicket.IsLuckySlow: DefaultJob
    Runtime = .NET 7.0.0 (7.0.22.15202), X64 RyuJIT; GC = Concurrent Workstation
    Mean = 32.280 ns, StdErr = 0.250 ns (0.77%), N = 100, StdDev = 2.496 ns
    Min = 28.418 ns, Q1 = 30.360 ns, Median = 31.542 ns, Q3 = 33.921 ns, Max = 37.623 ns
    IQR = 3.561 ns, LowerFence = 25.018 ns, UpperFence = 39.264 ns
    ConfidenceInterval = [31.434 ns; 33.127 ns] (CI 99.9%), Margin = 0.847 ns (2.62% of Mean)
    Skewness = 0.63, Kurtosis = 2.09, MValue = 2.91
    -------------------- Histogram --------------------
    [28.207 ns ; 29.529 ns) | @@@@@@@
    [29.529 ns ; 30.941 ns) | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    [30.941 ns ; 32.596 ns) | @@@@@@@@@@@@@@@@@@@@@@@
    [32.596 ns ; 33.910 ns) | @@@@@@@@@@
    [33.910 ns ; 35.321 ns) | @@@
    [35.321 ns ; 36.733 ns) | @@@@@@@@@@@@@@@@@@@
    [36.733 ns ; 38.329 ns) | @@@
    ---------------------------------------------------
    
    // * Summary *
    
    BenchmarkDotNet=v0.13.1, OS=Windows 10.0.25131
    AMD Ryzen 5 4600H with Radeon Graphics, 1 CPU, 12 logical and 6 physical cores
    .NET SDK=7.0.100-preview.2.22153.17
      [Host]     : .NET 7.0.0 (7.0.22.15202), X64 RyuJIT
      DefaultJob : .NET 7.0.0 (7.0.22.15202), X64 RyuJIT
    |      Method |      Mean |     Error |    StdDev |    Median |  Gen 0 | Allocated |
    |------------ |----------:|----------:|----------:|----------:|-------:|----------:|
    | IsLuckyFast |  6.417 ns | 0.1599 ns | 0.1496 ns |  6.408 ns |      - |         - |
    | IsLuckySlow | 32.280 ns | 0.8467 ns | 2.4964 ns | 31.542 ns | 0.0382 |      80 B |
    
    // * Warnings *
    MultimodalDistribution
      DetectLuckyTicket.IsLuckySlow: Default -> It seems that the distribution can have several modes (mValue = 2.91)
    
    // * Legends *
      Mean      : Arithmetic mean of all measurements
      Error     : Half of 99.9% confidence interval
      StdDev    : Standard deviation of all measurements
      Median    : Value separating the higher half of all measurements (50th percentile)
      Gen 0     : GC Generation 0 collects per 1000 operations
      Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
      1 ns      : 1 Nanosecond (0.000000001 sec)


    UPD: А не работает у вас, скорее всего, из-за того что:
    1. Вы перебираете не все варианты, а только до 999998 включительно.
    2. У вас WriteLine отрабатывает на все числа, а не только на счастливые, тк перепутаны фигурные скобки.
    Ответ написан
    4 комментария
  • Как можно исправить код для поиска квадратных уравнений?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    using static ConsoleApp.ConsoleInput;
    
    namespace ConsoleApp;
    
    public class Program
    {
        static void Main(string[] args)
        {
            new Program().Run(args);
        }
    
        private void Run(string[] args)
        {
            Console.WriteLine("Введите данные уравнения"); // Введите данные уравнения
            double a = RequestUserInputAsDouble("Введите число a:"); // Введите а
            double b = RequestUserInputAsDouble("Введите число b:"); // Введите b
            double c = RequestUserInputAsDouble("Введите число c:"); // Введите c
            Console.WriteLine("Ваше уравнение: " + a + "x^2 + " + b + "x + " + c + " = 0");
            double discriminant = CalculateDiscriminant(a, b, c);
    
            if (discriminant < 0) // Условие, если Дискриминант < 0
            {
                Console.WriteLine("Нет решений, т.к D < 0 "); // Вывод ответа
            }
            else if (discriminant > 0) // // Условие, если Дискриминант > 0
            {
                double x1 = (-b + Math.Sqrt(discriminant)) / (2 * a); // Обьявление переменной х1 и решение
                double x2 = (-b - Math.Sqrt(discriminant)) / (2 * a); // Обьявление переменной х2 и решение
                Console.WriteLine("Ваш ответ: x1 = " + x1 + " x2 = " + x2); // Вывод ответа
            }
            else // (D == 0)  Условие, если Дискриминант = 0
            {
                double x1 = (-b + Math.Sqrt(0)) / (2 * a); // Обьявление переменной х1 и решение
                double x2 = x1; // Обьявление переменной х2 и решение
                Console.WriteLine("Ваш ответ: x2 = x1 = " + x1); // Вывод ответа
            }
        }
    
        private double CalculateDiscriminant(double a, double b, double c)
        {
            // Вычисление переменной Дискриминант
            return b * b - (4 * a * c);
        }
    }


    Класс, который позволяет запросить ввод пользователя и если пользователь ввёл неверные данные, которые нельзя конвертировать в целевой тип данных, то ввод снова запрашивается у пользователя.
    using System.Globalization;
    
    namespace ConsoleApp;
    
    internal static class ConsoleInput
    {
        private static readonly CultureInfo CommaCulture =
            new(CultureInfo.InvariantCulture.LCID)
            {
                NumberFormat = { NumberDecimalSeparator = "," }
            };
        private static readonly CultureInfo PointCulture =
            new(CultureInfo.InvariantCulture.LCID)
            {
                NumberFormat = { NumberDecimalSeparator = "." }
            };
    
    
        /// <summary>
        /// Запросить ввод у пользователя. Если ввод нельзя конвертировать в целевой тип,
        /// то ввод будет запрошен повторно. Это обобщённый метод, позволящий реализовать 
        /// несколько других методов, требующих ввод в определённом формате.
        /// </summary>
        /// <typeparam name="TResult">
        /// Тип результата, который ожидается от метода конвертации.
        /// </typeparam>
        /// <param name="tryConvert">Ссылка на метод конвертации.</param>
        /// <param name="message">
        /// Сообщение, которое будет показано пользователю каждый новый запрос ввода значения.
        /// </param>
        /// <returns></returns>
        private static TResult RequestUserInput<TResult>(
            Func<string, (bool, TResult)> tryConvert, string? message = null)
            where TResult : struct
        {
            TResult result;
            while (true)
            {
                if (!string.IsNullOrWhiteSpace(message))
                {
                    Console.WriteLine(message);
                }
    
                string? line = Console.ReadLine();
                if (!string.IsNullOrWhiteSpace(line))
                {
                    var (success, convertedValue) = tryConvert(line);
                    if (success)
                    {
                        result = convertedValue;
                        break;
                    }
                }
            }
    
            return result;
        }
    
        /// <summary>
        /// Запросить у пользователя ввод числа типа double.
        /// Допускается в качестве разделителя "," и ".".
        /// </summary>
        /// <param name="message">
        /// Сообщение, которое будет показано пользователю каждый новый запрос ввода значения.
        /// </param>
        /// <returns></returns>
        public static double RequestUserInputAsDouble(string? message = null)
        {
            return RequestUserInput(userInput =>
            {
                CultureInfo culture = CultureInfo.InvariantCulture;
                if (userInput.Contains(",")) culture = CommaCulture;
                if (userInput.Contains(".")) culture = PointCulture;
                return double.TryParse(
                    userInput, NumberStyles.Float, culture, out var result)
                    ? (true, result)
                    : (false, 0d);
            }, message);
        }
    
        // И другие типы в том же духе
        public static int RequestUserInputAsInt32(string? message = null)
        {
            return RequestUserInput(userInput =>
                    int.TryParse(userInput, out var result)
                        ? (true, result)
                        : (false, 0),
                message);
        }
    }
    Ответ написан
    Комментировать