Skip to content

Instantly share code, notes, and snippets.

@bufferings
Created May 26, 2014 17:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bufferings/ede1e50332cf743849fb to your computer and use it in GitHub Desktop.
Save bufferings/ede1e50332cf743849fb to your computer and use it in GitHub Desktop.
“レッスンは何曜日?”をJavaでやってみた。なんというか・・・Javaっぽい?
package example;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import java.util.EnumMap;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeSet;
import org.junit.Test;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
public class WhatDayIsMyLesson {
public String execute(String input) {
List<Applicant> applicants = ApplicantLoader.from(input);
return LessonScheduler.arrange(applicants).toResultString();
}
public static class ApplicantLoader {
public static List<Applicant> from(String input) {
return new ApplicantLoader().applicantsOf(input);
}
private List<Applicant> applicantsOf(String input) {
return FluentIterable.from(Splitter.on('|').split(input))
.transform(new Function<String, Applicant>() {
@Override
public Applicant apply(String input) {
return applicantOf(input);
}
}).toList();
}
private Applicant applicantOf(String input) {
List<String> splits = Splitter.on('_').splitToList(input);
int id = Integer.parseInt(splits.get(0));
List<LessonDay> requestDays = requestDaysOf(splits.get(1));
return new Applicant(id, requestDays);
}
private List<LessonDay> requestDaysOf(String input) {
return FluentIterable.from(Lists.charactersOf(input))
.transform(new Function<Character, LessonDay>() {
@Override
public LessonDay apply(Character input) {
return LessonDay.of(input);
}
}).toList();
}
}
public enum LessonDay {
MONDAY('1'), TUESDAY('2'), WEDNESDAY('3'), THURSDAY('4'), FRIDAY('5');
private final char value;
private LessonDay(char value) {
this.value = value;
}
public char getValue() {
return value;
}
public static LessonDay of(char value) {
for (LessonDay day : values()) {
if (day.value == value) {
return day;
}
}
throw new IllegalArgumentException();
}
}
public static class Applicant {
private final int id;
private final List<LessonDay> requestDays;
private Applicant(int id, List<LessonDay> requestDays) {
this.id = id;
this.requestDays = ImmutableList.copyOf(requestDays);
}
public int getId() {
return id;
}
public LessonDay getRequestDay(int index) {
return requestDays.get(index);
}
}
public static class LessonScheduler {
private EnumMap<LessonDay, Lesson> lessons = new EnumMap<>(LessonDay.class);
public static LessonScheduler arrange(List<Applicant> applicants) {
LessonScheduler scheduler = new LessonScheduler();
final LinkedList<Applicant> acceptedApplicants = new LinkedList<>();
for (int i = 0; i < 5; i++) {
for (Applicant applicant : applicants) {
if (acceptedApplicants.contains(applicant)) {
continue;
}
boolean accepted = scheduler.accept(applicant.getRequestDay(i),
applicant);
if (accepted) {
acceptedApplicants.add(applicant);
}
}
}
return scheduler;
}
private boolean accept(LessonDay day, Applicant applicant) {
return getLessonFor(day).accept(applicant);
}
private Lesson getLessonFor(LessonDay day) {
if (!lessons.containsKey(day)) {
lessons.put(day, new Lesson(day));
}
return lessons.get(day);
}
public String toResultString() {
return Joiner.on('|').join(
FluentIterable.from(lessons.values()).transform(
new Function<Lesson, String>() {
@Override
public String apply(Lesson input) {
return input.toResultString();
}
}));
}
}
public static class Lesson {
private static final int CAPACITY = 4;
private final LessonDay day;
private TreeSet<Integer> acceptedApplicantIds = new TreeSet<>();
public Lesson(LessonDay day) {
this.day = day;
}
public boolean accept(Applicant applicant) {
if (isFull()) {
return false;
}
acceptedApplicantIds.add(applicant.getId());
return true;
}
private boolean isFull() {
return acceptedApplicantIds.size() >= CAPACITY;
}
public String toResultString() {
return day.getValue() + "_" + Joiner.on(':').join(acceptedApplicantIds);
}
}
@Test
public void testAll() {
/* 0 */test("1_12345", "1_1");
/* 1 */test("30_32451", "3_30");
/* 2 */test("1_12345|2_12345", "1_1:2");
/* 3 */test("3_12345|2_12345|1_12345", "1_1:2:3");
/* 4 */test("1_23415|2_12435|3_42135", "1_2|2_1|4_3");
/* 5 */test("1_23415|2_12435|3_42135|4_31245|5_53124",
"1_2|2_1|3_4|4_3|5_5");
/* 6 */test("40_12345|21_12345|3_12345|61_12345|10_12345",
"1_3:21:40:61|2_10");
/* 7 */test(
"1_23415|2_12435|3_42135|4_54321|5_12345|6_13524|7_42351|8_31254|9_24513|10_12345",
"1_2:5:6:10|2_1:9|3_8|4_3:7|5_4");
/* 8 */test(
"1_54321|2_54321|3_54321|4_54321|5_54321|6_54321|7_54321|8_54321|9_54321|10_54321|11_54321|12_54321|13_54321|14_54321|15_54321|16_54321|17_54321|18_54321|19_54321|20_54321|21_54321",
"1_17:18:19:20|2_13:14:15:16|3_9:10:11:12|4_5:6:7:8|5_1:2:3:4");
/* 9 */test(
"1_34152|2_23514|3_41325|4_15342|5_45312|6_35124|7_21453|8_52431|9_13245|10_54123|11_13245",
"1_4:9:11|2_2:7|3_1:6|4_3:5|5_8:10");
/* 10 */test(
"92_41532|58_14325|40_25413|5_45132|71_35124|23_13452|60_35241|77_31542|53_13542|72_12354",
"1_23:53:58:72|2_40|3_60:71:77|4_5:92");
/* 11 */test(
"55_24153|91_24531|9_12543|41_34215|72_15423|44_42531|6_42351|79_15243|21_35412|31_52413|74_24135|83_31254|33_35421|84_53421|89_53241|16_32415|36_15234|92_34521|62_12345|14_23415|40_23415|88_43251|52_45213|77_32154|59_53241",
"1_9:36:72:79|2_14:55:74:91|3_21:33:41:83|4_6:44:52:88|5_31:59:84:89");
/* 12 */test("62_52341|57_12543|6_52431", "1_57|5_6:62");
/* 13 */test("71_52143|16_24531|7_14523|99_41532|37_54123|72_43251",
"1_7|2_16|4_72:99|5_37:71");
/* 14 */test(
"29_23541|37_32145|28_34215|59_15234|27_35142|77_51324|23_31245|62_15342|46_23145|47_41523|7_52341|68_12534|5_43251",
"1_59:62:68|2_29:46|3_23:27:28:37|4_5:47|5_7:77");
/* 15 */test(
"17_34152|89_23451|49_43152|61_32541|15_25413|63_34521|16_31452|8_41352|54_41532|42_34521|53_12453|88_34251|4_21453|93_34512|18_25134|67_25134|50_14523",
"1_50:53|2_4:15:18:89|3_16:17:61:63|4_8:42:49:54|5_67:88:93");
/* 16 */test(
"10_23145|80_32154|41_41532|20_31254|96_45231|50_23514|28_12534|13_31425|52_12435|88_23541|69_34215|46_53241|22_24531|53_42351|84_15243|97_14352|8_24135|59_13524",
"1_28:52:84:97|2_10:22:50:88|3_13:20:69:80|4_8:41:53:96|5_46:59");
/* 17 */test(
"90_21453|58_43521|69_42351|12_51432|34_14352|23_45321|77_35421|71_24531|95_24153|49_13254|9_45231|78_21534|15_43512|54_41532|52_54321|59_24513|57_41532|75_35214|24_12435|97_52341|39_12453|53_12435|48_51234|32_51234",
"1_24:34:39:49|2_71:78:90:95|3_15:54:75:77|4_9:23:58:69|5_12:48:52:97");
/* 18 */test(
"99_42153|44_42351|88_14523|58_51234|82_14523|15_25134|74_25134|77_32145|60_13425|46_34512|45_12345|63_32145|98_15234|96_41325|38_43521|61_14325|26_21543|37_24153|40_31542|57_23415|97_12543|30_45231|56_41523|22_34512|83_31245|86_35412|16_54321",
"1_45:60:82:88|2_15:26:37:74|3_40:46:63:77|4_38:44:96:99|5_16:30:58:98");
/* 19 */test(
"55_13524|64_41523|40_23451|99_25314|65_21453|69_31524|77_45231|62_51432|21_13542|81_13452|66_21534|33_41352|5_52314|90_31452|6_42135|93_42351|84_43125|54_45213|76_21453|19_52134|50_21435|61_13542|30_35421|43_25431|24_25341|31_15234|39_15243|20_51423|67_13524",
"1_21:55:61:81|2_40:65:66:99|3_30:69:84:90|4_6:33:64:77|5_5:19:20:62");
}
void test(String input, String expected) {
assertThat(execute(input), is(expected));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment