-
Notifications
You must be signed in to change notification settings - Fork 1
/
restore_ip_addresses.pl
60 lines (49 loc) · 1.6 KB
/
restore_ip_addresses.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
% Not optimal because of fold usage
% https://leetcode.com/problems/restore-ip-addresses/
foldr(_, [], Out, Out) :- !.
foldr(Binary, [X | Xs], Acc, Out) :-
foldr(Binary, Xs, Acc, O1),
call(Binary, X, O1, Out).
atom_digits(NumStr, Digits) :-
atom_chars(NumStr, DigitsChars),
foldr([C,Acc,[D | Acc]]>>atom_number(C,D), DigitsChars, [], Digits).
concat_numbers(X, Y, Z) :-
number_string(X, XS),
number_string(Y, YS),
string_concat(XS, YS, ZS),
number_string(Z, ZS).
valid_ip_num(X) :-
X >= 0,
X < 256,
integer(X).
dots(D, [], [D]).
dots(D, ['.' | Acc], [D, '.' | Acc]).
dots(D, [C | Acc], [CD | Acc]) :-
C \== '.',
concat_numbers(C, D, CD),
valid_ip_num(CD).
dots(D, [C | Acc], ['.', CD | Acc]) :-
C \== '.',
dots_count(Acc, E),
E < 3,
concat_numbers(C, D, CD),
valid_ip_num(CD).
add_dot(X, A, A) :- X \== '.', !.
add_dot(_, A, B) :- B is A + 1.
dots_count(Xs, Y) :- foldl(add_dot, Xs, 0, Y).
combine_to_string(IP, IPStr) :- combine_to_string(IP, '', IPStr).
combine_to_string([], Acc, Acc).
combine_to_string(['.' | IP], Acc, IPStr) :-
!, string_concat(Acc, '.', NewAcc),
combine_to_string(IP, NewAcc, IPStr).
combine_to_string([D | IP], Acc, IPStr) :-
number_string(D, DStr),
string_concat(Acc, DStr, NewAcc),
combine_to_string(IP, NewAcc, IPStr).
restore_ip_addresses(IpStr, IPStr) :-
atom_digits(IpStr, IpDigits),
foldl(dots, IpDigits, [], IPRev),
dots_count(IPRev, 3),
\+ IPRev = ['.' | _],
reverse(IPRev, IP),
combine_to_string(IP, IPStr).