Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. Coding Challenge Of The Day

Coding Challenge Of The Day

Scheduled Pinned Locked Moved The Lounge
c++architecture
51 Posts 30 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Chris Maunder

    Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.

    cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

    R Offline
    R Offline
    RobertHarris
    wrote on last edited by
    #33

    First time post so hope this looks OK; 1 CRT "NUMERALS: ": ; INPUT NUM 2 CRT "NUMBER : ":ICONV(NUM, 'NR') 3 END Written in UniVerse BASIC.

    1 Reply Last reply
    0
    • L Lost User

      Or, somewhat more tersely,

      def r2d3(r,(s,M,C,X,I,z,V,L,D)=["%%s%d"%v for v in[1001,1000,100,10,1,0,5,50,500]]):
      return eval("".join([
      p%"+-"[eval( p%"%s>"%d%"")]
      for d,p in zip(map(eval,'%sz'%r),map(eval,'s%s'%r))
      ][1:]))

      Y Offline
      Y Offline
      yiangos
      wrote on last edited by
      #34

      Or, somewhere in between:

      def a6(roman):
      if len(roman)==0:
      return 0
      mapping={"I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000}
      values=[mapping[digit] for digit in roman.upper()]
      for i in range(len(values)):
      if i

      also, added capitalization tolerance, so that "MCM" and "mcm" evaluate the same. I haven't added a check that the argument is a valid roman numeral, but that is left as an exercise to the reader ;P

      Φευ! Εδόμεθα υπό ρηννοσχήμων λύκων!
      (Alas! We're devoured by lamb-guised wolves!)

      1 Reply Last reply
      0
      • C Chris Maunder

        Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.

        cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

        P Offline
        P Offline
        Pascal Ganaye
        wrote on last edited by
        #35

        I hope it will be obscure enough. ;)

        class Program
        class Program
        {
        static int RomanToArabic(string r)
        {
        int x, y, z = x = y = 0;
        foreach (char c in r)
        y += ((z = (int)Math.Pow(10, (z = "ivxlcdm".IndexOf((char)(c | ' '))) / 2) * (1 + 4 * (z & 1))) > x ? -2 * x + (x = z) : x = z);
        return y;
        }

            static void Main(string\[\] args)
            {
                Console.WriteLine(RomanToArabic("MDC"));	// 1600
                Console.WriteLine(RomanToArabic("mcmxcix"));	// 1999
                Console.ReadKey();
            }
            
        }
        

        }

        L 1 Reply Last reply
        0
        • L Luc Pattyn

          no arrays, no dictionaries, no obscure language, just some original coding:

          public static bool TryParseRoman(string wellFormedRoman, out int val) {
          val=0;
          int prevDigit=0;
          foreach (char c in wellFormedRoman) {
          int index="IVXLCDM".IndexOf(c);
          if (index<0) {val=0; return false;}
          int digit=1;
          int factor=5;
          while (--index>=0) { digit*=factor; factor=7-factor; }
          if (prevDigit

          BTW: is it Friday already?

          :)

          Luc Pattyn [My Articles] Nil Volentibus Arduum

          P Offline
          P Offline
          Pascal Ganaye
          wrote on last edited by
          #36

          This is definitely better than my attempt.

          1 Reply Last reply
          0
          • P Pascal Ganaye

            I hope it will be obscure enough. ;)

            class Program
            class Program
            {
            static int RomanToArabic(string r)
            {
            int x, y, z = x = y = 0;
            foreach (char c in r)
            y += ((z = (int)Math.Pow(10, (z = "ivxlcdm".IndexOf((char)(c | ' '))) / 2) * (1 + 4 * (z & 1))) > x ? -2 * x + (x = z) : x = z);
            return y;
            }

                static void Main(string\[\] args)
                {
                    Console.WriteLine(RomanToArabic("MDC"));	// 1600
                    Console.WriteLine(RomanToArabic("mcmxcix"));	// 1999
                    Console.ReadKey();
                }
                
            }
            

            }

            L Offline
            L Offline
            Luc Pattyn
            wrote on last edited by
            #37

            Nice. I like the % ' ' bits, and appreciate you used literal VII. :)

            Luc Pattyn [My Articles] Nil Volentibus Arduum

            P 1 Reply Last reply
            0
            • L Luc Pattyn

              Nice. I like the % ' ' bits, and appreciate you used literal VII. :)

              Luc Pattyn [My Articles] Nil Volentibus Arduum

              P Offline
              P Offline
              Pascal Ganaye
              wrote on last edited by
              #38

              oops I removed the % ' '... Ok I put back a:

              "ivxlcdm".IndexOf((char)(c | ' '))

              1 Reply Last reply
              0
              • C Chris Maunder

                Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.

                cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                P Offline
                P Offline
                Pascal Ganaye
                wrote on last edited by
                #39

                This is my final answer

                static int RomanToArabic(string roman, int x = 0, int y=0)
                {
                return roman.Length == 0 ? 0 : (y = (int)Math.Pow(10, (y = "ivxlcdm".IndexOf((char)(roman[0] | ' '))) / 2) * (1 + 4 * (y & 1))) + (y > x ? -2 * x : 0) + RomanToArabic(roman.Substring(1), y);
                }

                1 Reply Last reply
                0
                • C Chris Maunder

                  Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.

                  cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                  A Offline
                  A Offline
                  Alan Balkany
                  wrote on last edited by
                  #40

                  Geez, I thought it was going to be something hard.

                  "Microsoft -- Adding unnecessary complexity to your work since 1987!"

                  1 Reply Last reply
                  0
                  • C Chris Maunder

                    Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.

                    cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                    R Offline
                    R Offline
                    Reese Currie
                    wrote on last edited by
                    #41

                    OK, I admit it isn't very small. Scala is number 46 on the Tiobe Index this month, so perhaps it is obscure enough to qualify. Being a "functional" language there are actually 3 functions but I nested them in one.

                    def convertRomanToArabic(romanNumeral: String): Int = {
                      
                      var previous = 0
                      
                      def convertSingleRomanNumeral(numeral: Char): Int = {
                        numeral match {
                          case 'I' => 1
                          case 'V' => 5
                          case 'X' => 10
                          case 'L' => 50
                          case 'C' => 100
                          case 'D' => 500
                          case 'M' => 1000
                        }
                      }
                      
                      def addRomans(next: Int, accumulator: Int): Int = {
                        if (previous == 0) previous = accumulator
                        var addto = if (previous > next) next \* -1 else next
                        previous = next
                        accumulator + addto
                      }
                      
                      val values = romanNumeral.toList.map(n => convertSingleRomanNumeral(n))
                      values.reduceRight(addRomans)
                    }
                    
                    1 Reply Last reply
                    0
                    • C Chris Maunder

                      Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.

                      cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                      A Offline
                      A Offline
                      AnonimityPreferred
                      wrote on last edited by
                      #42

                      FUNCTION Roman2Dec(cRoman)

                      LOCAL nPointer := len(cRoman)  
                      LOCAL nPos := 0,nFaceVal := 0,nLastVal := 0, nReturn := 0
                      
                      WHILE nPointer > 0
                          nPos     := at(substr(cRoman, nPointer, 1),'IVXLCDM') -1 
                          nFaceVal := (10 ^ int((nPos)/2)) \* (1+((nPos) % 2 \* 4))
                          nReturn  += iif(nFaceVal < nLastVal, -nFaceVal, nFaceVal)
                          IF nFaceVal > nLastVal
                              nLastVal := nFaceVal
                          ENDIF
                          nPointer--    
                      ENDDO
                      

                      RETURN nReturn

                      A 1 Reply Last reply
                      0
                      • C Chris Losinger

                        for well-formed roman numerals, modern rules:

                        int r2d2(const char *r)
                        {
                        int val[128];
                        memset(val,0,sizeof(int)*128);
                        val['I']=1; val['V']=5;
                        val['X']=10; val['L']=50;
                        val['C']=100; val['D']=500; val['M']=1000;

                        int a = 0;
                        for (int cv, pv = 0, i=strlen(r)-1;i>=0;i--)
                        {
                        cv = val[r[i]];
                        a += cv * (pv > cv ? -1 : 1);
                        pv = cv;
                        }

                        return a;
                        

                        }

                        image processing toolkits | batch image processing

                        F Offline
                        F Offline
                        firegryphon
                        wrote on last edited by
                        #43

                        These aren't the roman numerals you're looking for.  You should go about your business.  Move along move along.

                        ragnaroknrol: Yes, but comparing a rabid wolverine gnawing on your face while stabbing you with a fountain pen to Vista is likely to make the wolverine look good, so it isn't exactly that big of a compliment.

                        1 Reply Last reply
                        0
                        • C Chris Maunder

                          Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.

                          cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                          U Offline
                          U Offline
                          User 8912811
                          wrote on last edited by
                          #44

                          In C#:

                          using System;
                          using System.Collections;
                          using System.Collections.Generic;
                          using System.ComponentModel;
                          using System.Data;
                          using System.Drawing;
                          using System.Linq;
                          using System.Text;
                          using System.Windows.Forms;

                          namespace RomanNumerConverter
                          {
                          public partial class Form1 : Form
                          {
                          public Form1()
                          {
                          InitializeComponent();
                          }

                              private void button1\_Click(object sender, EventArgs e)
                              {
                                  Hashtable ht = new Hashtable(); // Create a look-up table to look up Roman numerals and get there associated values.
                                  ht.Add('M', 1000);
                                  ht.Add('D', 500);
                                  ht.Add('C', 100);
                                  ht.Add('L', 50);
                                  ht.Add('X', 10);
                                  ht.Add('V', 5);
                                  ht.Add('I', 1);
                          
                                  String RomanNumber = textBox1.Text;
                                  int value = 0;
                                  for (int index = 0; index < RomanNumber.Length; index++)  // Go through the entered Roman numeral a character at a time
                                  {
                                      int nextVal;
                                      int currentVal = Convert.ToInt32(ht\[RomanNumber\[index\]\]); // Get the value of the current character.
                                      if (index + 1 < RomanNumber.Length) // if you are not at the end of the string
                                      {
                                          nextVal = Convert.ToInt32(ht\[RomanNumber\[index + 1\]\]);// Peek at the next number to see you need to use it to combine characters for a single value(e.g. IV equates to 4)
                                      }
                                      else
                                      {
                                          nextVal = 0; // No more characters so just set this to 0 to simplfy the algorithm.
                                      }
                                      if (nextVal > currentVal)// If the value of nextVal is greater than currentVal, we have a subtractive situation (e.g. IV)
                                      {
                                          currentVal = nextVal - currentVal;  // To determine the value you have to subtract the value of the first number of the pair from the second number(e.g. IV = 5 - 1 = 4)
                                          index++;// Used nextVal to help determine the number so increment the index to skip over that character in the next iteration.
                                      }
                                      value += currentVal; // Add the values of the Roman numerals up.
                                  }
                                  label1.Text = value.ToString();  //Convert the sum to string to use as a text label.  This is the converted number in Arabic numerals.
                              }
                          }
                          

                          }

                          1 Reply Last reply
                          0
                          • C Chris Maunder

                            Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.

                            cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                            N Offline
                            N Offline
                            nrkn
                            wrote on last edited by
                            #45

                            Hideous C# one-liner* with whitespace added to ahahahaha enhance readability.

                            static double RomanToInt( string roman ) {
                            return (
                            Enumerable.Range( 0, 3 )
                            .Select(
                            i =>
                            ( i + 1 ) * 2 - 2
                            )
                            .Aggregate(
                            roman.ToLower(),
                            ( current, i ) =>
                            current
                            .Replace(
                            "ivxlcdm".Substring( i, 2 ),
                            new string( "ivxlcdm"[ i ], 4 )
                            )
                            .Replace(
                            "ivxlcdm"[ i ].ToString() + "ivxlcdm"[ i + 2 ].ToString(),
                            "ivxlcdm"[ i + 1 ].ToString() + new string( "ivxlcdm"[ i ], 4 )
                            )
                            )
                            .Select(
                            i =>
                            "ivxlcdm".IndexOf( i )
                            )
                            .Select(
                            x =>
                            x % 2 == 0 ?
                            Math.Pow( 10, x / 2 ) :
                            Math.Pow( 10, ( x + 1 ) / 2 ) / 2
                            )
                            .Sum()
                            );
                            }

                            *Not counting the function declaration - trivial to convert to a true a one-liner but you asked for a function

                            C 1 Reply Last reply
                            0
                            • N nrkn

                              Hideous C# one-liner* with whitespace added to ahahahaha enhance readability.

                              static double RomanToInt( string roman ) {
                              return (
                              Enumerable.Range( 0, 3 )
                              .Select(
                              i =>
                              ( i + 1 ) * 2 - 2
                              )
                              .Aggregate(
                              roman.ToLower(),
                              ( current, i ) =>
                              current
                              .Replace(
                              "ivxlcdm".Substring( i, 2 ),
                              new string( "ivxlcdm"[ i ], 4 )
                              )
                              .Replace(
                              "ivxlcdm"[ i ].ToString() + "ivxlcdm"[ i + 2 ].ToString(),
                              "ivxlcdm"[ i + 1 ].ToString() + new string( "ivxlcdm"[ i ], 4 )
                              )
                              )
                              .Select(
                              i =>
                              "ivxlcdm".IndexOf( i )
                              )
                              .Select(
                              x =>
                              x % 2 == 0 ?
                              Math.Pow( 10, x / 2 ) :
                              Math.Pow( 10, ( x + 1 ) / 2 ) / 2
                              )
                              .Sum()
                              );
                              }

                              *Not counting the function declaration - trivial to convert to a true a one-liner but you asked for a function

                              C Offline
                              C Offline
                              Chris Maunder
                              wrote on last edited by
                              #46

                              Sweet.

                              cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                              N 1 Reply Last reply
                              0
                              • C Chris Maunder

                                Sweet.

                                cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                                N Offline
                                N Offline
                                nrkn
                                wrote on last edited by
                                #47

                                Better:

                                static int RomanToInt( string roman ) {
                                return roman
                                .ToLower()
                                .Select(
                                n =>
                                new Dictionary {
                                {'i', 1},
                                {'v', 5},
                                {'x', 10},
                                {'l', 50},
                                {'c', 100},
                                {'d', 500},
                                {'m', 1000},
                                }[ n ]
                                )
                                .Aggregate(
                                new[] {0, 0, 0},
                                ( c, d ) =>
                                new[] {
                                c[ 0 ] + ( d > c[ 2 ] ? d - c[ 1 ] : c[ 1 ] ),
                                d > c[ 2 ] ? 0 : d,
                                d
                                }
                                )
                                .Take( 2 )
                                .Sum();
                                }

                                1 Reply Last reply
                                0
                                • A AnonimityPreferred

                                  FUNCTION Roman2Dec(cRoman)

                                  LOCAL nPointer := len(cRoman)  
                                  LOCAL nPos := 0,nFaceVal := 0,nLastVal := 0, nReturn := 0
                                  
                                  WHILE nPointer > 0
                                      nPos     := at(substr(cRoman, nPointer, 1),'IVXLCDM') -1 
                                      nFaceVal := (10 ^ int((nPos)/2)) \* (1+((nPos) % 2 \* 4))
                                      nReturn  += iif(nFaceVal < nLastVal, -nFaceVal, nFaceVal)
                                      IF nFaceVal > nLastVal
                                          nLastVal := nFaceVal
                                      ENDIF
                                      nPointer--    
                                  ENDDO
                                  

                                  RETURN nReturn

                                  A Offline
                                  A Offline
                                  AnonimityPreferred
                                  wrote on last edited by
                                  #48

                                  My previous code after some Herbalife:-

                                  FUNC rr(c)
                                  r=0;p=0;b=len(c)
                                  WHILE b>0
                                  v=at(c[b],'IVXLCDM')-1
                                  f=10^int(v/2)*(v%2*4+1)
                                  r+=if(fp,p:=f,)
                                  b--
                                  END
                                  RETURN r

                                  Compiles with xHarbour.

                                  1 Reply Last reply
                                  0
                                  • C Chris Maunder

                                    Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.

                                    cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                                    V Offline
                                    V Offline
                                    VadimAlk
                                    wrote on last edited by
                                    #49

                                    private Dictionary R2A_dictionary = new Dictionary()
                                    {
                                    {'I', 1},
                                    {'V', 5},
                                    {'X', 10},
                                    {'L', 50},
                                    {'C', 100},
                                    {'D', 500},
                                    {'M', 1000},
                                    };

                                    private int ConvertRomanToArabic(string roman)
                                    {
                                    int result = 0;
                                    int previous = Int32.MaxValue, current = 0;
                                    for (int i = 0; i < roman.Length; i++)
                                    {
                                    current = R2A_dictionary[roman[i]];
                                    result += current;
                                    if (current > previous)
                                    result -= previous << 1;
                                    previous = current;
                                    }
                                    return result;
                                    }

                                    1 Reply Last reply
                                    0
                                    • C Chris Maunder

                                      Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.

                                      cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                                      J Offline
                                      J Offline
                                      jsc42
                                      wrote on last edited by
                                      #50

                                      If there are bonus points for using hated constructs, how about this one-liner using JavaScript's 'eval' function?

                                      function RtoA(r)
                                      { return eval(r.toUpperCase()
                                      .replace(/CM/g, '+900').replace(/CD/g, '+400').replace(/XC/g, '+90').replace(/XL/g, '+40')
                                      .replace(/IX/g, '+9').replace(/M/g, '+1000').replace(/D/g, '+500').replace(/C/g, '+100')
                                      .replace(/L/g, '+50').replace(/X/g, '+10').replace(/V/g, '+5').replace(/I/g, '+1'));
                                      }

                                      or for obscure use of Regular Expression matching and using string length as scale factors:

                                      function RtoA(r) // r is roman numerals in any case
                                      {
                                      var m = r.match(/^(M*)(CM)?(D)?(CD)?(C*)(XC)?(XL)?(L)?(X*)(IX)?(IV)?(V)?(I*)$/i);

                                      return  (   m\[1\].length \* 1000 +    // M
                                              m\[2\].length \* 450 + // CM
                                              m\[3\].length \* 500 + // D
                                              m\[4\].length \* 200 + // CD
                                              m\[5\].length \* 100 + // C
                                              m\[6\].length \* 45 +  // XC
                                              m\[7\].length \* 25 +  // XL
                                              m\[8\].length \* 50 +  // L
                                              m\[9\].length \* 10 +  // X
                                              m\[10\].length \* 4.5 +    // IX
                                              m\[11\].length \* 2 +  // IV
                                              m\[12\].length \* 5 +  // V
                                              m\[13\].length        // I
                                          );
                                      

                                      } // RtoA

                                      Of the three submissions that I have made, this is the only one that enforces the ordering of numerals (e.g. all Cs must be before all Is) and the fact that some character sequences can only appear once (e.g. D can only appear once, except when following CD which also can only appear once). The odd scale multiplier factors (e.g. 4.5) come from the fact that some letter combinations have 2 characters and the substring lengths are thus twice as long (IX = 2 chars = value of 9, so each char is worth 9 / 2 = 4.5).

                                      C 1 Reply Last reply
                                      0
                                      • J jsc42

                                        If there are bonus points for using hated constructs, how about this one-liner using JavaScript's 'eval' function?

                                        function RtoA(r)
                                        { return eval(r.toUpperCase()
                                        .replace(/CM/g, '+900').replace(/CD/g, '+400').replace(/XC/g, '+90').replace(/XL/g, '+40')
                                        .replace(/IX/g, '+9').replace(/M/g, '+1000').replace(/D/g, '+500').replace(/C/g, '+100')
                                        .replace(/L/g, '+50').replace(/X/g, '+10').replace(/V/g, '+5').replace(/I/g, '+1'));
                                        }

                                        or for obscure use of Regular Expression matching and using string length as scale factors:

                                        function RtoA(r) // r is roman numerals in any case
                                        {
                                        var m = r.match(/^(M*)(CM)?(D)?(CD)?(C*)(XC)?(XL)?(L)?(X*)(IX)?(IV)?(V)?(I*)$/i);

                                        return  (   m\[1\].length \* 1000 +    // M
                                                m\[2\].length \* 450 + // CM
                                                m\[3\].length \* 500 + // D
                                                m\[4\].length \* 200 + // CD
                                                m\[5\].length \* 100 + // C
                                                m\[6\].length \* 45 +  // XC
                                                m\[7\].length \* 25 +  // XL
                                                m\[8\].length \* 50 +  // L
                                                m\[9\].length \* 10 +  // X
                                                m\[10\].length \* 4.5 +    // IX
                                                m\[11\].length \* 2 +  // IV
                                                m\[12\].length \* 5 +  // V
                                                m\[13\].length        // I
                                            );
                                        

                                        } // RtoA

                                        Of the three submissions that I have made, this is the only one that enforces the ordering of numerals (e.g. all Cs must be before all Is) and the fact that some character sequences can only appear once (e.g. D can only appear once, except when following CD which also can only appear once). The odd scale multiplier factors (e.g. 4.5) come from the fact that some letter combinations have 2 characters and the substring lengths are thus twice as long (IX = 2 chars = value of 9, so each char is worth 9 / 2 = 4.5).

                                        C Offline
                                        C Offline
                                        Chris Maunder
                                        wrote on last edited by
                                        #51

                                        Oh wow. I think it's too early in the morning for that sort of shenanigans, especially a Monday morning. I feel queasy.

                                        cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                                        1 Reply Last reply
                                        0
                                        Reply
                                        • Reply as topic
                                        Log in to reply
                                        • Oldest to Newest
                                        • Newest to Oldest
                                        • Most Votes


                                        • Login

                                        • Don't have an account? Register

                                        • Login or register to search.
                                        • First post
                                          Last post
                                        0
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular
                                        • World
                                        • Users
                                        • Groups