Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
twitch
live-coding-fr
Commits
5e958cca
Commit
5e958cca
authored
Sep 06, 2021
by
Colin DAMON
Browse files
Markov chain implementation
parent
d1e372d0
Changes
9
Hide whitespace changes
Inline
Side-by-side
.gitlab-ci.yml
View file @
5e958cca
...
...
@@ -40,3 +40,4 @@ include:
-
local
:
"
/java-diamond/.gitlab-ci.yml"
-
local
:
"
/diamond-ts/.gitlab-ci.yml"
-
local
:
"
/java-memoizers/.gitlab-ci.yml"
-
local
:
"
/markov-chain/.gitlab-ci.yml"
markov-chain/.gitlab-ci.yml
0 → 100644
View file @
5e958cca
package-markov-chain
:
variables
:
PROJECT_FOLDER
:
"
markov-chain"
extends
:
.java
only
:
refs
:
-
master
-
merge_requests
changes
:
-
"
.gitlab-common-ci.yml"
-
"
markov-chain/**/*"
markov-chain/README.md
0 → 100644
View file @
5e958cca
# Markov Chain
Découverte du kata
[
Markov Chain
](
https://codingdojo.org/kata/MarkovChain/
)
-
**Auteurs**
: Anthony REY et Colin DAMON
-
**Date**
: 06/09/2021
-
**Langage**
: Java
-
**Niveau**
: Moyen
-
**Replay**
:
[
Twitch
](
https://www.twitch.tv/videos/1140906031
)
markov-chain/pom.xml
0 → 100644
View file @
5e958cca
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<version>
1.0.0
</version>
<groupId>
fr.ippon.kata
</groupId>
<artifactId>
java-parent
</artifactId>
<relativePath>
../java-parent
</relativePath>
</parent>
<version>
1.0.0-SNAPSHOT
</version>
<artifactId>
markov-chain
</artifactId>
<name>
MarkovChain
</name>
<developers>
<developer>
<email>
arey@ippon.fr
</email>
<name>
Anthony REY
</name>
</developer>
<developer>
<email>
cdamon@ippon.fr
</email>
<name>
Colin DAMON
</name>
</developer>
</developers>
</project>
markov-chain/src/main/java/fr/ippon/markov/MarkovChain.java
0 → 100644
View file @
5e958cca
package
fr.ippon.markov
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
public
class
MarkovChain
{
private
final
Map
<
String
,
WordStats
>
stats
=
new
ConcurrentHashMap
<>();
public
void
learn
(
String
text
)
{
String
[]
words
=
text
.
split
(
" "
);
for
(
int
i
=
0
;
i
<
words
.
length
-
1
;
i
++)
{
String
current
=
words
[
i
];
String
next
=
words
[
i
+
1
];
append
(
current
,
next
);
}
}
private
void
append
(
String
current
,
String
next
)
{
stats
.
computeIfAbsent
(
current
.
toLowerCase
(),
this
::
newWordStats
)
.
add
(
next
);
}
private
WordStats
newWordStats
(
String
dummy
)
{
return
new
WordStats
();
}
public
WordStats
stats
(
String
word
)
{
return
stats
.
getOrDefault
(
word
.
toLowerCase
(),
new
WordStats
());
}
public
Map
<
String
,
WordStats
>
stats
()
{
return
stats
;
}
}
markov-chain/src/main/java/fr/ippon/markov/Stat.java
0 → 100644
View file @
5e958cca
package
fr.ippon.markov
;
public
record
Stat
(
String
word
,
float
percentage
)
{
}
markov-chain/src/main/java/fr/ippon/markov/WordStats.java
0 → 100644
View file @
5e958cca
package
fr.ippon.markov
;
import
java.util.Collection
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.atomic.AtomicInteger
;
public
class
WordStats
{
private
final
AtomicInteger
size
=
new
AtomicInteger
();
private
final
Map
<
String
,
AtomicInteger
>
stats
=
new
ConcurrentHashMap
<>();
public
void
add
(
String
word
)
{
size
.
incrementAndGet
();
stats
.
computeIfAbsent
(
word
,
key
->
new
AtomicInteger
())
.
incrementAndGet
();
}
public
Collection
<
Stat
>
get
()
{
return
stats
.
entrySet
()
.
stream
()
.
map
(
entry
->
new
Stat
(
entry
.
getKey
(),
entry
.
getValue
()
.
floatValue
()
/
size
.
floatValue
()))
.
toList
();
}
}
markov-chain/src/test/java/fr/ippon/markov/MarkovChainTest.java
0 → 100644
View file @
5e958cca
package
fr.ippon.markov
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.*;
import
java.util.Map
;
import
org.junit.jupiter.api.Test
;
class
MarkovChainTest
{
private
final
MarkovChain
markov
=
new
MarkovChain
();
@Test
void
shouldGetStatsForOneWord
()
{
markov
.
learn
(
"Les"
);
assertThat
(
markov
.
stats
(
"Les"
)
.
get
()).
isEmpty
();
}
@Test
void
shoulGetStatsForTwoWords
()
{
markov
.
learn
(
"Les hommes"
);
assertThat
(
markov
.
stats
(
"Les"
)
.
get
()).
containsExactly
(
stat
(
"hommes"
,
1
f
));
}
@Test
void
shoulGetStatsWithMultipleFollowers
()
{
markov
.
learn
(
"Les hommes les plus grands"
);
assertThat
(
markov
.
stats
(
"Les"
)
.
get
()).
containsExactly
(
stat
(
"hommes"
,
0.5f
),
new
Stat
(
"plus"
,
0.5f
));
assertThat
(
markov
.
stats
(
"hommes"
)
.
get
()).
containsExactly
(
stat
(
"les"
,
1
f
));
}
@Test
void
shoulGetStats
()
{
markov
.
learn
(
"Les hommes les plus grands"
);
assertThatStats
(
markov
.
stats
()).
hasWord
(
"les"
)
.
withStat
(
"hommes"
,
0.5f
)
.
withStat
(
"plus"
,
0.5f
)
.
and
()
.
hasWord
(
"hommes"
)
.
withStat
(
"les"
,
1
f
);
}
private
static
Stat
stat
(
String
word
,
float
stat
)
{
return
new
Stat
(
word
,
stat
);
}
private
static
StatsAsserter
assertThatStats
(
Map
<
String
,
WordStats
>
stats
)
{
return
new
StatsAsserter
(
stats
);
}
private
static
class
StatsAsserter
{
private
final
Map
<
String
,
WordStats
>
stats
;
public
StatsAsserter
(
Map
<
String
,
WordStats
>
stats
)
{
this
.
stats
=
stats
;
}
public
WordStatAsserter
hasWord
(
String
word
)
{
assertThat
(
stats
).
containsKey
(
word
);
return
new
WordStatAsserter
(
stats
.
get
(
word
),
this
);
}
}
private
static
class
WordStatAsserter
{
private
final
WordStats
wordStats
;
private
final
StatsAsserter
source
;
public
WordStatAsserter
(
WordStats
wordStats
,
StatsAsserter
source
)
{
this
.
wordStats
=
wordStats
;
this
.
source
=
source
;
}
public
WordStatAsserter
withStat
(
String
word
,
float
percent
)
{
float
result
=
wordStats
.
get
()
.
stream
()
.
filter
(
stat
->
stat
.
word
()
.
equals
(
word
))
.
findFirst
()
.
orElseThrow
(
AssertionError:
:
new
)
.
percentage
();
assertThat
(
result
).
isEqualTo
(
percent
);
return
this
;
}
public
StatsAsserter
and
()
{
return
source
;
}
}
}
readme.md
View file @
5e958cca
...
...
@@ -44,6 +44,7 @@ Un kata de code est un petit exercice pensé pour s'entrainer jusqu'à maitriser
-
[
Tennis Refactoring kata
](
/tennis/refactoring
)
-
[
Puzzles
](
java-puzzles
)
-
[
Diamond
](
java-diamond
)
-
[
Markov chain
](
markov-chain
)
### Énervé
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment