1. C# / Говнокод #5294

    +116

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    namespace tickets
        {
            class ticket
            {
                int ticket_num; // номер билета
                int[] digit_mas = new int[6]; // массив циф номера билета
                int i = 5;
                bool repletion; // если значение превысило 999999 - то истина
                int divizor = 10; // делитель (для розбивания числа на цифры)
                int pre_divizor = 1; // предидущий делитель
                int pre_digit; // предидущая цифра
                int happy_TK_amount; // количество "счастливых" билетов
                public ticket(int num_of_ticket)
                {
                    if (num_of_ticket < 1000000 & num_of_ticket >= 100000)
                        ticket_num = num_of_ticket;
                    else
                        Console.WriteLine("out of range");
                }
                public void crash_num() // разбиваем число на цифры  
                {
                    if (i >= 0)
                    {
                        digit_mas[i] = (ticket_num % divizor - pre_digit) / pre_divizor; // от остачи от деления на порядок , вычетаем предидущю цифру , и делим на предидущий порядок - получаем цифру определённого порядка числа 
                        pre_divizor = divizor;
                        pre_digit = digit_mas[i];
                        divizor = divizor * 10;
                        i--; // пишем в обратном порядке , для правильной записи последовательности цифер
                        crash_num();
                    }
                }
                public void echo_digits()
                {
                    for (i = 0; i <= 5; i++)
                    {
                        Console.Write(digit_mas[i]);
                    }
                }
                public void happy_ticket() // щитает количество "счастливых" билетов
                {
                    for (repletion = false; repletion != true; )
                    {
                        if (digit_mas[0] + digit_mas[1] + digit_mas[2] == digit_mas[3] + digit_mas[4] + digit_mas[5]) // проверяет билет на предмет "счастливости"
                        {
                            happy_TK_amount++;
                        }
                        i = 5;
                        num_increase();
                    }
                    Console.WriteLine("there are " + happy_TK_amount + " happy tickets");
                }
                public void num_increase() // увеличивает номер билета на 1 
                {
                    if (i >= 0)
                    {
                        digit_mas[i]++;
                        if (digit_mas[i] == 10)
                        {
                            digit_mas[i] = 0;
                            if (digit_mas[0] == 0)
                                repletion = true;
                            else
                                i--; // уменшаем индекс , для движения от младшего - к старшему разряду 
                            num_increase();
                        }
                    }
                }
            }

    Написать программу определения количества шестизначных 'счастливых' билетов, у которых сумма первых 3 десятичных цифр равна сумме 3 последних десятичных цифр.

    подскажите плз , есть ли (естественно есть) , где и какое у меня какашкэ в коде , а то проверять меня некому , а индусом стать не хочу
    ЗЫ а вообше , здесь можно так делать (просить проверить )

    Запостил: WJIRIIA, 16 Января 2011

    Комментарии (33) RSS

    • первых 2 строчки - лишние
      из мейн :
      ticket TCK = new ticket(001001);
      TCK.crash_num();
      TCK.happy_ticket();
      Console.ReadLine();
      Ответить
    • > подскажите плз , есть ли (естественно есть) , где и какое у меня какашкэ в коде
      рука тянется к минусу, ибо
      > а вообше , здесь можно так делать (просить проверить )
      нужно соображать самому, в чем говно. Форумов, где можно спросить, и без нас предостаточно

      зы. Просьба Страйко сделать намёк об этом в эпиграфе сайта
      Ответить
      • Ну почему же. Пускай спросит, а потом страйо это выпилит.

        WJIRIIA:
        Плюсуют, значит говно есть.
        Ответить
        • ну зачем ему выпиливать, если плюсуют? плюсуют, значит нравится.
          Ответить
    • 1)
      //О, писька в комментариях!
      2)
      for(...)
      {
        одна_строчка();
      }
      лучше записать ввиде
      for(...)
        одна_строчка();
      3)При проверки на диапазон лучше использовать исключения в конструкторе.
      4)Функция
      num_increase() // увеличивает номер билета на 1
      доставила. :D
      Ответить
      • 2 описка , изначально было много операторов , удалил операторы , а скобки забыло)
        4 не совсем понял ...
        ну можно например увеличивать ticket_num на 1 , а потом о5 розбивать ?
        зачем лишние телодвижения ?
        Ответить
      • >
        num_increase() // увеличивает номер билета на 1
        Она ещё и рекурсивная. :D
        Ответить
      • >for(...)
        > одна_строчка();
        А потом станет
        for(...)
        первая_строчка();
        вторая_строчка();
        и будет весело.
        Ответить
        • Когда станет n-строк, так и добавите { }, зачем лишние ненужные действия. Или боитесь забыть потом? :D

          >и будет весело.
          Вы не любите веселиться? Оче6нь зря. :D
          Ответить
          • Я стараюсь использовать фигурные скобки даже при одной строке в цикле/условии - это, по крайней мере, создает единую стилистику. Лучше сразу писать так, чтобы не нужно было вспоминать. Собственно и конструкторы с деструкторами появились для того, чтобы не заставлять программиста помнить об необходимости инициализации/очистки. А веселиться надо обсуждая говнокод, а не создавая его ;)
            Ответить
            • >использовать фигурные скобки даже при одной строке в цикле/условии - это создает единую стилистику.
              Это Ваше право, но на мой взгляд это лишь портит восприятие (и стилистику).

              Похоже это чисто субъективная особенность восприятия каждого человека. Значит не мой способ, не ваш - нельзя советовать другим.

              Правда, у моего способа есть незначительное оправдание: меньше писать (экономия времени).
              Вообщем, это не важно. Не вижу смысла продолжать обсуждение.
              Ответить
              • Меньше писать -- не оправдание. Оправдание -- немного компактнее по вертикали код получается, легче читается.
                Ответить
                • Это само собой. За это мне и нравится стилистика без лишних скобок.
                  Ответить
    • var happyTickets = Enumerable.Range(0, 1000000)
      .Select(i => String.Format("{0:d6}", i))
      .Where(i => i[0] + i[1] + i[2] == i[3] + i[4] + i[5])
      .Count();
      Ответить
      • .Select(i => String.Format("{0:d6}", i))
        сорь , если я не прав , а это не насилие ?
        разве это дело не будет "думать" в разы дольше "ужасного" num_increase() ?
        Ответить
        • У Вас стоит задача написать самый оптимальный код? Тогда с комбинаторикой будет почти без циклов.
          А если задача меньше думать, написать за 5 минут и уйти с лабы в столовку с 5кой, то код NotLinoleum самое оно.
          Ответить
        • У меня выполняется за 1 секунду (3 GHz 1 core)
          Ответить
    • По хорошему, конечно, лучше применить не прямой перебор, а комбинаторику.
      Ответить
    • мало комментариев, мало

      PS: формула в первой главе учебника
      Ответить
    • О, школьные каникулы закончились!

      Говна там хватает, даже смотреть не буду. Начиная с использования класса (обратите внимание, локальные переменные ещё не проходили).
      Ответить
    • Ну епта! Это задача комбинаторная, здесь вообще нужно один алгоритм реализовать, правда для этого надо очень хорошо знать комбинаторику. 2-й курс Мех-Мат любого регионального универа, комбинаторика и теория вероятностей. Алгоритм реализуется в виде одной функции, где параметр n - целое неотрицательное чётное число, то бешь количество цифр в счастливом билете. Я на "С" реализовывал, хотя это и не принципиально.
      Ответить
      • > для этого надо очень хорошо знать комбинаторику
        > очень хорошо
        I LOLD
        Ответить
        • вообще надо многое очень хорошо знать. в жизни пригодится )))
          Ответить
    • Предлагаю такое решение. К сожалению, это на C, который знаю весьма поверхностно; С# не знаю вообще.

      #include <stdio.h>
      #define MAX_SUM (9 + 9 + 9)
      
      int main  (int argv, char **argc)
      {
      	int cnt[MAX_SUM + 1]; /* счётчики 3-х значных чисел с одинаковой суммой цифр */
      	int i, j, k;
      	int tickets_cnt;
      
      	for (i = 0; i <= MAX_SUM; i++)
      		cnt[i] = 0;
      
      	for (i = 0; i <= 9; i++) /* первая цифра */
      		for (j = 0; j <= 9; j++) /* вторая цифра */
      			for (k = 0; k <= 9; k++) /* третья цифра */
      				cnt[i + j + k]++;
      
      	tickets_cnt = -1; /* -1, а не 0, чтоб исключить билет '000000' */
      	for (i = 0; i <= MAX_SUM; i++)
      		tickets_cnt += cnt[i] * cnt[i];
      
      	printf("\"Счастливых\" билетов %d шт\n", tickets_cnt);
      
      	return 0;
      }
      Ответить
      • а мурку для случая двадцатисемизначных девятнацитиричных номеров можешь?
        Ответить
        • Неполная постановка задачи, ибо число цифр в двадцатисемизначном номере билета нечётное. В каких пропорциях предполагается делить номер билета на две половины, т.к. возможны варианты?

          Торжественный обмен сарказмом состоялся.

          Есть претензии к коду по существу? Сразу говорю, что сделано "на коленке", ибо комбинаторику не помню.
          Ответить
          • зато прекрасно умеешь брутить, ага
            это был не сарказм, а намёк, кстати
            то не вылезают из педивикии, то не загонишь, блин...
            Ответить
            • Извините, что? Безусловно, ваш пост имеет глубокий смысл, но он, увы, от меня ускользает. Если вас не затруднит, используйте для изложения ваших тезисов внятные формулировки.
              Ответить
              • > внятные формулировки
                http://en.wikipedia.org/wiki/RTFM?
                спойлер: а в соседней статье рассматриваются пермутации
                Ответить
    • Если кому интересно, решение задачи числа счастливых билетов в общем виде: http://www.ega-math.narod.ru/Quant/Tickets.htm

      Реализация на python:
      class SumCounter:
      	cache = {}
      
      	def __call__ (self, digcnt, digsum):
      		if (digcnt, digsum) not in self.cache	and digcnt > 0 and digsum >= 0:
      			if digcnt > 1:
      				self.cache[digcnt, digsum] = sum([ self.__call__(digcnt - 1, digsum - digit) for digit in range(10)])
      			elif digcnt == 1:
      				if 0 <= digsum <= 9:
      					self.cache[digcnt, digsum] = 1
      
      		return self.cache.get((digcnt, digsum), 0)
      
      sum_count = SumCounter()
      
      def happy_tickets (digcnt):
      	return sum([ sum_count(digcnt, digsum) ** 2 for digsum in range(digcnt * 9 + 1) ]) - 1
      
      for digcnt in range(2, 26):
      	print "%3d: %d" % (digcnt * 2, happy_tickets(digcnt))


      Результаты работы:

      4: 669
      6: 55251
      8: 4816029
      10: 432457639
      12: 39581170419
      14: 3671331273479
      16: 343900019857309
      18: 32458256583753951
      20: 3081918923741896839
      22: 294056694657804067999
      24: 28170312778225750242099
      26: 2707859169387181467852099
      28: 261046730157780861858821135
      30: 25228791861003454642059261391
      32: 2443553412892220489195278947229
      34: 237126779700111728623210793896699
      36: 23050391247812238203687824747157799
      38: 2244066255357188250744344225634235599
      40: 218768894829904122626725603838896148679
      42: 2135357526350288463038827371419714518259 9
      44: 2086610157206763614866736016835099941514 799
      46: 2041055591672347180981968644197833025496 32799
      48: 1998359874208731005735781531187223671517 1970099
      50: 1958235988893910037740658552689739094876 481545139
      Ответить
    • выебывания на c#

      var tt1 = from t1 in numbers
      from t2 in numbers
      from t3 in numbers
      let sum = t1 + t2 + t3
      group sum by new { k = t1 * 100 + t2 * 10 + t3, s = sum }
      into gr
      select gr;
      var tt2 = from l1 in tt1
      join l2 in tt1 on l1.Key.s equals l2.Key.s
      select l1.Key.k * 1000 + l2.Key.k;
      Ответить

    Добавить комментарий