about summary refs log tree commit diff
path: root/users/Profpatsch/advent-of-code
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2021-03-01T22·35+0100
committerProfpatsch <mail@profpatsch.de>2021-03-01T23·26+0000
commit851e32cfe759b553c75be02bc9c04ce7eeef8286 (patch)
tree08d52bb5f4bbe790758054dc4f05efda433c2d36 /users/Profpatsch/advent-of-code
parent4effd421cd62784aa8fcb29b06b810afe602f957 (diff)
feat(users/Profpatsch/advent-of-code): 2020 day 04 r/2261
Change-Id: I422e43f33737ef4d8e250634fa68926ae340206a
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2580
Tested-by: BuildkiteCI
Reviewed-by: Profpatsch <mail@profpatsch.de>
Diffstat (limited to 'users/Profpatsch/advent-of-code')
-rw-r--r--users/Profpatsch/advent-of-code/2020/04/main.py104
1 files changed, 104 insertions, 0 deletions
diff --git a/users/Profpatsch/advent-of-code/2020/04/main.py b/users/Profpatsch/advent-of-code/2020/04/main.py
new file mode 100644
index 0000000000..36bbed7146
--- /dev/null
+++ b/users/Profpatsch/advent-of-code/2020/04/main.py
@@ -0,0 +1,104 @@
+import sys
+import itertools
+import re
+import pprint
+
+def get_entry(fd):
+    def to_dict(keyval):
+        res = {}
+        for (k, v) in keyval:
+            assert k not in res
+            res[k] = v
+        return res
+
+    res = []
+    for line in fd:
+        if line == "\n":
+            yield to_dict(res)
+            res = []
+        else:
+            line = line.rstrip()
+            items = line.split(" ")
+            for i in items:
+                res.append(i.split(":", maxsplit=2))
+
+def val_hgt(hgt):
+    m = re.fullmatch(r'([0-9]+)(cm|in)', hgt)
+    if m:
+        (i, what) = m.group(1,2)
+        i = int(i)
+        if what == "cm":
+            return i >= 150 and i <= 193
+        elif what == "in":
+            return i >= 59 and i <= 76
+        else:
+            return False
+
+required_fields = [
+    { "name": "byr",
+      "check": lambda s: int(s) >= 1920 and int(s) <= 2002
+    },
+    { "name": "iyr",
+      "check": lambda s: int(s) >= 2010 and int(s) <= 2020
+    },
+    { "name": "eyr",
+      "check": lambda s: int(s) >= 2020 and int(s) <= 2030,
+    },
+    { "name": "hgt",
+      "check": lambda s: val_hgt(s)
+    },
+    { "name": "hcl",
+      "check": lambda s: re.fullmatch(r'#[0-9a-f]{6}', s)
+    },
+    { "name": "ecl",
+      "check": lambda s: re.fullmatch(r'amb|blu|brn|gry|grn|hzl|oth', s)
+    },
+    { "name": "pid",
+      "check": lambda s: re.fullmatch(r'[0-9]{9}', s)
+    },
+    # we should treat it as not required
+    # "cid"
+]
+
+required_dict = {}
+for f in required_fields:
+    required_dict[f["name"]] = f
+
+def validate(keyval):
+    if keyval[0] not in required_dict:
+        return { "ok": keyval }
+    if required_dict[keyval[0]]["check"](keyval[1]):
+        return { "ok": keyval }
+    else:
+        return { "validation": keyval }
+
+def all_fields(entry):
+    missing = []
+    for r in required_dict:
+        if r not in e:
+            missing.append(r)
+    if missing == []:
+        return { "ok": entry }
+    else:
+        return { "missing": missing }
+
+count=0
+for e in get_entry(sys.stdin):
+    a = all_fields(e)
+    if a.get("ok", False):
+        res = {}
+        bad = False
+        for keyval in e.items():
+            r = validate(keyval)
+            if r.get("validation", False):
+                bad = True
+            res[keyval[0]] = r
+        if bad:
+            pprint.pprint({ "validation": res })
+        else:
+            pprint.pprint({ "ok": e })
+            count = count+1
+    else:
+        pprint.pprint(a)
+
+print(count)