1. C++ / Говнокод #3850

    +168

    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
    if(x>=900&&x<1000)
                    {
                            std::cout<<"DCCCC";
                            if(x==901)
                                    std::cout<<"I";
                            else if(x==902)
                                    std::cout<<"II";
                            else if(x==903)
                                    std::cout<<"III";
                            else if(x==904)
                                    std::cout<<"IV";
                            else if(x==905)
                                    std::cout<<"V";
                            else if(x==906)
                                    std::cout<<"VI";
                            else if(x==907)
                                    std::cout<<"VII";
                            else if(x==908)
                                    std::cout<<"VIII";
                            else if(x==909)
                                    std::cout<<"IX";
                            if(x==910)
                            {
                                    std::cout<<"X";
                                    if(x==911)
                                            std::cout<<"I";
                                    else if(x==912)
                                            std::cout<<"II";
                                    else if(x==913)
                                            std::cout<<"III";
                                    else if(x==914)
                                            std::cout<<"IV";
                                    else if(x==915)
                                            std::cout<<"V";
                                    else if(x==916)
                                            std::cout<<"VI";
                                    else if(x==917)
                                            std::cout<<"VII";
                                    else if(x==918)
                                            std::cout<<"VIII";
                                    else if(x==919)
                                            std::cout<<"IX";
                            }
                            else if(x==920)
                            {
                                    std::cout<<"XX";
                                    if(x==921)
                                            std::cout<<"I";
                                    else if(x==922)
                                            std::cout<<"II";
                                    else if(x==923)
                                            std::cout<<"III";
                                    else if(x==924)
                                            std::cout<<"IV";
                                    else if(x==925)
                                            std::cout<<"V";
                                    else if(x==926)
                                            std::cout<<"VI";
                                    else if(x==927)
                                            std::cout<<"VII";
                                    else if(x==928)
                                            std::cout<<"VIII";
                                    else if(x==929)
                                            std::cout<<"IX";
                            }
        //

    Перевод числа <1000 в римские цифры... Единственное, что пришло в голову с утра, тупо перебор всех значений. Соответственно так весь код. Это полный 3.14здец?

    Запостил: ForEveR, 02 Августа 2010

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

    • http://ru.wikipedia.org/wiki/Римские_цифры
      там есть исходник, только на JS
      Ответить
      • Ух ты, какая интересная там на Паскале функция лежит! Неплохо.
        Ответить
        • ага, если еще написать её на чем-нить менее говеном и многословном - получится 4-5 строк.
          Ответить
          • Помню, я свой алгоритм, написанный на С++, переписал на Паскале. 150 строк превратились в 20. Просто я Паскаль знаю лучше цпп.
            Ответить
          • Не могу придумать, на чём. А в Delphi получилось только ускорить:
            function Arab2Roman2(arab: word): string;
            const
              ixcm = 'IIIXXXCCCMMM';
              vld = 'VXLCDM';
            var i, d, dd, dm, d1d, d1m: word;
            begin
              Result := '';
              i := 0;
              while arab > 0 do
                begin
                  DivMod(arab, 10, arab, d);
                  DivMod(d + 1, 5, d1d, d1m);
                  DivMod(d, 5, dd, dm);
                  d := i * 3 + 1;
                  if d1m = 0 then
                    Result := ixcm[d] + vld[i shl 1 + d1d] + Result
                  else
                    Result := Copy(vld, 1 + i shl 1, dd) + Copy(ixcm, d, dm) + Result;
                  inc(i);
                end;
            end;
            Ответить
            • неплохо, но у меня есть кой-какие мысли как сделать это еще лучше , вот только понять не могу как быть с переполнениями тут ixcm[d]
              когда i допустим = 4

              >>>Не могу придумать, на чём
              на любом языке с Си-подбным синтаксисом

              ЗЫ а это системная ф-ция делфей DivMod ?
              Ответить
              • i не бывает больше 3, т. к. arab всегда меньше 4000. (Иначе придётся кодировать пятёрки и десятки тысяч)

                DivMod() да, стандартная (модуль Math, вот исходник, если что):
                procedure DivMod(Dividend: Integer; Divisor: Word;
                  var Result, Remainder: Word);
                asm
                        PUSH    EBX
                        MOV     EBX,EDX
                        MOV     EDX,EAX
                        SHR     EDX,16
                        DIV     BX
                        MOV     EBX,Remainder
                        MOV     [ECX],AX
                        MOV     [EBX],DX
                        POP     EBX
                end;
                Ответить
                • >>>DivMod() да, стандартная
                  удобно придумано, до этого я думал, что только в асме так можно, реально очень удобно, я мечатал о появлении такой простой фичи...

                  >>>i не бывает больше 3
                  тупанул, кстати т.к. на Западе они годы иногда римскими цифрами пишут - их ожидает проблема 4000 )))
                  Ответить
                  • Так, начинаем форсить новую дату конца света :)
                    Ответить
            • итак в этой оптимизации несмотря на хорошие идеи есть пара недостатков
              1. выполняются 2 деления - даже если нам нужно одно - нужно перенести деления в условия а в самом условии написать if (dm == 4)

              2. убрать умножение i*3 и сдвиг i*2

              короче вот мой вариант
              private static final String arab2Roman(int arab){
                	  String res=new String();
                	  String arab_str=String.valueOf(arab); 
                	  for (int d,i2= 0,i3=0,j=arab_str.length()-1; j>=0;i2+=2,i3+=3,j--){
                	     d = (arab_str.charAt(j))-0x30;
                	     res=((d % 5 != 4) ? vld.substring(i2,i2+d / 5)+ixcm.substring(i3, i3+d % 5)):
                    String.valueOf((ixcm.charAt(i3)))+String.valueOf(vld.charAt(i2 + ((d+1) / 5)-1))
                          +res; 
                	  }
              return res;
              }
              private final static String ixcm="IIIXXXCCCMMM";
              private final static String vld="VXLCDM";

              извиняюсь за грубый ассемблерный хак в яве -0x30, просто деление я не люблю
              Ответить
              • блин я придумал как сделать еще лучше и с функцией DivMod и моим грязным асмохаком можно обойтись вообще одним делением.

                а от умножений можно отказатся приведенным выше способом
                Ответить
                • суть в том что при выполнении условия (d+1) div 5 ==0 d кратно 4, потому вместо (d+1) div 5 пишем (d div 5)+1
                  Ответить
            • короче в итоге код эволюцинирует в нечто такое
              private static final String arab2Roman(int arab){
              	String res=new String();
              	String arab_str=String.valueOf(arab); 
              	for (int d,dd5,dm5,i2= 0,i3=0,j=arab_str.length()-1; j>=0;i2+=2,i3+=3,j--){
              	   d = (arab_str.charAt(j))-0x30;
              	   dd5=d /5;dm5=d%5;
              	   res=((dm5 != 4) ? vld.substring(i2,i2+dd5)+ixcm.substring(i3, i3+dm5): 
              	   String.valueOf((ixcm.charAt(i3)))+String.valueOf(vld.charAt(i2 +dd5)))+res; 
                 }
                return res;
              }
              Ответить
              • и приницпе это можно постить на сей ресурс )))

                полный набор и 0x30; в яве
                и одно-двух буквенные неймы
                Ответить
              • а это можно оптимизировать заменив dd5= i2 +d /5 и поставив его вместо i2+dd5
                Ответить
              • короче с утреца глянув на этот код моя голова наполнилась новыми идеями дальнейшей оптимизации
                тут вообще можно избавится от делений т.к. d<10
                то деление на 5 эквивалентно ((d+3)>>3), ((d-1)>>2) не катит т.к. 9

                а остаток можно заменить на условие (d!=4 && d!=9), и взятие второго остатка можно тоже сделать через логику ну или на краняк вот так:
                d % 5 =(d>4) ? d-5 : d
                Ответить
                • а без условия в ветке где остаток!=4 будет так
                  d % 5 = (d-((d+3)>>3)) & 3;

                  в итоге получится весьма короткий код на сложениях, вычитаниях и сдвигах, и без условий.
                  public static final String arab2Roman(int arab){
                  	String res=new String();
                  	String arab_str=String.valueOf(arab % 4000); 
                  	for (int d,dd5,i2= 0,i3=0,j=arab_str.length()-1; j>=0;i2+=2,i3+=3,j--){			
                  	   d = (arab_str.charAt(j))-(char)'0';
                  	   dd5=i2+((d+3)>>3);
                  	   res=((d!=4 && d!=9) ? vld.substring(i2,dd5)+ ixcm.substring(i3, i3+d % 5) 
                  	   : new String(new char[] {ixcm.charAt(i3), vld.charAt(dd5)}))+res;		     
                      }
                    return res;
                  }

                  что можно кончно еще оптимизировать. ))
                  Ответить
                  • Круть :) Особенно с делениями жестоко :)
                    А тут можно ещё res сделать на StringBuilder'е. И вот это: new String(new char[] ... как-нибудь попробовать вынести (Но я тут хз, не силён в яве).
                    Ответить
                    • >>Круть
                      кстати отнимание (char)'0' все-равно по меркам явы хак, равно как -0x30;

                      >>А тут можно ещё res сделать на StringBuilder'е.
                      я хотел было, но там же не в конец добавлять надо а в начало - то есть insert, а он копирует целый массив, что слоу
                      Ответить
                    • да и вообще
                      1. это легко портировать в любой С-like язык, да и любой другой тож
                      2. в С/С++ можно намутить быструю сборку строки через указатели
                      Ответить
                    • >>>на StringBuilder'е
                      вообще можно собирать задом-наперед а потом сделать реверс, но сдается мне, что реверс будет выполнятся дольше чем весь мой алгоритм
                      Ответить
        • d := StrToInt(String(arab_str[arab_len-i]));
          Говнокод же.
          Ответить
      • Месяц назад не было, я дописал ;)
        Ответить
    • if(x==910) {
        std::cout<<"X";
        if(x==911)
      ...
      Гениально.
      А вообще, Гугль в помощь.
      Ответить
    • Спасибо за ссылки) Просто с утра рано писал, всю ночь не спал) Вот результат)
      Ответить
      • Быстрее бы отучиться и работать программистом в какой-нибудь канторе, а-то устал на автостоянке сторожем сутки работать =)
        Ответить
        • удаленка или полставки. или автостоянка это лучше?
          Ответить
          • Удаленка прямо с автостоянки убивает двоих зайцев.
            И мозг.
            Ответить
    • Полный ли это "3.14здец"? Это даже прокомментировать сложно. Это катастрофа!
      Ответить
    • #include <iostream>
      #include <string>
      #include <vector>

      int main()
      {
      int number=0;
      std::string Str1="I"; std::string Str3="V"; std::string Str5="X";
      std::string Str7="L"; std::string Str9="C"; std::string Str11="D";
      std::string Str13="M"; std::string Str2="IV"; std::string Str4="IX";
      std::string Str6="XL"; std::string Str8="XC"; std::string Str10="CD";
      std::string Str12="CM";
      int Array[]={1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
      std::vector<std::string> Arrayyy;
      Arrayyy.push_back(Str1); Arrayyy.push_back(Str2); Arrayyy.push_back(Str3);
      Arrayyy.push_back(Str4); Arrayyy.push_back(Str5); Arrayyy.push_back(Str6);
      Arrayyy.push_back(Str7); Arrayyy.push_back(Str8); Arrayyy.push_back(Str9);
      Arrayyy.push_back(Str10); Arrayyy.push_back(Str11); Arrayyy.push_back(Str12);
      Arrayyy.push_back(Str13);
      std::string res="";
      std::vector<int> Arr;
      for(int i=0;i<13;++i)
      {
      Arr.push_back(Array[i]);
      }
      std::cout<<"Enter number in arab: ";
      std::cin>>number;
      if(!number) res=" ";
      size_t i=Arr.size()-1;
      while(number>0)
      {
      if(number>=Arr[i])
      {
      res+=Arrayyy[i];
      number-=Arr[i];
      }
      else
      {
      i--;
      }
      }
      std::cout<<res<<'\n';
      return 0;
      }
      Длинный немного. Но полностью корректный.
      Ответить
      • >>std::string Str1="I"; std::string Str3="V"; std::string Str5="X";
        >>std::string Str7="L"; std::string Str9="C"; std::string Str11="D";
        >>std::string Str13="M"; std::string Str2="IV"; std::string Str4="IX";
        >>std::string Str6="XL"; std::string Str8="XC"; std::string Str10="CD";
        >>std::string Str12="CM";
        use Enum, Luke!
        Ответить
        • use array, Yoda! Enums are integer type. But string not.
          Ответить
          • array не катит. Там ведь есть и двухсимвольные.
            Ответить
            • > Там ведь есть и двухсимвольные.
              char* arrch[] = { "I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M" };
              Ответить
              • Угу. А какая разница с вектором или с чаром?)
                Хотя по размеру кода конечно есть.
                Ответить
    • а вообще я думаю, что если этот код выгравировать на свинцовой табличке и выкинуть в море, то он не утонет и будет скитаться на поверхности морской глади
      Ответить

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