John Perry
John Perry

Reputation: 3

Java language conversion

this is code I am using to translate some text to English from pig Latin and vice versa. Except the fromPig method does not seem to be working correctly.

Expected output: "java is a wonderful programming language, and object oriented programming is the best thing after sliced bread."

Got output: "avajavajay isyisyay ayay onderfulwonderfulway ogrammingprogrammingpray..."

So you can see that the words are inside but I need to get rid of the other parts on the ends of the word. Please try to provide code if you can fixing my mistake.

public class PigLatin {
    public String fromPig(String pigLatin) {
        String res="";
        String[] data=pigLatin.split(" ");
        for(String word : data)
        res += toEnglishWord(word) + " ";
        return res;
    }

    private String toEnglishWord(String word) {
        char punc=0;
        for(int i=0;i<word.length();i++) {
            if(word.charAt(i)=='.'||word.charAt(i)==','||word.charAt(i)==';'||word.charAt(i)=='!') {
                punc=word.charAt(i);
                break;
            }
        }
        word=word.replace(punc + "","");
        String[] data=word.split("-");
        String firstPart=data[0];
        String lastPart=data[0];
        if(lastPart.equals("yay"))
        return firstPart + punc ;
        else {
            lastPart=lastPart.replace("ay","");
            return(lastPart+firstPart+punc);
        }
    }
}

This is the class that needs to execute the sentences.

public class Convert {
    public static void main(String args []) {
        PigLatin demo=new PigLatin();
        String inEnglish="Now is the winter of our discontent " +
            "Made glorious summer by this sun of York; " +
            "And all the clouds that lour'd upon our house " +
            "In the deep bosom of the ocean buried.";
        String inPigLatin="avajay isyay ayay onderfulway ogrammingpray " +
            "anguagelay, andyay objectyay orientedyay ogrammingpray " +
            "isyay hetay estbay ingthay afteryay icedslay eadbray.";
        System.out.println(demo.toPig(inEnglish));
        System.out.println(demo.fromPig(inPigLatin));
    }
}      

Basically the english sentence needs to be converted to pig latin and the pig latin sentence needs to be converted to english.

English to piglatin is being done correctly. But piglatin to english is not.

Upvotes: 0

Views: 407

Answers (2)

user
user

Reputation: 7604

It's impossible to convert Pig Latin to English just like that - you need a human, a program with access to a database of words, or a neural net or something that's been trained on a database of words. Without that, you will only be convert words back to English if they originally started with a vowel or their first letter was a consonant and their second letter was a vowel. Otherwise, there is literally no way for a machine to tell where the word originally ended.

For that reason, you need to make a method that outputs a List<String> like this:

public static List<String> allPossibleSentences(String inPigLatin) {
    List<String> pigWords = Arrays.asList(inPigLatin.split("\\s"));
    //You can also use a method reference here
    List<List<String>> possSentences = cartesianProduct(pigWords.stream().map(word -> possibleEnglishWords(word)).collect(Collectors.toList()));
    return possSentences.stream().map(words -> String.join(" ", words)).collect(Collectors.toList());
  }

But since you need a fromPig method in your code, you can write it like this:

public static String fromPig(String inPigLatin) {
  return allPossibleSentences(inPigLatin).get(0);
}

This is overpowered, compared to the answer by Arvind Kumar Avinash, since it generates all permutations, but I feel it will be more useful if you have the most likely case and all possible sentences.

Example main method

public static void main(String[] args) {
    String inPigLatin="avajay isyay ayay onderfulway ogrammingpray " +
            "anguagelay andyay objectyay orientedyay ogrammingpray " +
            "isyay hetay estbay ingthay afteryay icedslay eadbray";
    System.out.println(fromPig(inPigLatin));
    inPigLatin = "icedslay eadbray";
    System.out.println("\nExpected = sliced bread, gotten = " + fromPig(inPigLatin));
    System.out.println(String.join("\n", allPossibleSentences(inPigLatin)));
}

Example output

java is a wonderful rogrammingp language and object oriented rogrammingp is the best hingt after liceds readb

Expected = sliced bread, gotten = liceds readb
liceds readb
liceds bread
liceds dbrea
sliced readb
sliced bread //Here you have the right answer, but your method has no way to confirm that
sliced dbrea
dslice readb
dslice bread
dslice dbrea

Your PigLatin class now

import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;

class PigLatin {

//Put your toPig and toPigWord methods here (I couldn't find them)

public static String fromPig(String inPigLatin) {
  return allPossibleSentences(inPigLatin).get(0);
}

/* Methods that above code relies on */
private static List<String> possibleEnglishWords(String word) {
    List<String> possibilities = new ArrayList<>();
    if (word.matches(".*yay$")) {
      possibilities.add(word.substring(0, word.length() - 3));
      return possibilities;
    }

    //Remove the pig latin part
    word = word.substring(0, word.length() - 2);
    for (int i = word.length() - 1; i >= 0; i --) {
      if (isVowel(word.charAt(i))) break;
      if (word == "anguagel") System.out.println("char = " + word.charAt(i));
      possibilities.add(word.substring(i) + word.substring(0, i));
    }
    return possibilities;
  }

  //Put all the words together
  public static List<List<String>> cartesianProduct(List<List<String>> possWordArr) {
      if (possWordArr.size() == 1) {
        List<List<String>> possSentencesAsWords = new ArrayList<>();
        possSentencesAsWords.add(possWordArr.get(0));
        return possSentencesAsWords;
      }
      return _cartesianProduct(0, possWordArr);
  }

  //Helper method
  private static List<List<String>> _cartesianProduct(int index, List<List<String>> possWordArr) {
      List<List<String>> ret = new ArrayList<>();
      if (index == possWordArr.size()) {
          ret.add(new ArrayList<>());
      } else {
          for (String word : possWordArr.get(index)) {
              for (List<String> words : _cartesianProduct(index + 1, possWordArr)) {
                  words.add(0, word);
                  ret.add(words);
              }
          }
      }
      return ret;
  }

  private static boolean isVowel(char c) {
    c = toUppercase(c);
    switch (c) {
      case 'A':
      case 'E':
      case 'I':
      case 'O':
      case 'U':
        return true;
      default:
        return false;
    }
  }

  private static char toUppercase(char c) {
    if (c >= 'a') return (char) (((char) (c - 'a')) + 'A');
    else return c;
  }
}

Upvotes: 0

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79085

Address the following problems:

  1. Convert the text to a single case (e.g. lowercase) because you are comparing with only lowercase vowels.
  2. The code inside your toEnglishWord is not correct. Change it as follows:
private String toEnglishWord(String word) {
    char punc = 0;
    for (int i = 0; i < word.length(); i++) {
        if (word.charAt(i) == '.' || word.charAt(i) == ',' || word.charAt(i) == ';' || word.charAt(i) == '!') {
            punc = word.charAt(i);
            break;
        }
    }
    // Trim the word, and remove all punctuation chars
    word = word.trim().replaceAll("[\\.,;!]", "");
    String english = "";

    // If the word ends with 'yay', remove 'yay' from its end. Otherwise, if the
    // word ends with 'ay', form the word as (3rd last letter + characters from
    // beginning till the 4th last character). Also, add the punctuation at the end
    if (word.length() > 2 && word.substring(word.length() - 3).equals("yay")) {
        english = word.substring(0, word.length() - 3) + String.valueOf(punc);
    } else if (word.length() > 3 && word.substring(word.length() - 2).equals("ay")) {
        english = word.substring(word.length() - 3, word.length() - 2) + word.substring(0, word.length() - 3)
                + String.valueOf(punc);
    }
    return english;
}

Demo:

class PigLatin {
    public String toPig(String english) {
        String res = "";
        String[] data = english.toLowerCase().split(" ");
        for (String word : data)
            res += toPigWord(word) + " ";
        return res;
    }

    public String fromPig(String pigLatin) {
        String res = "";
        String[] data = pigLatin.toLowerCase().split(" ");
        for (String word : data)
            res += toEnglishWord(word) + " ";
        return res;
    }

    private String toPigWord(String word) {
        char punc = 0;
        for (int i = 0; i < word.length(); i++) {
            if (word.charAt(i) == '.' || word.charAt(i) == ',' || word.charAt(i) == ';' || word.charAt(i) == '!') {
                punc = word.charAt(i);
                break;
            }
        }
        word = word.replace(punc + "", "");
        if (isFirstLetterVowel(word))
            return (word + "yay" + punc);
        else {
            int indexVowel = indexOfFirstVowel(word);
            String after = word.substring(indexVowel);
            String before = word.substring(0, indexVowel);
            return (after + before + "ay" + punc);
        }
    }

    private String toEnglishWord(String word) {
        char punc = 0;
        for (int i = 0; i < word.length(); i++) {
            if (word.charAt(i) == '.' || word.charAt(i) == ',' || word.charAt(i) == ';' || word.charAt(i) == '!') {
                punc = word.charAt(i);
                break;
            }
        }
        // Trim the word, and remove all punctuation chars
        word = word.trim().replaceAll("[\\.,;!]", "");
        String english = "";

        // If the word ends with 'yay', remove 'yay' from its end. Otherwise, if the
        // word ends with 'ay' and form the word as (3rd last letter + characters from
        // beginning to the 4th last character). Also, add the punctuation at the end
        if (word.length() > 2 && word.substring(word.length() - 3).equals("yay")) {
            english = word.substring(0, word.length() - 3) + String.valueOf(punc);
        } else if (word.length() > 3 && word.substring(word.length() - 2).equals("ay")) {
            english = word.substring(word.length() - 3, word.length() - 2) + word.substring(0, word.length() - 3)
                    + String.valueOf(punc);
        }
        return english;
    }

    private boolean isFirstLetterVowel(String word) {
        String temp = word.toLowerCase();
        return (temp.charAt(0) == 'a' || temp.charAt(0) == 'e' || temp.charAt(0) == 'i' || temp.charAt(0) == 'o'
                || temp.charAt(0) == 'u');
    }

    private int indexOfFirstVowel(String word) {
        int index = 0;
        String temp = word.toLowerCase();
        for (int i = 0; i < temp.length(); i++) {
            if (temp.charAt(i) == 'a' || temp.charAt(i) == 'e' || temp.charAt(i) == 'i' || temp.charAt(i) == 'o'
                    || temp.charAt(i) == 'u') {
                index = i;
                break;
            }
        }
        return index;
    }
}

class Main {
    public static void main(String[] args) {
        PigLatin pigLatin = new PigLatin();
        String str = "hello world! good morning! honesty is a good policy.";
        String strToPigLatin = pigLatin.toPig(str);
        System.out.println(strToPigLatin);
        System.out.println(pigLatin.fromPig(strToPigLatin));
    }
}

Output:

ellohay orldway! oodgay orningmay! onestyhay isyay ayay oodgay olicypay. 
hello world! good morning! honesty is a good policy. 

Note: With the current logic, there is no way to convert a word like ogrammingpray (which is the piglatin of programming) back to programming.

Upvotes: 1

Related Questions