You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
65 lines
1.7 KiB
65 lines
1.7 KiB
First parse with regex to make into a list |
|
#+begin_src emacs-lisp :results none |
|
(require 'dash) |
|
(with-temp-buffer |
|
(insert-file-contents "input") |
|
(goto-char (point-min)) |
|
(replace-regexp "\\([a-z]+\\),?" "\"\\1\"") |
|
(goto-char (point-min)) |
|
(insert "(setq avail '(") |
|
(end-of-line) |
|
(insert ") patterns '(") |
|
(goto-char (point-max)) |
|
(insert "))") |
|
|
|
(eval-buffer)) |
|
|
|
#+end_src |
|
|
|
Here we define a caching advice; this implementation works under the |
|
assumption that the original function accepts one string as a |
|
parameter |
|
#+begin_src emacs-lisp :results none |
|
(setq cache nil) |
|
|
|
(defun cached (fun r) |
|
(if (assoc-string r cache) (cdr (assoc-string r cache)) |
|
(let ((result (funcall fun r))) |
|
(push (cons r result) cache) |
|
result))) |
|
#+end_src |
|
|
|
Here we recur down the tree obtained by splitting with all possible |
|
prefixes. This is for part 1 |
|
#+begin_src emacs-lisp |
|
(defun suffixes (word) |
|
(--map (substring word (length it)) (--filter (string-prefix-p it word) avail))) |
|
|
|
(defun possible-p (word) |
|
(or (string= "" word) |
|
(-any #'possible-p (suffixes word)))) |
|
|
|
(advice-add #'possible-p :around 'cached) |
|
|
|
(length (-filter #'possible-p patterns)) |
|
#+end_src |
|
|
|
#+RESULTS: |
|
: 226 |
|
|
|
This is for part 2; |
|
#+begin_src emacs-lisp |
|
(defun suffixes (word) |
|
(--map (substring word (length it)) (--filter (string-prefix-p it word) avail))) |
|
|
|
(defun possible-arrangements (word) |
|
(if (string= "" word) 1 |
|
(-sum (-map #'possible-arrangements (suffixes word))))) |
|
|
|
(advice-add #'possible-arrangements :around #'cached) |
|
|
|
(-sum (-map #'possible-arrangements patterns)) |
|
#+end_src |
|
|
|
#+RESULTS: |
|
: 601201576113503
|
|
|