@KaktuZHD

Как можно подправить код для выполнения задачи?

Посчитать вероятность выпадения счастиливого билета
Напоминаю что билет состоит из 6 цифер. счастливый = билет у которого сумма трех левых цифер равна сумме трех правых чисел.
Посчитать перебором и проверкой всех билетов на то счастливый билет или нет

int ks = 0;
for (int i = 0; i < 999999; i++)
{
    char[] kstr = i.ToString("D6").ToCharArray();
    if ((kstr[0] + kstr[1]+ kstr[2]) == (kstr[3] + kstr[4]+ kstr[5])) ks++;
    {
        Console.WriteLine(ks);
    }
}


Не могу понять ,как перебрать числа для этой задачи
  • Вопрос задан
  • 141 просмотр
Пригласить эксперта
Ответы на вопрос 2
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 отрабатывает на все числа, а не только на счастливые, тк перепутаны фигурные скобки.
Ответ написан
lexxpavlov
@lexxpavlov
Программист, преподаватель
Лучше всего сделать 6 циклов от 0 до 9 и их счётчики использовать для получения суммы частей. Потому что получение цифр из числа - не такая простая операция, как кажется.

int cnt1 = 0, cnt2 = 0, cnt3 = 0;
var t0 = DateTime.Now;
for (int i = 0; i <= 999999; i++)
{
    var a1 = i / 100000 % 10;
    var a2 = i / 10000 % 10;
    var a3 = i / 1000 % 10;
    var b1 = i / 100 % 10;
    var b2 = i / 10 % 10;
    var b3 = i / 1 % 10;
    if (a1 + a2 + a3 == b1 + b2 + b3) cnt1++;
}
var t1 = DateTime.Now;

for (int a1 = 0; a1 <= 9; a1++)
for (int a2 = 0; a2 <= 9; a2++)
for (int a3 = 0; a3 <= 9; a3++)
for (int b1 = 0; b1 <= 9; b1++)
for (int b2 = 0; b2 <= 9; b2++)
for (int b3 = 0; b3 <= 9; b3++)
{
    if (a1 + a2 + a3 == b1 + b2 + b3) cnt2++;
}
var t2 = DateTime.Now;

for (int i = 0; i <= 999999; i++)
{
    string kstr = i.ToString("D6");
    var a1 = int.Parse(kstr[0] + "");
    var a2 = int.Parse(kstr[1] + "");
    var a3 = int.Parse(kstr[2] + "");
    var b1 = int.Parse(kstr[3] + "");
    var b2 = int.Parse(kstr[4] + "");
    var b3 = int.Parse(kstr[5] + "");
    if (a1 + a2 + a3 == b1 + b2 + b3) cnt3++;
}
var t3 = DateTime.Now;

Console.WriteLine($"{cnt1} {(t1 - t0).TotalMilliseconds} мс"); // 55252 21,0197 мс
Console.WriteLine($"{cnt2} {(t2 - t1).TotalMilliseconds} мс"); // 55252 1,8051 мс
Console.WriteLine($"{cnt3} {(t3 - t2).TotalMilliseconds} мс"); // 55252 106,1106 мс
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы