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
69f15321
Commit
69f15321
authored
Nov 27, 2020
by
Colin DAMON
Browse files
Kata implementation
parent
963409d6
Changes
3
Hide whitespace changes
Inline
Side-by-side
java-h2g2/src/main/java/fr/ippon/kata/h2g2/Book.java
0 → 100644
View file @
69f15321
package
fr.ippon.kata.h2g2
;
public
enum
Book
{
FIRST
,
SECOND
,
THIRD
,
FORTH
,
FIFTH
}
java-h2g2/src/main/java/fr/ippon/kata/h2g2/Shop.java
0 → 100644
View file @
69f15321
package
fr.ippon.kata.h2g2
;
import
static
java
.
util
.
stream
.
Collectors
.*;
import
java.math.BigDecimal
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.function.Function
;
import
java.util.function.Predicate
;
import
java.util.stream.Collectors
;
import
java.util.stream.IntStream
;
public
class
Shop
{
private
static
final
Map
<
Integer
,
Float
>
FACTORS
=
buildFactors
();
private
static
final
int
BOOK_PRICE
=
8
;
private
static
Map
<
Integer
,
Float
>
buildFactors
()
{
Map
<
Integer
,
Float
>
factors
=
new
HashMap
<>();
factors
.
put
(
5
,
0.75f
);
factors
.
put
(
4
,
0.80f
);
factors
.
put
(
3
,
0.90f
);
factors
.
put
(
2
,
0.95f
);
factors
.
put
(
1
,
1
f
);
factors
.
put
(
0
,
1
f
);
return
factors
;
}
public
static
float
buy
(
Book
...
books
)
{
Basket
basket
=
new
Basket
(
books
);
return
(
float
)
basket
.
getPacks
().
stream
().
map
(
packPrice
()).
reduce
(
BigDecimal
.
ZERO
,
BigDecimal:
:
add
).
floatValue
();
}
private
static
Function
<
Integer
,
BigDecimal
>
packPrice
()
{
return
count
->
BigDecimal
.
valueOf
(
BOOK_PRICE
*
count
*
FACTORS
.
get
(
count
));
}
private
static
final
class
Basket
{
private
final
Collection
<
Integer
>
packs
;
public
Basket
(
Book
...
books
)
{
packs
=
buildPacks
(
books
);
}
private
Collection
<
Integer
>
buildPacks
(
Book
[]
books
)
{
Map
<
Book
,
Integer
>
groupedBooks
=
groupBooks
(
books
);
List
<
Integer
>
packs
=
firstPackLevel
(
groupedBooks
);
return
optimizePacks
(
packs
);
}
private
Collection
<
Integer
>
optimizePacks
(
List
<
Integer
>
packs
)
{
int
threePack
=
countPackBySize
(
packs
,
3
);
int
fivePack
=
countPackBySize
(
packs
,
5
);
int
commonPacks
=
Math
.
min
(
fivePack
,
threePack
);
List
<
Integer
>
result
=
new
ArrayList
<>();
result
.
addAll
(
repeatPack
(
1
,
countPackBySize
(
packs
,
1
)));
result
.
addAll
(
repeatPack
(
2
,
countPackBySize
(
packs
,
2
)));
result
.
addAll
(
repeatPack
(
3
,
threePack
-
commonPacks
));
result
.
addAll
(
repeatPack
(
4
,
countPackBySize
(
packs
,
4
)
+
commonPacks
*
2
));
result
.
addAll
(
repeatPack
(
5
,
fivePack
-
commonPacks
));
return
result
;
}
private
List
<
Integer
>
repeatPack
(
int
packSize
,
int
packCount
)
{
return
IntStream
.
range
(
0
,
packCount
).
mapToObj
(
key
->
Integer
.
valueOf
(
packSize
)).
collect
(
Collectors
.
toList
());
}
private
int
countPackBySize
(
List
<
Integer
>
packs
,
int
size
)
{
return
(
int
)
packs
.
stream
().
filter
(
value
->
value
==
size
).
count
();
}
private
List
<
Integer
>
firstPackLevel
(
Map
<
Book
,
Integer
>
groupedBooks
)
{
List
<
Integer
>
packs
=
new
ArrayList
<>();
while
(
remainingBooks
(
groupedBooks
))
{
packs
.
add
(
groupedBooks
.
size
());
groupedBooks
=
groupedBooks
.
entrySet
().
stream
().
filter
(
booksRemaining
()).
collect
(
Collectors
.
toMap
(
Entry:
:
getKey
,
entry
->
entry
.
getValue
()
-
1
));
}
return
packs
;
}
private
boolean
remainingBooks
(
Map
<
Book
,
Integer
>
groupedBooks
)
{
return
!
groupedBooks
.
isEmpty
();
}
private
Predicate
<
Entry
<
Book
,
Integer
>>
booksRemaining
()
{
return
entry
->
entry
.
getValue
()
>
1
;
}
private
static
Map
<
Book
,
Integer
>
groupBooks
(
Book
...
books
)
{
return
Arrays
.
stream
(
books
)
.
collect
(
groupingBy
(
Function
.
identity
()))
.
entrySet
()
.
stream
()
.
collect
(
toMap
(
Entry:
:
getKey
,
entry
->
entry
.
getValue
().
size
()));
}
private
Collection
<
Integer
>
getPacks
()
{
return
packs
;
}
}
}
java-h2g2/src/test/java/fr/ippon/kata/h2g2/H2G2Test.java
0 → 100644
View file @
69f15321
package
fr.ippon.kata.h2g2
;
import
static
fr
.
ippon
.
kata
.
h2g2
.
Book
.*;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.*;
import
org.junit.jupiter.api.Test
;
class
H2G2Test
{
@Test
void
shouldBeFreeWithoutBooks
()
{
assertThat
(
Shop
.
buy
()).
isEqualTo
(
0
);
}
@Test
void
shouldPayFullPriceForOneBook
()
{
assertThat
(
Shop
.
buy
(
FIRST
)).
isEqualTo
(
8
);
}
@Test
void
shouldPayFullPriceForTwoFirstBooks
()
{
assertThat
(
Shop
.
buy
(
FIRST
,
FIRST
)).
isEqualTo
(
8
*
2
);
}
@Test
void
shouldGetFivePercentOffWithTwoBooksFromSeries
()
{
assertThat
(
Shop
.
buy
(
FIRST
,
SECOND
)).
isEqualTo
(
8
*
2
*
0.95f
);
}
@Test
void
shouldGetTenPercentOffWithThreeBooksFromSeries
()
{
assertThat
(
Shop
.
buy
(
THIRD
,
FORTH
,
FIFTH
)).
isEqualTo
(
8
*
3
*
0.90f
);
}
@Test
void
shouldGetTwentyPercentOffWithFourBooksFromSeries
()
{
assertThat
(
Shop
.
buy
(
SECOND
,
THIRD
,
FORTH
,
FIFTH
)).
isEqualTo
(
8
*
4
*
0.80f
);
}
@Test
void
shouldGetTwentyFivePercentOffWithFiveBooksFromSeries
()
{
assertThat
(
Shop
.
buy
(
FIRST
,
SECOND
,
THIRD
,
FORTH
,
FIFTH
)).
isEqualTo
(
8
*
5
*
0.75f
);
}
@Test
void
shouldGetBestPossibleReductionForFirstFirstSecond
()
{
assertThat
(
Shop
.
buy
(
FIRST
,
FIRST
,
SECOND
)).
isEqualTo
(
8
+
(
8
*
2
*
0.95f
));
}
@Test
void
shouldGetBestPossibleReductionForBasketOfHell
()
{
assertThat
(
Shop
.
buy
(
FIRST
,
FIRST
,
SECOND
,
SECOND
,
THIRD
,
THIRD
,
FORTH
,
FIFTH
)).
isEqualTo
(
2
*
8
*
4
*
0.8f
);
}
}
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