IT, Scala, Java, Web, Ubuntu

Category: IT (Page 3 of 13)

Look and Say Sequence (Java)

Look and say sequence is the sequence of numbers generated from the previous number by reading off the digits of which the number consists.

So the first number is 1 then there is one "1". one 1 -> 11
Now use the number "11" and there are two 1s. two 1s -> 21
21: one 2 and one 1 -> 1211
1211: one 1, one 2 and two 1s -> 111221
111221: three 1s, two 2s and one 1 -> 312211
312211: one 3, one 1, two 2s and two 1 -> 13112221
13112221: one 1, one 3, two 1s, three 2s and one 1 -> 1113213211
----------------------------------------------------------------
1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211 ...

The Java programme code which reads off the given number can be written like

public static String LookAndSayUsingForLoop(final String number)
{
  if (null == number || number.isEmpty())
  {
    return "";
  }
  int firstCharPosition = 0;
  final StringBuilder stringBuilder = new StringBuilder();
  for (int i = 0; i < number.length(); i++)
  {
    if (number.charAt(firstCharPosition) != number.charAt(i))
    {
      //
      // the char at the current position is not equal to the first char
      // in the group of the equal chars so collect the chars
      // from the first char position to just before the current position.
      //
      final String digitsFound = number.substring(firstCharPosition, i);
      stringBuilder.append(digitsFound
                          .length())
                   .append(number
                          .charAt(firstCharPosition));
      firstCharPosition = i; // set the new first char position
    }
  }
  /* add the leftover */
  stringBuilder.append(number
                      .substring(firstCharPosition,
                                 number.length())
                      .length())
               .append(number
                      .charAt(firstCharPosition));
  return stringBuilder.toString();
}
System.out.println(LookAndSayUsingForLoop("1"));
Result:
11
System.out.println(LookAndSayUsingForLoop("11"));
Result:
21
System.out.println(LookAndSayUsingForLoop("21"));
Result:
1211

So to get the first ten elements,

String result1 = number;
System.out.print(result1 + " ");
for (int i = 1; i < howMany; i++)
{
  result1 = LookAndSayUsingForLoop(result1);
  System.out.print(result1 + " ");
}

It prints out.

1 11 21 1211 111221 312211 13112221 1113213211 31131211131221 13211311123113112211 

It can be simpler if recursion is used.
The LookAndSayUsingForLoop method can be re-written like

private static String lookAndSayV1(final String number, final int position)
{
  if (number.length() == position)
  {
    // reached the end which means every digit in the number is
    // equal to one another so just read off the entire number.
    return String.valueOf(number.length()) + number.charAt(0);
  }
  final char firstChar = number.charAt(0);
  return firstChar == number.charAt(position) ?
            // the current char equals to the first one so keep checking
            lookAndSayV1(number, position + 1) :
            // otherwise, read off until just before the current position
            // then check from the current position
            // calling this function itself again.
            String.valueOf(number
                          .substring(0, position)
                          .length()) +
              firstChar +
              lookAndSayV1(number
                          .substring(position), 0);
}

The result is exactly the same as the one using ‘for’ loop.

System.out.println(lookAndSayV1("1", 0));
Result:
11
System.out.println(lookAndSayV1("11", 0));
Result:
21
System.out.println(lookAndSayV1("21", 0));
Result:
1211

To get the first ten elements, another recursive method can be used.

public static String lookAndSay(final int howMany, final String number)
{
  return 0 >= howMany ? "" : number + " " + lookAndSay(howMany - 1, lookAndSayV1(number, 0));
}
final String number = "1";
final String result = lookAndSay(10, number);
System.out.println(result);

Result:

1 11 21 1211 111221 312211 13112221 1113213211 31131211131221 13211311123113112211 

The method lookAndSayV1() can be re-written using only one return statement and a few conditional operations.

private static String lookAndSayV2(final String number, final int position)
{
  return number.length() == position ?
            String.valueOf(number
                          .length()) +
              number.charAt(0) :
            (number.charAt(0) == number.charAt(position) ?
                lookAndSayV2(number, position + 1) :
                String.valueOf(number
                              .substring(0, position)
                              .length()) +
                  number.charAt(0) +
                  lookAndSayV2(number
                            .substring(position), 0));
}

This works the same as the lookAndSayV1() method. The code would be more readable with readOff() method.

private static String readOff(final String digits)
{
  return String.valueOf(digits.length()) + digits.charAt(0);
}

