Loading...
Joro_Paspalev avatar Joro_Paspalev 23 Точки

Задача 5. C# Messages от More Exercise Introduction

Здравейте, може ли малко помощ на тази задача :

1.Messages

Write a program, which emulates typing an SMS, following this guide:

1

2

abc

3

def

4

ghi

5

jkl

6

mno

7

pqrs

8

tuv

9

wxyz

 

0

space

 

Following the guide, 2 becomes “a”, 22 becomes “b” and so on.

Examples

Input

Output

 

Input

Output

 

Input

Output

5

44

33

555

555

666

hello

9

44

33

999

0

8

44

33

777

33

hey there

7

6

33

33

8

0

6

33

meet me

Hints

  • A native approach would be to just put all the possible combinations of digits in a giant switch statement.
  • A cleverer approach would be to come up with a mathematical formula, which converts a number to its alphabet representation:

Digit

2

3

4

5

6

7

8

9

  • Index
  • 0 1 2
  • 3 4 5
  • 6 7 8
  • 9 11 12
  • 13 14 15
  • 16 17 18 19
  • 20 21 22
  • 23 24 25 26
  • Letter
  • a b c
  • d e f
  • g h i
  • j  k  l
  • m  n  o
  • p  q  r  s
  • t u v
  • w  x  y  z
  • Let’s take the number 222 (c) for example. Our algorithm would look like this:
    • Find the number of digits the number has “e.g. 222 è 3 digits
    • Find the main digit of the number “e.g.  222 è 2
    • Find the offset of the number. To do that, you can use the formula: (main digit - 2) * 3
    • If the main digit is 8 or 9, we need to add 1 to the offset, since the digits 7 and 9 have 4 letters each
    • Finally, find the letter index (a è 0, c è 2, etc.). To do that, we can use the following formula: (offset + digit length - 1).
    • After we’ve found the letter index, we can just add that to the ASCII code of the lowercase letter “a” (97)

И трите нулеви тестове минават, но след това се чупи някъде. Моля някой за малко съвет? 

Направил съм я по стандартния начин с Switch case конструкция, като входните данни от конзолата първо се четяха като целочислени тип Integer, сега ги направих да са String, но отново същия резултат в Judge 20/100 точки.

Ето и кода: https://pastebin.com/tQtUbLey - Вариант със string

https://pastebin.com/jd1gR5nG - Вариант с Integer

 

0
Module: C# Advanced
RadostinStoychev avatar RadostinStoychev 128 Точки

Здрасти, мисля че идеята на тази задачка беше да не се използвaт case-ove или вложени if-ove.
Виж това решение:

 

namespace P05_Messages
{
    using System;

    class P05_Messages
    {
        static void Main(string[] args)
        {
            int clicks = int.Parse(Console.ReadLine());
            string message = string.Empty;

            for (int i = 0; i < clicks; i++)
            {
                string digits = Console.ReadLine();
                int digitLength = digits.Length;
                int digit = digits[0] - '0';    // ASCII hack hehehe
                int offset = (digit - 2) * 3;

                if (digit == 0)
                {
                    message += (char)(digit + 32);
                    continue;
                }

                if (digit == 8 || digit == 9)
                {
                    offset++;
                }
                int letterIndex = offset + digitLength - 1;
                message += (char)(letterIndex + 97);
            }

            Console.WriteLine(message);
        }
    }
}

 

0
13/05/2019 15:11:31
Joro_Paspalev avatar Joro_Paspalev 23 Точки

Здравей, 

да така е. Решавам я и по двата начина.

Първо реших да я напиша със знанията които имам до момента без да ползвам формулата, която е дадена в подсказката наготово, но още при първото ми решение резултата бе 20/100 точки - и зациклих.

Благодарение на колежката вече съм на 100/100 точки.

Сега започвам с втория вариант, който ти си посочил. Като цяло стъпките са ми ясни, но не схващам за какво е:

1. Main Digit - единиците ли се търсят или стотиците - т.е. с % деление ли го търсим къто остатък или с целичислено деление / за да намерим цялото числи.

2. Какво е offset - по скоро защо ни е? Каква е идеята на формулата (main digit - 2) * 3. Защо -2, защо *3;

3. If the main digit is 8 or 9, we need to add 1 to the offset, since the digits 7 and 9 have 4 letters each - тук може би има грешка в описанието - би трябвало ако основната цифра е 7 или 9, а не 8 или 9 според мен?

4. Каква е логиката на формулата 

  • (offset + digit length - 1).

Много въпроси, но така ще е докато се науча :)

Поздрави,

0
RadostinStoychev avatar RadostinStoychev 128 Точки

Main Digit --> примерно 666, цифрата е 6.
Ако го обърнеш от int в string, string-а сам по себе си е масив от char-ове.
              6 6 6
index     0 1 2
Когато вземеш елемента на нулевия индекс получаваш '6' но като char. Но според ASCII таблицата https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html десетичната стойност на този char е 54, а на '0' -> 48 (54 - 48 = 6).
За да го обърнеш към int по-лесно използваш:

int digit = digits[0] - '0';

Май си прав, че има грешка в условието сега го забелязах и аз, не се опитвай да задълбаваш толкова на тази задачка, вече сме на touch screen :D

0
13/05/2019 16:19:03
Joro_Paspalev avatar Joro_Paspalev 23 Точки

Това с int digit = digits[0] - '0'; ми хареса. Умно измислено.

Докато схвана цялата логика ми отне известно време, но вече съм наясно каква е идеята, а за реализацията и варианти много.

Аз реших задачата по този начин:

using System;

namespace _05__Messages___difficult
{
    class Program
    {
        static void Main(string[] args)
        {
            int countOfLetters = int.Parse(Console.ReadLine());
            string word = string.Empty;

            for (int i = 1; i <= countOfLetters; i++)
            {
                string currentDigit = Console.ReadLine(); //44
                int mainDigit = int.Parse(currentDigit[0].ToString());

                if (mainDigit == 8 || mainDigit == 9)
                {
                    int offset = ((mainDigit - 2) * 3) + 1;
                    int offsetInSquare = currentDigit.Length;
                    int totalOffset = offset + offsetInSquare - 1;
                    char letter = (char)(97 + totalOffset);
                    word += letter;
                }
                else if (mainDigit == 0)
                {
                    word += ' ';
                }
                else
                {
                    int offset = (mainDigit - 2) * 3;
                    int offsetInSquare = currentDigit.Length;
                    int totalOffset = offset + offsetInSquare - 1;
                    char letter = (char)(97 + totalOffset);
                    word += letter;
                }
            }
            Console.WriteLine(word);
        }
    }
}
Благодаря за помощта!

1
AnitaBogoeva avatar AnitaBogoeva 0 Точки

Здравей, ако можеш да обясниш логиката на формулите  (main digit - 2) * 3 и (offset + digit length - 1), ще съм ти много благодарна, защото и аз си блъскам главата с тях.

0
Joro_Paspalev avatar Joro_Paspalev 23 Точки

Здравей,

относно (main digit - 2) * 3 - каква е презумцията - Тук търсим с колко позиции е изместен текущия символ спрямо началото. Търсим 2 неща - с колко основни символи е изместен спрямо първия символ и второ с колко символа е изместен в текущото квадратче. Ще се опитам с пример понеже надали ме разбираш.

Ако искаме символа ни да е "j" как се смята с формулата показана по-горе.

Първо гледаме Main Digit-a колко е - в случая е 5 т.е. (5-2)*3=3*3=9 - т.е. 9 символа са минали (a b c  d e f  g h i) преди да дойде квадратчето където се намира "j" 

Ако клавиша 1 и той беше запълнене с букви (и то 3 на брой) тогава формулата щеше да е (5-1)*3

Ако буквите започваха от 3тата цифра формулата би била (5-3)*3=6 - защото символите ще бъдета само abc и d e f общо 6;

Сега трябва да разберем "j" на каква позиция е в самото квадратче, а те са 1 2 или 3 - "j" ни е на първа позиция вътре в квадратчето

Следователно прилагаме следващата формула (offset + digit length - 1) където offset ни е това изместване което намерихме сега, digit length ни е позицията на символа "j" вътре в квадратчето т.е. 1 позиция (ако беше k щеше да е 2ра позиция, ако беше L трета), а -1 се използва поради разбинаването на нашето броене и това как индексира символите компютъра например: String text = "Ivan" броя на буквите е 4бр (I-1, v-2, a-3, n-4) но като индексация започвайки от 0 се броят така (I-0, v-1, a-2, n-3)

В крайна сметка аз го разбрах този пример така: Представих си че трябва да индексирам цялата английска азбука от A  до Z както е направено в таблицата горе. Символите са от от 1 до 26 (т.е общо 26бр) но индексите им са от 0 до 25 защото се включва и нулата (т.е отново са общо 26бр)

Така де но ако не са разделени на групи от по 3 символа за да изпиша Z трябва да натисна клавиша 26 пъти, за Х 24 пъти, а това ще е доста трудно за изписване на цял SMS със сто символа. И от тук е идеята да се раздели на блокове от по 3 (или 4) символа в блок, да се намери колко блока с по колко символа в този блок има преди символа който искаме да изпишем и това е решението.

Поздрави,

0
AnitaBogoeva avatar AnitaBogoeva 0 Точки

Много благодаря за изчерпателния отговор, всичко ми се изясни. :) 

0
Joro_Paspalev avatar Joro_Paspalev 23 Точки

Радвам се.

Успех!

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.