Професионална програма
Loading...
+ Нов въпрос
Elena123456 avatar Elena123456 166 Точки

09. Kamino Factory-with Dictionary And Regex

Здравейте,

преди да завърша Фундаментал модула трябваше да пробвам дали е възможно да се опрости решението на Kamino Factory. Винаги ми се е струвало малко странно една такава задача с толкова кратко и ясно изсикване (да се намери ДНК с най-дългата секвенция от 1, ако две ДНК секвенции от 1  са с еднаква дължина да се вземе тази ДНК с най-ляв индекс на съответната секвенция, а ако и те вече са еднакви да се вземе тази ДНК с най-голяма сума) да достига до 100 и повече реда код. Дори съм виждала как самият автор на задачата я решава, като и при него достигна над 100 реда.

Опитвам се да приложа друг подход:

- чрез един regex намирам всички секвенции от 1;

-след като forech() през MatchCollection аз ще намеря най-дългата секвенция, както и нейния startIndex;

-ще пазя в речник дължината на най-дългата секвенция от 1, нейния startIndex и максималната сума на цялата текуща ДНК;

-след като получа командата "Clone them!" аз ще сортирам речника по горните изисквания  -първо по дължината на максималната секвенция, после по най-малък StartIndex (най-ляв) и накрая по най-голяма сума на цялата ДНК;

-от всичко, което съм сортирала аз ще взема само първия речник.

https://pastebin.com/SzJpwxgE - 30/100 ми е резултата, като получавам коректно аутпутите при дадените инпути.

Моля за помощ, като не изключвам възможността просто Judge да не ми харесва кода.

https://softuni.bg/trainings/resources/officedocument/49571/arrays-exercise-csharp-fundamentals-may-2020/2830

https://judge.softuni.bg/Contests/Compete/Index/1206#8

Тагове:
0
C# Fundamentals 27/11/2020 14:23:47
MartinBG avatar MartinBG 3597 Точки
Best Answer

Подходът за намиране на най-добър DNA е валиден и работи.

Проблемът е, че по условие трябва да се отпечата индекса на най-добият DNA образец от всички въведени такива, а решението не пази тази информация.

Например при вход:

1
0
0
1
Clone them!

Трябва да се отпечата :

Best DNA sample 3 with sum: 1.
1

Защото "1" е третият по ред образец от подадените на входа (0, 0, 1).

 

Регекса може да се съкрати направо на @"1+"

 

Има ли причнина, поради която избягвате да ползвате помощен клас и се опитвате да пазите данните във вложени колекции? Това доста усложнява кода.

 

За сравнение, ето примерно решение с помощен клас:

using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Collections.Generic;

namespace KaminoFactory
{
    internal static class Program
    {
        static void Main(string[] args)
        {
            Console.ReadLine(); // skip DNA sequence length from input - not needed by this solution

            var dnaSamples = new List<DnaSample>();

            string input;
            while ("Clone them!" != (input = Console.ReadLine()))
            {
                dnaSamples.Add(new DnaSample(input?.Replace("!", "")));
            }

            var bestDnaSample = dnaSamples
                .OrderByDescending(sample => sample.Length)
                .ThenBy(sample => sample.Index)
                .ThenByDescending(sample => sample.Sum)
                .First();

            Console.WriteLine(
                $"Best DNA sample {dnaSamples.IndexOf(bestDnaSample) + 1} with sum: {bestDnaSample.Sum}.");
            Console.WriteLine(string.Join(' ', bestDnaSample.Dna.ToCharArray()));
        }

        private class DnaSample
        {
            private static readonly Regex OnesRegex = new Regex(@"1+");
            public string Dna { get; }
            public int Sum { get; private set; }
            public int Length { get; private set; }
            public int Index { get; private set; }

            public DnaSample(string dna)
            {
                Dna = dna;
                Sum = 0;
                Length = 0;
                Index = 0;
                Init();
            }

            private void Init()
            {
                foreach (Match sequence in OnesRegex.Matches(Dna))
                {
                    if (sequence.Length <= Length) continue;
                    Length = sequence.Length;
                    Index = sequence.Index;
                }

                foreach (var c in Dna.Where(c => c == '1')) Sum++;
            }
        }
    }
}

 

2
27/11/2020 16:38:54
Elena123456 avatar Elena123456 166 Точки

Благодаря Ви отново за намирането на грешката ми. Прав сте, че не трябва да се принтира StartIndex на най-добрата секвенция от 1, а самата поредност на ДНК, както се подава от инпута. Разреших този проблем с добавянето на един CounterDNK, като му задавам стойност 0 извън while цикъла и при въвеждане на всяка една ДНК го увеличавам с 1. Съответно и него запаметявам в речник. При сортировката на речниците, както и да ги сортирам този counter ще си запази числото, т.е. аз ще зная коя по поредност( на кой индекс) е била bestDNK.

Така  вече Judge е съгласен с мен и ми дава 100/100 https://pastebin.com/SzJpwxgE

И благодаря, че ми напомняте за класовете. Зная, че са много важни, питат за тях на интервюта и, че ще са ни от голяма помощ за задачи с по-голяма сложност. Умишлени малко ги избягвах до този момент, защото самият Фундаментал модул, изпитите и подготовката за изпитите е насочена към масиви, листове, речници и регулярни изрази. Опитвах се до този момент максимално да усвоя работата с всички тях. В Advanced модула, когато наблегна на обекти и класове, отново ще се върна на вашето решение на KaminoFactory с помощен клас и на една задача от More Exercices Dictionary- "Dragon Army", за която открих и видео материал на решението с обекти.

Още веднъж благодаря и извинявайте, че толкова много Ви отнемам от времето.

Хубав уикенд!

Поздрави!

Ели

3
18/12/2020 23:43:46
krum_43 avatar krum_43 452 Точки

Това решение е добро,но изисква добри познания относно дефиниране и използване на класове,което не е обект на този модул.

0