private static String lookAndSayV3(final String number, final int position)
{
  return number.length() == position ?
            readOff(number) :
            (number.charAt(0) == number.charAt(position) ?
                lookAndSayV3(number, position + 1) :
                readOff(number
                      .substring(0, position)) +
                      lookAndSayV3(number
                                  .substring(position), 0));
}

public static String lookAndSay3(final int howMany, final String number)
{
  return 0 >= howMany ? "" : number + " " + lookAndSay3(howMany - 1, lookAndSayV3(number, 0));
}

If the numbers should be stored in a List object, it can be done like

public static void lookAndSayUsingList(final String number, final int howMany, final List<String> resultList)
{
  resultList.add(number);
  if (resultList.size() < howMany)
  {
    lookAndSayUsingList(lookAndSayV3(number, 0), howMany, resultList);
  }
}
final List<String> resultList = new ArrayList<String>();
lookAndSayUsingList(number, howMany, resultList);
System.out.println(resultList);

If you prefer having returned result,

private static List<String> lookAndSayUsingList2(final String number, final int howMany, final List<String> list)
{
  list.add(number);
  if (list.size() < howMany)
  {
    return lookAndSayUsingList2(lookAndSayV3(number, 0), howMany, list);
  }
  return Collections.unmodifiableList(new ArrayList<String>(list));
}

The last line which returns an unmodifiable list object should use a new ArrayList object instead of directly using list.
Just making list unmodifiableList is not enough as the caller of this method can still modify the given parameter list
e.g.) Just have Collections.unmodifiableList(list); will result in

final List<String> resultList = new ArrayList<String>();
resultList.add(number);
final List<String> result = lookAndSayUsingList2(resultList, howMany);
// result.add("test"); // <- this does not work! runtime exception!
resultList.add("test"); // <- yet this does!!!
// Now the result has "test" at the end although it's unmodifiable List.
// It was modified using resultList.

If you don’t want to pass a List object, create another method and use it with the lookAndSayUsingList2() method.

public static List<String> lookAndSayUsingList2(final String number, final int howMany)
{
  final List<String> list = new ArrayList<String>();
  return lookAndSayUsingList2(number, howMany, list);
}
System.out.println(lookAndSayUsingList2(number, howMany));

Finally, using a Function object.

public interface LookAndSayFunction
{
  void apply(String number, int howMany);
}
final List<String> resultListFromFunctionObject = new ArrayList<String>();
new LookAndSayFunction() {
  @Override
  public void apply(final String number, final int howMany)
  {
    resultListFromFunctionObject.add(number);
    if (resultListFromFunctionObject.size() < howMany)
    {
      apply(lookAndSayV3(number, 0), howMany);
    }
  }
}.apply(number, howMany);

System.out.println(resultListFromFunctionObject);

Don’t want to get a mutable List object staying outside the function?

public interface Function1<T, R>
{
  R apply(T input);
}

public interface Function2<T1, T2, R>
{
  R apply(T1 input1, T2 input2);
}
final Function2<String, Integer, List<String>> anotherFunction =
  new Function2<String, Integer, List<String>>() {
    @Override
    public List<String> apply(final String number, final Integer howMany)
    {
      return new Function<List<String>>() {
        @Override
        public List<String> apply()
        {
          final List<String> resultList = new ArrayList<String>();
          return new Function1<String, List<String>>() {
            @Override
            public List<String> apply(final String number)
            {
              resultList.add(number);
              if (resultList.size() < howMany.intValue())
              {
                return apply(lookAndSayV3(number, 0));
              }
              return Collections.unmodifiableList(resultList);
            }
          }.apply(number);
        }
      }.apply();
    }
  };

System.out.println(anotherFunction.apply(number, howMany));

Or currying can be used.

final Function1<Integer, Function1<String, List<String>>> lookAndSayWithCurrying =
new Function1<Integer, Function1<String, List<String>>>() {
  @Override
  public Function1<String, List<String>> apply(final Integer howMany)
  {
    return new Function1<String, List<String>>() {
      @Override
      public List<String> apply(final String number)
      {
        final List<String> resultList = new ArrayList<String>();
        return new Function1<String, List<String>>() {
          @Override
          public List<String> apply(final String number)
          {
            resultList.add(number);
            if (resultList.size() < howMany.intValue())
            {
              return apply(lookAndSayV3(number, 0));
            }
            return Collections.unmodifiableList(resultList);
          }
        }.apply(number);
      }
    };
  }
};
System.out.println(lookAndSayWithCurrying.apply(howMany)
        .apply(number));

The function can be reused.

final Function1<String, List<String>> lookAndSayToGet10Elements = lookAndSayWithCurrying.apply(10);
System.out.println(lookAndSayToGet10Elements.apply(number));
System.out.println(lookAndSayToGet10Elements.apply(number));
Result:
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]
final Function1<String, List<String>> lookAndSayToGet5Elements = lookAndSayWithCurrying.apply(5);
System.out.println(lookAndSayToGet5Elements.apply(number));
Result:
[1, 11, 21, 1211, 111221]
System.out.println(lookAndSayToGet5Elements.apply("111221"));
Result:
[111221, 312211, 13112221, 1113213211, 31131211131221]
System.out.println(lookAndSayToGet5Elements.apply("21"));
Result:
[21, 1211, 111221, 312211, 13112221]
System.out.println(lookAndSayToGet5Elements.apply("1"));
Result:
[1, 11, 21, 1211, 111221]

If you want to fix the number and get different numbers of elements as the results from the look and say function,

final Function1<String, Function1<Integer, List<String>>> lookAndSayWithCurryingAndNumberFixed =
  new Function1<String, Function1<Integer, List<String>>>() {
    @Override
    public Function1<Integer, List<String>> apply(final String number)
    {
      return new Function1<Integer, List<String>>() {
        @Override
        public List<String> apply(final Integer howMany)
        {
          final List<String> resultList = new ArrayList<String>();
          return new Function1<String, List<String>>() {
            @Override
            public List<String> apply(final String number)
            {
              resultList.add(number);
              if (resultList.size() < howMany.intValue())
              {
                return apply(lookAndSayV3(number, 0));
              }
              return Collections.unmodifiableList(resultList);
            }
          }.apply(number);
        }
      };
    }
  };
final Function1<Integer, List<String>> lookAndSayWithNumberFixed = lookAndSayWithCurryingAndNumberFixed.apply("1");
System.out.println(lookAndSayWithNumberFixed.apply(3));
System.out.println(lookAndSayWithNumberFixed.apply(5));
System.out.println(lookAndSayWithNumberFixed.apply(10));

Results:

[1, 11, 21]
[1, 11, 21, 1211, 111221]
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]

Here are all the examples.

Results:

Using LookAndReadUsingForLoop: 
String result1 = number;
System.out.print(result1 + " ");
for (int i = 1; i < howMany; i++)
{
  result1 = LookAndSayUsingForLoop(result1);
  System.out.print(result1 + " ");
}
1 11 21 1211 111221 312211 13112221 1113213211 31131211131221 13211311123113112211 
--------------------------------------------------------------------------------

Using lookAndSayV1: 
System.out.println(lookAndSay(howMany, number));
1 11 21 1211 111221 312211 13112221 1113213211 31131211131221 13211311123113112211 
--------------------------------------------------------------------------------

Using lookAndSaV2: 
System.out.println(lookAndSay2(howMany, number));
1 11 21 1211 111221 312211 13112221 1113213211 31131211131221 13211311123113112211 
--------------------------------------------------------------------------------

Using lookAndSaV3: 
System.out.println(lookAndSay3(howMany, number));
1 11 21 1211 111221 312211 13112221 1113213211 31131211131221 13211311123113112211 
--------------------------------------------------------------------------------

Using lookAndSayUsingList: 
final List<String> resultList = new ArrayList<String>();
lookAndSayUsingList(number, howMany, resultList);
System.out.println(resultList);
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]
--------------------------------------------------------------------------------

Using lookAndSayUsingList2: 
System.out.println(lookAndSayUsingList2(number, howMany, new ArrayList<String>()));
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]
--------------------------------------------------------------------------------

Using another lookAndSayUsingList2 (without passing List): 
System.out.println(lookAndSayUsingList2(number, howMany))
--------------------------------------------------------------------------------

Using Function object: 
final List<String> resultListFromFunctionObject = new ArrayList<String>();
new LookAndSayFunction() {
  @Override
  public void apply(final String number, final int howMany)
  {
    resultListFromFunctionObject.add(number);
    if (resultListFromFunctionObject.size() < howMany)
    {
      apply(lookAndSayV3(number, 0), howMany);
    }
  }
}.apply(number, howMany);
System.out.println(resultListFromFunctionObject);
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]
--------------------------------------------------------------------------------

