]> Repositorios git - scryer-prolog.git/commitdiff
add least_time example
authorMark Thom <[email protected]>
Fri, 20 Mar 2020 02:42:11 +0000 (20:42 -0600)
committerMark Thom <[email protected]>
Fri, 20 Mar 2020 02:42:11 +0000 (20:42 -0600)
src/prolog/examples/least_time.pl [new file with mode: 0644]

diff --git a/src/prolog/examples/least_time.pl b/src/prolog/examples/least_time.pl
new file mode 100644 (file)
index 0000000..d6bd92b
--- /dev/null
@@ -0,0 +1,64 @@
+/*  least_time.pl
+ *
+ *  By Mark Thom, 2020
+ *
+ *  find_min_time/2 solves a problem sometimes posed in the first round
+ *  of Google interviews: given a time of day in 24 H format, what is the
+ *  lexographically least permutation of the time that is itself a
+ *  valid time in 24 H format?
+ *
+ *  Full generality is achieved using the reif library.
+ */
+
+:- module(least_time, [find_min_time/2,
+                      write_time_nl/1]).
+
+
+:- use_module(library(dcgs)).
+:- use_module(library(format)).
+:- use_module(library(reif)).
+
+
+permutation([], []).
+permutation([X|Xs], Ys) :-
+    permutation(Xs, Yss),
+    select(X, Ys, Yss).
+
+
+valid_time([H1,H2,M1,M2], T) :-
+    memberd_t(H1, [0,1,2], TH1),
+    memberd_t(H2, [0,1,2,3,4,5,6,7,8,9], TH2),
+    memberd_t(M1, [0,1,2,3,4,5], TM1),
+    memberd_t(M2, [0,1,2,3,4,5,6,7,8,9], TM2),
+    (  maplist(=(true), [TH1, TH2, TM1, TM2]) ->       
+       (  H1 =:= 2 ->
+         (  H2 =< 3 ->
+            T = true
+         ;  T = false
+         )
+       ;  T = true
+       )
+    ;  T = false
+    ).
+
+
+permuted_times(Time, PermutedTimes) :-
+    setof(P, permutation(Time, P), PermutedTimes0),
+    tfilter(valid_time, PermutedTimes0, PermutedTimes).
+
+
+find_min_time(Time, Min) :-
+    valid_time(Time, true),
+    permuted_times(Time, PermutedTimes),
+    find_min_time_(PermutedTimes, Time, Min).
+
+find_min_time_([], Min, Min).
+find_min_time_([Time|Times], MinSoFar, Min) :-
+    (  Time @< MinSoFar ->
+       find_min_time_(Times, Time, Min)
+    ;  find_min_time_(Times, MinSoFar, Min)
+    ).
+
+
+write_time_nl(Time) :-
+    format("\"~w~w:~w~w\"~n", Time).