Skip to content

Commit

Permalink
FSM.Matched
Browse files Browse the repository at this point in the history
  • Loading branch information
Pastor committed Dec 24, 2024
1 parent 5b233fa commit c618c8d
Show file tree
Hide file tree
Showing 8 changed files with 278 additions and 58 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ vol8/5.utext
vol8/5.fsm.utext
vol8/5.rgx.utext
duplicate.csv
.output
6 changes: 6 additions & 0 deletions vol8/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,10 @@
<name>vol8</name>
<description>Модуль №8. Конечные автоматы</description>

<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
</project>
94 changes: 94 additions & 0 deletions vol8/src/main/java/ru/mifi/practice/vol8/process/Information.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package ru.mifi.practice.vol8.process;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

public abstract class Information {
private static final Set<String> ACCEPTING = Set.of("КАБО-01-23", "КАБО-02-23", "КВБО-01-23");

private record Student(String code, String group, String fio) implements Comparable<Student> {
@Override
public int compareTo(Student o) {
return code.compareTo(o.code);
}
}

public static void main(String[] args) throws IOException {
String fileName = "C:\\Users\\Pastor\\Downloads\\courseid_9687_participants.csv";
String output = ".output";
Statistics statistics = new Statistics.Default("E:\\GitHub\\algorithms-and-data-structures-2024\\students");
final Map<String, Statistics.Information> scanned = statistics.scan();
Map<String, List<Student>> students = new HashMap<>();
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String line;
br.readLine();
while ((line = br.readLine()) != null) {
String[] values = line.split(",");
String io = values[0].trim().replaceAll("\"", "");
String f = values[1].trim().replaceAll("\"", "");
String code = values[2].trim().toUpperCase(Locale.ROOT).replaceAll("\"", "")
.replace('К', 'K').replace('Л', 'L').replace('Р', 'R');
String group = values[4].trim().toUpperCase(Locale.ROOT).replaceAll("\"", "");
if (!code.isEmpty()) {
String reduced = String.join(".", io.chars().filter(Character::isUpperCase).mapToObj(Character::toString).reduce("",
(a, b) -> a + b, (a, b) -> a + b).split("")) + ".";
students.computeIfAbsent(group, k -> new ArrayList<>())
.add(new Student(code, group, String.format("%s %s", f, reduced)));
}
}
}
students.forEach((k, v) -> v.sort(Student::compareTo));
File outputFile = new File(output);
outputFile.mkdirs();
for (Map.Entry<String, List<Student>> entry : students.entrySet()) {
if (!ACCEPTING.contains(entry.getKey())) {
continue;
}
try (BufferedWriter bw = new BufferedWriter(new FileWriter(new File(outputFile, entry.getKey() + ".adoc")))) {
bw.append(":stem: latexmath").append("\n\n");
bw.append("= `").append(entry.getKey()).append("`\n").append("\n");
bw.append("**Данные: общее количество файлов / общее количество уникальных строк / из них дублей**").append("\n").append("\n");
bw.append("[cols=\"^1m,^2m,3m,^3m,1m,3m\"]").append("\n");
bw.append("|===").append("\n");
bw.append("|№|Код|ФИО|Данные|Зачет|Примечание").append("\n");
int count = 1;
for (Student student : entry.getValue()) {
bw.append("\n");
bw.append("|").append(String.valueOf(count++)).append("\n");
bw.append("|**").append(student.code).append("**\n");
bw.append("|").append(student.fio).append("\n");
Statistics.Information information = scanned.get(student.code.toUpperCase(Locale.ROOT));
if (information != null) {
bw.append("|").append(String.valueOf(information.files())).append("/")
.append(String.valueOf(information.lines())).append("/")
.append(String.valueOf(information.duplicates()))
.append("\n");
bw.append("|").append("\n");
if (information.lines() / 2 < information.duplicates()) {
bw.append("|дубли").append("\n");
} else {
bw.append("|").append("\n");
}
} else {
bw.append("|").append("\n");
bw.append("|").append("\n");
bw.append("|").append("\n");
}
}
bw.append("\n");
bw.append("|===").append("\n");
}
}
System.out.println("Всего уникальных строк: " + statistics.uniqueLines().size());
}
}
91 changes: 91 additions & 0 deletions vol8/src/main/java/ru/mifi/practice/vol8/process/Statistics.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package ru.mifi.practice.vol8.process;

import com.google.common.hash.HashCode;
import com.google.common.hash.Hashing;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Stream;

public interface Statistics {
Map<String, Information> scan() throws IOException;

Set<String> uniqueLines();

record Information(int files, long lines, long duplicates) {

}

final class Default implements Statistics {
private final Set<String> lines = new HashSet<>();
private final File root;

public Default(String filePath) {
this.root = new File(filePath);
}

@Override
public Set<String> uniqueLines() {
return lines;
}

@Override
public Map<String, Information> scan() throws IOException {
File[] files = root.listFiles(File::isDirectory);
if (files == null) {
return Map.of();
}
Map<String, Information> map = new HashMap<>();
for (File file : files) {
String name = file.getName();
var information = scan(file);
map.put(name.toUpperCase(Locale.ROOT), information);
}
return map;
}

private Information scan(File file) throws IOException {
AtomicInteger files = new AtomicInteger(0);
AtomicLong duplicates = new AtomicLong(0);
Set<String> uniqueLines = new HashSet<>();
try (Stream<Path> stream = Files.walk(file.toPath())) {
stream.filter(Files::isRegularFile).filter(path -> path.toString().toLowerCase(Locale.ROOT).endsWith(".java"))
.forEach(path -> {
files.getAndIncrement();
parse(path, duplicates, uniqueLines);
});
}
return new Information(files.get(), uniqueLines.size(), duplicates.get());
}

private void parse(Path path, AtomicLong duplicates, Set<String> uniqueLines) {
try (var reader = Files.newBufferedReader(path)) {
reader.lines().map(String::trim).map(line -> line.toLowerCase(Locale.ROOT))
.filter(line -> line.length() > 2)
.filter(line -> !line.startsWith("import") && !line.startsWith("class") && !line.contains("main("))
.forEach(line -> {
HashCode hashCode = Hashing.sha512().hashString(line, StandardCharsets.UTF_8);
String hash = hashCode.toString();
if (uniqueLines.contains(hash)) {
duplicates.incrementAndGet();
} else {
uniqueLines.add(hash);
this.lines.add(hash);
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
40 changes: 28 additions & 12 deletions vol8/src/main/java/ru/mifi/practice/vol8/regexp/machine/Input.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ static Input of(String text) {

Marker mark();

void reset(Marker marker);
default void reset(Marker marker) {
reset(marker.pos());
}

void reset(int pos);

Optional<Character> peek();

Expand All @@ -20,55 +24,67 @@ static Input of(String text) {

boolean hasNext();

int index();

record Marker(int pos) {
}

final class StringInput implements Input {
private final char[] chars;
private int it;
private int index;

public StringInput(String text) {
this.chars = text.toCharArray();
}

private StringInput(char[] chars, int it) {
this.chars = chars;
this.it = it;
this.index = it;
}

@Override
public Marker mark() {
return new Marker(it);
return new Marker(index);
}

@Override
public void reset(Marker marker) {
it = marker.pos();
public void reset(int pos) {
index = pos;
}

@Override
public Optional<Character> peek() {
if (it >= chars.length) {
if (index >= chars.length) {
return Optional.empty();
}
return Optional.of(chars[it]);
return Optional.of(chars[index]);
}

@Override
public void next() {
if (it < chars.length) {
it++;
if (index < chars.length) {
index++;
}
}

@Override
public Input copy() {
return new StringInput(chars, it);
return new StringInput(chars, index);
}

@Override
public boolean hasNext() {
return it < chars.length;
return index < chars.length;
}

@Override
public int index() {
return index;
}

@Override
public String toString() {
return index + ":" + peek().orElse(' ');
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ public Machine(Tree tree) {
@Override
public boolean match(String text) {
Input input = new Input.StringInput(text);
return match(state, input);
return match(state, input).ok();
}

private static boolean match(State state, Input input) {
private static State.Match match(State state, Input input) {
if (state.accept(input)) {
return state.match(input);
}
return false;
return new State.Match(false, input.copy());
}
}
}
Loading

0 comments on commit c618c8d

Please sign in to comment.