Using Function object with returned List object: 
final Function2<String, Integer, List<String>> anotherFunction = new Function2<String, Integer, List<String>>() {
  @Override
  public List<String> apply(final String number, final Integer howMany)
  {
    return new Function<List<String>>() {
      @Override
      public List<String> apply()
      {
        final List<String> resultList = new ArrayList<String>();
        return new Function1<String, List<String>>() {
          @Override
          public List<String> apply(final String number)
          {
            resultList.add(number);
            if (resultList.size() < howMany.intValue())
            {
              return apply(lookAndSayV3(number, 0));
            }
            return Collections.unmodifiableList(resultList);
          }
        }.apply(number);
      }
    }.apply();
  }
};
System.out.println(anotherFunction.apply(number, howMany));
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]

System.out.println(anotherFunction.apply(number, 5));
[1, 11, 21, 1211, 111221]

System.out.println(anotherFunction.apply(number, 7));
[1, 11, 21, 1211, 111221, 312211, 13112221]
--------------------------------------------------------------------------------

Using currying (number of elements fixed): 
final Function1<Integer, Function1<String, List<String>>> lookAndSayWithCurrying =
  new Function1<Integer, Function1<String, List<String>>>() {
    @Override
    public Function1<String, List<String>> apply(final Integer howMany)
    {
      return new Function1<String, List<String>>() {
        @Override
        public List<String> apply(final String number)
        {
          final List<String> resultList = new ArrayList<String>();
          return new Function1<String, List<String>>() {
            @Override
            public List<String> apply(final String number)
            {
              resultList.add(number);
              if (resultList.size() < howMany.intValue())
              {
                return apply(lookAndSayV3(number, 0));
              }
              return Collections.unmodifiableList(resultList);
            }
          }.apply(number);
        }
      };
    }
  };
lookAndSayWithCurrying.apply(howMany)
    .apply(number);
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]

final Function1<String, List<String>> lookAndSayToGet10Elements = lookAndSayWithCurrying.apply(10);
System.out.println(lookAndSayToGet10Elements.apply(number));
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]

System.out.println(lookAndSayToGet10Elements.apply(number));
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]

System.out.println(lookAndSayToGet10Elements.apply(number));
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]


final Function1<String, List<String>> lookAndSayToGet5Elements = lookAndSayWithCurrying.apply(5);
System.out.println(lookAndSayToGet5Elements.apply(number));
[1, 11, 21, 1211, 111221]

System.out.println(lookAndSayToGet5Elements.apply(number));
[1, 11, 21, 1211, 111221]

System.out.println(lookAndSayToGet5Elements.apply(number));
[1, 11, 21, 1211, 111221]

System.out.println(lookAndSayToGet5Elements.apply("111221"));
[111221, 312211, 13112221, 1113213211, 31131211131221]

System.out.println(lookAndSayToGet5Elements.apply("21"));
[21, 1211, 111221, 312211, 13112221]

System.out.println(lookAndSayToGet5Elements.apply("1"));
[1, 11, 21, 1211, 111221]
--------------------------------------------------------------------------------

Using currying (number fixed): 
final Function1<String, Function1<Integer, List<String>>> lookAndSayWithCurryingAndNumberFixed =
  new Function1<String, Function1<Integer, List<String>>>() {
    @Override
    public Function1<Integer, List<String>> apply(final String number)
    {
      return new Function1<Integer, List<String>>() {
        @Override
        public List<String> apply(final Integer howMany)
        {
          final List<String> resultList = new ArrayList<String>();
          return new Function1<String, List<String>>() {
            @Override
            public List<String> apply(final String number)
            {
              resultList.add(number);
              if (resultList.size() < howMany.intValue())
              {
                return apply(lookAndSayV3(number, 0));
              }
              return Collections.unmodifiableList(resultList);
            }
          }.apply(number);
        }
      };
    }
  };
final Function1<Integer, List<String>> lookAndSayWithNumberFixed = lookAndSayWithCurryingAndNumberFixed.apply("1");
System.out.println(lookAndSayWithNumberFixed.apply(howMany));
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]

System.out.println(lookAndSayWithNumberFixed.apply(3));
[1, 11, 21]

System.out.println(lookAndSayWithNumberFixed.apply(5));
[1, 11, 21, 1211, 111221]

System.out.println(lookAndSayWithNumberFixed.apply(10));
[1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, 31131211131221, 13211311123113112211]

What’s new in new mQlicker

