Author: Nicholas Prado <nmprado@nzen.ws>
Date: Sat Dec 5 23:13:02 UTC 2020
Parent: 55c763b6ba38065a1a111e6a9370a9f2a476488e
Log message:
feat 200402 validates passports This only needed one regex, thankfully.
1: diff --git a/src/java/Exercise200402.java b/src/java/Exercise200402.java 2: new file mode 100644 3: index 0000000..55a3e1c 4: --- /dev/null 5: +++ b/src/java/Exercise200402.java 6: @@ -0,0 +1,273 @@ 7: + 8: +import java.io.IOException; 9: +import java.nio.file.Files; 10: +import java.nio.file.InvalidPathException; 11: +import java.nio.file.Path; 12: +import java.nio.file.Paths; 13: +import java.util.Collection; 14: +import java.util.HashSet; 15: +import java.util.LinkedList; 16: +import java.util.List; 17: +import java.util.Map; 18: +import java.util.regex.*; 19: +import java.util.Set; 20: +import java.util.TreeMap; 21: + 22: +public class Exercise200402 23: +{ 24: + 25: + public static void main( String args[] ) 26: + { 27: + final String here = "e20042.m "; 28: + if ( args.length < 1 ) 29: + { 30: + throw new RuntimeException( here +"add a filename argument" ); 31: + } 32: + String userSaysFile = args[ 0 ]; 33: + List<String> fileLines = new LinkedList<>(); 34: + try 35: + { 36: + Path where = Paths.get( userSaysFile ); 37: + fileLines = Files.readAllLines( where ); 38: + } 39: + catch ( IOException | InvalidPathException ie ) 40: + { 41: + System.err.println( here +"couldn't read file "+ userSaysFile +" because "+ ie ); 42: + return; 43: + } 44: + /* 45: + - interpretation of spec - 46: + */ 47: + int valid = 0; 48: + Collection<String> onePassport = new LinkedList<>(); 49: + int lineNum = 0; 50: + boolean parsing = false; 51: + Exercise200402 buh = new Exercise200402(); 52: + Pattern hexColor = Pattern.compile( "#[abcdef\\d]{6}" ); 53: + for ( String line : fileLines ) 54: + { 55: + if ( line.isEmpty() ) 56: + { 57: + lineNum += 1; 58: + if ( ! onePassport.isEmpty() ) 59: + { 60: + Exercise200402.Passport person = buh.new Passport( onePassport ); 61: + if ( person.valid( hexColor ) ) 62: + { 63: + valid += 1; 64: + System.out.println( "\t"+ person ); 65: + } 66: + } 67: + onePassport.clear(); 68: + continue; 69: + } 70: + else 71: + { 72: + onePassport.add( line ); 73: + } 74: + } 75: + if ( ! onePassport.isEmpty() ) 76: + { 77: + Exercise200402.Passport person = buh.new Passport( onePassport ); 78: + if ( person.valid( hexColor ) ) 79: + { 80: + valid += 1; 81: + System.out.println( "\t"+ person ); 82: + } 83: + } 84: + System.out.println( here +"input summed to "+ valid +" of "+ lineNum +" total" ); 85: + } 86: + 87: + 88: + private class Passport 89: + { 90: + String birthYear = ""; 91: + String issueYear = ""; 92: + String expirationYear = ""; 93: + String height = ""; 94: + String hairColor = ""; 95: + String eyeColor = ""; 96: + String passportId = ""; 97: + String countryId = ""; 98: + final String byr = "byr", 99: + iyr = "iyr", 100: + eyr = "eyr", 101: + hgt = "hgt", 102: + hcl = "hcl", 103: + ecl = "ecl", 104: + pid = "pid", 105: + cid = "cid"; 106: + 107: + public Passport( 108: + Collection<String> input 109: + ) { 110: + parse( input ); 111: + } 112: + private void parse( 113: + Collection<String> input 114: + ) { 115: + final String here = "e20012.pp.p "; 116: + for ( String line : input ) 117: + { 118: + String[] lineElements = line.split( " " ); 119: + for ( String element : lineElements ) 120: + { 121: + int colonInd = element.indexOf( ':' ); 122: + String aspect = element.substring( 0, colonInd ); 123: + String content = element.substring( colonInd +1 ); 124: + switch ( aspect ) 125: + { 126: + case byr : 127: + birthYear = content; 128: + break; 129: + case iyr : 130: + issueYear = content; 131: + break; 132: + case eyr : 133: + expirationYear = content; 134: + break; 135: + case hgt : 136: + height = content; 137: + break; 138: + case hcl : 139: + hairColor = content; 140: + break; 141: + case ecl : 142: + eyeColor = content; 143: + break; 144: + case pid : 145: + passportId = content; 146: + break; 147: + case cid : 148: + countryId = content; 149: + break; 150: + } 151: + } 152: + } 153: + } 154: + public boolean valid( 155: + Pattern hexColor 156: + ) { 157: + if ( birthYear.isEmpty() 158: + || issueYear.isEmpty() 159: + || expirationYear.isEmpty() 160: + || height.isEmpty() 161: + || hairColor.isEmpty() 162: + || eyeColor.isEmpty() 163: + || passportId.isEmpty() ) 164: + // || countryId.isEmpty(); // haha, hacking 165: + { 166: + // System.out.println( "v not full" ); 167: + return false; 168: + } 169: + else if ( ! clamp( birthYear, 1920, 2002 ) ) 170: + { 171: + // System.out.println( "v not birthyear "+ birthYear ); 172: + return false; 173: + } 174: + else if ( ! clamp( issueYear, 2010, 2020 ) ) 175: + { 176: + // System.out.println( "v not issueYear "+ issueYear ); 177: + return false; 178: + } 179: + else if ( ! clamp( expirationYear, 2020, 2030 ) ) 180: + { 181: + // System.out.println( "v not expirationYear "+ expirationYear ); 182: + return false; 183: + } 184: + else if ( ! eye() ) 185: + { 186: + // System.out.println( "v not eye "+ eyeColor ); 187: + return false; 188: + } 189: + else if ( ! height() ) 190: + { 191: + // System.out.println( "v not eye "+ eyeColor ); 192: + return false; 193: + } 194: + else if ( ! hexColor.matcher( hairColor ).find() ) 195: + { 196: + // System.out.println( "v not hair matcher "+ hairColor ); 197: + return false; 198: + } 199: + else if ( passportId.length() != 9 || ! clamp( passportId, 0, 999_999_999 ) ) 200: + { 201: + // System.out.println( "v not passport "+ passportId ); 202: + return false; 203: + } 204: + return true; 205: + } 206: + private boolean clamp( 207: + String asChars, int min, int max 208: + ) { 209: + try { 210: + int value = Integer.parseInt( asChars ); 211: + return value >= min && value <= max; 212: + } 213: + catch ( NumberFormatException nfe ) 214: + { 215: + return false; 216: + } 217: + } 218: + private boolean eye( 219: + ) { 220: + return eyeColor.equals( "amb" ) 221: + || eyeColor.equals( "blu" ) 222: + || eyeColor.equals( "brn" ) 223: + || eyeColor.equals( "gry" ) 224: + || eyeColor.equals( "grn" ) 225: + || eyeColor.equals( "hzl" ) 226: + || eyeColor.equals( "oth" ); 227: + } 228: + private boolean height( 229: + ) { 230: + if ( height.endsWith( "in" ) ) 231: + return clamp( height.substring( 0, height.length() -2 ), 59, 76 ); 232: + else if ( height.endsWith( "cm" ) ) 233: + return clamp( height.substring( 0, height.length() -2 ), 150, 193 ); 234: + else 235: + return false; 236: + } 237: + public String toString( 238: + ) { 239: + return ""/* 240: + "by"+ birthYear 241: + +" iy"+ issueYear 242: + +"\t ey"+ expirationYear 243: + +"\t ec_"+ eyeColor 244: + */ 245: + +"\t h "+ height.substring( 0, height.length() -2 ) +"_"+ height.substring( height.length() -2 ) 246: + /* 247: + +" pi"+ passportId 248: + +" _"+ hairColor 249: + */ ; 250: + } 251: + } 252: +} 253: + 254: + 255: + 256: + 257: + 258: + 259: + 260: + 261: + 262: + 263: + 264: + 265: + 266: + 267: + 268: + 269: + 270: + 271: + 272: + 273: + 274: + 275: + 276: + 277: + 278: + 279: + 280: diff --git a/src/res/20_04_2_example.txt b/src/res/20_04_2_example.txt 281: new file mode 100644 282: index 0000000..b526855 283: --- /dev/null 284: +++ b/src/res/20_04_2_example.txt 285: @@ -0,0 +1,26 @@ 286: +eyr:1972 cid:100 287: +hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926 288: + 289: +iyr:2019 290: +hcl:#602927 eyr:1967 hgt:170cm 291: +ecl:grn pid:012533040 byr:1946 292: + 293: +hcl:dab227 iyr:2012 294: +ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277 295: + 296: +hgt:59cm ecl:zzz 297: +eyr:2038 hcl:74454a iyr:2023 298: +pid:3556412378 byr:2007 299: + 300: +pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980 301: +hcl:#623a2f 302: + 303: +eyr:2029 ecl:blu cid:129 byr:1989 304: +iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm 305: + 306: +hcl:#888785 307: +hgt:164cm byr:2001 iyr:2015 cid:88 308: +pid:545766238 ecl:hzl 309: +eyr:2022 310: + 311: +iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719 312: \ No newline at end of file