import module java.xml; void main() throws Exception { var verses = loadVerses(); var cumalativeLength = 0; var versePositions = new TreeMap(); for (var verse : verses) { versePositions.put(cumalativeLength, verse); cumalativeLength += verse.text.length(); } var one_thirtieth = cumalativeLength / 30; for (int juzIndex = 0; juzIndex < 30; juzIndex++) { var firstVerseOfJuz = versePositions.ceilingEntry(one_thirtieth * juzIndex).getValue(); println((juzIndex + 1) + ". " + firstVerseOfJuz); } } List loadVerses() throws Exception { var quranBytes = Files.readAllBytes(Path.of("quran-simple-clean.xml")); var sha256Hex = HexFormat.of().formatHex(MessageDigest.getInstance("SHA256").digest(quranBytes)); if (!sha256Hex.equals("bc1cf471e8d9df2f265aae2de23810916dcbb70d6bb1c167453b1647ba1d54c7")) { throw new IllegalStateException("Qur'an XML file doesn't match"); } var builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); var document = builder.parse(new ByteArrayInputStream(quranBytes)); var verses = new ArrayList(); for (var suraNode : getChildren(document.getDocumentElement(), "sura")) { var surahNumber = Integer.parseInt(suraNode.getAttribute("index")); for (var ayaNode : getChildren(suraNode, "aya")) { var ayaNumber = Integer.parseInt(ayaNode.getAttribute("index")); verses.add(new Verse(surahNumber, ayaNumber, ayaNode.getAttribute("text"))); } } return verses; } List getChildren(Element element, String tagName) { return asList(element.getElementsByTagName(tagName)); } List asList(NodeList nodeList) { return new AbstractList<>() { @Override public int size() { return nodeList.getLength(); } @Override public Element get(int index) { return (Element)nodeList.item(index); } }; } record Verse(int surahNumber, int verseNumber, String text) { @Override public String toString() { return "(" + surahNumber + ":" + verseNumber + ") " + text; } }