-
-
Save ferd/5d8c2997bb2b834af302e4856681d91f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%%% @doc [17/950] | |
%%% fill this with the sorrows of the fourth challenge | |
%%% @end | |
-module(day04). | |
-export([p1/0, p2/0]). | |
-export([valid/1, valid2/1]). | |
p1() -> | |
count_passwords(206938,679128, fun valid/1). | |
p2() -> | |
count_passwords(206938,679128, fun valid2/1). | |
count_passwords(A, B, F) -> | |
count_passwords(A, B, F, 0). | |
count_passwords(A, B, _Pred, N) when A > B -> N; | |
count_passwords(A, B, Pred, N) -> | |
case Pred(A) of | |
true -> count_passwords(A+1, B, Pred, N+1); | |
false -> count_passwords(A+1, B, Pred, N) | |
end. | |
valid(N) -> | |
valid(N, 10, undefined, false, true). | |
valid(_, _, _, _, false) -> | |
%% This clause is an optimization I thought of after the video was done | |
%% and cuts down run-time in half by bailing out early. | |
false; | |
valid(N, Div, undefined, Doubles, Incr) -> | |
{ok, D, NextDiv} = next_digit(N, Div), | |
valid(N, NextDiv, D, Doubles, Incr); | |
valid(N, Div, Last, Doubles, Incr) -> | |
case next_digit(N, Div) of | |
undefined -> | |
Doubles andalso Incr; | |
{ok, D, NextDiv} -> | |
valid(N, NextDiv, D, | |
Doubles orelse D =:= Last, | |
Incr andalso D =< Last) | |
end. | |
valid2(N) -> | |
valid2(N, 10, undefined, 0, false, true). | |
valid2(_, _, _, _, _, false) -> | |
%% This clause is an optimization I thought of after the video was done | |
%% and cuts down run-time in half by bailing out early. | |
false; | |
valid2(N, Div, undefined, _, Double, Incr) -> | |
{ok, D, NextDiv} = next_digit(N, Div), | |
valid2(N, NextDiv, D, 1, Double, Incr); | |
valid2(N, Div, Last, Seq, Double, Incr) -> | |
case next_digit(N, Div) of | |
undefined -> | |
(Double orelse Seq == 2) andalso Incr; | |
{ok, D, NextDiv} -> | |
NewSeq = if D =:= Last -> Seq+1; | |
D =/= Last -> 1 | |
end, | |
valid2(N, NextDiv, D, NewSeq, | |
Double orelse (Seq == 2 andalso NewSeq == 1), | |
Incr andalso D =< Last) | |
end. | |
%% @doc `Div' must start at 10. | |
next_digit(N, Div) when Div > N*10 -> undefined; | |
next_digit(N, Div) -> {ok, (N rem Div) div (Div div 10), Div*10}. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment