Transpose Data before Rearrangement
【Question】
CONTEXT: I'm writing a program that fills a school timetable of 7 hours and 5 days based on the available teaching hours of the professors. The data of professors comes from a text file.
Main class:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Main{
static ArrayList<profesor>profesors = new ArrayList<profesor>();
static String timetable[][] = new String[7][5];
public static void main(String[]args) throws Exception{
timetable[0][0] = "lua"; timetable[0][1] = "maa"; timetable[0][2] = "mia"; timetable[0][3] = "jua"; timetable[0][4] = "via";
timetable[1][0] = "lub"; timetable[1][1] = "mab"; timetable[1][2] = "mib"; timetable[1][3] = "jub"; timetable[1][4] = "vib";
timetable[2][0] = "luc"; timetable[2][1] = "mac"; timetable[2][2] = "mic"; timetable[2][3] = "juc"; timetable[2][4] = "vic";
timetable[3][0] = "lud"; timetable[3][1] = "mad"; timetable[3][2] = "mid"; timetable[3][3] = "jud"; timetable[3][4] = "vid";
timetable[4][0] = "lue"; timetable[4][1] = "mae"; timetable[4][2] = "mie"; timetable[4][3] = "jue"; timetable[4][4] = "vie";
timetable[5][0] = "luf"; timetable[5][1] = "maf"; timetable[5][2] = "mif"; timetable[5][3] = "juf"; timetable[5][4] = "vif";
timetable[6][0] = "lug"; timetable[6][1] = "mag"; timetable[6][2] = "mig"; timetable[6][3] = "jug"; timetable[6][4] = "vig";
readList();
fillTimetable();
displayTimetable();
}
private static void readList() throws Exception {
FileReader file = new FileReader("list.txt");
BufferedReader reader=new BufferedReader(file);
String line =reader.readLine();
String lineSplit[]= new String[27];
while(line != null){
lineSplit = line.split("\\s+");
profesors.add(new profesor(lineSplit[0], lineSplit[1], new String[]{ lineSplit[2], lineSplit[3], lineSplit[4], lineSplit[5], lineSplit[6], lineSplit[7],lineSplit[8], lineSplit[9], lineSplit[10], lineSplit[11], lineSplit[12], lineSplit[13], lineSplit[14], lineSplit[15], lineSplit[16], lineSplit[17], lineSplit[18], lineSplit[19], lineSplit[20], lineSplit[21], lineSplit[22], lineSplit[23], lineSplit[24], lineSplit[25], lineSplit[26]}));
line = reader.readLine();
}
}
private static void fillTimetable() {
String[] materias = new String[13];
materias[0] = "Matematica";
materias[1] = "Apesca";
materias[2] = "NavegacionI";
materias[3] = "TecPesc";
materias[4] = "MeteorologiaI";
materias[5] = "ComunicacionesI";
materias[6] = "IngTecI";
materias[7] = "Supervivencia";
materias[8] = "ManiobraI";
materias[9] = "MaquinasI";
materias[10] = "EquiposElectronicos";
materias[11] = "PrimerosAux";
materias[12] = "CargaEstiva";
int counterMatematica = 1;
int counterApesca = 1;
int counterNavegacionI = 1;
int counterTecPesc = 1;
int counterMeteorologiaI = 1;
int counterComunicacionesI = 1;
int counterIngTecI = 1;
int counterSupervivencia = 1;
int counterManiobraI = 1;
int counterMaquinasI = 1;
int counterEquiposElectronicos = 1;
int counterPrimerosAux = 1;
int counterCargaEstiva = 1;
for(int a = 0, p = 0, i=0, k=0;i<34;p++, i++){
if(p == 6){//23
k++;
p = 0;
}
if (k==5){break;}
if (a==23){break;}
//i periods k days
for(int j=0;j<profesors.size();j++){
String[] ah = profesors.get(j).getAvalideHours();
String pname = profesors.get(j).getName();
String psubject = profesors.get(j).getSubject();
for(int y = 0; y<24;y++){
if(ah[y].equals(timetable[p][k]) ){
if(psubject.equals(materias[0])){
if(counterMatematica<=2){
timetable[p][k] = psubject + " " + pname;
counterMatematica++;
break;
}}
if(psubject.equals(materias[1])){
if(counterApesca<=3){
timetable[p][k] = psubject + " " + pname;
counterApesca++;
break;
}}
if(psubject.equals(materias[2])){
if(counterNavegacionI<=4){
timetable[p][k] = psubject + " " + pname;
counterNavegacionI++;
break;
}}
if(psubject.equals(materias[3])){
if(counterTecPesc<=2){
timetable[p][k] = psubject + " " + pname;
counterTecPesc++;
break;
}}
if(psubject.equals(materias[4])){
if(counterMeteorologiaI<=1){
timetable[p][k] = psubject + " " + pname;
counterMeteorologiaI++;
break;
}}
if(psubject.equals(materias[5])){
if(counterComunicacionesI<=1){
timetable[p][k] = psubject + " " + pname;
counterComunicacionesI++;
break;
}}
if(psubject.equals(materias[6])){
if(counterIngTecI<=2){
timetable[p][k] = psubject + " " + pname;
counterIngTecI++;
break;
}}
if(psubject.equals(materias[7])){
if(counterSupervivencia<=1){
timetable[p][k] = psubject + " " + pname;
counterSupervivencia++;
break;
}}
if(psubject.equals(materias[8])){
if(counterManiobraI<=3){
timetable[p][k] = psubject + " " + pname;
counterManiobraI++;
break;
}}
if(psubject.equals(materias[9])){
if(counterMaquinasI<=1){
timetable[p][k] = psubject + " " + pname;
counterMaquinasI++;
break;
}}
if(psubject.equals(materias[10])){
if(counterEquiposElectronicos<=1){
timetable[p][k] = psubject + " " + pname;
counterEquiposElectronicos++;
break;
}}
if(psubject.equals(materias[11])){
if(counterPrimerosAux<=1){
timetable[p][k] = psubject + " " + pname;
counterPrimerosAux++;
break;
}}
if(psubject.equals(materias[12])){
if(counterCargaEstiva<=1){
timetable[p][k] = psubject + " " + pname;
counterCargaEstiva++;
break;
}}
}
}
}
}
}
private static void displayTimetable() {
// TODO Auto-generated method stub
}
}
Professor class:
import java.util.Arrays;
public class profesor {
private String name;
private String subject;
private String[] avalidehours=new String[25];
public profesor(String string, String string2, String[] strings) {
name = string;
subject = string2;
avalidehours = strings;
}
public String toString(){
return name + subject + Arrays.toString(avalidehours);
}
public String getName(){
return name;
}
public String getSubject(){
return subject;
}
public String[] getAvalideHours(){
return avalidehours;
}
}
This is the text file:
Petitti Matematica mif mig vif vig ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ
Canales Apesca luc lud mac mad mic mid juc jud ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ
Lucero NavegacionI lub luc lud lue mab mac mad mae mib mic mid mie jub juc jud jue vib vic vid vie ññ ññ ññ ññ ññ
Bergamaschi TecPesc lua luf maa maf mia mif jua juf via vif ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ
Mazza MeteorologiaI mab mac jub juc ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ
Puebla ComunicacionesI lua lub luc lud maa mab mac mad mia mib mic mid jua jub juc jud via vib bic bid ññ ññ ññ ññ ññ
Chiatti IngTecI mib mic mid mie jub juc jud jue ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ
Jimenez Supervivencia maa mab jua jub ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ
Rubino ManiobraI mab mac mad mae maf mib mic mid mie mif ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ
Velasco MaquinasI vib vic vid vie vif ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ
Luceroo EquiposElectronicos lub luc lud lue mab mac mad mae mib mic mid mie jub juc jud jue vib vic vid vie ññ ññ ññ ññ ññ
Atenas PrimerosAux vib vic vid vie ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ
Fuster CargaEstiva lue luf lug mae maf mag mie mif mig jue juf jug vie vif vig ññ ññ ññ ññ ññ ññ ññ ññ ññ ññ
And this is the resulting timetable I got:
monday tuesday wednesday thursday friday
7 null null null null null
6 TecPesc ManiobraI Matematica CargaEstiva Matematica
5 NavegacionI ManiobraI EquiposElectronicos null null
4 Apesca NavegacionI ManiobraI null null
3 Apesca Apesca IngTecI MeteorologiaI PrimerosAux
2 NavegacionI NavegacionI IngTecI Supervivencia MaquinasI
1 TecPesc ComunicacionesI null null null
Problems:
I have two problems with the output:
1. I get 2 hours of the same subject in the same day but one is, for example, in hour 1 and the other at hour 6.
2. I get empty spaces in the middle of the day and that should not happen.
【Answer】
The key to creating a correct timetable is assigning professors properly during same time frame. The algorithm is like this. First, create a two-field 2D table (as A2 shows in the script below). professor field contains names of professors; and codeArray field contains lists of available teaching hours for professors. Second, create a time code table of 5 days * 6 hours according to the information you provide (A3). Third, loop over A3’s table to find professors from the codeArrays matching the current time code. Last, create a timetable (which have fields from Monday to Friday), populate the selected professors into it, or enter comma-separated professor combination strings.
It involves structured computations, multilevel loop and sequence searching. It’s very complicated to handle all these in Java. In this case, you can achieve the algorithm in SPL (Structured Process Language) in simple and easy-to-understand code:
A |
|
1 |
=file("d:\\source.txt").import(;" ") |
2 |
=A1.new(#2:professor,~.array().to(3,27).select(~!="ññ"):codeArray) |
3 |
=["lua","maa","mia","jua","via","lub","mab","mib","jub","vib", "luc","mac","mic","juc","vic","lud","mad","mid","jud","vid","lue","mae","mie","jue","vie", "luf","maf","mif","juf","vif", "lug","mag","mig","jug","vig"] |
4 |
=A3.(A2.select(codeArray.pos(A3.~)).(professor)) |
5 |
=create(monday,tuesday,wednesday,thursday,friday).record(A4.(~.concat@c())) |
A1: Import text file source.txt separated by spaces.
A2: Create a 2D table made up of professor field and codeArray field based on A1’s table. The former contains professor names, which is stored in A1’s 2nd column; and the latter contains time code lists of professors, which corresponds non-ññ data from column 3 to column 27 in A1.
A3: Create a time code table of 5 days * 6 hous.
A4: Loop over A3 to find professors from the codeArrays matching the current time code.
A5: Create a timetable (which have fields from Monday to Friday) and populate comma-separated professor combinations strings into it.
The SPL script is easily integrated with a Java application. See How to Call an SPL Script in Java.
SPL Official Website 👉 https://www.scudata.com
SPL Feedback and Help 👉 https://www.reddit.com/r/esProcSPL
SPL Learning Material 👉 https://c.scudata.com
SPL Source Code and Package 👉 https://github.com/SPLWare/esProc
Discord 👉 https://discord.gg/cFTcUNs7
Youtube 👉 https://www.youtube.com/@esProc_SPL