I’ve been developing mQlicker for approximately two years. Dr. Raban, Sverre and I co-founded a startup about two year ago and we started developing it. The first official release happened last February, and now we are about to release a new version of mQlicker. Before we do, I’d like to point out the new features and changes in the new one.

mQlicker is a audience response system (audience interaction system / classroom interaction system) which can give a voice to the audience. It can be used for classroom, presentation, lecture, survey, quiz, etc. It consists of two main UIs which are the user UI for those who want to get the responses from people and the respondent UI for those who respond.

What's new in new mQlicker

What’s new in new mQlicker

1. Respondent UI

1.1. Design Change in Respondent UI

OLD: Respondent UI

OLD: Respondent UI

The old version of the respondent UI for computers doesn’t look so pretty. The look is also too different from the one displayed on the mobile devices (Please see how it looks on iPhone).
The new one looks prettier and similar to the mobile one.

Respondent UI: iPhone

Respondent UI: iPhone

New Respondent UI

New Respondent UI

1.2. Page Breaks.

OLD: All qeustions on one page

OLD: All qeustions on one page


In the old version, there is no way to put a different number of question on one page. So all the questions are on a single page as you can see.

New Respondent UI with different number of question on each page.

New Respondent UI with different number of question on each page.


The new version has page break so it can have many pages with a different number of questions as you wish.
New Respondent UI with one question on one page.

New Respondent UI with one question on one page.

1.3. Optional Questions.

Old Respondent UI without optional questions

Old Respondent UI without optional questions


The old version does not support an optional questions which means all the questions are mandatory. Therefore, if you forget to answer any question, your answer cannot be submitted.

New Respondent UI with an optional question

New Respondent UI with an optional question


From the new version, optional questions can be created.

1.4. Missing Answer Indicator for Mandatory Questions.

Old Respondent UI with no missing answer indicator

Old Respondent UI with no missing answer indicator


There was no way to find the missing answers without checking each question carefully when you forgot to answer some questions.

New Respondent UI with a missing answer indicator

New Respondent UI with a missing answer indicator


The new one highlights it, so you can simple take care of those missing ones.

1.5. Other Answer

Old Respondent UI with no other answer

Old Respondent UI with no other answer


The multiple choice questions did not allow the respondent to answer anything other than the ones provided with the question.

New Respondent UI with other answer

New Respondent UI with other answer


However, the new version has other answer field so now you can get some other opinions than what you provided from the respondents.

1.6. Result is Visible to the Respondents.

Old Respondent UI with no result after submission

Old Respondent UI with no result after submission


Previously, the respondents can see the result of all the responses after submit their answers.

New Respondent UI with result after answer submission

New Respondent UI with result after answer submission


New Respondent UI with result after answer submission

New Respondent UI with result after answer submission


New Respondent UI with result after answer submission

New Respondent UI with result after answer submission


New Respondent UI with result after answer submission

New Respondent UI with result after answer submission


With new one, it is possible to see the result although it needs a little more improvement (the improved one will come soon).

2. User UI

Old User UI

Old User UI

New User UI

New User UI

2.1. Rich Text Editor

Please compare the new one with the old one. You could only have plain text without any formatting. Now, it is possible to format your text just like using a word processor.

2.2 Result Visible to Respondent

As already mentioned above, you can set the interaction to make the response result visible to the respondents once they submit their answers.

2.3. Other Answer

You can make the multiple choice questions have other answers with the label you want (Other? Something else?, etc).

2.4 Optional Question

Questions and be optional so not all of them are mandatory.

2.5. Page Breaks

You can easily set the number of questions per page by just clicking the page breaker bar to enable and disabled it.

2.6. Images in Question

Now you can upload an image file or set the location of the image to display it with the question.

User UI - Question with image

User UI – Question with image


User UI - Question with image

User UI – Question with image


User UI - Question with image

User UI – Question with image


Respondent UI - Question with image

Respondent UI – Question with image

2.7 Slide type question

Sometimes you only need to provide some text that you want your audience to read. Now you can have a slide type question which only displays the text you provide!

2.8. Running Session Indicator

New User UI has a running session indicator

New User UI has a running session indicator


The new one has a running session indicator icon on the interaction so you can easily recognise which one has any running sessions without expanding interaction.

OK, that’s it. There are still several minor things but not that big deal so I rather not talk about here.
I hope you enjoy the new mQlicker.

« Older posts Newer posts »

© 2026 Kevin's Blog

Theme by Anders Noren — Up ↑