
// LookAndSay.java
// Andrew Davison, ad@coe.psu.ac.th, April 2023

/* Generate the first n values in the '1' look-and-say sequence,
   and display the nth value as a vectorgram. 

   The '1' look-and-say sequence begins as follows:

    1, 11, 21, 1211, 111221, 312211, 13112221, 
    1113213211, 31131211131221, ... 

   To generate a new number read off the digits of the 
   previous number, counting the number of digits in groups 
   of the same digit.

   https://en.wikipedia.org/wiki/Look-and-say_sequence

   https://rosettacode.org/wiki/Look-and-say_sequence


   Usage:
     > compile LookAndSay.java
     > run LookAndSay <n>
   e.g.
     > run LookAndSay 14
*/

import java.util.*;


public class LookAndSay
{

  public static void main(String[] args)
  {
    if (args.length != 1) {
      System.out.println("Usage: run LookAndSay <n>");
      return;
    }
    int n = Math.abs(Nut.parseInt(args[0]));

    String numStr = "1";
    for (int i = 1; i < n; i++) {
      System.out.println(i + ". " + numStr);
      numStr = lookandSay(numStr);
    }
    System.out.println(n + ". " + numStr);


    // map 1-3 ==> 0-2
    /* This step isn't really necessary, but I wanted
       to duplicate the images shown in:
          "Wonders of Numbers", Clifford A. Pickover, OUP, 2001
          Chapter 55, Audioacfive Decay, p.134-138
    */
    char[] chs = numStr.toCharArray();
    for(int i=0; i < chs.length; i++) {
      if (Character.isDigit(chs[i]))
        chs[i] -= 1;
    }
    numStr = new String(chs);
    // System.out.println(numStr);

    Nut.vectorgram(3, numStr, 8); // 3 directions
  } /* main */


  public static String lookandSay(String numStr)
  {
    StringBuilder sb= new StringBuilder();

    char startCh = numStr.charAt(0);
    numStr = numStr.substring(1) + " ";
    int multiple = 1;

    for(char ch: numStr.toCharArray()) {
      if (ch != startCh) {
        sb.append(multiple + "" + startCh);
        multiple = 1;
        startCh = ch;
      }
      else
        multiple += 1;
    }
    return sb.toString();
  } /* lookandSay */




}  // end of LookAndSay class